pub(crate) fn try_from_plaintext(
        mls_plaintext: &MlsPlaintext,
        ciphersuite: &Ciphersuite,
        backend: &impl OpenMlsCryptoProvider,
        context: &GroupContext,
        sender: LeafIndex,
        secrets: Secrets,
        padding_size: usize,
    ) -> Result<MlsCiphertext, MlsCiphertextError> {
        log::debug!("MlsCiphertext::try_from_plaintext");
        log::trace!("  ciphersuite: {}", ciphersuite);
        // Check the plaintext has the correct wire format
        if mls_plaintext.wire_format() != WireFormat::MlsCiphertext {
            return Err(MlsCiphertextError::WrongWireFormat);
        }
        // Serialize the content AAD
        let mls_ciphertext_content_aad = MlsCiphertextContentAad {
            group_id: context.group_id().clone(),
            epoch: context.epoch(),
            content_type: *mls_plaintext.content_type(),
            authenticated_data: mls_plaintext.authenticated_data().into(),
        };
        let mls_ciphertext_content_aad_bytes =
            mls_ciphertext_content_aad.tls_serialize_detached()?;
        // Extract generation and key material for encryption
        let secret_type = SecretType::try_from(mls_plaintext)
            .map_err(|_| MlsCiphertextError::InvalidContentType)?;
        let (generation, (ratchet_key, mut ratchet_nonce)) = secrets
            .secret_tree
            .secret_for_encryption(ciphersuite, backend, sender, secret_type)?;
        // Sample reuse guard uniformly at random.
        let reuse_guard: ReuseGuard = ReuseGuard::from_random(backend);
        // Prepare the nonce by xoring with the reuse guard.
        ratchet_nonce.xor_with_reuse_guard(&reuse_guard);
        // Encrypt the payload
        let ciphertext = ratchet_key
            .aead_seal(
                backend,
                &Self::encode_padded_ciphertext_content_detached(
                    mls_plaintext,
                    padding_size,
                    ciphersuite.mac_length(),
                )?,
                &mls_ciphertext_content_aad_bytes,
                &ratchet_nonce,
            )
            .map_err(|e| {
                log::error!("MlsCiphertext::try_from_plaintext encryption error {:?}", e);
                MlsCiphertextError::EncryptionError
            })?;
        // Derive the sender data key from the key schedule using the ciphertext.
        let sender_data_key = secrets
            .epoch_secrets
            .sender_data_secret()
            .derive_aead_key(backend, &ciphertext);
        // Derive initial nonce from the key schedule using the ciphertext.
        let sender_data_nonce = secrets
            .epoch_secrets
            .sender_data_secret()
            .derive_aead_nonce(ciphersuite, backend, &ciphertext);
        // Compute sender data nonce by xoring reuse guard and key schedule
        // nonce as per spec.
        let mls_sender_data_aad = MlsSenderDataAad::new(
            context.group_id().clone(),
            context.epoch(),
            *mls_plaintext.content_type(),
        );
        // Serialize the sender data AAD
        let mls_sender_data_aad_bytes = mls_sender_data_aad.tls_serialize_detached()?;
        let sender_data = MlsSenderData::new(mls_plaintext.sender_index(), generation, reuse_guard);
        // Encrypt the sender data
        let encrypted_sender_data = sender_data_key
            .aead_seal(
                backend,
                &sender_data.tls_serialize_detached()?,
                &mls_sender_data_aad_bytes,
                &sender_data_nonce,
            )
            .map_err(|e| {
                log::error!("MlsCiphertext::try_from_plaintext encryption error {:?}", e);
                MlsCiphertextError::EncryptionError
            })?;
        Ok(MlsCiphertext {
            wire_format: WireFormat::MlsCiphertext,
            group_id: context.group_id().clone(),
            epoch: context.epoch(),
            content_type: *mls_plaintext.content_type(),
            authenticated_data: mls_plaintext.authenticated_data().into(),
            encrypted_sender_data: encrypted_sender_data.into(),
            ciphertext: ciphertext.into(),
        })
    }
