// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // Copyright by contributors to this project. // SPDX-License-Identifier: (Apache-2.0 OR MIT) use alloc::{vec, vec::Vec};
use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize}; use mls_rs_core::crypto::HpkeSecretKey;
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] pubasyncfn update_secrets<P: CipherSuiteProvider>(
&mutself,
cipher_suite_provider: &P,
signer_index: LeafIndex,
path_secret: PathSecret,
public_tree: &TreeKemPublic,
) -> Result<(), MlsError> { // Identify the lowest common // ancestor of the leaves at index and at GroupInfo.signer_index. Set the private key // for this node to the private key derived from the path_secret. let lca_index = leaf_lca_level(self.self_index.into(), signer_index.into()) as usize - 2;
// For each parent of the common ancestor, up to the root of the tree, derive a new // path secret and set the private key for the node to the private key derived from the // path secret. The private key MUST be the private key that corresponds to the public // key in the node.
// Create a ratchet tree for Alice, Bob and Charlie. Alice generates an update path for // Charlie. Return (Public Tree, Charlie's private key, update path, path secret) // The ratchet tree returned has leaf indexes as [alice, bob, charlie] #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] asyncfn update_secrets_setup(
cipher_suite: CipherSuite,
) -> (TreeKemPublic, TreeKemPrivate, TreeKemPrivate, PathSecret) { let cipher_suite_provider = test_cipher_suite_provider(cipher_suite);
let (alice_leaf, alice_hpke_secret, alice_signing) =
get_basic_test_node_sig_key(cipher_suite, "alice").await;
let bob_leaf = get_basic_test_node(cipher_suite, "bob").await;
let (charlie_leaf, charlie_hpke_secret, _charlie_signing) =
get_basic_test_node_sig_key(cipher_suite, "charlie").await;
// Create a new public tree with Alice let (mut public_tree, mut alice_private) = TreeKemPublic::derive(
alice_leaf,
alice_hpke_secret,
&BasicIdentityProvider,
&Default::default(),
)
.await
.unwrap();
// Add bob and charlie to the tree
public_tree
.add_leaves(
vec![bob_leaf, charlie_leaf],
&BasicIdentityProvider,
&cipher_suite_provider,
)
.await
.unwrap();
// Alice's secret key is longer now
alice_private.secret_keys.resize(3, None);
// Generate an update path for Alice let encap_gen = TreeKem::new(&mut public_tree, &mut alice_private)
.encap(
&mut get_test_group_context(42, cipher_suite).await,
&[],
&alice_signing,
default_properties(),
None,
&cipher_suite_provider, #[cfg(test)]
&Default::default(),
)
.await
.unwrap();
// Get a path secret from Alice for Charlie let path_secret = encap_gen.path_secrets[1].clone().unwrap();
// Private key for Charlie let charlie_private = TreeKemPrivate::new_self_leaf(LeafIndex(2), charlie_hpke_secret);
#[maybe_async::test(not(mls_build_async), async(mls_build_async, crate::futures_test))] asyncfn test_update_secrets() { let cipher_suite = TEST_CIPHER_SUITE;
let (public_tree, mut charlie_private, alice_private, path_secret) =
update_secrets_setup(cipher_suite).await;
let existing_private = charlie_private.secret_keys.first().cloned().unwrap();
// Add the secrets for Charlie to his private key
charlie_private
.update_secrets(
&test_cipher_suite_provider(cipher_suite),
LeafIndex(0),
path_secret,
&public_tree,
)
.await
.unwrap();
// Make sure that Charlie's private key didn't lose keys
assert_eq!(charlie_private.secret_keys.len(), 3);
// Check that the intersection of the secret keys of Alice and Charlie matches. // The intersection contains only the root.
assert_eq!(alice_private.secret_keys[2], charlie_private.secret_keys[2]);
#[maybe_async::test(not(mls_build_async), async(mls_build_async, crate::futures_test))] asyncfn test_update_secrets_key_mismatch() { let cipher_suite = TEST_CIPHER_SUITE;
let (mut public_tree, mut charlie_private, _, path_secret) =
update_secrets_setup(cipher_suite).await;
// Sabotage the public tree
public_tree
.nodes
.borrow_as_parent_mut(public_tree.total_leaf_count().root())
.unwrap()
.public_key = random_bytes(32).into();
// Add the secrets for Charlie to his private key let res = charlie_private
.update_secrets(
&test_cipher_suite_provider(cipher_suite),
LeafIndex(0),
path_secret,
&public_tree,
)
.await;
// The update operation should have removed all the other keys in our direct path we // previously added
assert!(private_key.secret_keys.iter().skip(1).all(|n| n.is_none()));
// The secret key for our leaf should have been updated accordingly
assert_eq!(private_key.secret_keys.first().unwrap(), &Some(new_secret));
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.