| 8 | /// |
| 9 | |
| 10 | State::State(bytes group_id, |
| 11 | CipherSuite suite, |
| 12 | HPKEPrivateKey enc_priv, |
| 13 | SignaturePrivateKey sig_priv, |
| 14 | const LeafNode& leaf_node, |
| 15 | ExtensionList extensions) |
| 16 | : _suite(suite) |
| 17 | , _group_id(std::move(group_id)) |
| 18 | , _epoch(0) |
| 19 | , _tree(suite) |
| 20 | , _transcript_hash(suite) |
| 21 | , _extensions(std::move(extensions)) |
| 22 | , _index(0) |
| 23 | , _identity_priv(std::move(sig_priv)) |
| 24 | { |
| 25 | // Verify that the client supports the proposed group extensions |
| 26 | if (!leaf_node.verify_extension_support(_extensions)) { |
| 27 | throw InvalidParameterError("Client doesn't support required extensions"); |
| 28 | } |
| 29 | |
| 30 | _index = _tree.add_leaf(leaf_node); |
| 31 | _tree.set_hash_all(); |
| 32 | _tree_priv = TreeKEMPrivateKey::solo(suite, _index, std::move(enc_priv)); |
| 33 | if (!_tree_priv.consistent(_tree)) { |
| 34 | throw InvalidParameterError("LeafNode inconsistent with private key"); |
| 35 | } |
| 36 | |
| 37 | // XXX(RLB): Convert KeyScheduleEpoch to take GroupContext? |
| 38 | auto ctx = tls::marshal(group_context()); |
| 39 | _key_schedule = |
| 40 | KeyScheduleEpoch(_suite, random_bytes(_suite.secret_size()), ctx); |
| 41 | _keys = _key_schedule.encryption_keys(_tree.size); |
| 42 | |
| 43 | // Update the interim transcript hash with a virtual confirmation tag |
| 44 | _transcript_hash.update_interim( |
| 45 | _key_schedule.confirmation_tag(_transcript_hash.confirmed)); |
| 46 | } |
| 47 | |
| 48 | TreeKEMPublicKey |
| 49 | State::import_tree(const bytes& tree_hash, |
nothing calls this directly
no test coverage detected