/// Try to create a new `MlsCiphertext` from an `MlsPlaintext`
Try to create a new `MlsCiphertext` from an `MlsPlaintext`
Try to create a new ` MlsCiphertext ` from an ` MlsPlaintext `
pub(crate) fn try_from_plaintext(
        mls_plaintext: &MlsPlaintext,
        ciphersuite: &Ciphersuite,
        backend: &impl OpenMlsCryptoProvider,
        context: &GroupContext,
        sender: LeafIndex,
        secrets: Secrets,
        padding_size: usize,
    ) -> Result<MlsCiphertext, MlsCiphertextError> {
        log::debug!("MlsCiphertext::try_from_plaintext");
        log::trace!("  ciphersuite: {}", ciphersuite);
        // Check the plaintext has the correct wire format
        if mls_plaintext.wire_format() != WireFormat::MlsCiphertext {
            return Err(MlsCiphertextError::WrongWireFormat);
        }
        // Serialize the content AAD
        let mls_ciphertext_content_aad = MlsCiphertextContentAad {
            group_id: context.group_id().clone(),
            epoch: context.epoch(),
            content_type: *mls_plaintext.content_type(),
            authenticated_data: mls_plaintext.authenticated_data().into(),
        };
        let mls_ciphertext_content_aad_bytes =
            mls_ciphertext_content_aad.tls_serialize_detached()?;
        // Extract generation and key material for encryption
        let secret_type = SecretType::try_from(mls_plaintext)
            .map_err(|_| MlsCiphertextError::InvalidContentType)?;
        let (generation, (ratchet_key, mut ratchet_nonce)) = secrets
            .secret_tree
            .secret_for_encryption(ciphersuite, backend, sender, secret_type)?;
        // Sample reuse guard uniformly at random.
        let reuse_guard: ReuseGuard = ReuseGuard::from_random(backend);
        // Prepare the nonce by xoring with the reuse guard.
        ratchet_nonce.xor_with_reuse_guard(&reuse_guard);
        // Encrypt the payload
        let ciphertext = ratchet_key
            .aead_seal(
                backend,
                &Self::encode_padded_ciphertext_content_detached(
                    mls_plaintext,
                    padding_size,
                    ciphersuite.mac_length(),
                )?,
                &mls_ciphertext_content_aad_bytes,
                &ratchet_nonce,
            )
            .map_err(|e| {
                log::error!("MlsCiphertext::try_from_plaintext encryption error {:?}", e);
                MlsCiphertextError::EncryptionError
            })?;
        // Derive the sender data key from the key schedule using the ciphertext.
        let sender_data_key = secrets
            .epoch_secrets
            .sender_data_secret()
            .derive_aead_key(backend, &ciphertext);
        // Derive initial nonce from the key schedule using the ciphertext.
        let sender_data_nonce = secrets
            .epoch_secrets
            .sender_data_secret()
            .derive_aead_nonce(ciphersuite, backend, &ciphertext);
        // Compute sender data nonce by xoring reuse guard and key schedule
        // nonce as per spec.
        let mls_sender_data_aad = MlsSenderDataAad::new(
            context.group_id().clone(),
            context.epoch(),
            *mls_plaintext.content_type(),
        );
        // Serialize the sender data AAD
        let mls_sender_data_aad_bytes = mls_sender_data_aad.tls_serialize_detached()?;
        let sender_data = MlsSenderData::new(mls_plaintext.sender_index(), generation, reuse_guard);
        // Encrypt the sender data
        let encrypted_sender_data = sender_data_key
            .aead_seal(
                backend,
                &sender_data.tls_serialize_detached()?,
                &mls_sender_data_aad_bytes,
                &sender_data_nonce,
            )
            .map_err(|e| {
                log::error!("MlsCiphertext::try_from_plaintext encryption error {:?}", e);
                MlsCiphertextError::EncryptionError
            })?;
        Ok(MlsCiphertext {
            wire_format: WireFormat::MlsCiphertext,
            group_id: context.group_id().clone(),
            epoch: context.epoch(),
            content_type: *mls_plaintext.content_type(),
            authenticated_data: mls_plaintext.authenticated_data().into(),
            encrypted_sender_data: encrypted_sender_data.into(),
            ciphertext: ciphertext.into(),
        })
    }
