Merge pull request #356 from logos-blockchain/marvin/bip-32-comp

Key protocol compatibility with BIP-032/Keycard
This commit is contained in:
jonesmarvin8 2026-03-19 11:59:01 -04:00 committed by GitHub
commit 666353d7df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 1222 additions and 687 deletions

1
Cargo.lock generated
View File

@ -8971,6 +8971,7 @@ dependencies = [
"nssa", "nssa",
"nssa_core", "nssa_core",
"optfield", "optfield",
"rand 0.8.5",
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2",

View File

@ -28,4 +28,3 @@ async-stream.workspace = true
[dev-dependencies] [dev-dependencies]
tempfile.workspace = true tempfile.workspace = true

View File

@ -11,50 +11,50 @@
"channel_id": "0101010101010101010101010101010101010101010101010101010101010101", "channel_id": "0101010101010101010101010101010101010101010101010101010101010101",
"initial_accounts": [ "initial_accounts": [
{ {
"account_id": "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV", "account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r",
"balance": 10000 "balance": 10000
}, },
{ {
"account_id": "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo", "account_id": "2RHZhw9h534Zr3eq2RGhQete2Hh667foECzXPmSkGni2",
"balance": 20000 "balance": 20000
} }
], ],
"initial_commitments": [ "initial_commitments": [
{ {
"npk":[ "npk": [
177, 139,
64, 19,
1, 158,
11, 11,
87, 155,
38,
254,
159,
231, 231,
165, 85,
1, 206,
94, 132,
64, 228,
137, 220,
243, 114,
76, 145,
249, 89,
101, 113,
251, 156,
129, 238,
33, 142,
101, 242,
189, 74,
30, 182,
42, 91,
11, 43,
191, 100,
34, 6,
103, 190,
186, 31,
227, 15,
230 31,
] , 88,
96,
204
],
"account": { "account": {
"program_owner": [ "program_owner": [
0, 0,
@ -73,38 +73,38 @@
}, },
{ {
"npk": [ "npk": [
32, 173,
67,
72,
164,
106,
53,
66,
239,
141,
15,
52,
230,
136,
177,
2,
236,
207,
243,
134, 134,
135, 33,
210, 223,
143, 54,
87, 226,
232, 10,
71,
215, 215,
128, 254,
194, 143,
120, 172,
113, 24,
224, 244,
4, 243,
165 208,
65,
112,
118,
70,
217,
240,
69,
100,
129,
3,
121,
25,
213,
132,
42,
45
], ],
"account": { "account": {
"program_owner": [ "program_owner": [
@ -157,4 +157,4 @@
37, 37,
37 37
] ]
} }

View File

@ -59,11 +59,11 @@ impl InitialData {
let mut private_charlie_key_chain = KeyChain::new_os_random(); let mut private_charlie_key_chain = KeyChain::new_os_random();
let mut private_charlie_account_id = let mut private_charlie_account_id =
AccountId::from(&private_charlie_key_chain.nullifer_public_key); AccountId::from(&private_charlie_key_chain.nullifier_public_key);
let mut private_david_key_chain = KeyChain::new_os_random(); let mut private_david_key_chain = KeyChain::new_os_random();
let mut private_david_account_id = let mut private_david_account_id =
AccountId::from(&private_david_key_chain.nullifer_public_key); AccountId::from(&private_david_key_chain.nullifier_public_key);
// Ensure consistent ordering // Ensure consistent ordering
if private_charlie_account_id > private_david_account_id { if private_charlie_account_id > private_david_account_id {
@ -120,7 +120,7 @@ impl InitialData {
self.private_accounts self.private_accounts
.iter() .iter()
.map(|(key_chain, account)| CommitmentsInitialData { .map(|(key_chain, account)| CommitmentsInitialData {
npk: key_chain.nullifer_public_key.clone(), npk: key_chain.nullifier_public_key.clone(),
account: account.clone(), account: account.clone(),
}) })
.collect() .collect()
@ -138,7 +138,7 @@ impl InitialData {
}) })
}) })
.chain(self.private_accounts.iter().map(|(key_chain, account)| { .chain(self.private_accounts.iter().map(|(key_chain, account)| {
let account_id = AccountId::from(&key_chain.nullifer_public_key); let account_id = AccountId::from(&key_chain.nullifier_public_key);
InitialAccountData::Private(Box::new(InitialAccountDataPrivate { InitialAccountData::Private(Box::new(InitialAccountDataPrivate {
account_id, account_id,
account: account.clone(), account: account.clone(),

View File

@ -175,7 +175,7 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(from), from: format_private_account_id(from),
to: None, to: None,
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)), to_npk: Some(hex::encode(to_keys.nullifier_public_key.0)),
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)), to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
amount: 100, amount: 100,
}); });
@ -335,7 +335,7 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(from), from: format_private_account_id(from),
to: None, to: None,
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)), to_npk: Some(hex::encode(to_keys.nullifier_public_key.0)),
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)), to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
amount: 100, amount: 100,
}); });

View File

@ -70,7 +70,7 @@ async fn sync_private_account_with_non_zero_chain_index() -> Result<()> {
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: format_private_account_id(from), from: format_private_account_id(from),
to: None, to: None,
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)), to_npk: Some(hex::encode(to_keys.nullifier_public_key.0)),
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)), to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
amount: 100, amount: 100,
}); });

View File

@ -1123,7 +1123,7 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
let subcommand = TokenProgramAgnosticSubcommand::Mint { let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: format_private_account_id(definition_account_id), definition: format_private_account_id(definition_account_id),
holder: None, holder: None,
holder_npk: Some(hex::encode(holder_keys.nullifer_public_key.0)), holder_npk: Some(hex::encode(holder_keys.nullifier_public_key.0)),
holder_vpk: Some(hex::encode(holder_keys.viewing_public_key.0)), holder_vpk: Some(hex::encode(holder_keys.viewing_public_key.0)),
amount: mint_amount, amount: mint_amount,
}; };

View File

