Class: Melos::Struct::PrivateMessage

Inherits:
Base
  • Object
show all
Defined in:
lib/melos/struct/structs.rb

Overview

6.3

Constant Summary collapse

STRUCT =
[
  [:group_id, :vec],
  [:epoch, :uint64],
  [:content_type, :uint8],
  [:authenticated_data, :vec],
  [:encrypted_sender_data, :vec],
  [:ciphertext, :vec]
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#deserialize_select_elem_with_context, #initialize, #raw

Constructor Details

This class inherits a constructor from Melos::Struct::Base

Instance Attribute Details

#authenticated_dataObject (readonly)

Returns the value of attribute authenticated_data.



811
812
813
# File 'lib/melos/struct/structs.rb', line 811

def authenticated_data
  @authenticated_data
end

#ciphertextObject (readonly)

Returns the value of attribute ciphertext.



811
812
813
# File 'lib/melos/struct/structs.rb', line 811

def ciphertext
  @ciphertext
end

#content_typeObject (readonly)

Returns the value of attribute content_type.



811
812
813
# File 'lib/melos/struct/structs.rb', line 811

def content_type
  @content_type
end

#encrypted_sender_dataObject (readonly)

Returns the value of attribute encrypted_sender_data.



811
812
813
# File 'lib/melos/struct/structs.rb', line 811

def encrypted_sender_data
  @encrypted_sender_data
end

#epochObject (readonly)

Returns the value of attribute epoch.



811
812
813
# File 'lib/melos/struct/structs.rb', line 811

def epoch
  @epoch
end

#group_idObject (readonly)

Returns the value of attribute group_id.



811
812
813
# File 'lib/melos/struct/structs.rb', line 811

def group_id
  @group_id
end

Class Method Details

.create(group_id:, epoch:, content_type:, authenticated_data:, encrypted_sender_data:, ciphertext:) ⇒ Object



821
822
823
824
825
826
827
828
829
830
# File 'lib/melos/struct/structs.rb', line 821

def self.create(group_id:, epoch:, content_type:, authenticated_data:, encrypted_sender_data:, ciphertext:)
  new_instance = self.allocate
  new_instance.instance_variable_set(:@group_id, group_id)
  new_instance.instance_variable_set(:@epoch, epoch)
  new_instance.instance_variable_set(:@content_type, content_type)
  new_instance.instance_variable_set(:@authenticated_data, authenticated_data)
  new_instance.instance_variable_set(:@encrypted_sender_data, encrypted_sender_data)
  new_instance.instance_variable_set(:@ciphertext, ciphertext)
  new_instance
end

.private_content_aad_impl(gid, ep, ct, ad) ⇒ Object



844
845
846
# File 'lib/melos/struct/structs.rb', line 844

def self.private_content_aad_impl(gid, ep, ct, ad)
  Melos::Vec.from_string(gid) + [ep].pack('Q>') + [ct].pack('C') + Melos::Vec.from_string(ad)
end

.protect(authenticated_content, suite, secret_tree, sender_data_secret, padding_size) ⇒ Object



848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
# File 'lib/melos/struct/structs.rb', line 848

def self.protect(authenticated_content, suite, secret_tree, sender_data_secret, padding_size)
  leaf_index = authenticated_content.content.sender.leaf_index
  content_type = authenticated_content.content.content_type
  reuse_guard = SecureRandom.random_bytes(4)
  key, nonce, generation = Melos::SecretTree::ratchet_and_get(suite, content_type, secret_tree, leaf_index)
  new_nonce = apply_nonce_reuse_guard(nonce, reuse_guard)

  private_message_content_plain = serialize_private_message_content(authenticated_content.content, authenticated_content.auth, padding_size)
  aad = private_content_aad_impl(
    authenticated_content.content.group_id,
    authenticated_content.content.epoch,
    authenticated_content.content.content_type,
    authenticated_content.content.authenticated_data)
  private_message_content_ciphertext = Melos::Crypto.aead_encrypt(suite, key, new_nonce, aad, private_message_content_plain)

  sender_data_plain = Melos::Struct::SenderData.create(
    leaf_index: leaf_index,
    generation: generation,
    reuse_guard: reuse_guard
  )
  sd_aad = sender_data_aad_impl(
    authenticated_content.content.group_id,
    authenticated_content.content.epoch,
    authenticated_content.content.content_type)
  sender_data_key   = Melos::Crypto.sender_data_key(suite, sender_data_secret, private_message_content_ciphertext)
  sender_data_nonce = Melos::Crypto.sender_data_nonce(suite, sender_data_secret, private_message_content_ciphertext)
  sender_data_ciphertext = Melos::Crypto.aead_encrypt(suite, sender_data_key, sender_data_nonce, sd_aad, sender_data_plain.raw)

  create(
    group_id: authenticated_content.content.group_id,
    epoch: authenticated_content.content.epoch,
    content_type: authenticated_content.content.content_type,
    authenticated_data: authenticated_content.content.authenticated_data,
    encrypted_sender_data: sender_data_ciphertext,
    ciphertext: private_message_content_ciphertext
  )
end

.sender_data_aad_impl(gid, ep, ct) ⇒ Object



836
837
838
# File 'lib/melos/struct/structs.rb', line 836

def self.sender_data_aad_impl(gid, ep, ct)
  Melos::Vec.from_string(gid) + [ep].pack('Q>') + [ct].pack('C')
end

Instance Method Details

#private_content_aadObject



840
841
842
# File 'lib/melos/struct/structs.rb', line 840

def private_content_aad
  self.class.private_content_aad_impl(group_id, epoch, content_type, authenticated_data)
end

#sender_data_aadObject



832
833
834
# File 'lib/melos/struct/structs.rb', line 832

def sender_data_aad
  self.class.sender_data_aad_impl(group_id, epoch, content_type)
end

#unprotect(suite, secret_tree, sender_data_secret) ⇒ Object



886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
# File 'lib/melos/struct/structs.rb', line 886

def unprotect(suite, secret_tree, sender_data_secret)
  sender_data = decrypt_sender_data(suite, sender_data_secret)
  key, nonce, _ = Melos::SecretTree.ratchet_until_and_get(suite, content_type, secret_tree, sender_data.leaf_index, sender_data.generation)
  new_nonce = self.class.apply_nonce_reuse_guard(nonce, sender_data.reuse_guard)
  stream = StringIO.new(Melos::Crypto.aead_decrypt(suite, key, new_nonce, private_content_aad, ciphertext))
  pmc = Melos::Struct::PrivateMessageContent.new_with_content_type(stream, content_type)

  fc = Melos::Struct::FramedContent.create(
    group_id: group_id,
    epoch: epoch,
    sender: Melos::Struct::Sender.create_member(sender_data.leaf_index),
    authenticated_data: authenticated_data,
    content_type: content_type,
    content: pmc.content
  )

  Melos::Struct::AuthenticatedContent.create(
    wire_format: Melos::Constants::WireFormat::MLS_PRIVATE_MESSAGE, # private_message
    content: fc,
    auth: pmc.auth
  )
end