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 0b20a310..2c80f3bb 100644 --- a/key_protocol/src/key_management/key_tree/keys_private.rs +++ b/key_protocol/src/key_management/key_tree/keys_private.rs @@ -111,7 +111,7 @@ impl KeyNode for ChildKeysPrivate { } fn account_id(&self) -> nssa::AccountId { - nssa::AccountId::from(&self.value.0.nullifier_public_key) + nssa::AccountId::account_id_without_identifier(&self.value.0.nullifier_public_key) } } diff --git a/key_protocol/src/key_management/secret_holders.rs b/key_protocol/src/key_management/secret_holders.rs index 02890631..45e640da 100644 --- a/key_protocol/src/key_management/secret_holders.rs +++ b/key_protocol/src/key_management/secret_holders.rs @@ -20,16 +20,17 @@ pub struct SeedHolder { /// Secret spending key object. Can produce `PrivateKeyHolder` objects. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] -pub struct SecretSpendingKey(pub [u8; 32]); +pub struct SecretSpendingKey(pub(crate) [u8; 32]); pub type ViewingSecretKey = Scalar; #[derive(Serialize, Deserialize, Debug, Clone)] /// Private key holder. Produces public keys. Can produce `account_id`. Can produce shared secret /// for recepient. +#[expect(clippy::partial_pub_fields, reason = "TODO: fix later")] pub struct PrivateKeyHolder { pub nullifier_secret_key: NullifierSecretKey, - pub viewing_secret_key: ViewingSecretKey, + pub(crate) viewing_secret_key: ViewingSecretKey, } impl SeedHolder { diff --git a/key_protocol/src/key_protocol_core/mod.rs b/key_protocol/src/key_protocol_core/mod.rs index 8232d9f4..3ec91c99 100644 --- a/key_protocol/src/key_protocol_core/mod.rs +++ b/key_protocol/src/key_protocol_core/mod.rs @@ -46,7 +46,7 @@ impl NSSAUserData { ) -> bool { let mut check_res = true; for (account_id, (key, _)) in accounts_keys_map { - let expected_account_id = nssa::AccountId::from(&key.nullifier_public_key); + let expected_account_id = nssa::AccountId::account_id_without_identifier(&key.nullifier_public_key); if expected_account_id != *account_id { println!("{expected_account_id}, {account_id}"); check_res = false; diff --git a/nssa/core/src/account.rs b/nssa/core/src/account.rs index 0f9248e3..5cbb7337 100644 --- a/nssa/core/src/account.rs +++ b/nssa/core/src/account.rs @@ -177,6 +177,39 @@ impl AccountId { pub const fn into_value(self) -> [u8; 32] { self.value } + + #[must_use] + pub fn generate_account_id(value: &NullifierPublicKey, identifier: Option) -> Self { + const PRIVATE_ACCOUNT_ID_PREFIX: &[u8; 32] = + b"/LEE/v0.3/AccountId/Private/\x00\x00\x00\x00"; + + let mut bytes = Vec::::new(); + bytes.extend_from_slice(PRIVATE_ACCOUNT_ID_PREFIX); + bytes.extend_from_slice(&value.0); + + match identifier { + None => {}, + Some(identifier) => bytes.extend_from_slice(&identifier.to_le_bytes()), + } + + Self::new( + Impl::hash_bytes(&bytes) + .as_bytes() + .try_into() + .expect("Conversion should not fail"), + ) + } + + #[must_use] + pub fn account_id_with_identifier(value: &NullifierPublicKey, identifier: u128) -> Self { + Self::generate_account_id(value, Some(identifier)) + } + + #[must_use] + pub fn account_id_without_identifier(value: &NullifierPublicKey) -> Self { + Self::generate_account_id(value, None) + } + } impl AsRef<[u8]> for AccountId { @@ -351,4 +384,22 @@ mod tests { assert_eq!(nonce, nonce_restored); } + + + #[test] + fn account_id_from_nullifier_public_key() { + let nsk = [ + 57, 5, 64, 115, 153, 56, 184, 51, 207, 238, 99, 165, 147, 214, 213, 151, 30, 251, 30, + 196, 134, 22, 224, 211, 237, 120, 136, 225, 188, 220, 249, 28, + ]; + let npk = NullifierPublicKey::from(&nsk); + let expected_account_id = AccountId::new([ + 139, 72, 194, 222, 215, 187, 147, 56, 55, 35, 222, 205, 156, 12, 204, 227, 166, 44, 30, + 81, 186, 14, 167, 234, 28, 236, 32, 213, 125, 251, 193, 233, + ]); + + let account_id = AccountId::account_id_without_identifier(&npk); + + assert_eq!(account_id, expected_account_id); + } } diff --git a/nssa/core/src/nullifier.rs b/nssa/core/src/nullifier.rs index bb11cb4b..1825b286 100644 --- a/nssa/core/src/nullifier.rs +++ b/nssa/core/src/nullifier.rs @@ -2,29 +2,12 @@ use borsh::{BorshDeserialize, BorshSerialize}; use risc0_zkvm::sha::{Impl, Sha256 as _}; use serde::{Deserialize, Serialize}; -use crate::{Commitment, account::AccountId}; +use crate::{Commitment}; #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] #[cfg_attr(any(feature = "host", test), derive(Clone, Hash))] pub struct NullifierPublicKey(pub [u8; 32]); -impl From<&NullifierPublicKey> for AccountId { - fn from(value: &NullifierPublicKey) -> Self { - const PRIVATE_ACCOUNT_ID_PREFIX: &[u8; 32] = - b"/LEE/v0.3/AccountId/Private/\x00\x00\x00\x00"; - - let mut bytes = [0; 64]; - bytes[0..32].copy_from_slice(PRIVATE_ACCOUNT_ID_PREFIX); - bytes[32..].copy_from_slice(&value.0); - Self::new( - Impl::hash_bytes(&bytes) - .as_bytes() - .try_into() - .expect("Conversion should not fail"), - ) - } -} - impl AsRef<[u8]> for NullifierPublicKey { fn as_ref(&self) -> &[u8] { self.0.as_slice() @@ -137,20 +120,4 @@ mod tests { assert_eq!(npk, expected_npk); } - #[test] - fn account_id_from_nullifier_public_key() { - let nsk = [ - 57, 5, 64, 115, 153, 56, 184, 51, 207, 238, 99, 165, 147, 214, 213, 151, 30, 251, 30, - 196, 134, 22, 224, 211, 237, 120, 136, 225, 188, 220, 249, 28, - ]; - let npk = NullifierPublicKey::from(&nsk); - let expected_account_id = AccountId::new([ - 139, 72, 194, 222, 215, 187, 147, 56, 55, 35, 222, 205, 156, 12, 204, 227, 166, 44, 30, - 81, 186, 14, 167, 234, 28, 236, 32, 213, 125, 251, 193, 233, - ]); - - let account_id = AccountId::from(&npk); - - assert_eq!(account_id, expected_account_id); - } } diff --git a/nssa/src/privacy_preserving_transaction/circuit.rs b/nssa/src/privacy_preserving_transaction/circuit.rs index 2ab141a3..38fa5cfa 100644 --- a/nssa/src/privacy_preserving_transaction/circuit.rs +++ b/nssa/src/privacy_preserving_transaction/circuit.rs @@ -205,7 +205,7 @@ mod tests { let recipient = AccountWithMetadata::new( Account::default(), false, - AccountId::from(&recipient_keys.npk()), + AccountId::account_id_without_identifier(&recipient_keys.npk()), ); let balance_to_move: u128 = 37; @@ -275,14 +275,14 @@ mod tests { data: Data::default(), }, true, - AccountId::from(&sender_keys.npk()), + AccountId::account_id_without_identifier(&sender_keys.npk()), ); let commitment_sender = Commitment::new(&sender_keys.npk(), &sender_pre.account); let recipient = AccountWithMetadata::new( Account::default(), false, - AccountId::from(&recipient_keys.npk()), + AccountId::account_id_without_identifier(&recipient_keys.npk()), ); let balance_to_move: u128 = 37;