@ -606,7 +606,7 @@ fn test_wallet_ffi_get_private_account_keys() -> Result<()> {
.unwrap() .unwrap()
.0; .0;
let expected_npk = &key_chain.nullifer_public_key; let expected_npk = &key_chain.nullifier_public_key;
let expected_vpk = &key_chain.viewing_public_key; let expected_vpk = &key_chain.viewing_public_key;
assert_eq!(&keys.npk(), expected_npk); assert_eq!(&keys.npk(), expected_npk);

View File

@ -39,7 +39,7 @@ impl KeyNode for ChildKeysPrivate {
value: ( value: (
KeyChain { KeyChain {
secret_spending_key: ssk, secret_spending_key: ssk,
nullifer_public_key: npk, nullifier_public_key: npk,
viewing_public_key: vpk, viewing_public_key: vpk,
private_key_holder: PrivateKeyHolder { private_key_holder: PrivateKeyHolder {
nullifier_secret_key: nsk, nullifier_secret_key: nsk,
@ -54,10 +54,7 @@ impl KeyNode for ChildKeysPrivate {
} }
fn nth_child(&self, cci: u32) -> Self { fn nth_child(&self, cci: u32) -> Self {
#[expect( #[expect(clippy::arithmetic_side_effects, reason = "TODO: fix later")]
clippy::arithmetic_side_effects,
reason = "Multiplying finite field scalars gives no unexpected side effects"
)]
let parent_pt = let parent_pt =
Scalar::from_repr(self.value.0.private_key_holder.nullifier_secret_key.into()) Scalar::from_repr(self.value.0.private_key_holder.nullifier_secret_key.into())
.expect("Key generated as scalar, must be valid representation") .expect("Key generated as scalar, must be valid representation")
@ -67,7 +64,8 @@ impl KeyNode for ChildKeysPrivate {
input.extend_from_slice(b"LEE_seed_priv"); input.extend_from_slice(b"LEE_seed_priv");
input.extend_from_slice(&parent_pt.to_bytes()); input.extend_from_slice(&parent_pt.to_bytes());
input.extend_from_slice(&cci.to_le_bytes()); #[expect(clippy::big_endian_bytes, reason = "BIP-032 uses big endian")]
input.extend_from_slice(&cci.to_be_bytes());
let hash_value = hmac_sha512::HMAC::mac(input, self.ccc); let hash_value = hmac_sha512::HMAC::mac(input, self.ccc);
@ -90,7 +88,7 @@ impl KeyNode for ChildKeysPrivate {
value: ( value: (
KeyChain { KeyChain {
secret_spending_key: ssk, secret_spending_key: ssk,
nullifer_public_key: npk, nullifier_public_key: npk,
viewing_public_key: vpk, viewing_public_key: vpk,
private_key_holder: PrivateKeyHolder { private_key_holder: PrivateKeyHolder {
nullifier_secret_key: nsk, nullifier_secret_key: nsk,
@ -113,18 +111,26 @@ impl KeyNode for ChildKeysPrivate {
} }
fn account_id(&self) -> nssa::AccountId { fn account_id(&self) -> nssa::AccountId {
nssa::AccountId::from(&self.value.0.nullifer_public_key) nssa::AccountId::from(&self.value.0.nullifier_public_key)
} }
} }
impl<'keys> From<&'keys ChildKeysPrivate> for &'keys (KeyChain, nssa::Account) { #[expect(
fn from(value: &'keys ChildKeysPrivate) -> Self { clippy::single_char_lifetime_names,
reason = "TODO add meaningful name"
)]
impl<'a> From<&'a ChildKeysPrivate> for &'a (KeyChain, nssa::Account) {
fn from(value: &'a ChildKeysPrivate) -> Self {
&value.value &value.value
} }
} }
impl<'keys> From<&'keys mut ChildKeysPrivate> for &'keys mut (KeyChain, nssa::Account) { #[expect(
fn from(value: &'keys mut ChildKeysPrivate) -> Self { clippy::single_char_lifetime_names,
reason = "TODO add meaningful name"
)]
impl<'a> From<&'a mut ChildKeysPrivate> for &'a mut (KeyChain, nssa::Account) {
fn from(value: &'a mut ChildKeysPrivate) -> Self {
&mut value.value &mut value.value
} }
} }
@ -166,7 +172,7 @@ mod tests {
7, 123, 125, 191, 233, 183, 201, 4, 20, 214, 155, 210, 45, 234, 27, 240, 194, 111, 97, 7, 123, 125, 191, 233, 183, 201, 4, 20, 214, 155, 210, 45, 234, 27, 240, 194, 111, 97,
247, 155, 113, 122, 246, 192, 0, 70, 61, 76, 71, 70, 2, 247, 155, 113, 122, 246, 192, 0, 70, 61, 76, 71, 70, 2,
]); ]);
let expected_vsk: ViewingSecretKey = [ let expected_vsk = [
155, 90, 54, 75, 228, 130, 68, 201, 129, 251, 180, 195, 250, 64, 34, 230, 241, 204, 155, 90, 54, 75, 228, 130, 68, 201, 129, 251, 180, 195, 250, 64, 34, 230, 241, 204,
216, 50, 149, 156, 10, 67, 208, 74, 9, 10, 47, 59, 50, 202, 216, 50, 149, 156, 10, 67, 208, 74, 9, 10, 47, 59, 50, 202,
]; ];
@ -179,7 +185,7 @@ mod tests {
assert!(expected_ssk == keys.value.0.secret_spending_key); assert!(expected_ssk == keys.value.0.secret_spending_key);
assert!(expected_ccc == keys.ccc); assert!(expected_ccc == keys.ccc);
assert!(expected_nsk == keys.value.0.private_key_holder.nullifier_secret_key); assert!(expected_nsk == keys.value.0.private_key_holder.nullifier_secret_key);
assert!(expected_npk == keys.value.0.nullifer_public_key); assert!(expected_npk == keys.value.0.nullifier_public_key);
assert!(expected_vsk == keys.value.0.private_key_holder.viewing_secret_key); assert!(expected_vsk == keys.value.0.private_key_holder.viewing_secret_key);
assert!(expected_vpk_as_bytes == keys.value.0.viewing_public_key.to_bytes()); assert!(expected_vpk_as_bytes == keys.value.0.viewing_public_key.to_bytes());
} }
@ -197,31 +203,31 @@ mod tests {
let child_node = ChildKeysPrivate::nth_child(&root_node, 42_u32); let child_node = ChildKeysPrivate::nth_child(&root_node, 42_u32);
let expected_ccc: [u8; 32] = [ let expected_ccc: [u8; 32] = [
145, 59, 225, 32, 54, 168, 14, 45, 60, 253, 57, 202, 31, 86, 142, 234, 51, 57, 154, 88, 27, 73, 133, 213, 214, 63, 217, 184, 164, 17, 172, 140, 223, 95, 255, 157, 11, 0, 58,
132, 200, 92, 191, 220, 144, 42, 184, 108, 35, 226, 146, 53, 82, 147, 121, 120, 199, 50, 30, 28, 103, 24, 121, 187,
]; ];
let expected_nsk: NullifierSecretKey = [ let expected_nsk: NullifierSecretKey = [
19, 100, 119, 73, 191, 225, 234, 219, 129, 88, 40, 229, 63, 225, 189, 136, 69, 172, 124, 61, 40, 92, 33, 135, 3, 41, 200, 234, 3, 69, 102, 184, 57, 191, 106, 151, 194,
221, 186, 147, 83, 150, 207, 70, 17, 228, 70, 113, 87, 227, 31, 192, 103, 132, 141, 112, 249, 108, 192, 117, 24, 48, 70, 216,
]; ];
let expected_npk = nssa_core::NullifierPublicKey([ let expected_npk = nssa_core::NullifierPublicKey([
133, 235, 223, 151, 12, 69, 26, 222, 60, 125, 235, 125, 167, 212, 201, 168, 101, 242, 116, 231, 246, 189, 145, 240, 37, 59, 219, 223, 216, 246, 116, 171, 223, 55, 197, 200,
111, 239, 1, 228, 12, 252, 146, 53, 75, 17, 187, 255, 122, 181, 134, 192, 221, 40, 218, 167, 239, 5, 11, 95, 147, 247, 162, 226,
]); ]);
let expected_vsk: ViewingSecretKey = [ let expected_vsk: ViewingSecretKey = [
218, 219, 193, 132, 160, 6, 178, 194, 139, 248, 199, 81, 17, 133, 37, 201, 58, 104, 49, 33, 155, 68, 60, 102, 70, 47, 105, 194, 129, 44, 26, 143, 198, 44, 244, 185, 31, 236,
222, 187, 46, 156, 93, 14, 118, 209, 243, 38, 101, 77, 45, 252, 205, 89, 138, 107, 39, 38, 154, 73, 109, 166, 41, 114,
]; ];
let expected_vpk_as_bytes: [u8; 33] = [ let expected_vpk_as_bytes: [u8; 33] = [
3, 164, 65, 167, 88, 167, 179, 51, 159, 27, 241, 174, 77, 174, 142, 106, 128, 96, 69, 2, 78, 213, 113, 117, 105, 162, 248, 175, 68, 128, 232, 106, 204, 208, 159, 11, 78, 48,
74, 117, 231, 42, 193, 235, 153, 206, 116, 102, 7, 101, 192, 45, 244, 127, 112, 46, 0, 93, 184, 1, 77, 132, 160, 75, 152, 88,
]; ];
assert!(expected_ccc == child_node.ccc); assert!(expected_ccc == child_node.ccc);
assert!(expected_nsk == child_node.value.0.private_key_holder.nullifier_secret_key); assert!(expected_nsk == child_node.value.0.private_key_holder.nullifier_secret_key);
assert!(expected_npk == child_node.value.0.nullifer_public_key); assert!(expected_npk == child_node.value.0.nullifier_public_key);
assert!(expected_vsk == child_node.value.0.private_key_holder.viewing_secret_key); assert!(expected_vsk == child_node.value.0.private_key_holder.viewing_secret_key);
assert!(expected_vpk_as_bytes == child_node.value.0.viewing_public_key.to_bytes()); assert!(expected_vpk_as_bytes == child_node.value.0.viewing_public_key.to_bytes());
} }

