fn encrypt_to_copath(
        &self,
        crypto: &impl OpenMlsCrypto,
        public_keys: Vec<HpkePublicKey>,
        group_context: &[u8],
        new_leaves_indexes: HashSet<&LeafIndex>,
    ) -> Result<Vec<UpdatePathNode>, TreeError> {
        let copath = treemath::copath(self.private_tree.leaf_index(), self.leaf_count())
            .expect("encrypt_to_copath: Error when computing copath.");
        // Return if the length of the copath is zero
        if copath.is_empty() {
            return Ok(vec![]);
        }
        let path_secrets = self.private_tree.path_secrets();

        debug_assert_eq!(path_secrets.len(), copath.len());
        if path_secrets.len() != copath.len() {
            return Err(TreeError::InvalidArguments);
        }
        debug_assert_eq!(public_keys.len(), copath.len());
        if public_keys.len() != copath.len() {
            return Err(TreeError::InvalidArguments);
        }

        let mut direct_path_nodes = vec![];
        let mut ciphertexts = vec![];
        for (path_secret, copath_node) in path_secrets.iter().zip(copath.iter()) {
            let node_ciphertexts: Vec<HpkeCiphertext> = self
                .resolve(*copath_node, &new_leaves_indexes)
                .iter()
                .map(|&index| {
                    let pk = self.nodes[index].public_hpke_key().unwrap();
                    self.ciphersuite.hpke_seal_secret(
                        crypto,
                        pk,
                        group_context,
                        &[],
                        &path_secret.path_secret,
                    )
                })
                .collect();
            // TODO Check that all public keys are non-empty
            // TODO Handle potential errors
            ciphertexts.push(node_ciphertexts);
        }
        for (public_key, node_ciphertexts) in public_keys.iter().zip(ciphertexts.iter()) {
            direct_path_nodes.push(UpdatePathNode {
                // TODO: don't clone ...
                public_key: public_key.clone(),
                encrypted_path_secret: node_ciphertexts.clone().into(),
            });
        }
        Ok(direct_path_nodes)
    }
/// Encrypt the path secrets to the co path and return the update path.
Encrypt the path secrets to the co path and return the update path.
Encrypt the path secrets to the co path and return the update path .
fn encrypt_to_copath(
        &self,
        crypto: &impl OpenMlsCrypto,
        public_keys: Vec<HpkePublicKey>,
        group_context: &[u8],
        new_leaves_indexes: HashSet<&LeafIndex>,
    ) -> Result<Vec<UpdatePathNode>, TreeError> {
        let copath = treemath::copath(self.private_tree.leaf_index(), self.leaf_count())
            .expect("encrypt_to_copath: Error when computing copath.");
        // Return if the length of the copath is zero
        if copath.is_empty() {
            return Ok(vec![]);
        }
        let path_secrets = self.private_tree.path_secrets();
        debug_assert_eq!(path_secrets.len(), copath.len());
        if path_secrets.len() != copath.len() {
            return Err(TreeError::InvalidArguments);
        }
        debug_assert_eq!(public_keys.len(), copath.len());
        if public_keys.len() != copath.len() {
            return Err(TreeError::InvalidArguments);
        }
        let mut direct_path_nodes = vec![];
        let mut ciphertexts = vec![];
        for (path_secret, copath_node) in path_secrets.iter().zip(copath.iter()) {
            let node_ciphertexts: Vec<HpkeCiphertext> = self
                .resolve(*copath_node, &new_leaves_indexes)
                .iter()
                .map(|&index| {
                    let pk = self.nodes[index].public_hpke_key().unwrap();
                    self.ciphersuite.hpke_seal_secret(
                        crypto,
                        pk,
                        group_context,
                        &[],
                        &path_secret.path_secret,
                    )
                })
                .collect();
            // TODO Check that all public keys are non-empty
            // TODO Handle potential errors
            ciphertexts.push(node_ciphertexts);
        }
        for (public_key, node_ciphertexts) in public_keys.iter().zip(ciphertexts.iter()) {
            direct_path_nodes.push(UpdatePathNode {
                // TODO: don't clone ...
                public_key: public_key.clone(),
                encrypted_path_secret: node_ciphertexts.clone().into(),
            });
        }
        Ok(direct_path_nodes)
    }
fn encrypt_to_copath ( & self , crypto : & impl OpenMlsCrypto , public_keys : Vec < HpkePublicKey > , group_context : & [ u8 ] , new_leaves_indexes : HashSet < & LeafIndex > , ) -> Result < Vec < UpdatePathNode > , TreeError > { let copath = treemath :: copath ( self . private_tree . leaf_index ( ) , self . leaf_count ( ) ) . expect ( " " ) ; // Return if the length of the copath is zero if copath . is_empty ( ) { return Ok ( vec ! [ ] ) ; } let path_secrets = self . private_tree . path_secrets ( ) ; debug_assert_eq ! ( path_secrets len ( ) copath len ( ) ) ; if path_secrets . len ( ) != copath . len ( ) { return Err ( TreeError :: InvalidArguments ) ; } debug_assert_eq ! ( public_keys len ( ) copath len ( ) ) ; if public_keys . len ( ) != copath . len ( ) { return Err ( TreeError :: InvalidArguments ) ; } let mut direct_path_nodes = vec ! [ ] ; let mut ciphertexts = vec ! [ ] ; for ( path_secret , copath_node ) in path_secrets . iter ( ) . zip ( copath . iter ( ) ) { let node_ciphertexts : Vec < HpkeCiphertext > = self . resolve ( * copath_node , & new_leaves_indexes ) . iter ( ) . map ( | & index | { let pk = self . nodes [ index ] . public_hpke_key ( ) . unwrap ( ) ; self . ciphersuite . hpke_seal_secret ( crypto , pk , group_context , & [ ] , & path_secret . path_secret , ) } ) . collect ( ) ; // TODO Check that all public keys are non-empty // TODO Handle potential errors ciphertexts . push ( node_ciphertexts ) ; } for ( public_key , node_ciphertexts ) in public_keys . iter ( ) . zip ( ciphertexts . iter ( ) ) { direct_path_nodes . push ( UpdatePathNode { // TODO: don't clone ... public_key : public_key . clone ( ) , encrypted_path_secret : node_ciphertexts . clone ( ) . into ( ) , } ) ; } Ok ( direct_path_nodes ) }
Encrypt the path secrets to the co path and return the update path.
Encrypt the path secrets to the co path and return the update path .
&self
crypto
&impl OpenMlsCrypto
public_keys
Vec<HpkePublicKey>
group_context
&[u8]
new_leaves_indexes
HashSet<&LeafIndex>
&self
crypto
&impl OpenMlsCrypto
public_keys
Vec<HpkePublicKey>
group_context
&[u8]
new_leaves_indexes
HashSet<&LeafIndex>