From 2e0450bfcd16d1dc3da2a9ded7add691919a5833 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Mon, 15 Dec 2025 17:24:59 -0500 Subject: [PATCH] private key protocol fixes --- .../key_management/key_tree/keys_private.rs | 41 +++++++++-- .../src/key_management/secret_holders.rs | 68 ++++++++++++++++++- 2 files changed, 102 insertions(+), 7 deletions(-) diff --git a/key_protocol/src/key_management/key_tree/keys_private.rs b/key_protocol/src/key_management/key_tree/keys_private.rs index c91f03e..67d2a29 100644 --- a/key_protocol/src/key_management/key_tree/keys_private.rs +++ b/key_protocol/src/key_management/key_tree/keys_private.rs @@ -1,6 +1,8 @@ use k256::{Scalar, elliptic_curve::PrimeField}; -use nssa_core::encryption::IncomingViewingPublicKey; +use nssa_core::{NullifierPublicKey, encryption::IncomingViewingPublicKey}; use serde::{Deserialize, Serialize}; +use sha2::{Digest, digest::FixedOutput}; +use common::HashType; use crate::key_management::{ KeyChain, @@ -33,7 +35,20 @@ impl KeyNode for ChildKeysPrivate { let isk = ssk.generate_incoming_viewing_secret_key(); let ovk = ssk.generate_outgoing_viewing_secret_key(); - let npk = (&nsk).into(); + + let npk: NullifierPublicKey = { + let mut hasher = sha2::Sha256::new(); + + hasher.update("NSSA_keys"); + hasher.update(nsk); + hasher.update([7u8]); + hasher.update([0u8; 22]); + + NullifierPublicKey { + 0: ::from(hasher.finalize_fixed()) + } + }; + let ipk = IncomingViewingPublicKey::from_scalar(isk); Self { @@ -56,6 +71,7 @@ impl KeyNode for ChildKeysPrivate { } fn nth_child(&self, cci: u32) -> Self { + // parent_pt = ovk_par + scalar(nsk_par)*isk_par let parent_pt = Scalar::from_repr( self.value .0 @@ -91,11 +107,24 @@ impl KeyNode for ChildKeysPrivate { .last_chunk::<32>() .expect("hash_value is 64 bytes, must be safe to get last 32"); - let nsk = ssk.generate_nullifier_secret_key(); - let isk = ssk.generate_incoming_viewing_secret_key(); - let ovk = ssk.generate_outgoing_viewing_secret_key(); + let nsk = ssk.generate_child_nullifier_secret_key(cci); + let isk = ssk.generate_child_incoming_viewing_secret_key(cci); + let ovk = ssk.generate_child_outgoing_viewing_secret_key(cci); + + //TODO: separate out into its own function + let npk: NullifierPublicKey = { + let mut hasher = sha2::Sha256::new(); + + hasher.update("NSSAchain"); + hasher.update(nsk); + hasher.update([7u8]); + hasher.update([0u8; 22]); + + NullifierPublicKey { + 0: ::from(hasher.finalize_fixed()) + } + }; - let npk = (&nsk).into(); let ipk = IncomingViewingPublicKey::from_scalar(isk); Self { diff --git a/key_protocol/src/key_management/secret_holders.rs b/key_protocol/src/key_management/secret_holders.rs index c7ac6e9..4bfee81 100644 --- a/key_protocol/src/key_management/secret_holders.rs +++ b/key_protocol/src/key_management/secret_holders.rs @@ -115,11 +115,77 @@ impl SecretSpendingKey { outgoing_viewing_secret_key: self.generate_outgoing_viewing_secret_key(), } } + + pub fn generate_child_nullifier_secret_key(&self, cci: u32) -> NullifierSecretKey { + let mut key = vec![]; + key.extend_from_slice(b"NSSAchain"); + + let mut input = vec![]; + + input.extend_from_slice(&self.0); + input.extend_from_slice(&[1u8]); + input.extend_from_slice(&cci.to_le_bytes()); + input.extend_from_slice(&[0u8;22]); + + let hash_value = hmac_sha512::HMAC::mac(input, key); + + + *hash_value + .first_chunk::<32>() + .expect("hash_value is 64 bytes, must be safe to get first 32") + } + + pub fn generate_child_incoming_viewing_secret_key(&self, cci: u32) -> IncomingViewingSecretKey { + let mut key = vec![]; + key.extend_from_slice(b"NSSAchain"); + + let mut input = vec![]; + + input.extend_from_slice(&self.0); + input.extend_from_slice(&[2u8]); + input.extend_from_slice(&cci.to_le_bytes()); + input.extend_from_slice(&[0u8;22]); + + let hash_value = hmac_sha512::HMAC::mac(input, key); + + + *hash_value + .first_chunk::<32>() + .expect("hash_value is 64 bytes, must be safe to get first 32") + } + + pub fn generate_child_outgoing_viewing_secret_key(&self, cci: u32) -> OutgoingViewingSecretKey { + let mut key = vec![]; + key.extend_from_slice(b"NSSAchain"); + + let mut input = vec![]; + + input.extend_from_slice(&self.0); + input.extend_from_slice(&[3u8]); + input.extend_from_slice(&cci.to_le_bytes()); + input.extend_from_slice(&[0u8;22]); + + let hash_value = hmac_sha512::HMAC::mac(input, key); + + + *hash_value + .first_chunk::<32>() + .expect("hash_value is 64 bytes, must be safe to get first 32") + } } impl PrivateKeyHolder { pub fn generate_nullifier_public_key(&self) -> NullifierPublicKey { - (&self.nullifier_secret_key).into() + let mut hasher = sha2::Sha256::new(); + + hasher.update("NSSA_keys"); + hasher.update(self.nullifier_secret_key); + hasher.update([7u8]); + hasher.update([0u8; 22]); + + NullifierPublicKey { + 0: ::from(hasher.finalize_fixed()) + } } pub fn generate_incoming_viewing_public_key(&self) -> IncomingViewingPublicKey {