pub ( crate ) fn try_from_plaintext ( mls_plaintext : & MlsPlaintext , ciphersuite : & Ciphersuite , backend : & impl OpenMlsCryptoProvider , context : & GroupContext , sender : LeafIndex , secrets : Secrets , padding_size : usize , ) -> Result < MlsCiphertext , MlsCiphertextError > { log :: debug ! ( " " ) ; log :: trace ! ( " " ciphersuite ) ; // Check the plaintext has the correct wire format if mls_plaintext . wire_format ( ) != WireFormat :: MlsCiphertext { return Err ( MlsCiphertextError :: WrongWireFormat ) ; } // Serialize the content AAD let mls_ciphertext_content_aad = MlsCiphertextContentAad { group_id : context . group_id ( ) . clone ( ) , epoch : context . epoch ( ) , content_type : * mls_plaintext . content_type ( ) , authenticated_data : mls_plaintext . authenticated_data ( ) . into ( ) , } ; let mls_ciphertext_content_aad_bytes = mls_ciphertext_content_aad . tls_serialize_detached ( ) ? ; // Extract generation and key material for encryption let secret_type = SecretType :: try_from ( mls_plaintext ) . map_err ( | _ | MlsCiphertextError :: InvalidContentType ) ? ; let ( generation , ( ratchet_key , mut ratchet_nonce ) ) = secrets . secret_tree . secret_for_encryption ( ciphersuite , backend , sender , secret_type ) ? ; // Sample reuse guard uniformly at random. let reuse_guard : ReuseGuard = ReuseGuard :: from_random ( backend ) ; // Prepare the nonce by xoring with the reuse guard. ratchet_nonce . xor_with_reuse_guard ( & reuse_guard ) ; // Encrypt the payload let ciphertext = ratchet_key . aead_seal ( backend , & Self :: encode_padded_ciphertext_content_detached ( mls_plaintext , padding_size , ciphersuite . mac_length ( ) , ) ? , & mls_ciphertext_content_aad_bytes , & ratchet_nonce , ) . map_err ( | e | { log :: error ! ( " " e ) ; MlsCiphertextError :: EncryptionError } ) ? ; // Derive the sender data key from the key schedule using the ciphertext. let sender_data_key = secrets . epoch_secrets . sender_data_secret ( ) . derive_aead_key ( backend , & ciphertext ) ; // Derive initial nonce from the key schedule using the ciphertext. let sender_data_nonce = secrets . epoch_secrets . sender_data_secret ( ) . derive_aead_nonce ( ciphersuite , backend , & ciphertext ) ; // Compute sender data nonce by xoring reuse guard and key schedule // nonce as per spec. let mls_sender_data_aad = MlsSenderDataAad :: new ( context . group_id ( ) . clone ( ) , context . epoch ( ) , * mls_plaintext . content_type ( ) , ) ; // Serialize the sender data AAD let mls_sender_data_aad_bytes = mls_sender_data_aad . tls_serialize_detached ( ) ? ; let sender_data = MlsSenderData :: new ( mls_plaintext . sender_index ( ) , generation , reuse_guard ) ; // Encrypt the sender data let encrypted_sender_data = sender_data_key . aead_seal ( backend , & sender_data . tls_serialize_detached ( ) ? , & mls_sender_data_aad_bytes , & sender_data_nonce , ) . map_err ( | e | { log :: error ! ( " " e ) ; MlsCiphertextError :: EncryptionError } ) ? ; Ok ( MlsCiphertext { wire_format : WireFormat :: MlsCiphertext , group_id : context . group_id ( ) . clone ( ) , epoch : context . epoch ( ) , content_type : * mls_plaintext . content_type ( ) , authenticated_data : mls_plaintext . authenticated_data ( ) . into ( ) , encrypted_sender_data : encrypted_sender_data . into ( ) , ciphertext : ciphertext . into ( ) , } ) }
Try to create a new `MlsCiphertext` from an `MlsPlaintext`
Try to create a new ` MlsCiphertext ` from an ` MlsPlaintext `
mls_plaintext
&MlsPlaintext
ciphersuite
&Ciphersuite
backend
&impl OpenMlsCryptoProvider
context
&GroupContext
sender
LeafIndex
secrets
Secrets
padding_size
usize
mls_plaintext
&MlsPlaintext
ciphersuite
&Ciphersuite
backend
&impl OpenMlsCryptoProvider
context
&GroupContext
sender
LeafIndex
secrets
Secrets
padding_size
usize