fix: suggestions fix 3

This commit is contained in:
Pravdyvy 2025-11-26 14:53:26 +02:00
parent 77570c48e9
commit 30f19b245d
4 changed files with 36 additions and 22 deletions

View File

@ -34,8 +34,15 @@ impl KeyNode for ChildKeysPublic {
let hash_value = hmac_sha512::HMAC::mac(&hash_input, self.ccc); let hash_value = hmac_sha512::HMAC::mac(&hash_input, self.ccc);
let csk = nssa::PrivateKey::try_new(*hash_value.first_chunk::<32>().unwrap()).unwrap(); let csk = nssa::PrivateKey::try_new(
let ccc = *hash_value.last_chunk::<32>().unwrap(); *hash_value
.first_chunk::<32>()
.expect("hash_value is 64 bytes, must be safe to get first 32"),
)
.unwrap();
let ccc = *hash_value
.last_chunk::<32>()
.expect("hash_value is 64 bytes, must be safe to get last 32");
let cpk = nssa::PublicKey::new_from_private_key(&csk); let cpk = nssa::PublicKey::new_from_private_key(&csk);
Self { Self {

View File

@ -16,19 +16,23 @@ pub mod keys_public;
pub mod traits; pub mod traits;
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct KeyTree<Node: KeyNode> { pub struct KeyTree<N: KeyNode> {
pub key_map: BTreeMap<ChainIndex, Node>, pub key_map: BTreeMap<ChainIndex, N>,
pub addr_map: HashMap<nssa::Address, ChainIndex>, pub addr_map: HashMap<nssa::Address, ChainIndex>,
} }
pub type KeyTreePublic = KeyTree<ChildKeysPublic>; pub type KeyTreePublic = KeyTree<ChildKeysPublic>;
pub type KeyTreePrivate = KeyTree<ChildKeysPrivate>; pub type KeyTreePrivate = KeyTree<ChildKeysPrivate>;
impl<Node: KeyNode> KeyTree<Node> { impl<N: KeyNode> KeyTree<N> {
pub fn new(seed: &SeedHolder) -> Self { pub fn new(seed: &SeedHolder) -> Self {
let seed_fit: [u8; 64] = seed.seed.clone().try_into().unwrap(); let seed_fit: [u8; 64] = seed
.seed
.clone()
.try_into()
.expect("SeedHolder seed is 64 bytes long");
let root_keys = Node::root(seed_fit); let root_keys = N::root(seed_fit);
let address = root_keys.address(); let address = root_keys.address();
let key_map = BTreeMap::from_iter([(ChainIndex::root(), root_keys)]); let key_map = BTreeMap::from_iter([(ChainIndex::root(), root_keys)]);
@ -37,12 +41,9 @@ impl<Node: KeyNode> KeyTree<Node> {
Self { key_map, addr_map } Self { key_map, addr_map }
} }
pub fn new_from_root(root: Node) -> Self { pub fn new_from_root(root: N) -> Self {
let mut key_map = BTreeMap::new(); let addr_map = HashMap::from_iter([(root.address(), ChainIndex::root())]);
let mut addr_map = HashMap::new(); let key_map = BTreeMap::from_iter([(ChainIndex::root(), root)]);
addr_map.insert(root.address(), ChainIndex::root());
key_map.insert(ChainIndex::root(), root);
Self { key_map, addr_map } Self { key_map, addr_map }
} }
@ -91,7 +92,9 @@ impl<Node: KeyNode> KeyTree<Node> {
pub fn generate_new_node(&mut self, parent_cci: ChainIndex) -> Option<nssa::Address> { pub fn generate_new_node(&mut self, parent_cci: ChainIndex) -> Option<nssa::Address> {
let father_keys = self.key_map.get(&parent_cci)?; let father_keys = self.key_map.get(&parent_cci)?;
let next_child_id = self.find_next_last_child_of_id(&parent_cci).unwrap(); let next_child_id = self
.find_next_last_child_of_id(&parent_cci)
.expect("Can be None only if parent is not present");
let next_cci = parent_cci.nth_child(next_child_id); let next_cci = parent_cci.nth_child(next_child_id);
let child_keys = father_keys.nth_child(next_child_id); let child_keys = father_keys.nth_child(next_child_id);
@ -104,19 +107,19 @@ impl<Node: KeyNode> KeyTree<Node> {
Some(address) Some(address)
} }
pub fn get_node(&self, addr: nssa::Address) -> Option<&Node> { pub fn get_node(&self, addr: nssa::Address) -> Option<&N> {
self.addr_map self.addr_map
.get(&addr) .get(&addr)
.and_then(|chain_id| self.key_map.get(chain_id)) .and_then(|chain_id| self.key_map.get(chain_id))
} }
pub fn get_node_mut(&mut self, addr: nssa::Address) -> Option<&mut Node> { pub fn get_node_mut(&mut self, addr: nssa::Address) -> Option<&mut N> {
self.addr_map self.addr_map
.get(&addr) .get(&addr)
.and_then(|chain_id| self.key_map.get_mut(chain_id)) .and_then(|chain_id| self.key_map.get_mut(chain_id))
} }
pub fn insert(&mut self, addr: nssa::Address, chain_index: ChainIndex, node: Node) { pub fn insert(&mut self, addr: nssa::Address, chain_index: ChainIndex, node: N) {
self.addr_map.insert(addr, chain_index.clone()); self.addr_map.insert(addr, chain_index.clone());
self.key_map.insert(chain_index, node); self.key_map.insert(chain_index, node);
} }

View File

@ -1,6 +1,9 @@
/// Trait, that reperesents a Node in hierarchical key tree
pub trait KeyNode { pub trait KeyNode {
/// Tree root node
fn root(seed: [u8; 64]) -> Self; fn root(seed: [u8; 64]) -> Self;
/// `cci`'s child of node
fn nth_child(&self, cci: u32) -> Self; fn nth_child(&self, cci: u32) -> Self;
fn chain_code(&self) -> &[u8; 32]; fn chain_code(&self) -> &[u8; 32];

View File

@ -8,6 +8,8 @@ use rand::{RngCore, rngs::OsRng};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::{Digest, digest::FixedOutput}; use sha2::{Digest, digest::FixedOutput};
const NSSA_ENTROPY_BYTES: [u8; 32] = [0; 32];
#[derive(Debug)] #[derive(Debug)]
///Seed holder. Non-clonable to ensure that different holders use different seeds. ///Seed holder. Non-clonable to ensure that different holders use different seeds.
/// Produces `TopSecretKeyHolder` objects. /// Produces `TopSecretKeyHolder` objects.
@ -36,7 +38,8 @@ impl SeedHolder {
let mut enthopy_bytes: [u8; 32] = [0; 32]; let mut enthopy_bytes: [u8; 32] = [0; 32];
OsRng.fill_bytes(&mut enthopy_bytes); OsRng.fill_bytes(&mut enthopy_bytes);
let mnemonic = Mnemonic::from_entropy(&enthopy_bytes).unwrap(); let mnemonic = Mnemonic::from_entropy(&enthopy_bytes)
.expect("Enthropy must be a multiple of 32 bytes");
let seed_wide = mnemonic.to_seed("mnemonic"); let seed_wide = mnemonic.to_seed("mnemonic");
Self { Self {
@ -45,10 +48,8 @@ impl SeedHolder {
} }
pub fn new_mnemonic(passphrase: String) -> Self { pub fn new_mnemonic(passphrase: String) -> Self {
// Enthropy bytes must be deterministic as well let mnemonic = Mnemonic::from_entropy(&NSSA_ENTROPY_BYTES)
let enthopy_bytes: [u8; 32] = [0; 32]; .expect("Enthropy must be a multiple of 32 bytes");
let mnemonic = Mnemonic::from_entropy(&enthopy_bytes).unwrap();
let seed_wide = mnemonic.to_seed(passphrase); let seed_wide = mnemonic.to_seed(passphrase);
Self { Self {