View File

@ -13,17 +13,25 @@ pub struct ChildKeysPublic {
} }
impl ChildKeysPublic { impl ChildKeysPublic {
#[expect(clippy::big_endian_bytes, reason = "BIP-032 uses big endian")]
fn compute_hash_value(&self, cci: u32) -> [u8; 64] { fn compute_hash_value(&self, cci: u32) -> [u8; 64] {
let mut hash_input = vec![]; let mut hash_input = vec![];
if 2_u32.pow(31) > cci { if ((2_u32).pow(31)).cmp(&cci) == std::cmp::Ordering::Greater {
// Non-harden // Non-harden.
hash_input.extend_from_slice(self.cpk.value()); // BIP-032 compatibility requires 1-byte header from the public_key;
// Not stored in `self.cpk.value()`.
let sk = secp256k1::SecretKey::from_byte_array(*self.csk.value())
.expect("32 bytes, within curve order");
let pk = secp256k1::PublicKey::from_secret_key(&secp256k1::Secp256k1::new(), &sk);
hash_input.extend_from_slice(&secp256k1::PublicKey::serialize(&pk));
} else { } else {
// Harden // Harden.
hash_input.extend_from_slice(&[0_u8]);
hash_input.extend_from_slice(self.csk.value()); hash_input.extend_from_slice(self.csk.value());
} }
hash_input.extend_from_slice(&cci.to_le_bytes());
hash_input.extend_from_slice(&cci.to_be_bytes());
hmac_sha512::HMAC::mac(hash_input, self.ccc) hmac_sha512::HMAC::mac(hash_input, self.ccc)
} }
@ -55,11 +63,13 @@ impl KeyNode for ChildKeysPublic {
) )
.unwrap(); .unwrap();
let csk = nssa::PrivateKey::try_new( let csk = nssa::PrivateKey::try_new({
csk.add_tweak(&Scalar::from_le_bytes(*self.csk.value()).unwrap()) let scalar = Scalar::from_be_bytes(*self.csk.value()).unwrap();
csk.add_tweak(&scalar)
.expect("Expect a valid Scalar") .expect("Expect a valid Scalar")
.secret_bytes(), .secret_bytes()
) })
.unwrap(); .unwrap();
assert!( assert!(
@ -94,8 +104,12 @@ impl KeyNode for ChildKeysPublic {
} }
} }
impl<'keys> From<&'keys ChildKeysPublic> for &'keys nssa::PrivateKey { #[expect(
fn from(value: &'keys ChildKeysPublic) -> Self { clippy::single_char_lifetime_names,
reason = "TODO add meaningful name"
)]
impl<'a> From<&'a ChildKeysPublic> for &'a nssa::PrivateKey {
fn from(value: &'a ChildKeysPublic) -> Self {
&value.csk &value.csk
} }
} }
@ -126,6 +140,7 @@ mod tests {
202, 148, 181, 228, 35, 222, 58, 84, 156, 24, 146, 86, 202, 148, 181, 228, 35, 222, 58, 84, 156, 24, 146, 86,
]) ])
.unwrap(); .unwrap();
let expected_cpk: PublicKey = PublicKey::try_new([ let expected_cpk: PublicKey = PublicKey::try_new([
219, 141, 130, 105, 11, 203, 187, 124, 112, 75, 223, 22, 11, 164, 153, 127, 59, 247, 219, 141, 130, 105, 11, 203, 187, 124, 112, 75, 223, 22, 11, 164, 153, 127, 59, 247,
244, 166, 75, 66, 242, 224, 35, 156, 161, 75, 41, 51, 76, 245, 244, 166, 75, 66, 242, 224, 35, 156, 161, 75, 41, 51, 76, 245,
@ -149,26 +164,20 @@ mod tests {
let cci = (2_u32).pow(31) + 13; let cci = (2_u32).pow(31) + 13;
let child_keys = ChildKeysPublic::nth_child(&root_keys, cci); let child_keys = ChildKeysPublic::nth_child(&root_keys, cci);
print!(
"{} {}",
child_keys.csk.value()[0],
child_keys.csk.value()[1]
);
let expected_ccc = [ let expected_ccc = [
126, 175, 244, 41, 41, 173, 134, 103, 139, 140, 195, 86, 194, 147, 116, 48, 71, 107, 149, 226, 13, 4, 194, 12, 69, 29, 9, 234, 209, 119, 98, 4, 128, 91, 37, 103, 192, 31,
253, 235, 114, 139, 60, 115, 226, 205, 215, 248, 240, 190, 196, 6, 130, 126, 123, 20, 90, 34, 173, 209, 101, 248, 155, 36,
]; ];
let expected_csk: PrivateKey = PrivateKey::try_new([ let expected_csk: PrivateKey = PrivateKey::try_new([
128, 148, 53, 165, 222, 155, 163, 108, 186, 182, 124, 67, 90, 86, 59, 123, 95, 224, 9, 65, 33, 228, 25, 82, 219, 117, 91, 217, 11, 223, 144, 85, 246, 26, 123, 216, 107,
171, 4, 51, 131, 254, 57, 241, 178, 82, 161, 204, 206, 79, 107, 213, 33, 52, 188, 22, 198, 246, 71, 46, 245, 174, 16, 47,
]) ])
.unwrap(); .unwrap();
let expected_cpk: PublicKey = PublicKey::try_new([ let expected_cpk: PublicKey = PublicKey::try_new([
149, 240, 55, 15, 178, 67, 245, 254, 44, 141, 95, 223, 238, 62, 85, 11, 248, 9, 11, 40, 142, 143, 238, 159, 105, 165, 224, 252, 108, 62, 53, 209, 176, 219, 249, 38, 90, 241,
69, 211, 116, 13, 189, 35, 8, 95, 233, 154, 129, 58, 201, 81, 194, 146, 236, 5, 83, 152, 238, 243, 138, 16, 229, 15,
]) ])
.unwrap(); .unwrap();
@ -189,26 +198,20 @@ mod tests {
let cci = 13; let cci = 13;
let child_keys = ChildKeysPublic::nth_child(&root_keys, cci); let child_keys = ChildKeysPublic::nth_child(&root_keys, cci);
print!(
"{} {}",
child_keys.csk.value()[0],
child_keys.csk.value()[1]
);
let expected_ccc = [ let expected_ccc = [
50, 29, 113, 102, 49, 130, 64, 0, 247, 95, 135, 187, 118, 162, 65, 65, 194, 53, 189, 79, 228, 242, 119, 211, 203, 198, 175, 95, 36, 4, 234, 139, 45, 137, 138, 54, 211, 187,
242, 66, 178, 168, 2, 51, 193, 155, 72, 209, 2, 207, 251, 16, 28, 79, 80, 232, 216, 101, 145, 19, 101, 220, 217, 141,
]; ];
let expected_csk: PrivateKey = PrivateKey::try_new([ let expected_csk: PrivateKey = PrivateKey::try_new([
162, 32, 211, 190, 180, 74, 151, 246, 189, 93, 8, 57, 182, 239, 125, 245, 192, 255, 24, 185, 147, 32, 242, 145, 91, 123, 77, 42, 33, 134, 84, 12, 165, 117, 70, 158, 201, 95,
186, 251, 23, 194, 186, 252, 121, 190, 54, 147, 199, 1, 109, 153, 14, 12, 92, 235, 128, 156, 194, 169, 68, 35, 165, 127,
]) ])
.unwrap(); .unwrap();
let expected_cpk: PublicKey = PublicKey::try_new([ let expected_cpk: PublicKey = PublicKey::try_new([
183, 48, 207, 170, 221, 111, 118, 9, 40, 67, 123, 162, 159, 169, 34, 157, 23, 37, 232, 119, 16, 145, 121, 97, 244, 186, 35, 136, 34, 140, 171, 206, 139, 11, 208, 207, 121,
102, 231, 187, 199, 191, 205, 146, 159, 22, 79, 100, 10, 223, 158, 45, 28, 22, 140, 98, 161, 179, 212, 173, 238, 220, 2, 34,
]) ])
.unwrap(); .unwrap();
@ -230,19 +233,19 @@ mod tests {
let child_keys = ChildKeysPublic::nth_child(&root_keys, cci); let child_keys = ChildKeysPublic::nth_child(&root_keys, cci);
let expected_ccc = [ let expected_ccc = [
101, 15, 69, 152, 144, 22, 105, 89, 175, 21, 13, 50, 160, 167, 93, 80, 94, 99, 192, 221, 208, 47, 189, 174, 152, 33, 25, 151, 114, 233, 191, 57, 15, 40, 140, 46, 87, 126,
252, 1, 126, 196, 217, 149, 164, 60, 75, 237, 90, 104, 83, 58, 215, 40, 246, 111, 166, 113, 183, 145, 173, 11, 27, 182,
]; ];
let expected_csk: PrivateKey = PrivateKey::try_new([ let expected_csk: PrivateKey = PrivateKey::try_new([
46, 196, 131, 199, 190, 180, 250, 222, 41, 188, 221, 156, 255, 239, 251, 207, 239, 202, 223, 29, 87, 189, 126, 24, 117, 225, 190, 57, 0, 143, 207, 168, 231, 139, 170, 192, 81,
166, 216, 107, 236, 195, 48, 167, 69, 97, 13, 132, 117, 76, 89, 254, 126, 10, 115, 42, 141, 157, 70, 171, 199, 231, 198, 132,
]) ])
.unwrap(); .unwrap();
let expected_cpk: PublicKey = PublicKey::try_new([ let expected_cpk: PublicKey = PublicKey::try_new([
93, 151, 154, 238, 175, 198, 53, 146, 255, 43, 37, 52, 214, 165, 69, 161, 38, 20, 68, 96, 123, 245, 51, 214, 216, 215, 205, 70, 145, 105, 221, 166, 169, 122, 27, 94, 112,
166, 143, 80, 149, 216, 124, 203, 240, 114, 168, 111, 33, 83, 228, 110, 249, 177, 85, 173, 180, 248, 185, 199, 112, 246, 83, 33,
]) ])
.unwrap(); .unwrap();

View File

@ -16,7 +16,7 @@ pub type PublicAccountSigningKey = [u8; 32];
pub struct KeyChain { pub struct KeyChain {
pub secret_spending_key: SecretSpendingKey, pub secret_spending_key: SecretSpendingKey,
pub private_key_holder: PrivateKeyHolder, pub private_key_holder: PrivateKeyHolder,
pub nullifer_public_key: NullifierPublicKey, pub nullifier_public_key: NullifierPublicKey,
pub viewing_public_key: ViewingPublicKey, pub viewing_public_key: ViewingPublicKey,
} }
@ -30,13 +30,13 @@ impl KeyChain {
let private_key_holder = secret_spending_key.produce_private_key_holder(None); let private_key_holder = secret_spending_key.produce_private_key_holder(None);
let nullifer_public_key = private_key_holder.generate_nullifier_public_key(); let nullifier_public_key = private_key_holder.generate_nullifier_public_key();
let viewing_public_key = private_key_holder.generate_viewing_public_key(); let viewing_public_key = private_key_holder.generate_viewing_public_key();
Self { Self {
secret_spending_key, secret_spending_key,
private_key_holder, private_key_holder,
nullifer_public_key, nullifier_public_key,
viewing_public_key, viewing_public_key,
} }
} }
@ -50,13 +50,13 @@ impl KeyChain {
let private_key_holder = secret_spending_key.produce_private_key_holder(None); let private_key_holder = secret_spending_key.produce_private_key_holder(None);
let nullifer_public_key = private_key_holder.generate_nullifier_public_key(); let nullifier_public_key = private_key_holder.generate_nullifier_public_key();
let viewing_public_key = private_key_holder.generate_viewing_public_key(); let viewing_public_key = private_key_holder.generate_viewing_public_key();
Self { Self {
secret_spending_key, secret_spending_key,
private_key_holder, private_key_holder,
nullifer_public_key, nullifier_public_key,
viewing_public_key, viewing_public_key,
} }
} }
@ -93,7 +93,7 @@ mod tests {
// Check that key holder fields are initialized with expected types // Check that key holder fields are initialized with expected types
assert_ne!( assert_ne!(
account_id_key_holder.nullifer_public_key.as_ref(), account_id_key_holder.nullifier_public_key.as_ref(),
&[0_u8; 32] &[0_u8; 32]
); );
} }
@ -119,7 +119,7 @@ mod tests {
let utxo_secret_key_holder = top_secret_key_holder.produce_private_key_holder(None); let utxo_secret_key_holder = top_secret_key_holder.produce_private_key_holder(None);
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key(); let nullifier_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key(); let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
let pub_account_signing_key = nssa::PrivateKey::new_os_random(); let pub_account_signing_key = nssa::PrivateKey::new_os_random();
@ -150,7 +150,7 @@ mod tests {
println!("Account {:?}", account.value().to_base58()); println!("Account {:?}", account.value().to_base58());
println!( println!(
"Nulifier public key {:?}", "Nulifier public key {:?}",
hex::encode(nullifer_public_key.to_byte_array()) hex::encode(nullifier_public_key.to_byte_array())
); );
println!( println!(
"Viewing public key {:?}", "Viewing public key {:?}",
@ -183,7 +183,7 @@ mod tests {
fn non_trivial_chain_index() { fn non_trivial_chain_index() {
let keys = account_with_chain_index_2_for_tests(); let keys = account_with_chain_index_2_for_tests();
let eph_key_holder = EphemeralKeyHolder::new(&keys.nullifer_public_key); let eph_key_holder = EphemeralKeyHolder::new(&keys.nullifier_public_key);
let key_sender = eph_key_holder.calculate_shared_secret_sender(&keys.viewing_public_key); let key_sender = eph_key_holder.calculate_shared_secret_sender(&keys.viewing_public_key);
let key_receiver = keys.calculate_shared_secret_receiver( let key_receiver = keys.calculate_shared_secret_receiver(

View File

@ -79,6 +79,7 @@ impl SeedHolder {
impl SecretSpendingKey { impl SecretSpendingKey {
#[must_use] #[must_use]
#[expect(clippy::big_endian_bytes, reason = "BIP-032 uses big endian")]
pub fn generate_nullifier_secret_key(&self, index: Option<u32>) -> NullifierSecretKey { pub fn generate_nullifier_secret_key(&self, index: Option<u32>) -> NullifierSecretKey {
const PREFIX: &[u8; 8] = b"LEE/keys"; const PREFIX: &[u8; 8] = b"LEE/keys";
const SUFFIX_1: &[u8; 1] = &[1]; const SUFFIX_1: &[u8; 1] = &[1];
@ -93,13 +94,14 @@ impl SecretSpendingKey {
hasher.update(PREFIX); hasher.update(PREFIX);
hasher.update(self.0); hasher.update(self.0);
hasher.update(SUFFIX_1); hasher.update(SUFFIX_1);
hasher.update(index.to_le_bytes()); hasher.update(index.to_be_bytes());
hasher.update(SUFFIX_2); hasher.update(SUFFIX_2);
<NullifierSecretKey>::from(hasher.finalize_fixed()) <NullifierSecretKey>::from(hasher.finalize_fixed())
} }
#[must_use] #[must_use]
#[expect(clippy::big_endian_bytes, reason = "BIP-032 uses big endian")]
pub fn generate_viewing_secret_key(&self, index: Option<u32>) -> ViewingSecretKey { pub fn generate_viewing_secret_key(&self, index: Option<u32>) -> ViewingSecretKey {
const PREFIX: &[u8; 8] = b"LEE/keys"; const PREFIX: &[u8; 8] = b"LEE/keys";
const SUFFIX_1: &[u8; 1] = &[2]; const SUFFIX_1: &[u8; 1] = &[2];
@ -114,7 +116,7 @@ impl SecretSpendingKey {
hasher.update(PREFIX); hasher.update(PREFIX);
hasher.update(self.0); hasher.update(self.0);
hasher.update(SUFFIX_1); hasher.update(SUFFIX_1);
hasher.update(index.to_le_bytes()); hasher.update(index.to_be_bytes());
hasher.update(SUFFIX_2); hasher.update(SUFFIX_2);
hasher.finalize_fixed().into() hasher.finalize_fixed().into()

View File

@ -46,7 +46,7 @@ impl NSSAUserData {
) -> bool { ) -> bool {
let mut check_res = true; let mut check_res = true;
for (account_id, (key, _)) in accounts_keys_map { for (account_id, (key, _)) in accounts_keys_map {
let expected_account_id = nssa::AccountId::from(&key.nullifer_public_key); let expected_account_id = nssa::AccountId::from(&key.nullifier_public_key);
if expected_account_id != *account_id { if expected_account_id != *account_id {
println!("{expected_account_id}, {account_id}"); println!("{expected_account_id}, {account_id}");
check_res = false; check_res = false;

View File

@ -37,4 +37,4 @@ test-case = "3.3.1"
[features] [features]
default = [] default = []
prove = ["risc0-zkvm/prove"] prove = ["risc0-zkvm/prove"]
test-utils = [] test-utils = []

View File

@ -8,10 +8,12 @@ license = { workspace = true }
workspace = true workspace = true
[dependencies] [dependencies]
nssa = { workspace = true, optional = true, features = ["test-utils"], default-features = true } nssa = { workspace = true, optional = true, features = [
"test-utils",
], default-features = true }
nssa_core.workspace = true nssa_core.workspace = true
token_core.workspace = true token_core.workspace = true
amm_core.workspace = true amm_core.workspace = true
[features] [features]
nssa = ["dep:nssa"] nssa = ["dep:nssa"]

View File

@ -20,50 +20,50 @@
"indexer_rpc_url": "ws://localhost:8779", "indexer_rpc_url": "ws://localhost:8779",
"initial_accounts": [ "initial_accounts": [
{ {
"account_id": "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV", "account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r",
"balance": 10000 "balance": 10000
}, },
{ {
"account_id": "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo", "account_id": "2RHZhw9h534Zr3eq2RGhQete2Hh667foECzXPmSkGni2",
"balance": 20000 "balance": 20000
} }
], ],
"initial_commitments": [ "initial_commitments": [
{ {
"npk":[ "npk": [
177, 139,
64, 19,
1, 158,
11, 11,
87, 155,
38,
254,
159,
231, 231,
165, 85,
1, 206,
94, 132,
64, 228,
137, 220,
243, 114,
76, 145,
249, 89,
101, 113,
251, 156,
129, 238,
33, 142,
101, 242,
189, 74,
30, 182,
42, 91,
11, 43,
191, 100,
34, 6,
103, 190,
186, 31,
227, 15,
230 31,
] , 88,
96,
204
],
"account": { "account": {
"program_owner": [ "program_owner": [
0, 0,
@ -82,38 +82,38 @@
}, },
{ {
"npk": [ "npk": [
32, 173,
67,
72,
164,
106,
53,
66,
239,
141,
15,
52,
230,
136,
177,
2,
236,
207,
243,
134, 134,
135, 33,
210, 223,
143, 54,
87, 226,
232, 10,
71,
215, 215,
128, 254,
194, 143,
120, 172,
113, 24,
224, 244,
4, 243,
165 208,
65,
112,
118,
70,
217,
240,
69,
100,
129,
3,
121,
25,
213,
132,
42,
45
], ],
"account": { "account": {
"program_owner": [ "program_owner": [
@ -166,4 +166,4 @@
37, 37,
37 37
] ]
} }

View File

@ -20,49 +20,49 @@
"indexer_rpc_url": "ws://localhost:8779", "indexer_rpc_url": "ws://localhost:8779",
"initial_accounts": [ "initial_accounts": [
{ {
"account_id": "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV", "account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r",
"balance": 10000 "balance": 10000
}, },
{ {
"account_id": "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo", "account_id": "2RHZhw9h534Zr3eq2RGhQete2Hh667foECzXPmSkGni2",
"balance": 20000 "balance": 20000
} }
], ],
"initial_commitments": [ "initial_commitments": [
{ {
"npk": [ "npk": [
63, 139,
202, 19,
178, 158,
11,
155,
231, 231,
183, 85,
82, 206,
237, 132,
212,
216,
221,
215,
255,
153,
101,
177,
161,
254,
210,
128,
122,
54,
190,
230,
151,
183,
64,
225,
229,
113,
1,
228, 228,
97 220,
114,
145,
89,
113,
156,
238,
142,
242,
74,
182,
91,
43,
100,
6,
190,
31,
15,
31,
88,
96,
204
], ],
"account": { "account": {
"program_owner": [ "program_owner": [
@ -82,38 +82,38 @@
}, },
{ {
"npk": [ "npk": [
192, 173,
251, 134,
166, 33,
243, 223,
167, 54,
236, 226,
84, 10,
249, 71,
35, 215,
136, 254,
130, 143,
172, 172,
219, 24,
225,
161,
139,
229,
89,
243,
125,
194,
213,
209,
30,
23,
174,
100,
244, 244,
124, 243,
74, 208,
140, 65,
47 112,
118,
70,
217,
240,
69,
100,
129,
3,
121,
25,
213,
132,
42,
45
], ],
"account": { "account": {
"program_owner": [ "program_owner": [

View File

@ -123,7 +123,7 @@ pub unsafe extern "C" fn wallet_ffi_get_private_account_keys(
}; };
// NPK is a 32-byte array // NPK is a 32-byte array
let npk_bytes = key_chain.nullifer_public_key.0; let npk_bytes = key_chain.nullifier_public_key.0;
// VPK is a compressed secp256k1 point (33 bytes) // VPK is a compressed secp256k1 point (33 bytes)
let vpk_bytes = key_chain.viewing_public_key.to_bytes(); let vpk_bytes = key_chain.viewing_public_key.to_bytes();

View File

@ -1,147 +1,479 @@
{ {
"override_rust_log": null, "override_rust_log": null,
"sequencer_addr": "http://127.0.0.1:3040", "sequencer_addr": "http://127.0.0.1:3040",
"seq_poll_timeout": "30s", "seq_poll_timeout": "30s",
"seq_tx_poll_max_blocks": 15, "seq_tx_poll_max_blocks": 15,
"seq_poll_max_retries": 10, "seq_poll_max_retries": 10,
"seq_block_poll_max_amount": 100, "seq_block_poll_max_amount": 100,
"initial_accounts": [ "initial_accounts": [
{
"Public": {
"account_id": "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV",
"pub_sign_key": [
16,
162,
106,
154,
236,
125,
52,
184,
35,
100,
238,
174,
69,
197,
41,
77,
187,
10,
118,
75,
0,
11,
148,
238,
185,
181,
133,
17,
220,
72,
124,
77
]
}
},
{
"Public": {
"account_id": "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo",
"pub_sign_key": [
113,
121,
64,
177,
204,
85,
229,
214,
178,
6,
109,
191,
29,
154,
63,
38,
242,
18,
244,
219,
8,
208,
35,
136,
23,
127,
207,
237,
216,
169,
190,
27
]
}
},
{ {
"Private": { "Public": {
"account_id": "2ECgkFTaXzwjJBXR7ZKmXYQtpHbvTTHK9Auma4NL9AUo", "account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r",
"account": { "pub_sign_key": [
"program_owner": [ 127,
0, 39,
0, 48,
0, 152,
0, 242,
0, 91,
0, 113,
0, 230,
0 192,
], 5,
"balance": 10000, 169,
"data": [], 81,
"nonce": 0 159,
38,
120,
218,
141,
28,
127,
1,
246,
162,
119,
120,
226,
217,
148,
138,
189,
249,
1,
251
]
}
}, },
"key_chain": { {
"secret_spending_key": [112, 17, 152, 192, 217, 201, 142, 92, 111, 68, 85, 222, 107, 73, 78, 196, 118, 226, 37, 17, 185, 177, 149, 182, 9, 85, 187, 152, 163, 144, 68, 121], "Public": {
"private_key_holder": { "account_id": "2RHZhw9h534Zr3eq2RGhQete2Hh667foECzXPmSkGni2",
"nullifier_secret_key": [52, 33, 235, 245, 42, 132, 163, 182, 114, 56, 144, 187, 147, 23, 184, 227, 128, 12, 180, 142, 217, 110, 188, 177, 155, 141, 23, 127, 216, 185, 33, 126], "pub_sign_key": [
"viewing_secret_key": [44, 81, 165, 166, 34, 188, 192, 240, 40, 9, 83, 189, 215, 184, 246, 154, 247, 227, 155, 16, 121, 238, 4, 245, 63, 135, 192, 213, 222, 247, 120, 86] 244,
}, 52,
"nullifer_public_key": [13, 25, 40, 5, 198, 248, 210, 248, 237, 121, 124, 145, 186, 142, 253, 216, 236, 69, 193, 32, 166, 167, 49, 133, 172, 111, 159, 46, 84, 17, 157, 23], 248,
"viewing_public_key": [3, 43, 116, 165, 161, 27, 150, 158, 175, 198, 215, 27, 121, 126, 158, 224, 249, 92, 168, 163, 173, 115, 120, 122, 89, 173, 133, 94, 39, 238, 62, 52, 193] 116,
} 23,
} 32,
}, 1,
{ 69,
"Private": { 134,
"account_id": "E8HwiTyQe4H9HK7icTvn95HQMnzx49mP9A2ddtMLpNaN", 174,
"account": { 67,
"program_owner": [ 53,
0, 109,
0, 42,
0, 236,
0, 98,
0, 87,
0, 218,
0, 8,
0 98,
], 34,
"balance": 20000, 246,
"data": [], 4,
"nonce": 0 221,
183,
93,
105,
115,
59,
134,
252,
76
]
}
}, },
"key_chain": { {
"secret_spending_key": [48, 175, 124, 10, 230, 240, 166, 14, 249, 254, 157, 226, 208, 124, 122, 177, 203, 139, 192, 180, 43, 120, 55, 151, 50, 21, 113, 22, 254, 83, 148, 56], "Private": {
"private_key_holder": { "account_id": "HWkW5qd4XK3me6sCAb4bfPj462k33DjtKtEcYpuzNwB",
"nullifier_secret_key": [99, 82, 190, 140, 234, 10, 61, 163, 15, 211, 179, 54, 70, 166, 87, 5, 182, 68, 117, 244, 217, 23, 99, 9, 4, 177, 230, 125, 109, 91, 160, 30], "account": {
"viewing_secret_key": [205, 32, 76, 251, 255, 236, 96, 119, 61, 111, 65, 100, 75, 218, 12, 22, 17, 170, 55, 226, 21, 154, 161, 34, 208, 74, 27, 1, 119, 13, 88, 128] "program_owner": [
}, 0,
"nullifer_public_key": [32, 67, 72, 164, 106, 53, 66, 239, 141, 15, 52, 230, 136, 177, 2, 236, 207, 243, 134, 135, 210, 143, 87, 232, 215, 128, 194, 120, 113, 224, 4, 165], 0,
"viewing_public_key": [2, 79, 110, 46, 203, 29, 206, 205, 18, 86, 27, 189, 104, 103, 113, 181, 110, 53, 78, 172, 11, 171, 190, 18, 126, 214, 81, 77, 192, 154, 58, 195, 238] 0,
0,
0,
0,
0,
0
],
"balance": 10000,
"data": [],
"nonce": 0
},
"key_chain": {
"secret_spending_key": [
14,
202,
241,
109,
32,
181,
152,
140,
76,
153,
108,
57,
77,
192,
181,
97,
108,
144,
122,
45,
219,
5,
203,
193,
82,
123,
83,
34,
250,
214,
137,
63
],
"private_key_holder": {
"nullifier_secret_key": [
174,
56,
101,
30,
248,
249,
100,
0,
122,
199,
209,
246,
58,
163,
223,
146,
59,
143,
78,
95,
41,
186,
106,
187,
53,
63,
75,
244,
233,
185,
110,
199
],
"viewing_secret_key": [
251,
85,
223,
73,
142,
127,
134,
132,
185,
210,
100,
103,
198,
108,
229,
80,
176,
211,
249,
114,
110,
7,
225,
17,
7,
69,
204,
32,
47,
242,
103,
247
]
},
"nullifier_public_key": [
139,
19,
158,
11,
155,
231,
85,
206,
132,
228,
220,
114,
145,
89,
113,
156,
238,
142,
242,
74,
182,
91,
43,
100,
6,
190,
31,
15,
31,
88,
96,
204
],
"viewing_public_key": [
3,
136,
153,
50,
191,
184,
135,
36,
29,
107,
57,
9,
218,
135,
249,
213,
118,
215,
118,
173,
30,
137,
116,
77,
17,
86,
62,
154,
31,
173,
19,
167,
211
]
}
}
},
{
"Private": {
"account_id": "HUpbRQ1vEcZv5y6TDYv9tpt1VA64ji2v4RDLJfK2rpZn",
"account": {
"program_owner": [
0,
0,
0,
0,
0,
0,
0,
0
],
"balance": 20000,
"data": [],
"nonce": 0
},
"key_chain": {
"secret_spending_key": [
32,
162,
244,
221,
2,
133,
168,
250,
240,
52,
92,
187,
157,
116,
249,
203,
143,
194,
214,
112,
115,
142,
153,
78,
241,
173,
103,
242,
192,
196,
29,
133
],
"private_key_holder": {
"nullifier_secret_key": [
188,
235,
121,
54,
131,
206,
7,
215,
94,
231,
102,
22,
12,
27,
253,
161,
248,
206,
41,
160,
206,
149,
5,
217,
127,
235,
154,
230,
198,
232,
102,
31
],
"viewing_secret_key": [
89,
116,
140,
122,
211,
179,
190,
229,
18,
94,
56,
235,
48,
99,
104,
228,
111,
72,
231,
18,
247,
97,
110,
60,
238,
138,
0,
25,
92,
44,
30,
145
]
},
"nullifier_public_key": [
173,
134,
33,
223,
54,
226,
10,
71,
215,
254,
143,
172,
24,
244,
243,
208,
65,
112,
118,
70,
217,
240,
69,
100,
129,
3,
121,
25,
213,
132,
42,
45
],
"viewing_public_key": [
2,
43,
42,
253,
112,
83,
195,
164,
26,
141,
92,
28,
224,
120,
155,
119,
225,
1,
45,
42,
245,
172,
134,
136,
52,
183,
170,
96,
115,
212,
114,
120,
37
]
}
}
} }
} ],
} "basic_auth": null
],
"basic_auth": null
} }

View File

@ -174,40 +174,40 @@ mod tests {
let initial_acc1 = serde_json::from_str( let initial_acc1 = serde_json::from_str(
r#"{ r#"{
"Public": { "Public": {
"account_id": "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV", "account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r",
"pub_sign_key": [ "pub_sign_key": [
16, 127,
39,
48,
152,
242,
91,
113,
230,
192,
5,
169,
81,
159,
38,
120,
218,
141,
28,
127,
1,
246,
162, 162,
106, 119,
154, 120,
236, 226,
125, 217,
52,
184,
35,
100,
238,
174,
69,
197,
41,
77,
187,
10,
118,
75,
0,
11,
148, 148,
238, 138,
185, 189,
181, 249,
133, 1,
17, 251
220,
72,
124,
77
] ]
} }
}"#, }"#,
@ -217,40 +217,40 @@ mod tests {
let initial_acc2 = serde_json::from_str( let initial_acc2 = serde_json::from_str(
r#"{ r#"{
"Public": { "Public": {
"account_id": "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo", "account_id": "2RHZhw9h534Zr3eq2RGhQete2Hh667foECzXPmSkGni2",
"pub_sign_key": [ "pub_sign_key": [
113,
121,
64,
177,
204,
85,
229,
214,
178,
6,
109,
191,
29,
154,
63,
38,
242,
18,
244, 244,
219, 52,
8, 248,
208, 116,
35,
136,
23, 23,
127, 32,
207, 1,
237, 69,
216, 134,
169, 174,
190, 67,
27 53,
109,
42,
236,
98,
87,
218,
8,
98,
34,
246,
4,
221,
183,
93,
105,
115,
59,
134,
252,
76
] ]
} }
}"#, }"#,

View File

@ -145,7 +145,7 @@ impl WalletSubcommand for NewSubcommand {
println!( println!(
"Generated new account with account_id Private/{account_id} at path {chain_index}", "Generated new account with account_id Private/{account_id} at path {chain_index}",
); );
println!("With npk {}", hex::encode(key.nullifer_public_key.0)); println!("With npk {}", hex::encode(key.nullifier_public_key.0));
println!( println!(
"With vpk {}", "With vpk {}",
hex::encode(key.viewing_public_key.to_bytes()) hex::encode(key.viewing_public_key.to_bytes())
@ -208,7 +208,7 @@ impl WalletSubcommand for AccountSubcommand {
.get_private_account(account_id) .get_private_account(account_id)
.context("Private account not found in storage")?; .context("Private account not found in storage")?;
println!("npk {}", hex::encode(key.nullifer_public_key.0)); println!("npk {}", hex::encode(key.nullifier_public_key.0));
println!("vpk {}", hex::encode(key.viewing_public_key.to_bytes())); println!("vpk {}", hex::encode(key.viewing_public_key.to_bytes()));
} }
} }

View File

@ -219,88 +219,88 @@ impl Default for WalletConfig {
basic_auth: None, basic_auth: None,
initial_accounts: { initial_accounts: {
let init_acc_json = r#" let init_acc_json = r#"
[ [
{ {
"Public": { "Public": {
"account_id": "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV", "account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r",
"pub_sign_key": [ "pub_sign_key": [
16, 127,
39,
48,
152,
242,
91,
113,
230,
192,
5,
169,
81,
159,
38,
120,
218,
141,
28,
127,
1,
246,
162, 162,
106, 119,
154, 120,
236, 226,
125, 217,
52,
184,
35,
100,
238,
174,
69,
197,
41,
77,
187,
10,
118,
75,
0,
11,
148, 148,
238, 138,
185, 189,
181, 249,
133, 1,
17, 251
220,
72,
124,
77
] ]
} }
}, },
{ {
"Public": { "Public": {
"account_id": "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo", "account_id": "2RHZhw9h534Zr3eq2RGhQete2Hh667foECzXPmSkGni2",
"pub_sign_key": [ "pub_sign_key": [
113,
121,
64,
177,
204,
85,
229,
214,
178,
6,
109,
191,
29,
154,
63,
38,
242,
18,
244, 244,
219, 52,
8, 248,
208, 116,
35,
136,
23, 23,
127, 32,
207, 1,
237, 69,
216, 134,
169, 174,
190, 67,
27 53,
109,
42,
236,
98,
87,
218,
8,
98,
34,
246,
4,
221,
183,
93,
105,
115,
59,
134,
252,
76
] ]
} }
}, },
{ {
"Private": { "Private": {
"account_id": "FpdcxBrMkHWqXCBQ6FG98eYfWGY6jWZRsKNSi1FwDMxy", "account_id": "HWkW5qd4XK3me6sCAb4bfPj462k33DjtKtEcYpuzNwB",
"account": { "account": {
"program_owner": [ "program_owner": [
0, 0,
@ -318,151 +318,184 @@ impl Default for WalletConfig {
}, },
"key_chain": { "key_chain": {
"secret_spending_key": [ "secret_spending_key": [
239, 14,
27, 202,
159, 241,
83, 109,
199, 32,
194, 181,
132,
33,
20,
28,
217,
103,
101,
57,
27,
125,
84,
57,
19,
86,
98,
135,
161,
221,
108,
125,
152, 152,
174, 140,
161, 76,
64, 153,
16, 108,
200 57,
77,
192,
181,
97,
108,
144,
122,
45,
219,
5,
203,
193,
82,
123,
83,
34,
250,
214,
137,
63
], ],
"private_key_holder": { "private_key_holder": {
"nullifier_secret_key": [ "nullifier_secret_key": [
71, 174,
195, 56,
16, 101,
119, 30,
248,
249,
100,
0, 0,
98,
35,
106,
139,
82,
145,
50,
27,
140,
206,
19,
53,
122, 122,
166, 199,
76, 209,
195, 246,
0, 58,
16, 163,
19, 223,
21, 146,
59,
143, 143,
155, 78,
119, 95,
9, 41,
200, 186,
81, 106,
105 187,
53,
63,
75,
244,
233,
185,
110,
199
], ],
"viewing_secret_key": [ "viewing_secret_key": [
5, 251,
117, 85,
221, 223,
27, 73,
236, 142,
199, 127,
53, 134,
22, 132,
185,
210,
100,
103,
198,
108,
229,
80,
176,
211,
249, 249,
231, 114,
98, 110,
147, 7,
213, 225,
116, 17,
191, 7,
82, 69,
188, 204,
148, 32,
175, 47,
98, 242,
139, 103,
52, 247
232,
249,
220,
217,
83,
58,
112,
155,
197,
196
] ]
}, },
"nullifer_public_key": [ "nullifier_public_key": [
177, 139,
64, 19,
1, 158,
11, 11,
87, 155,
38,
254,
159,
231, 231,
165, 85,
1, 206,
94, 132,
64, 228,
137, 220,
243, 114,
76, 145,
249, 89,
101, 113,
251, 156,
129, 238,
33, 142,
101, 242,
189, 74,
30, 182,
42, 91,
11, 43,
191, 100,
34, 6,
103, 190,
186, 31,
227, 15,
230 31,
88,
96,
204
], ],
"viewing_public_key": [ "viewing_public_key": [
2, 69, 126, 43, 158, 209, 172, 144, 23, 185, 208, 25, 163, 166, 176, 200, 225, 251, 106, 211, 4, 199, 112, 243, 207, 144, 135, 56, 157, 167, 32, 219, 38] 3,
136,
153,
50,
191,
184,
135,
36,
29,
107,
57,
9,
218,
135,
249,
213,
118,
215,
118,
173,
30,
137,
116,
77,
17,
86,
62,
154,
31,
173,
19,
167,
211
]
} }
} }
}, },
{ {
"Private": { "Private": {
"account_id": "E8HwiTyQe4H9HK7icTvn95HQMnzx49mP9A2ddtMLpNaN", "account_id": "HUpbRQ1vEcZv5y6TDYv9tpt1VA64ji2v4RDLJfK2rpZn",
"account": { "account": {
"program_owner": [ "program_owner": [
0, 0,
@ -480,20 +513,177 @@ impl Default for WalletConfig {
}, },
"key_chain": { "key_chain": {
"secret_spending_key": [ "secret_spending_key": [
48, 175, 124, 10, 230, 240, 166, 14, 249, 254, 157, 226, 208, 124, 122, 177, 203, 139, 192, 180, 43, 120, 55, 151, 50, 21, 113, 22, 254, 83, 148, 56], 32,
162,
244,
221,
2,
133,
168,
250,
240,
52,
92,
187,
157,
116,
249,
203,
143,
194,
214,
112,
115,
142,
153,
78,
241,
173,
103,
242,
192,
196,
29,
133
],
"private_key_holder": { "private_key_holder": {
"nullifier_secret_key": [ "nullifier_secret_key": [
99, 82, 190, 140, 234, 10, 61, 163, 15, 211, 179, 54, 70, 166, 87, 5, 182, 68, 117, 244, 217, 23, 99, 9, 4, 177, 230, 125, 109, 91, 160, 30 188,
235,
121,
54,
131,
206,
7,
215,
94,
231,
102,
22,
12,
27,
253,
161,
248,
206,
41,
160,
206,
149,
5,
217,
127,
235,
154,
230,
198,
232,
102,
31
], ],
"viewing_secret_key": [ "viewing_secret_key": [
205, 32, 76, 251, 255, 236, 96, 119, 61, 111, 65, 100, 75, 218, 12, 22, 17, 170, 55, 226, 21, 154, 161, 34, 208, 74, 27, 1, 119, 13, 88, 128 89,
116,
140,
122,
211,
179,
190,
229,
18,
94,
56,
235,
48,
99,
104,
228,
111,
72,
231,
18,
247,
97,
110,
60,
238,
138,
0,
25,
92,
44,
30,
145
] ]
}, },
"nullifer_public_key": [ "nullifier_public_key": [
32, 67, 72, 164, 106, 53, 66, 239, 141, 15, 52, 230, 136, 177, 2, 236, 207, 243, 134, 135, 210, 143, 87, 232, 215, 128, 194, 120, 113, 224, 4, 165 173,
134,
33,
223,
54,
226,
10,
71,
215,
254,
143,
172,
24,
244,
243,
208,
65,
112,
118,
70,
217,
240,
69,
100,
129,
3,
121,
25,
213,
132,
42,
45
], ],
"viewing_public_key": [ "viewing_public_key": [
2, 79, 110, 46, 203, 29, 206, 205, 18, 86, 27, 189, 104, 103, 113, 181, 110, 53, 78, 172, 11, 171, 190, 18, 126, 214, 81, 77, 192, 154, 58, 195, 238 2,
43,
42,
253,
112,
83,
195,
164,
26,
141,
92,
28,
224,
120,
155,
119,
225,
1,
45,
42,
245,
172,
134,
136,
52,
183,
170,
96,
115,
212,
114,
120,
37
] ]
} }
} }

View File

@ -265,7 +265,7 @@ impl WalletCore {
#[must_use] #[must_use]
pub fn get_private_account_commitment(&self, account_id: AccountId) -> Option<Commitment> { pub fn get_private_account_commitment(&self, account_id: AccountId) -> Option<Commitment> {
let (keys, account) = self.storage.user_data.get_private_account(account_id)?; let (keys, account) = self.storage.user_data.get_private_account(account_id)?;
Some(Commitment::new(&keys.nullifer_public_key, account)) Some(Commitment::new(&keys.nullifier_public_key, account))
} }
/// Poll transactions. /// Poll transactions.
@ -469,7 +469,7 @@ impl WalletCore {
let affected_accounts = private_account_key_chains let affected_accounts = private_account_key_chains
.flat_map(|(acc_account_id, key_chain, index)| { .flat_map(|(acc_account_id, key_chain, index)| {
let view_tag = EncryptedAccountData::compute_view_tag( let view_tag = EncryptedAccountData::compute_view_tag(
&key_chain.nullifer_public_key, &key_chain.nullifier_public_key,
&key_chain.viewing_public_key, &key_chain.viewing_public_key,
); );

View File

@ -214,7 +214,7 @@ async fn private_acc_preparation(
let nsk = from_keys.private_key_holder.nullifier_secret_key; let nsk = from_keys.private_key_holder.nullifier_secret_key;
let from_npk = from_keys.nullifer_public_key; let from_npk = from_keys.nullifier_public_key;
let from_vpk = from_keys.viewing_public_key; let from_vpk = from_keys.viewing_public_key;
// TODO: Remove this unwrap, error types must be compatible // TODO: Remove this unwrap, error types must be compatible

View File

@ -39,7 +39,7 @@ impl WalletCore {
let mut nsk = None; let mut nsk = None;
let mut proof = None; let mut proof = None;
let from_npk = from_keys.nullifer_public_key; let from_npk = from_keys.nullifier_public_key;
let from_vpk = from_keys.viewing_public_key; let from_vpk = from_keys.viewing_public_key;
let sender_commitment = Commitment::new(&from_npk, &from_acc); let sender_commitment = Commitment::new(&from_npk, &from_acc);