refactor(lee): verbose key domains and the ask key chain

This commit is contained in:
Artem Gureev 2026-08-03 12:30:50 +00:00
parent cbd10c5bba
commit fc8f7f2d42
18 changed files with 379 additions and 396 deletions

View File

@ -592,7 +592,8 @@ async fn ppt_cant_chain_call_faucet() -> Result<()> {
let faucet_program_id = programs::faucet().id();
let vault_program_id = programs::vault().id();
let auth_transfer_program_id = programs::authenticated_transfer().id();
let nsk: lee_core::NullifierSecretKey = [3; 32];
let ask = lee_core::AuthorizationSecretKey([3; 32]);
let nsk = lee_core::NullifierSecretKey::from(&ask);
let npk = NullifierPublicKey::from(&nsk);
let vpk = ViewingPublicKey::from_bytes(vec![4_u8; 1184]).unwrap();
let attacker_vault_id = {
@ -661,7 +662,8 @@ async fn prove_init_with_commitment_root(
sender_id,
);
let nsk: lee_core::NullifierSecretKey = [7; 32];
let ask = lee_core::AuthorizationSecretKey([7; 32]);
let nsk = lee_core::NullifierSecretKey::from(&ask);
let npk = NullifierPublicKey::from(&nsk);
let vpk = ViewingPublicKey::from_bytes(vec![4_u8; 1184]).unwrap();
let recipient_account_id = AccountId::for_regular_private_account(&npk, &vpk, 0);
@ -697,7 +699,8 @@ async fn init_with_dummy_commitment_root_produces_valid_root() -> Result<()> {
let (_, expected_digest) = ctx.sequencer_client().get_proofs_and_root(vec![]).await?;
let nsk: lee_core::NullifierSecretKey = [7; 32];
let ask = lee_core::AuthorizationSecretKey([7; 32]);
let nsk = lee_core::NullifierSecretKey::from(&ask);
let npk = NullifierPublicKey::from(&nsk);
let vpk = ViewingPublicKey::from_bytes(vec![4_u8; 1184]).unwrap();
let recipient_account_id = AccountId::for_regular_private_account(&npk, &vpk, 0);

View File

@ -22,8 +22,8 @@ use lee::{
public_transaction as putx,
};
use lee_core::{
DUMMY_COMMITMENT_HASH, InputAccountIdentity, MembershipProof, NullifierPublicKey,
NullifierWitness, PrivateWitness, WitnessKind,
AuthorizationSecretKey, DUMMY_COMMITMENT_HASH, InputAccountIdentity, MembershipProof,
NullifierPublicKey, NullifierSecretKey, NullifierWitness, PrivateWitness, WitnessKind,
account::{AccountWithMetadata, Nonce, data::Data},
encryption::ViewingPublicKey,
};
@ -255,7 +255,8 @@ pub async fn tps_test() -> Result<()> {
#[expect(dead_code, reason = "No idea if we need this, should we remove it?")]
fn build_privacy_transaction() -> PrivacyPreservingTransaction {
let program = programs::authenticated_transfer();
let sender_nsk = [1; 32];
let sender_ask = AuthorizationSecretKey([1; 32]);
let sender_nsk = NullifierSecretKey::from(&sender_ask);
let sender_vpk = ViewingPublicKey::from_seed(&[99_u8; 32], &[100_u8; 32]);
let sender_npk = NullifierPublicKey::from(&sender_nsk);
let sender_pre = AccountWithMetadata::new(
@ -268,7 +269,8 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
true,
AccountId::for_regular_private_account(&sender_npk, &sender_vpk, 0),
);
let recipient_nsk = [2; 32];
let recipient_ask = AuthorizationSecretKey([2; 32]);
let recipient_nsk = NullifierSecretKey::from(&recipient_ask);
let recipient_vpk = ViewingPublicKey::from_seed(&[101_u8; 32], &[102_u8; 32]);
let recipient_npk = NullifierPublicKey::from(&recipient_nsk);
let recipient_pre = AccountWithMetadata::new(

View File

@ -339,7 +339,7 @@ mod tests {
}
/// Pins the end-to-end derivation for a fixed (GMS, `ProgramId`, `PdaSeed`). Any change
/// to `secret_spending_key_for_pda`, the `PrivateKeyHolder` nsk/npk chain, or the
/// to `secret_spending_key_for_pda`, the `PrivateKeyHolder` ask/nsk/npk chain, or the
/// `AccountId::for_private_pda` formula breaks this test. Mirrors the pinned-value
/// pattern from `for_private_pda_matches_pinned_value` in `lee_core`.
#[test]
@ -357,8 +357,8 @@ mod tests {
let account_id = AccountId::for_private_pda(&program_id, &seed, &npk, &vpk, u128::MAX);
let expected_npk = NullifierPublicKey([
136, 176, 234, 71, 208, 8, 143, 142, 126, 155, 132, 18, 71, 27, 88, 56, 100, 90, 79,
215, 76, 92, 60, 166, 104, 35, 51, 91, 16, 114, 188, 112,
73, 227, 101, 209, 210, 127, 85, 171, 217, 20, 52, 68, 63, 127, 88, 157, 162, 165, 221,
15, 86, 162, 128, 15, 56, 89, 95, 33, 216, 229, 181, 123,
]);
// AccountId is derived from (program_id, seed, npk), so it changes when npk changes.
// We verify npk is pinned, and AccountId is deterministically derived from it.

View File

@ -1,6 +1,8 @@
use std::collections::BTreeMap;
use lee_core::{NullifierPublicKey, PrivateAccountKind, encryption::ViewingPublicKey};
use lee_core::{
NullifierPublicKey, NullifierSecretKey, PrivateAccountKind, encryption::ViewingPublicKey,
};
use serde::{Deserialize, Serialize};
use sha2::Digest as _;
@ -36,7 +38,7 @@ impl ChildKeysPrivate {
// to generate the `ssk` and `ccc` values.
let mut parent_hash = sha2::Sha256::new();
parent_hash.update(b"LEE/keys");
parent_hash.update(self.value.0.private_key_holder.nullifier_secret_key);
parent_hash.update(self.value.0.private_key_holder.nullifier_secret_key());
parent_hash.update(self.value.0.private_key_holder.viewing_secret_key.d);
parent_hash.update(self.value.0.private_key_holder.viewing_secret_key.z);
let parent_pt = parent_hash.finalize();
@ -58,10 +60,10 @@ impl ChildKeysPrivate {
}
fn from_ssk_and_ccc(ssk: SecretSpendingKey, ccc: [u8; 32], cci: Option<u32>) -> Self {
let nsk = ssk.generate_nullifier_secret_key(cci);
let ask = ssk.generate_authorization_secret_key(cci);
let vsk = ssk.generate_viewing_secret_seed_key(cci);
let npk = NullifierPublicKey::from(&nsk);
let npk = NullifierPublicKey::from(&NullifierSecretKey::from(&ask));
let vpk = ViewingPublicKey::from(&vsk);
Self {
@ -71,7 +73,7 @@ impl ChildKeysPrivate {
nullifier_public_key: npk,
viewing_public_key: vpk,
private_key_holder: PrivateKeyHolder {
nullifier_secret_key: nsk,
authorization_secret_key: ask,
viewing_secret_key: vsk,
},
},
@ -130,95 +132,104 @@ mod tests {
111, 13, 5, 195, 75, 20, 255, 162, 85, 40, 251, 8, 168,
];
let expected_ask = lee_core::AuthorizationSecretKey([
3, 154, 34, 187, 166, 138, 64, 10, 172, 210, 224, 75, 165, 157, 94, 27, 81, 209, 194,
189, 60, 171, 252, 226, 25, 136, 158, 59, 56, 39, 60, 175,
]);
let expected_nsk: NullifierSecretKey = [
154, 102, 103, 5, 34, 235, 227, 13, 22, 182, 226, 11, 7, 67, 110, 162, 99, 193, 174,
34, 234, 19, 222, 2, 22, 12, 163, 252, 88, 11, 0, 163,
227, 13, 41, 248, 160, 185, 37, 158, 48, 134, 157, 185, 50, 249, 13, 114, 128, 43, 92,
148, 161, 91, 158, 206, 209, 246, 46, 49, 114, 165, 72, 64,
];
let expected_npk = lee_core::NullifierPublicKey([
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,
42, 60, 83, 112, 244, 198, 238, 159, 150, 105, 13, 134, 103, 228, 213, 247, 121, 42,
65, 51, 122, 196, 228, 163, 244, 251, 219, 119, 8, 14, 68, 16,
]);
let expected_vsk = ViewingSecretKey::new(
[
187, 143, 146, 12, 68, 148, 25, 203, 21, 92, 131, 2, 221, 81, 117, 62, 98, 194,
159, 177, 102, 254, 236, 182, 76, 242, 116, 219, 17, 166, 99, 36,
92, 182, 50, 80, 228, 152, 149, 83, 44, 33, 179, 59, 237, 153, 45, 46, 216, 142,
62, 31, 28, 18, 44, 27, 130, 54, 10, 13, 148, 111, 214, 107,
],
[
80, 97, 83, 209, 145, 99, 168, 99, 89, 29, 153, 236, 82, 99, 134, 114, 168, 19,
223, 69, 34, 47, 76, 76, 15, 97, 245, 184, 25, 103, 251, 82,
135, 73, 174, 183, 171, 136, 40, 174, 28, 18, 73, 1, 183, 13, 208, 39, 113, 79,
136, 163, 234, 119, 117, 192, 103, 49, 193, 16, 188, 111, 4, 78,
],
);
// Length matches MlKem768EncapsulationKey::LEN.
// Length matches MlKem768EncapsulationKey::LEN. Oracle-sourced from the ML-KEM-768
// implementation, unlike every other vector here; its trailing 32 bytes are
// rho = SHA3-512(d || 3)[..32] per FIPS-203, checked against the independent `d`.
let expected_vpk: [u8; 1184] = [
127, 229, 162, 212, 104, 117, 4, 150, 192, 103, 122, 195, 14, 35, 12, 60, 52, 23, 220,
150, 100, 203, 34, 34, 127, 232, 156, 43, 218, 109, 6, 160, 67, 35, 210, 194, 25, 181,
118, 237, 25, 129, 51, 160, 189, 51, 99, 184, 57, 28, 121, 240, 236, 2, 170, 198, 26,
91, 172, 110, 52, 32, 186, 35, 179, 202, 234, 249, 15, 242, 100, 198, 168, 163, 120,
205, 118, 85, 195, 210, 187, 95, 150, 154, 8, 68, 165, 237, 87, 166, 101, 57, 4, 18,
11, 122, 235, 180, 199, 154, 165, 158, 55, 136, 30, 237, 43, 167, 215, 68, 80, 102, 0,
71, 90, 130, 206, 240, 215, 69, 199, 83, 7, 60, 184, 128, 230, 184, 61, 93, 201, 204,
165, 104, 9, 127, 220, 52, 246, 217, 131, 251, 2, 170, 133, 6, 51, 40, 224, 101, 61,
16, 135, 32, 182, 201, 68, 58, 171, 54, 161, 184, 243, 38, 106, 200, 251, 17, 172, 8,
24, 73, 230, 55, 85, 20, 147, 222, 165, 200, 116, 135, 47, 20, 227, 56, 220, 64, 120,
215, 245, 58, 86, 102, 149, 252, 193, 163, 160, 59, 82, 138, 249, 171, 1, 54, 199, 193,
171, 85, 38, 64, 56, 121, 106, 84, 57, 252, 94, 147, 16, 191, 196, 104, 47, 129, 84,
21, 252, 160, 81, 207, 184, 199, 3, 177, 74, 117, 115, 175, 138, 108, 36, 198, 5, 32,
15, 218, 3, 20, 19, 15, 251, 209, 86, 128, 139, 148, 78, 10, 34, 144, 149, 74, 102, 48,
59, 70, 124, 47, 193, 100, 26, 9, 104, 178, 102, 156, 199, 242, 101, 147, 161, 87, 27,
234, 192, 204, 41, 36, 43, 83, 219, 15, 211, 66, 91, 76, 73, 13, 113, 155, 203, 193,
160, 130, 84, 103, 47, 70, 100, 147, 169, 65, 119, 84, 121, 122, 161, 76, 203, 144,
248, 145, 22, 8, 46, 121, 44, 77, 20, 149, 66, 179, 56, 149, 231, 98, 184, 9, 64, 14,
67, 196, 34, 8, 123, 21, 80, 169, 168, 223, 230, 133, 0, 66, 159, 230, 69, 201, 205,
169, 105, 196, 21, 71, 84, 70, 58, 165, 165, 134, 186, 232, 60, 70, 51, 57, 239, 74,
174, 116, 234, 36, 178, 49, 42, 168, 250, 104, 141, 106, 0, 109, 52, 86, 104, 243, 62,
214, 137, 48, 107, 2, 152, 206, 227, 175, 147, 236, 19, 113, 27, 191, 231, 235, 167,
114, 104, 23, 126, 203, 94, 242, 149, 171, 115, 170, 89, 244, 58, 29, 176, 73, 203, 44,
8, 32, 9, 226, 32, 78, 246, 38, 235, 149, 133, 25, 243, 47, 124, 180, 200, 211, 165,
137, 56, 169, 117, 31, 244, 65, 91, 135, 146, 158, 20, 75, 102, 32, 65, 250, 103, 199,
36, 48, 31, 155, 164, 191, 222, 85, 37, 66, 243, 17, 120, 104, 0, 228, 83, 200, 116, 6,
199, 106, 236, 139, 246, 216, 152, 241, 211, 85, 106, 200, 44, 231, 240, 66, 3, 193,
147, 16, 145, 65, 49, 33, 53, 247, 69, 47, 44, 113, 86, 117, 6, 20, 193, 183, 128, 178,
181, 21, 251, 99, 39, 149, 210, 146, 106, 181, 186, 7, 36, 63, 186, 234, 191, 164, 193,
162, 127, 250, 122, 189, 219, 21, 92, 48, 86, 209, 184, 99, 160, 201, 162, 145, 20,
138, 154, 18, 37, 180, 209, 165, 165, 51, 187, 78, 193, 175, 135, 6, 55, 216, 178, 10,
40, 246, 98, 128, 80, 14, 38, 69, 113, 123, 54, 94, 43, 50, 106, 167, 17, 77, 163, 148,
117, 225, 9, 7, 253, 240, 157, 96, 103, 33, 100, 37, 37, 20, 53, 138, 234, 55, 45, 232,
154, 9, 150, 192, 116, 36, 119, 106, 95, 119, 34, 220, 84, 174, 19, 227, 33, 209, 96,
197, 148, 230, 197, 59, 117, 130, 7, 116, 11, 0, 197, 16, 249, 151, 31, 4, 64, 29, 165,
247, 110, 176, 166, 4, 112, 136, 101, 208, 7, 179, 38, 183, 134, 58, 107, 207, 160, 38,
159, 67, 112, 20, 225, 199, 179, 133, 117, 144, 54, 199, 15, 204, 80, 154, 116, 84, 88,
109, 113, 5, 207, 226, 21, 62, 247, 122, 14, 156, 9, 8, 76, 26, 148, 67, 196, 128, 176,
78, 51, 161, 151, 75, 248, 154, 31, 168, 9, 4, 3, 107, 222, 245, 178, 21, 84, 7, 25,
155, 118, 97, 135, 63, 89, 233, 11, 207, 148, 155, 38, 106, 104, 102, 140, 104, 67,
149, 20, 30, 196, 44, 197, 128, 34, 182, 80, 30, 32, 137, 34, 212, 164, 177, 164, 12,
115, 41, 156, 111, 71, 230, 120, 111, 218, 25, 117, 218, 75, 167, 32, 37, 57, 50, 99,
181, 203, 40, 105, 248, 150, 114, 121, 73, 127, 198, 191, 161, 44, 56, 213, 243, 71, 2,
56, 192, 243, 107, 179, 27, 96, 21, 116, 169, 64, 15, 97, 166, 151, 200, 11, 40, 204,
71, 168, 220, 9, 55, 43, 146, 244, 212, 166, 192, 180, 189, 237, 162, 42, 29, 33, 52,
193, 4, 178, 157, 244, 28, 209, 44, 26, 36, 147, 126, 94, 164, 37, 47, 115, 38, 23,
165, 96, 106, 140, 42, 69, 146, 194, 93, 71, 175, 49, 147, 32, 246, 97, 94, 41, 116,
127, 174, 18, 16, 14, 163, 17, 180, 213, 203, 166, 33, 139, 214, 18, 170, 27, 41, 59,
175, 200, 101, 14, 128, 45, 179, 167, 136, 232, 138, 56, 124, 145, 75, 233, 132, 161,
196, 164, 72, 80, 60, 187, 38, 90, 90, 17, 66, 134, 59, 2, 165, 29, 76, 24, 38, 211,
177, 83, 119, 20, 239, 59, 77, 34, 3, 42, 47, 60, 89, 46, 103, 168, 120, 17, 199, 50,
17, 103, 107, 48, 8, 53, 220, 159, 212, 65, 198, 80, 8, 11, 235, 97, 203, 196, 240, 44,
56, 121, 77, 91, 196, 160, 129, 242, 149, 226, 57, 106, 180, 76, 161, 203, 18, 37, 166,
153, 44, 40, 28, 74, 8, 11, 6, 166, 54, 10, 103, 247, 23, 35, 7, 47, 173, 133, 71, 85,
3, 168, 250, 120, 126, 174, 37, 80, 128, 107, 7, 161, 130, 155, 136, 92, 48, 215, 119,
196, 124, 85, 157, 234, 2, 166, 137, 65, 121, 222, 112, 47, 17, 43, 23, 111, 88, 5,
195, 41, 8, 191, 227, 21, 173, 35, 199, 196, 188, 162, 191, 195, 204, 137, 54, 16, 73,
178, 150, 249, 234, 22, 216, 123, 157, 144, 218, 118, 53, 193, 67, 65, 84, 162, 244,
165, 24, 110, 246, 146, 228, 212, 180, 150, 116, 201, 37, 128, 76, 41, 188, 42, 79,
148, 52, 196, 176, 178, 224, 48, 168, 13, 129, 193, 131, 185, 131, 93, 40, 145, 56,
180, 29, 153, 83, 39, 69, 232, 96, 238, 137, 104, 150, 2, 202, 239, 149, 248, 154, 115,
115, 127, 3, 8, 32, 61, 96, 66, 25, 181, 14, 72, 73, 97, 186, 134, 140, 33, 69, 33, 74,
95, 42, 170, 49, 164, 173, 200, 156, 66, 32, 71, 126, 122, 140, 148, 144, 114, 143,
233, 199, 104, 82, 179, 49, 43, 114, 130, 182, 71, 4, 45, 101, 65, 136, 196, 72, 129,
128, 204, 239, 137, 84, 230, 210, 18, 214, 252, 40, 198, 210, 24, 158, 53, 151, 166,
24, 47, 143, 8, 158, 119, 240, 204, 210, 242, 96, 191, 147, 106, 98, 198, 93, 193, 163,
31, 132, 36, 16, 50, 83, 24, 225, 250, 106, 55, 231, 188, 90, 194, 128, 10, 225, 186,
41, 225, 165, 126, 57, 32, 163, 129, 42, 68, 113, 177, 239, 106, 144, 217, 188, 192,
174, 38, 161, 189, 24, 107, 14, 54, 167, 221, 120, 194, 6, 22, 163, 86, 96, 47, 220,
227, 176, 173, 52, 150, 183, 25, 40, 200, 19, 134, 51, 172, 126, 35, 147, 79, 207, 235,
9, 243, 197, 84, 4, 194, 142, 207, 118, 121, 133, 58, 12, 58, 226, 22, 106, 172, 56,
223, 161, 145, 60, 28, 47, 95, 84, 127, 1, 235, 72, 0, 131, 202, 15, 151, 93, 52, 18,
13, 247, 91, 80, 240, 229, 85, 72, 135, 84, 230, 113, 196, 162, 3, 24, 87, 176, 80,
202, 99, 44, 87, 229, 96, 254, 27, 181, 181, 58, 191, 116, 19, 68, 235, 35, 86, 227,
89, 49, 70, 102, 54, 153, 224, 117, 34, 113, 57, 121, 202, 42, 248, 24, 125, 134, 134,
57, 126, 204, 131, 191, 181, 71, 197, 184, 137, 48, 76, 29, 174, 137, 154, 253, 50, 68,
184, 122, 173, 106, 144, 207, 48, 213, 156, 182, 26, 103, 203, 133, 131, 47, 184, 189,
109, 4, 182, 126, 71, 180, 153, 18, 82, 77, 201, 23, 176, 92, 12, 146, 48, 26, 236,
139, 157, 174, 214, 77, 253, 163, 94, 52, 133, 88, 200, 251, 156, 197, 201, 7, 239,
117, 83, 57, 188, 85, 31, 196, 106, 164, 147, 36, 32, 241, 143, 54, 121, 195, 183, 98,
182, 135, 90, 84, 118, 212, 91, 115, 41, 75, 193, 156, 44, 9, 196, 199, 241, 123, 148,
31, 105, 126, 160, 234, 16, 196, 149, 192, 66, 34, 199, 132, 160, 98, 229, 90, 158, 46,
108, 112, 126, 165, 115, 234, 128, 164, 241, 132, 171, 186, 212, 121, 74, 217, 165,
111, 216, 21, 169, 89, 86, 173, 163, 183, 61, 28, 117, 104, 211, 206, 30, 194, 180, 34,
180, 151, 150, 212, 90, 75, 139, 138, 253, 52, 60, 252, 5, 126, 152, 12, 153, 77, 232,
167, 14, 163, 130, 76, 18, 117, 96, 113, 144, 234, 22, 56, 106, 210, 78, 83, 50, 43,
99, 120, 20, 172, 89, 61, 10, 75, 121, 118, 226, 153, 53, 161, 144, 53, 246, 37, 213,
216, 48, 183, 124, 58, 161, 145, 126, 238, 120, 112, 103, 65, 176, 40, 104, 60, 47, 10,
138, 154, 89, 174, 164, 69, 182, 168, 196, 131, 68, 18, 189, 204, 74, 180, 16, 233,
178, 175, 57, 180, 212, 58, 148, 92, 2, 16, 255, 103, 27, 212, 117, 12, 10, 54, 105,
253, 9, 124, 250, 210, 14, 127, 151, 74, 49, 209, 59, 125, 184, 183, 175, 251, 200,
172, 120, 59, 41, 89, 199, 3, 161, 189, 138, 50, 69, 108, 102, 155, 210, 17, 73, 235,
75, 145, 132, 67, 89, 88, 225, 182, 156, 248, 199, 112, 52, 22, 134, 80, 40, 250, 42,
185, 57, 200, 90, 137, 16, 158, 98, 114, 48, 151, 35, 128, 49, 49, 118, 195, 57, 40,
94, 103, 156, 186, 1, 112, 130, 178, 59, 22, 71, 153, 173, 195, 178, 216, 149, 24, 202,
245, 123, 117, 106, 44, 55, 128, 37, 165, 26, 103, 158, 52, 10, 188, 10, 195, 146, 204,
85, 66, 66, 162, 73, 25, 59, 107, 57, 149, 100, 216, 24, 69, 49, 134, 233, 96, 29, 176,
8, 188, 121, 145, 44, 35, 199, 4, 48, 24, 76, 69, 250, 92, 126, 40, 52, 162, 72, 113,
81, 96, 116, 105, 150, 59, 211, 236, 141, 87, 178, 9, 17, 117, 43, 139, 17, 150, 153,
114, 195, 212, 2, 192, 56, 91, 70, 200, 75, 2, 57, 171, 147, 184, 236, 15, 64, 26, 191,
131, 179, 13, 195, 195, 166, 208, 180, 93, 186, 155, 102, 189, 57, 82, 73, 39, 44, 249,
249, 183, 33, 112, 59, 130, 20, 193, 41, 40, 128, 131, 106, 136, 51, 75, 56, 188, 167,
119, 5, 118, 73, 84, 168, 38, 121, 182, 190, 252, 182, 87, 142, 33, 66, 131, 75, 36,
216, 181, 186, 213, 148, 191, 182, 115, 159, 83, 1, 14, 170, 55, 21, 251, 65, 135, 117,
171, 147, 38, 210, 129, 251, 151, 177, 213, 1, 18, 22, 241, 62, 173, 80, 76, 85, 129,
139, 192, 137, 205, 203, 114, 181, 121, 40, 141, 9, 194, 58, 20, 200, 126, 151, 51,
129, 146, 92, 156, 93, 192, 72, 26, 33, 138, 107, 138, 124, 193, 138, 8, 244, 84, 116,
28, 156, 123, 1, 19, 186, 119, 231, 157, 70, 160, 5, 34, 80, 201, 4, 39, 38, 217, 85,
53, 10, 40, 136, 145, 225, 26, 65, 32, 76, 33, 245, 72, 166, 5, 165, 44, 67, 86, 99,
87, 9, 148, 131, 72, 223, 71, 179, 243, 39, 36, 34, 145, 86, 134, 12, 127, 103, 3, 191,
254, 216, 195, 12, 197, 184, 238, 67, 34, 226, 4, 100, 135, 165, 40, 164, 113, 110,
132, 68, 100, 72, 217, 67, 169, 199, 96, 120, 152, 27, 26, 241, 103, 61, 162, 154, 113,
55, 75, 156, 17, 114, 105, 145, 158, 13, 251, 50, 221, 219, 150, 88, 5, 184, 92, 137,
164, 25, 117, 51, 87, 233, 93, 5, 84, 125, 251, 162, 110, 231, 36, 2, 235, 251, 185,
45, 180, 132, 53, 104, 206, 144, 133, 67, 164, 76, 84, 152, 236, 157, 253, 115, 97,
195, 177, 172, 233, 51, 161, 196, 66, 59, 233, 88, 133, 12, 146, 172, 148, 236, 58, 5,
226, 48, 53, 219, 185, 72, 86, 7, 249, 151, 205, 32, 57, 163, 17, 71, 37, 162, 97, 137,
142, 252, 190, 58, 196, 70, 181, 4, 48, 123, 9, 75, 198, 100, 134, 36, 18, 45, 99, 18,
191, 75, 55, 30, 144, 197, 0, 44, 71, 199, 78, 121, 92, 76, 84, 43, 133, 139, 77, 105,
83, 178, 221, 215, 108, 55, 58, 7, 106, 96, 146, 9, 70, 140, 250, 187, 206, 95, 54, 74,
30, 146, 15, 182, 5, 79, 41, 135, 59, 75, 103, 82, 63, 39, 69, 178, 215, 49, 234, 146,
127, 186, 192, 189, 107, 140, 11, 39, 162, 120, 90, 133, 106, 184, 87, 144, 5, 80, 80,
22, 241, 181, 128, 201, 61, 186, 124, 9, 165, 192, 78, 67, 141, 57, 10, 94, 36, 75,
118, 21, 105, 252, 45, 196, 60, 23, 182, 189, 252, 152, 182, 72, 229, 213, 89, 165,
222, 151, 52, 182, 110, 127, 158,
];
assert!(expected_ssk == keys.value.0.secret_spending_key);
assert!(expected_ccc == keys.ccc);
assert!(expected_nsk == keys.value.0.private_key_holder.nullifier_secret_key);
assert!(expected_ask == keys.value.0.private_key_holder.authorization_secret_key);
assert!(expected_nsk == keys.value.0.private_key_holder.nullifier_secret_key());
assert!(expected_npk == keys.value.0.nullifier_public_key);
assert!(expected_vsk == keys.value.0.private_key_holder.viewing_secret_key);
assert!(expected_vpk == keys.value.0.viewing_public_key.to_bytes());
@ -230,105 +241,119 @@ mod tests {
let child_node = ChildKeysPrivate::nth_child(&root_node, 42_u32);
let expected_ssk = key_management::secret_holders::SecretSpendingKey([
151, 183, 113, 151, 215, 187, 207, 64, 197, 182, 207, 32, 5, 49, 180, 98, 119, 14, 248,
175, 39, 100, 47, 109, 148, 173, 217, 253, 159, 234, 209, 113,
147, 244, 221, 25, 228, 53, 3, 55, 123, 178, 86, 169, 79, 154, 246, 163, 157, 33, 28,
244, 16, 118, 43, 39, 193, 5, 29, 152, 132, 154, 95, 26,
]);
let expected_ccc = [
138, 243, 142, 163, 62, 107, 63, 131, 230, 158, 185, 60, 204, 50, 243, 222, 13, 123,
98, 116, 131, 194, 7, 25, 129, 209, 163, 72, 178, 143, 192, 240,
18, 103, 41, 76, 65, 124, 115, 176, 148, 75, 103, 77, 166, 183, 172, 236, 189, 17, 53,
249, 173, 195, 106, 161, 244, 2, 14, 94, 158, 49, 84, 164,
];
let expected_ask = lee_core::AuthorizationSecretKey([
11, 214, 158, 158, 46, 193, 62, 186, 255, 46, 72, 251, 83, 23, 191, 113, 182, 211, 86,
144, 187, 225, 221, 167, 83, 141, 174, 223, 217, 171, 50, 87,
]);
let expected_nsk: NullifierSecretKey = [
196, 33, 11, 39, 220, 84, 119, 182, 187, 194, 135, 20, 124, 33, 244, 205, 96, 58, 102,
52, 74, 67, 110, 213, 24, 16, 160, 64, 247, 3, 107, 235,
89, 206, 155, 18, 194, 73, 132, 144, 61, 65, 163, 8, 52, 169, 8, 140, 255, 86, 219,
218, 141, 64, 238, 76, 118, 16, 30, 186, 23, 70, 79, 222,
];
let expected_npk = lee_core::NullifierPublicKey([
247, 253, 217, 86, 157, 208, 39, 172, 59, 190, 88, 165, 7, 173, 183, 106, 172, 211, 4,
180, 51, 107, 177, 107, 51, 117, 231, 176, 200, 103, 1, 121,
29, 80, 209, 224, 61, 151, 130, 4, 70, 165, 106, 126, 91, 188, 92, 203, 46, 39, 37, 11,
136, 10, 158, 67, 32, 147, 250, 231, 112, 76, 133, 178,
]);
let expected_vsk = ViewingSecretKey::new(
[
185, 209, 179, 92, 7, 131, 98, 121, 215, 46, 154, 56, 238, 106, 162, 225, 83, 82,
134, 3, 80, 186, 35, 178, 161, 204, 205, 163, 28, 19, 149, 18,
87, 215, 216, 10, 193, 212, 245, 90, 212, 110, 113, 151, 70, 34, 227, 123, 166,
189, 105, 219, 135, 194, 119, 50, 69, 66, 100, 121, 13, 217, 34, 135,
],
[
174, 24, 72, 205, 129, 123, 131, 9, 146, 152, 224, 151, 10, 184, 224, 109, 94, 149,
117, 60, 26, 10, 212, 125, 113, 147, 87, 67, 73, 26, 101, 193,
103, 65, 25, 44, 172, 134, 69, 145, 152, 56, 155, 81, 211, 101, 141, 240, 222, 39,
175, 218, 137, 42, 131, 133, 193, 25, 222, 112, 3, 80, 255, 98,
],
);
// Length matches MlKem768EncapsulationKey::LEN.
// Length matches MlKem768EncapsulationKey::LEN. Oracle-sourced from the ML-KEM-768
// implementation, unlike every other vector here; its trailing 32 bytes are
// rho = SHA3-512(d || 3)[..32] per FIPS-203, checked against the independent `d`.
let expected_vpk: [u8; 1184] = [
215, 229, 207, 120, 148, 177, 148, 197, 72, 222, 134, 3, 231, 146, 123, 226, 36, 84,
232, 179, 205, 16, 241, 142, 9, 81, 58, 54, 12, 115, 148, 182, 19, 245, 22, 203, 57,
71, 11, 204, 156, 130, 30, 170, 199, 201, 25, 2, 21, 34, 155, 136, 124, 145, 223, 128,
177, 207, 92, 38, 252, 165, 118, 61, 128, 71, 154, 242, 105, 165, 52, 7, 6, 244, 120,
227, 134, 191, 25, 169, 150, 123, 246, 138, 25, 196, 126, 156, 144, 33, 123, 120, 44,
142, 89, 201, 49, 219, 205, 87, 236, 110, 64, 129, 102, 100, 155, 26, 101, 121, 42,
236, 82, 111, 141, 117, 75, 71, 194, 73, 123, 170, 110, 69, 149, 107, 96, 195, 55, 122,
140, 131, 106, 140, 156, 147, 75, 28, 128, 138, 113, 86, 37, 63, 173, 214, 200, 2, 214,
84, 234, 176, 120, 252, 184, 99, 192, 65, 112, 150, 99, 26, 174, 187, 183, 187, 64, 90,
248, 100, 66, 63, 195, 3, 44, 43, 128, 59, 149, 107, 66, 180, 67, 200, 183, 200, 36,
91, 7, 65, 228, 159, 79, 44, 89, 35, 163, 145, 92, 227, 104, 2, 72, 5, 7, 193, 21, 51,
116, 198, 184, 6, 192, 188, 68, 183, 163, 193, 142, 244, 217, 155, 197, 187, 189, 174,
225, 45, 126, 112, 93, 194, 156, 102, 150, 1, 188, 222, 76, 108, 73, 149, 44, 28, 219,
66, 95, 215, 204, 148, 217, 16, 36, 121, 112, 2, 51, 10, 195, 137, 12, 93, 203, 146,
138, 211, 15, 201, 42, 72, 146, 186, 160, 222, 235, 127, 83, 48, 182, 49, 248, 29, 138,
16, 32, 232, 179, 163, 187, 161, 174, 152, 187, 93, 76, 166, 48, 230, 219, 111, 123,
181, 103, 130, 28, 109, 235, 115, 45, 57, 193, 206, 160, 17, 52, 92, 194, 25, 3, 80,
97, 142, 249, 151, 94, 250, 95, 12, 57, 11, 165, 92, 47, 85, 182, 48, 22, 60, 97, 244,
59, 194, 135, 180, 133, 106, 227, 56, 192, 60, 91, 15, 241, 146, 89, 240, 130, 219,
202, 187, 43, 85, 98, 50, 104, 64, 114, 113, 80, 54, 69, 69, 5, 43, 90, 19, 0, 0, 188,
251, 184, 70, 160, 18, 117, 76, 53, 209, 166, 96, 34, 224, 137, 115, 183, 168, 243, 19,
1, 255, 4, 97, 162, 199, 104, 72, 213, 111, 62, 54, 172, 82, 184, 82, 143, 71, 99, 25,
104, 74, 120, 70, 84, 235, 32, 22, 20, 218, 163, 77, 194, 125, 75, 22, 72, 236, 192,
200, 107, 91, 156, 201, 10, 178, 87, 19, 181, 211, 91, 17, 145, 200, 17, 179, 65, 75,
200, 186, 89, 144, 91, 184, 116, 214, 51, 91, 42, 162, 243, 202, 92, 18, 54, 0, 213,
67, 149, 151, 51, 29, 220, 196, 160, 201, 68, 113, 210, 164, 175, 152, 121, 168, 231,
161, 91, 132, 218, 1, 171, 176, 84, 100, 57, 1, 3, 2, 196, 194, 76, 181, 79, 171, 157,
35, 162, 155, 192, 210, 149, 142, 120, 189, 127, 151, 96, 202, 225, 73, 242, 81, 112,
237, 224, 155, 130, 130, 34, 196, 153, 131, 161, 113, 163, 172, 114, 48, 207, 32, 151,
172, 83, 145, 79, 210, 100, 161, 92, 82, 216, 90, 104, 238, 212, 38, 50, 107, 17, 228,
195, 190, 6, 151, 165, 148, 245, 102, 51, 8, 185, 8, 85, 59, 247, 219, 95, 219, 170,
155, 233, 123, 27, 64, 251, 56, 24, 200, 16, 181, 212, 146, 61, 116, 106, 215, 214, 62,
118, 27, 68, 233, 148, 73, 135, 199, 74, 184, 89, 159, 217, 139, 24, 208, 250, 30, 224,
97, 185, 237, 193, 8, 216, 23, 186, 5, 50, 41, 161, 203, 22, 217, 23, 194, 191, 148,
124, 10, 212, 171, 209, 210, 145, 184, 171, 74, 35, 220, 43, 145, 241, 23, 43, 92, 171,
216, 43, 114, 77, 155, 147, 156, 86, 56, 170, 27, 1, 54, 182, 169, 96, 22, 201, 51,
145, 94, 143, 133, 106, 47, 176, 112, 197, 197, 96, 80, 73, 164, 207, 179, 22, 229,
171, 201, 223, 219, 13, 219, 1, 91, 224, 252, 171, 199, 217, 25, 60, 128, 135, 9, 71,
105, 231, 86, 34, 21, 155, 50, 0, 105, 72, 117, 108, 175, 140, 9, 181, 249, 139, 97, 3,
161, 66, 248, 42, 67, 113, 132, 8, 119, 232, 6, 169, 18, 157, 222, 53, 176, 56, 137,
120, 18, 115, 199, 187, 112, 48, 223, 211, 206, 152, 252, 108, 179, 129, 20, 227, 248,
183, 234, 87, 202, 49, 17, 69, 215, 118, 89, 188, 180, 33, 238, 245, 206, 40, 179, 129,
242, 59, 73, 254, 117, 114, 250, 179, 103, 109, 250, 202, 99, 152, 2, 167, 130, 169,
35, 71, 89, 211, 140, 71, 103, 154, 121, 108, 147, 191, 186, 73, 10, 73, 203, 23, 55,
106, 144, 98, 227, 157, 25, 27, 81, 67, 11, 57, 88, 227, 116, 61, 100, 94, 23, 166,
146, 57, 226, 72, 124, 33, 65, 226, 35, 167, 206, 156, 202, 213, 213, 158, 89, 249,
181, 19, 113, 109, 217, 71, 168, 142, 180, 122, 30, 5, 54, 170, 155, 73, 56, 170, 124,
139, 4, 165, 103, 82, 32, 183, 84, 7, 239, 117, 135, 239, 48, 24, 28, 210, 49, 137, 6,
158, 65, 211, 113, 205, 135, 146, 83, 10, 46, 90, 27, 97, 135, 135, 185, 173, 69, 58,
34, 247, 141, 150, 6, 158, 117, 23, 198, 139, 65, 81, 179, 187, 194, 247, 203, 127,
106, 232, 119, 122, 215, 197, 110, 69, 203, 174, 227, 63, 185, 106, 14, 184, 104, 113,
233, 83, 92, 104, 38, 188, 9, 135, 107, 108, 121, 193, 33, 209, 89, 39, 137, 17, 208,
26, 21, 238, 169, 86, 181, 193, 153, 82, 8, 151, 53, 39, 88, 91, 252, 3, 33, 75, 127,
9, 168, 53, 34, 1, 173, 202, 123, 157, 174, 170, 199, 254, 187, 196, 144, 37, 29, 48,
112, 173, 107, 147, 155, 69, 134, 137, 156, 247, 123, 242, 72, 5, 43, 106, 89, 179,
204, 41, 15, 60, 48, 78, 214, 180, 26, 170, 67, 71, 66, 146, 113, 220, 159, 153, 201,
176, 116, 154, 21, 186, 33, 180, 72, 39, 187, 240, 80, 112, 132, 144, 173, 210, 12, 76,
184, 146, 89, 178, 178, 82, 109, 71, 201, 241, 160, 207, 219, 124, 77, 2, 105, 124,
178, 71, 3, 38, 64, 41, 83, 170, 137, 82, 242, 144, 76, 102, 82, 7, 25, 149, 141, 169,
46, 4, 68, 40, 244, 146, 131, 107, 148, 18, 111, 85, 104, 243, 28, 75, 176, 249, 88,
82, 123, 89, 29, 104, 135, 230, 117, 67, 26, 249, 108, 145, 76, 38, 175, 89, 185, 94,
106, 128, 201, 150, 151, 194, 133, 21, 81, 213, 231, 15, 117, 44, 61, 86, 223, 162, 56,
190, 166, 177, 157, 137, 60, 208, 155, 234, 158, 252, 30,
70, 98, 188, 35, 130, 206, 210, 76, 99, 161, 241, 144, 206, 228, 9, 64, 229, 7, 98, 67,
101, 1, 53, 181, 205, 7, 43, 212, 16, 207, 248, 34, 80, 88, 18, 51, 104, 163, 6, 33,
119, 127, 223, 148, 109, 72, 52, 53, 190, 193, 153, 2, 68, 97, 142, 118, 59, 64, 6,
108, 56, 99, 136, 111, 50, 130, 13, 90, 73, 154, 85, 126, 246, 146, 39, 18, 104, 88, 8,
90, 13, 109, 124, 22, 52, 104, 24, 244, 179, 19, 84, 85, 63, 14, 138, 53, 185, 167, 15,
82, 218, 67, 155, 184, 88, 58, 122, 136, 189, 12, 179, 96, 12, 25, 224, 197, 72, 222,
85, 41, 48, 228, 133, 135, 139, 29, 213, 250, 177, 85, 75, 201, 115, 242, 47, 156, 145,
40, 50, 33, 85, 168, 4, 85, 83, 198, 207, 246, 220, 138, 131, 166, 134, 42, 114, 116,
190, 164, 15, 64, 227, 8, 214, 88, 1, 118, 197, 79, 179, 194, 18, 184, 84, 163, 163,
12, 49, 140, 115, 84, 222, 136, 117, 140, 215, 169, 179, 240, 118, 51, 68, 130, 99,
152, 170, 26, 7, 54, 188, 81, 76, 196, 25, 133, 147, 218, 136, 212, 42, 27, 178, 48,
129, 207, 167, 137, 35, 154, 1, 137, 213, 166, 105, 107, 46, 1, 103, 29, 18, 132, 29,
210, 150, 10, 117, 129, 45, 248, 97, 38, 245, 113, 200, 165, 130, 87, 161, 100, 25,
132, 53, 135, 154, 139, 86, 92, 9, 171, 130, 72, 75, 228, 212, 180, 1, 7, 67, 81, 208,
178, 239, 37, 182, 156, 196, 113, 3, 198, 191, 60, 24, 131, 58, 10, 14, 35, 249, 38,
144, 97, 22, 66, 27, 105, 153, 210, 173, 182, 54, 177, 122, 180, 191, 7, 149, 127, 125,
214, 46, 9, 0, 88, 246, 69, 33, 166, 120, 47, 138, 18, 53, 160, 215, 76, 93, 122, 103,
139, 90, 160, 78, 149, 31, 53, 161, 46, 92, 228, 161, 169, 149, 166, 48, 48, 76, 229,
102, 68, 80, 37, 137, 220, 44, 39, 143, 252, 40, 242, 90, 114, 140, 17, 191, 158, 225,
102, 201, 181, 190, 215, 164, 100, 131, 76, 7, 126, 199, 151, 24, 59, 50, 94, 248, 132,
4, 113, 89, 50, 115, 199, 206, 48, 1, 224, 88, 19, 32, 20, 196, 255, 71, 197, 180, 211,
139, 139, 131, 88, 204, 107, 123, 132, 145, 4, 74, 252, 106, 165, 113, 81, 79, 4, 111,
140, 244, 15, 216, 86, 42, 253, 243, 29, 21, 55, 46, 200, 242, 199, 216, 97, 49, 53, 3,
134, 221, 178, 117, 192, 40, 149, 6, 212, 32, 222, 218, 100, 75, 200, 171, 19, 155, 45,
186, 248, 180, 147, 140, 191, 242, 6, 96, 69, 200, 74, 213, 116, 0, 204, 209, 154, 220,
219, 44, 5, 216, 40, 0, 109, 4, 233, 236, 130, 181, 186, 188, 115, 59, 174, 207, 74,
19, 210, 41, 162, 1, 203, 141, 58, 72, 196, 219, 186, 113, 236, 138, 186, 107, 115,
119, 254, 42, 201, 237, 2, 62, 89, 176, 52, 47, 59, 36, 188, 214, 185, 185, 187, 191,
34, 160, 29, 185, 184, 15, 12, 210, 97, 252, 160, 38, 141, 164, 143, 33, 68, 6, 25,
170, 192, 134, 24, 178, 164, 137, 57, 95, 245, 188, 224, 182, 94, 5, 52, 141, 104, 26,
41, 8, 39, 98, 226, 244, 3, 237, 90, 24, 201, 250, 92, 120, 152, 26, 150, 230, 71, 192,
154, 74, 201, 180, 62, 16, 140, 15, 167, 90, 16, 96, 65, 185, 232, 145, 63, 212, 156,
160, 191, 38, 207, 46, 131, 97, 51, 98, 142, 116, 138, 92, 104, 186, 56, 229, 140, 92,
196, 193, 204, 107, 139, 22, 34, 0, 39, 50, 10, 159, 222, 115, 4, 90, 170, 64, 150,
116, 37, 172, 86, 24, 144, 248, 126, 251, 144, 119, 73, 36, 7, 50, 102, 14, 134, 216,
16, 38, 185, 0, 29, 185, 191, 2, 82, 3, 14, 225, 24, 170, 74, 118, 158, 180, 18, 95, 1,
192, 120, 68, 112, 21, 2, 130, 16, 235, 133, 67, 18, 171, 147, 179, 159, 146, 236, 162,
254, 152, 200, 102, 104, 131, 71, 246, 134, 124, 64, 97, 118, 89, 159, 188, 166, 104,
59, 7, 187, 224, 124, 194, 38, 248, 132, 233, 231, 53, 96, 208, 172, 11, 203, 9, 92,
55, 63, 164, 114, 118, 2, 56, 63, 197, 92, 91, 98, 196, 37, 25, 23, 206, 172, 249, 19,
156, 165, 91, 36, 216, 17, 195, 163, 192, 37, 86, 98, 44, 201, 74, 163, 117, 157, 174,
74, 34, 250, 183, 63, 194, 91, 131, 1, 12, 5, 147, 136, 176, 107, 84, 34, 69, 230, 153,
106, 87, 160, 68, 170, 75, 39, 230, 172, 113, 91, 8, 231, 244, 51, 23, 124, 43, 32,
176, 141, 43, 153, 5, 24, 107, 161, 216, 71, 177, 44, 195, 134, 28, 17, 127, 137, 245,
23, 250, 232, 98, 157, 186, 199, 224, 162, 34, 155, 180, 65, 82, 234, 1, 147, 162, 98,
128, 194, 121, 90, 150, 183, 35, 250, 124, 207, 33, 70, 65, 25, 195, 143, 228, 70, 193,
86, 73, 75, 128, 36, 219, 75, 143, 231, 91, 77, 223, 216, 163, 62, 185, 207, 111, 215,
163, 49, 65, 128, 10, 247, 78, 88, 230, 127, 222, 203, 36, 149, 210, 171, 76, 26, 105,
85, 18, 139, 24, 80, 148, 231, 58, 194, 153, 87, 84, 103, 210, 79, 236, 203, 52, 95,
74, 164, 84, 192, 99, 40, 215, 123, 114, 244, 102, 89, 97, 160, 255, 212, 68, 206, 50,
133, 145, 132, 82, 93, 117, 39, 227, 134, 84, 80, 211, 28, 110, 163, 127, 19, 2, 22,
46, 124, 53, 213, 12, 31, 161, 70, 153, 251, 105, 121, 52, 145, 124, 7, 203, 107, 252,
33, 145, 70, 243, 82, 69, 241, 20, 121, 54, 201, 135, 58, 183, 17, 161, 150, 62, 69,
76, 253, 34, 206, 192, 171, 119, 101, 113, 128, 185, 32, 185, 185, 84, 17, 59, 40, 40,
52, 20, 98, 81, 85, 8, 42, 58, 189, 65, 219, 101, 124, 72, 44, 108, 128, 147, 120, 123,
171, 213, 17, 5, 157, 200, 141, 55, 118, 174, 232, 160, 155, 36, 117, 193, 24, 2, 117,
204, 209, 199, 72, 233, 38, 99, 88, 85, 122, 160, 11, 88, 84, 79, 232, 50, 34, 195,
136, 128, 47, 128, 186, 109, 179, 129, 205, 26, 81, 65, 242, 17, 13, 250, 48, 41, 220,
71, 126, 3, 23, 221, 52, 196, 62, 153, 102, 167, 242, 188, 195, 89, 170, 91, 131, 6,
157, 28, 78, 58, 201, 176, 185, 202, 90, 233, 112, 172, 105, 2, 129, 252, 38, 101, 194,
181, 7, 196, 76, 68, 114, 20, 208, 215, 62, 49, 209, 90, 29, 238, 78, 190, 42, 134,
255, 44, 171, 200, 73, 155, 242, 162, 87, 76, 97, 216, 137, 95, 83,
];
assert!(expected_ssk == child_node.value.0.secret_spending_key);
assert!(expected_ccc == child_node.ccc);
assert!(expected_nsk == child_node.value.0.private_key_holder.nullifier_secret_key);
assert!(
expected_ask
== child_node
.value
.0
.private_key_holder
.authorization_secret_key
);
assert!(expected_nsk == child_node.value.0.private_key_holder.nullifier_secret_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_vpk == child_node.value.0.viewing_public_key.to_bytes());

View File

@ -1,6 +1,8 @@
use bip39::Mnemonic;
use common::HashType;
use lee_core::{NullifierPublicKey, NullifierSecretKey, encryption::ViewingPublicKey};
use lee_core::{
AuthorizationSecretKey, NullifierPublicKey, NullifierSecretKey, encryption::ViewingPublicKey,
};
use ml_kem;
use rand::{RngCore as _, rngs::OsRng};
use serde::{Deserialize, Serialize};
@ -36,7 +38,7 @@ impl ViewingSecretKey {
/// for recepient.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct PrivateKeyHolder {
pub nullifier_secret_key: NullifierSecretKey,
pub authorization_secret_key: AuthorizationSecretKey,
pub viewing_secret_key: ViewingSecretKey,
}
@ -87,41 +89,35 @@ impl SeedHolder {
impl SecretSpendingKey {
#[must_use]
#[expect(clippy::big_endian_bytes, reason = "BIP-032 uses big endian")]
pub fn generate_nullifier_secret_key(&self, index: Option<u32>) -> NullifierSecretKey {
const PREFIX: &[u8; 8] = b"LEE/keys";
const SUFFIX_1: &[u8; 1] = &[1];
const SUFFIX_2: &[u8; 19] = &[0; 19];
pub fn generate_authorization_secret_key(&self, index: Option<u32>) -> AuthorizationSecretKey {
const DOMAIN: &[u8; 35] = b"/LEE/v0.3/Keys/Authorization/Secret";
let index = index.unwrap_or(0);
let mut hasher = sha2::Sha256::new();
hasher.update(PREFIX);
hasher.update(DOMAIN);
hasher.update(self.0);
hasher.update(SUFFIX_1);
hasher.update(index.to_be_bytes());
hasher.update(SUFFIX_2);
<NullifierSecretKey>::from(hasher.finalize_fixed())
AuthorizationSecretKey(hasher.finalize_fixed().into())
}
#[must_use]
pub fn generate_nullifier_secret_key(&self, index: Option<u32>) -> NullifierSecretKey {
<NullifierSecretKey>::from(&self.generate_authorization_secret_key(index))
}
#[must_use]
#[expect(clippy::big_endian_bytes, reason = "BIP-032 uses big endian")]
pub fn generate_viewing_secret_seed_key(&self, index: Option<u32>) -> ViewingSecretKey {
const PREFIX: &[u8; 8] = b"LEE/keys";
const SUFFIX_1: &[u8; 1] = &[2];
const SUFFIX_2: &[u8; 19] = &[0; 19];
const DOMAIN: &[u8; 29] = b"/LEE/v0.3/Keys/Viewing/Secret";
let index = index.unwrap_or(0);
let mut bytes: Vec<u8> = Vec::with_capacity(64);
bytes.extend_from_slice(PREFIX);
bytes.extend_from_slice(&self.0);
bytes.extend_from_slice(SUFFIX_1);
bytes.extend_from_slice(&index.to_be_bytes());
bytes.extend_from_slice(SUFFIX_2);
let bytes: [u8; 64] = bytes
.try_into()
.expect("`generate_viewing_secret_seed_key`: bytes must be exactly 64");
let mut bytes = [0_u8; 29 + 32 + 4];
bytes[..29].copy_from_slice(DOMAIN);
bytes[29..61].copy_from_slice(&self.0);
bytes[61..].copy_from_slice(&index.to_be_bytes());
let full_seed = hmac_sha512::HMAC::mac(bytes, b"LEE_viewing_seed");
@ -139,7 +135,7 @@ impl SecretSpendingKey {
#[must_use]
pub fn produce_private_key_holder(&self, index: Option<u32>) -> PrivateKeyHolder {
PrivateKeyHolder {
nullifier_secret_key: self.generate_nullifier_secret_key(index),
authorization_secret_key: self.generate_authorization_secret_key(index),
viewing_secret_key: self.generate_viewing_secret_seed_key(index),
}
}
@ -158,9 +154,14 @@ impl From<&ViewingSecretKey> for ViewingPublicKey {
}
impl PrivateKeyHolder {
#[must_use]
pub fn nullifier_secret_key(&self) -> NullifierSecretKey {
(&self.authorization_secret_key).into()
}
#[must_use]
pub fn generate_nullifier_public_key(&self) -> NullifierPublicKey {
(&self.nullifier_secret_key).into()
NullifierPublicKey::from(&self.nullifier_secret_key())
}
#[must_use]

View File

@ -15,7 +15,9 @@ pub use encryption::{
EncryptedAccountData, EncryptionScheme, EphemeralPublicKey, EphemeralSecretKey,
ML_KEM_768_CIPHERTEXT_LEN, SharedSecretKey, ViewTag,
};
pub use nullifier::{Identifier, Nullifier, NullifierPublicKey, NullifierSecretKey};
pub use nullifier::{
AuthorizationSecretKey, Identifier, Nullifier, NullifierPublicKey, NullifierSecretKey,
};
pub use program::PrivateAccountKind;
pub mod account;

View File

@ -48,16 +48,29 @@ impl AsRef<[u8]> for NullifierPublicKey {
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[cfg_attr(any(feature = "host", test), derive(Hash))]
pub struct AuthorizationSecretKey(pub [u8; 32]);
impl From<&AuthorizationSecretKey> for NullifierSecretKey {
fn from(value: &AuthorizationSecretKey) -> Self {
const DOMAIN: &[u8; 31] = b"/LEE/v0.3/Keys/Nullifier/Secret";
let mut bytes = [0_u8; 31 + 32];
bytes[..31].copy_from_slice(DOMAIN);
bytes[31..].copy_from_slice(&value.0);
Impl::hash_bytes(&bytes)
.as_bytes()
.try_into()
.expect("hash should be exactly 32 bytes long")
}
}
impl From<&NullifierSecretKey> for NullifierPublicKey {
fn from(value: &NullifierSecretKey) -> Self {
const PREFIX: &[u8; 8] = b"LEE/keys";
const SUFFIX_1: &[u8; 1] = &[7];
const SUFFIX_2: &[u8; 23] = &[0; 23];
let mut bytes = Vec::new();
bytes.extend_from_slice(PREFIX);
bytes.extend_from_slice(value);
bytes.extend_from_slice(SUFFIX_1);
bytes.extend_from_slice(SUFFIX_2);
const DOMAIN: &[u8; 31] = b"/LEE/v0.3/Keys/Nullifier/Public";
let mut bytes = [0_u8; 31 + 32];
bytes[..31].copy_from_slice(DOMAIN);
bytes[31..].copy_from_slice(value);
Self(
Impl::hash_bytes(&bytes)
.as_bytes()
@ -154,6 +167,17 @@ mod tests {
assert_eq!(nullifier, expected_nullifier);
}
#[test]
fn from_authorization_key() {
let ask = AuthorizationSecretKey([0; 32]);
let expected_nsk: NullifierSecretKey = [
31, 33, 90, 89, 193, 14, 149, 46, 107, 38, 51, 65, 178, 242, 118, 11, 235, 198, 242,
144, 192, 64, 39, 205, 244, 122, 210, 55, 11, 245, 117, 29,
];
let nsk = NullifierSecretKey::from(&ask);
assert_eq!(nsk, expected_nsk);
}
#[test]
fn from_secret_key() {
let nsk = [
@ -161,8 +185,8 @@ mod tests {
196, 134, 22, 224, 211, 237, 120, 136, 225, 188, 220, 249, 28,
];
let expected_npk = NullifierPublicKey([
78, 20, 20, 5, 177, 198, 233, 100, 175, 134, 174, 200, 24, 205, 68, 215, 130, 74, 35,
54, 154, 184, 219, 42, 168, 106, 126, 147, 133, 244, 18, 218,
58, 181, 207, 24, 227, 133, 192, 231, 242, 216, 230, 219, 31, 227, 236, 94, 99, 245,
206, 251, 237, 189, 88, 218, 215, 106, 66, 227, 136, 152, 140, 218,
]);
let npk = NullifierPublicKey::from(&nsk);
assert_eq!(npk, expected_npk);
@ -177,8 +201,8 @@ mod tests {
let npk = NullifierPublicKey::from(&nsk);
let vpk = ViewingPublicKey::from_seed(&[1_u8; 32], &[2_u8; 32]);
let expected_account_id = AccountId::new([
242, 239, 57, 244, 89, 109, 65, 201, 223, 100, 43, 87, 205, 83, 148, 161, 176, 22, 208,
220, 68, 135, 10, 171, 182, 80, 54, 74, 228, 244, 236, 7,
226, 149, 99, 147, 82, 211, 97, 152, 31, 46, 87, 113, 237, 244, 197, 108, 71, 191, 161,
199, 140, 177, 247, 73, 95, 64, 202, 90, 8, 157, 188, 147,
]);
let account_id = AccountId::for_regular_private_account(&npk, &vpk, 0);
@ -195,8 +219,8 @@ mod tests {
let npk = NullifierPublicKey::from(&nsk);
let vpk = ViewingPublicKey::from_seed(&[1_u8; 32], &[2_u8; 32]);
let expected_account_id = AccountId::new([
149, 125, 157, 109, 119, 81, 9, 163, 231, 181, 214, 43, 57, 113, 221, 72, 180, 149,
189, 170, 32, 181, 255, 231, 19, 92, 235, 59, 153, 185, 172, 206,
44, 36, 222, 50, 57, 159, 215, 6, 246, 54, 45, 150, 94, 148, 148, 71, 212, 113, 165,
10, 187, 162, 184, 70, 96, 35, 42, 230, 251, 72, 237, 80,
]);
let account_id = AccountId::for_regular_private_account(&npk, &vpk, 1);
@ -214,8 +238,8 @@ mod tests {
let npk = NullifierPublicKey::from(&nsk);
let vpk = ViewingPublicKey::from_seed(&[1_u8; 32], &[2_u8; 32]);
let expected_account_id = AccountId::new([
30, 232, 222, 201, 233, 125, 124, 194, 58, 39, 121, 96, 185, 84, 168, 109, 80, 111,
159, 112, 84, 100, 133, 244, 16, 34, 221, 35, 128, 131, 98, 159,
50, 122, 67, 122, 59, 36, 150, 204, 128, 54, 55, 152, 14, 220, 163, 211, 246, 221, 197,
75, 12, 199, 163, 151, 234, 194, 188, 13, 27, 120, 249, 220,
]);
let account_id = AccountId::for_regular_private_account(&npk, &vpk, identifier);

View File

@ -151,7 +151,7 @@ fn prove_privacy_preserving_execution_circuit_fully_private() {
commitment_set.extend(std::slice::from_ref(&commitment_sender));
let expected_new_nullifiers = vec![
(
Nullifier::for_account_update(&commitment_sender, &sender_keys.nsk),
Nullifier::for_account_update(&commitment_sender, &sender_keys.nsk()),
commitment_set.digest(),
),
(
@ -165,7 +165,7 @@ fn prove_privacy_preserving_execution_circuit_fully_private() {
let expected_private_account_1 = Account {
program_owner: program.id(),
balance: 100 - balance_to_move,
nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk),
nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk()),
..Default::default()
};
let expected_private_account_2 = Account {
@ -182,7 +182,7 @@ fn prove_privacy_preserving_execution_circuit_fully_private() {
let esk_1 = EphemeralSecretKey::new(
&sender_account_id,
&[0; 32],
&sender_nonce.private_account_nonce_increment(&sender_keys.nsk),
&sender_nonce.private_account_nonce_increment(&sender_keys.nsk()),
);
let shared_secret_1 = SharedSecretKey::encapsulate_deterministic(&sender_keys.vpk(), &esk_1).0;
@ -202,7 +202,7 @@ fn prove_privacy_preserving_execution_circuit_fully_private() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: commitment_set
.get_proof_for(&commitment_sender)
.expect("sender's commitment must be in the set"),
@ -332,7 +332,7 @@ fn update_note_view_tag_is_the_supplied_value() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: fed_tag,
nsk: keys.nsk,
nsk: keys.nsk(),
membership_proof: commitment_set.get_proof_for(&commitment).unwrap(),
},
})],
@ -615,7 +615,7 @@ fn private_authorized_init_encrypts_regular_kind_with_identifier() {
identifier,
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Init {
npk: NullifierPublicKey::from(&keys.nsk),
npk: NullifierPublicKey::from(&keys.nsk()),
commitment_root: DUMMY_COMMITMENT_HASH,
},
})],
@ -680,7 +680,7 @@ fn private_authorized_update_encrypts_regular_kind_with_identifier() {
let esk = EphemeralSecretKey::new(
&account_id,
&[0; 32],
&Nonce::default().private_account_nonce_increment(&keys.nsk),
&Nonce::default().private_account_nonce_increment(&keys.nsk()),
);
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &esk).0;
let account = Account {
@ -704,7 +704,7 @@ fn private_authorized_update_encrypts_regular_kind_with_identifier() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: keys.nsk,
nsk: keys.nsk(),
membership_proof: commitment_set.get_proof_for(&commitment).unwrap(),
},
})],
@ -733,7 +733,7 @@ fn private_pda_update_encrypts_pda_kind_with_identifier() {
let esk = EphemeralSecretKey::new(
&pda_id,
&[0; 32],
&Nonce::default().private_account_nonce_increment(&keys.nsk),
&Nonce::default().private_account_nonce_increment(&keys.nsk()),
);
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &esk).0;
let pda_account = Account {
@ -764,7 +764,7 @@ fn private_pda_update_encrypts_pda_kind_with_identifier() {
kind: WitnessKind::Pda { binding: None },
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: keys.nsk,
nsk: keys.nsk(),
membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(),
},
}),
@ -847,7 +847,7 @@ fn private_pda_update_identifier_mismatch_fails() {
kind: WitnessKind::Pda { binding: None },
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: keys.nsk,
nsk: keys.nsk(),
membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(),
},
}),

View File

@ -78,7 +78,7 @@ fn private_changer_claimer_no_data_change_no_claim_succeeds() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: (0, vec![]),
},
})],
@ -112,7 +112,7 @@ fn private_changer_claimer_data_change_no_claim_fails() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: (0, vec![]),
},
})],

View File

@ -68,7 +68,7 @@ fn circuit_fails_if_invalid_auth_keys_are_provided() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: recipient_keys.nsk,
nsk: recipient_keys.nsk(),
membership_proof: (0, vec![]),
},
}),
@ -124,7 +124,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_balance_is_provid
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: (0, vec![]),
},
}),
@ -180,7 +180,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_program_owner_is_
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: (0, vec![]),
},
}),
@ -236,7 +236,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_data_is_provided(
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: (0, vec![]),
},
}),
@ -292,7 +292,7 @@ fn circuit_should_fail_if_new_private_account_with_non_default_nonce_is_provided
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: (0, vec![]),
},
}),
@ -346,7 +346,7 @@ fn circuit_should_fail_if_new_private_account_is_provided_with_default_values_bu
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: (0, vec![]),
},
}),
@ -752,7 +752,7 @@ fn circuit_should_fail_if_there_are_repeated_ids() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: (1, vec![]),
},
}),
@ -763,7 +763,7 @@ fn circuit_should_fail_if_there_are_repeated_ids() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: (1, vec![]),
},
}),
@ -804,7 +804,7 @@ fn private_authorized_uninitialized_account() {
identifier: 0,
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Init {
npk: NullifierPublicKey::from(&private_keys.nsk),
npk: NullifierPublicKey::from(&private_keys.nsk()),
commitment_root: DUMMY_COMMITMENT_HASH,
},
})],
@ -906,7 +906,7 @@ fn private_account_claimed_then_used_without_init_flag_should_fail() {
identifier: 0,
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Init {
npk: NullifierPublicKey::from(&private_keys.nsk),
npk: NullifierPublicKey::from(&private_keys.nsk()),
commitment_root: DUMMY_COMMITMENT_HASH,
},
})],
@ -951,7 +951,7 @@ fn private_account_claimed_then_used_without_init_flag_should_fail() {
identifier: 0,
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Init {
npk: NullifierPublicKey::from(&private_keys.nsk),
npk: NullifierPublicKey::from(&private_keys.nsk()),
commitment_root: DUMMY_COMMITMENT_HASH,
},
})],
@ -1104,7 +1104,7 @@ fn two_private_pda_family_members_receive_and_spend() {
kind: WitnessKind::Pda { binding: None },
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: alice_keys.nsk,
nsk: alice_keys.nsk(),
membership_proof: state
.get_proof_for_commitment(&commitment_pda_0)
.expect("pda_0 must be in state"),
@ -1143,7 +1143,7 @@ fn two_private_pda_family_members_receive_and_spend() {
kind: WitnessKind::Pda { binding: None },
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: alice_keys.nsk,
nsk: alice_keys.nsk(),
membership_proof: state
.get_proof_for_commitment(&commitment_pda_1)
.expect("pda_1 must be in state"),
@ -1174,7 +1174,7 @@ fn two_private_pda_family_members_receive_and_spend() {
balance: 0,
nonce: alice_pda_1_account
.nonce
.private_account_nonce_increment(&alice_keys.nsk),
.private_account_nonce_increment(&alice_keys.nsk()),
..Account::default()
};
let commitment_pda_1_after_spend =
@ -1199,7 +1199,7 @@ fn two_private_pda_family_members_receive_and_spend() {
},
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: alice_keys.nsk,
nsk: alice_keys.nsk(),
membership_proof: state
.get_proof_for_commitment(&commitment_pda_1_after_spend)
.expect("pda_1 after spend must be in state"),

View File

@ -332,7 +332,7 @@ fn authorized_public_account_claiming_succeeds_when_executed_privately() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: state
.get_proof_for_commitment(&sender_commitment)
.expect("sender's commitment must be in state"),
@ -353,7 +353,7 @@ fn authorized_public_account_claiming_succeeds_when_executed_privately() {
.transition_from_privacy_preserving_transaction(&tx, 1, 0)
.unwrap();
let nullifier = Nullifier::for_account_update(&sender_commitment, &sender_keys.nsk);
let nullifier = Nullifier::for_account_update(&sender_commitment, &sender_keys.nsk());
assert!(state.private_state.1.contains(&nullifier));
assert_eq!(
@ -420,8 +420,8 @@ fn private_chained_call(number_of_calls: u32) {
dependencies.insert(simple_transfers.id(), simple_transfers);
let program_with_deps = ProgramWithDependencies::new(chain_caller, dependencies);
let from_new_nonce = Nonce::default().private_account_nonce_increment(&from_keys.nsk);
let to_new_nonce = Nonce::default().private_account_nonce_increment(&to_keys.nsk);
let from_new_nonce = Nonce::default().private_account_nonce_increment(&from_keys.nsk());
let to_new_nonce = Nonce::default().private_account_nonce_increment(&to_keys.nsk());
let from_expected_post = Account {
balance: initial_balance - u128::from(number_of_calls) * amount,
@ -449,7 +449,7 @@ fn private_chained_call(number_of_calls: u32) {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: from_keys.nsk,
nsk: from_keys.nsk(),
membership_proof: state
.get_proof_for_commitment(&from_commitment)
.expect("from's commitment must be in state"),
@ -462,7 +462,7 @@ fn private_chained_call(number_of_calls: u32) {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: to_keys.nsk,
nsk: to_keys.nsk(),
membership_proof: state
.get_proof_for_commitment(&to_commitment)
.expect("to's commitment must be in state"),

View File

@ -7,8 +7,8 @@
use std::collections::HashMap;
use lee_core::{
BlockId, Commitment, DUMMY_COMMITMENT_HASH, InputAccountIdentity, Nullifier,
NullifierPublicKey, NullifierSecretKey, NullifierWitness, PrivateWitness, Timestamp,
AuthorizationSecretKey, BlockId, Commitment, DUMMY_COMMITMENT_HASH, InputAccountIdentity,
Nullifier, NullifierPublicKey, NullifierSecretKey, NullifierWitness, PrivateWitness, Timestamp,
WitnessKind,
account::{Account, AccountId, AccountWithMetadata, Nonce, data::Data},
encryption::ViewingPublicKey,
@ -138,14 +138,18 @@ impl TestPublicKeys {
}
pub struct TestPrivateKeys {
pub nsk: NullifierSecretKey,
pub ask: AuthorizationSecretKey,
pub d: [u8; 32],
pub z: [u8; 32],
}
impl TestPrivateKeys {
pub fn nsk(&self) -> NullifierSecretKey {
(&self.ask).into()
}
pub fn npk(&self) -> NullifierPublicKey {
NullifierPublicKey::from(&self.nsk)
NullifierPublicKey::from(&self.nsk())
}
pub fn vpk(&self) -> ViewingPublicKey {
@ -241,7 +245,7 @@ fn test_public_account_keys_2() -> TestPublicKeys {
pub fn test_private_account_keys_1() -> TestPrivateKeys {
TestPrivateKeys {
nsk: [13; 32],
ask: AuthorizationSecretKey([13; 32]),
d: [31; 32],
z: [32; 32],
}
@ -249,7 +253,7 @@ pub fn test_private_account_keys_1() -> TestPrivateKeys {
pub fn test_private_account_keys_2() -> TestPrivateKeys {
TestPrivateKeys {
nsk: [38; 32],
ask: AuthorizationSecretKey([38; 32]),
d: [83; 32],
z: [84; 32],
}
@ -334,7 +338,7 @@ fn private_balance_transfer_for_tests(
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: state
.get_proof_for_commitment(&sender_commitment)
.expect("sender's commitment must be in state"),
@ -395,7 +399,7 @@ fn deshielded_balance_transfer_for_tests(
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: sender_keys.nsk,
nsk: sender_keys.nsk(),
membership_proof: state
.get_proof_for_commitment(&sender_commitment)
.expect("sender's commitment must be in state"),

View File

@ -76,7 +76,7 @@ fn transition_from_privacy_preserving_transaction_private() {
&sender_account_id,
&Account {
program_owner: crate::test_methods::simple_balance_transfer().id(),
nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk),
nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk()),
balance: sender_private_account.balance - balance_to_move,
data: Data::default(),
},
@ -84,7 +84,7 @@ fn transition_from_privacy_preserving_transaction_private() {
let sender_pre_commitment = Commitment::new(&sender_account_id, &sender_private_account);
let expected_new_nullifier =
Nullifier::for_account_update(&sender_pre_commitment, &sender_keys.nsk);
Nullifier::for_account_update(&sender_pre_commitment, &sender_keys.nsk());
let expected_new_commitment_2 = Commitment::new(
&recipient_account_id,
@ -211,7 +211,7 @@ fn transition_from_privacy_preserving_transaction_deshielded() {
&sender_account_id,
&Account {
program_owner: crate::test_methods::simple_balance_transfer().id(),
nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk),
nonce: sender_nonce.private_account_nonce_increment(&sender_keys.nsk()),
balance: sender_private_account.balance - balance_to_move,
data: Data::default(),
},
@ -219,7 +219,7 @@ fn transition_from_privacy_preserving_transaction_deshielded() {
let sender_pre_commitment = Commitment::new(&sender_account_id, &sender_private_account);
let expected_new_nullifier =
Nullifier::for_account_update(&sender_pre_commitment, &sender_keys.nsk);
Nullifier::for_account_update(&sender_pre_commitment, &sender_keys.nsk());
assert!(state.private_state.0.contains(&sender_pre_commitment));
assert!(!state.private_state.0.contains(&expected_new_commitment));
@ -528,7 +528,7 @@ fn malicious_authorization_changer_should_fail_in_privacy_preserving_circuit() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: recipient_keys.nsk,
nsk: recipient_keys.nsk(),
membership_proof: state
.get_proof_for_commitment(&recipient_commitment)
.expect("recipient's commitment must be in state"),

View File

@ -171,7 +171,7 @@ fn privacy_malicious_programs_cannot_drain_public_victim() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: attacker_keys.nsk,
nsk: attacker_keys.nsk(),
membership_proof,
},
}),
@ -333,7 +333,7 @@ fn privacy_malicious_programs_cannot_drain_private_victim() {
kind: WitnessKind::Regular,
nullifier: NullifierWitness::Update {
view_tag: 0,
nsk: attacker_keys.nsk,
nsk: attacker_keys.nsk(),
membership_proof,
},
}),

View File

@ -1,12 +1,9 @@
use std::collections::HashMap;
use key_protocol::key_management::{
KeyChain,
key_tree::chain_index::ChainIndex,
secret_holders::{PrivateKeyHolder, SecretSpendingKey, ViewingSecretKey},
KeyChain, key_tree::chain_index::ChainIndex, secret_holders::SecretSpendingKey,
};
use lee::{Account, AccountId, Data, PrivateKey, PublicKey, V03State, program::Program};
use lee_core::{NullifierPublicKey, encryption::ViewingPublicKey};
use serde::{Deserialize, Serialize};
const PRIVATE_KEY_PUB_ACC_A: [u8; 32] = [
@ -29,46 +26,6 @@ const SSK_PRIV_ACC_B: [u8; 32] = [
180, 43, 120, 55, 151, 50, 21, 113, 22, 254, 83, 148, 56,
];
const NSK_PRIV_ACC_A: [u8; 32] = [
25, 21, 186, 59, 180, 224, 101, 64, 163, 208, 228, 43, 13, 185, 100, 123, 156, 47, 80, 179, 72,
51, 115, 11, 180, 99, 21, 201, 48, 194, 118, 144,
];
const NSK_PRIV_ACC_B: [u8; 32] = [
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,
];
const VSK_D_PRIV_ACC_A: [u8; 32] = [
255, 250, 140, 26, 222, 223, 174, 95, 132, 108, 124, 88, 30, 247, 82, 72, 52, 70, 84, 139, 241,
187, 41, 163, 19, 231, 232, 122, 225, 55, 134, 184,
];
const VSK_Z_PRIV_ACC_A: [u8; 32] = [
225, 24, 98, 78, 31, 203, 175, 248, 213, 17, 133, 207, 10, 135, 132, 151, 59, 184, 5, 81, 28,
238, 137, 62, 233, 227, 99, 17, 236, 159, 244, 63,
];
const VSK_D_PRIV_ACC_B: [u8; 32] = [
128, 85, 85, 103, 226, 218, 119, 56, 60, 252, 31, 113, 232, 215, 156, 2, 159, 247, 156, 192,
12, 178, 229, 236, 255, 120, 146, 211, 169, 117, 153, 180,
];
const VSK_Z_PRIV_ACC_B: [u8; 32] = [
165, 80, 169, 87, 248, 88, 167, 154, 27, 67, 131, 122, 50, 130, 111, 40, 164, 180, 204, 75,
188, 140, 110, 132, 113, 133, 222, 8, 49, 123, 187, 18,
];
const NPK_PRIV_ACC_A: [u8; 32] = [
167, 108, 50, 153, 74, 47, 151, 188, 140, 79, 195, 31, 181, 9, 40, 167, 201, 32, 175, 129, 45,
245, 223, 193, 210, 170, 247, 128, 167, 140, 155, 129,
];
const NPK_PRIV_ACC_B: [u8; 32] = [
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,
];
const DEFAULT_PROGRAM_OWNER: [u32; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
const PUB_ACC_A_INITIAL_BALANCE: u128 = 10000;
@ -133,26 +90,23 @@ pub fn initial_pub_accounts_private_keys() -> Vec<PublicAccountPrivateInitialDat
]
}
fn initial_priv_accounts_private_keys() -> Vec<PrivateAccountPrivateInitialData> {
let key_chain_1 = KeyChain {
secret_spending_key: SecretSpendingKey(SSK_PRIV_ACC_A),
private_key_holder: PrivateKeyHolder {
nullifier_secret_key: NSK_PRIV_ACC_A,
viewing_secret_key: ViewingSecretKey::new(VSK_D_PRIV_ACC_A, VSK_Z_PRIV_ACC_A),
},
nullifier_public_key: NullifierPublicKey(NPK_PRIV_ACC_A),
viewing_public_key: ViewingPublicKey::from_seed(&VSK_D_PRIV_ACC_A, &VSK_Z_PRIV_ACC_A),
};
fn key_chain_from_ssk(ssk: [u8; 32]) -> KeyChain {
let secret_spending_key = SecretSpendingKey(ssk);
let private_key_holder = secret_spending_key.produce_private_key_holder(None);
let nullifier_public_key = private_key_holder.generate_nullifier_public_key();
let viewing_public_key = private_key_holder.generate_viewing_public_key();
let key_chain_2 = KeyChain {
secret_spending_key: SecretSpendingKey(SSK_PRIV_ACC_B),
private_key_holder: PrivateKeyHolder {
nullifier_secret_key: NSK_PRIV_ACC_B,
viewing_secret_key: ViewingSecretKey::new(VSK_D_PRIV_ACC_B, VSK_Z_PRIV_ACC_B),
},
nullifier_public_key: NullifierPublicKey(NPK_PRIV_ACC_B),
viewing_public_key: ViewingPublicKey::from_seed(&VSK_D_PRIV_ACC_B, &VSK_Z_PRIV_ACC_B),
};
KeyChain {
secret_spending_key,
private_key_holder,
nullifier_public_key,
viewing_public_key,
}
}
fn initial_priv_accounts_private_keys() -> Vec<PrivateAccountPrivateInitialData> {
let key_chain_1 = key_chain_from_ssk(SSK_PRIV_ACC_A);
let key_chain_2 = key_chain_from_ssk(SSK_PRIV_ACC_B);
vec![
PrivateAccountPrivateInitialData {
@ -313,13 +267,35 @@ pub fn initial_state_testnet() -> V03State {
mod tests {
use std::str::FromStr as _;
use key_protocol::key_management::secret_holders::ViewingSecretKey;
use super::*;
const VSK_D_PRIV_ACC_A: [u8; 32] = [
4, 118, 187, 42, 14, 254, 144, 150, 125, 176, 205, 240, 109, 81, 234, 177, 244, 236, 108,
71, 107, 10, 107, 169, 95, 134, 75, 193, 213, 57, 81, 218,
];
const VSK_Z_PRIV_ACC_A: [u8; 32] = [
117, 29, 113, 136, 175, 148, 38, 38, 110, 220, 157, 155, 245, 13, 239, 244, 106, 126, 188,
90, 204, 28, 82, 70, 200, 16, 219, 33, 43, 210, 125, 239,
];
const VSK_D_PRIV_ACC_B: [u8; 32] = [
100, 59, 111, 232, 245, 32, 102, 179, 205, 119, 145, 238, 9, 235, 62, 38, 55, 252, 179,
217, 219, 211, 6, 188, 85, 160, 68, 54, 61, 114, 102, 81,
];
const VSK_Z_PRIV_ACC_B: [u8; 32] = [
123, 246, 87, 46, 116, 95, 39, 122, 251, 71, 207, 144, 70, 227, 120, 27, 98, 59, 67, 247,
209, 194, 110, 231, 250, 247, 205, 243, 31, 142, 104, 208,
];
const PUB_ACC_A_TEXT_ADDR: &str = "6iArKUXxhUJqS7kCaPNhwMWt3ro71PDyBj7jwAyE2VQV";
const PUB_ACC_B_TEXT_ADDR: &str = "7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo";
const PRIV_ACC_A_TEXT_ADDR: &str = "EVesBKsYRVtkjnTcsbk8tWHkBn2xZmzAXzwgrP3ZaVoZ";
const PRIV_ACC_B_TEXT_ADDR: &str = "94MXhZnueurjX6v37CYDKVEKYBiyhYArvtEdceq2XDQP";
const PRIV_ACC_A_TEXT_ADDR: &str = "GSx3EttJzQqhFPibttxguyhKXkiD4DJmA2dMmuszEmFv";
const PRIV_ACC_B_TEXT_ADDR: &str = "Dec1rT4DynCafh6k5pmywLGUU16RpxcxCdrSVYq8ukaN";
#[test]
fn pub_state_consistency() {
@ -358,78 +334,24 @@ mod tests {
let init_private_accs_keys = initial_priv_accounts_private_keys();
let init_comms = initial_commitments();
// `nsk`/`npk` carry no constants of their own: the key chains derive from `SSK_*`, and the
// two address canaries below pin H(PREFIX || npk || vpk || identifier), so drift anywhere
// in ask -> nsk -> npk or in vsk -> vpk moves one of them. Nothing is left unpinned.
// `VSK_*` stays pinned separately because it is the last value on the vsk -> vpk leg that
// a test can compare directly.
assert_eq!(
init_private_accs_keys[0]
.key_chain
.secret_spending_key
.produce_private_key_holder(None)
.nullifier_secret_key,
init_private_accs_keys[0]
.key_chain
.private_key_holder
.nullifier_secret_key
);
assert_eq!(
init_private_accs_keys[0]
.key_chain
.secret_spending_key
.produce_private_key_holder(None)
.viewing_secret_key,
init_private_accs_keys[0]
.key_chain
.private_key_holder
.viewing_secret_key
);
assert_eq!(
init_private_accs_keys[0]
.key_chain
.private_key_holder
.generate_nullifier_public_key(),
init_private_accs_keys[0].key_chain.nullifier_public_key
);
assert_eq!(
init_private_accs_keys[0]
.key_chain
.private_key_holder
.generate_viewing_public_key(),
init_private_accs_keys[0].key_chain.viewing_public_key
);
assert_eq!(
init_private_accs_keys[1]
.key_chain
.secret_spending_key
.produce_private_key_holder(None)
.nullifier_secret_key,
init_private_accs_keys[1]
.key_chain
.private_key_holder
.nullifier_secret_key
ViewingSecretKey::new(VSK_D_PRIV_ACC_A, VSK_Z_PRIV_ACC_A)
);
assert_eq!(
init_private_accs_keys[1]
.key_chain
.secret_spending_key
.produce_private_key_holder(None)
.private_key_holder
.viewing_secret_key,
init_private_accs_keys[1]
.key_chain
.private_key_holder
.viewing_secret_key
);
assert_eq!(
init_private_accs_keys[1]
.key_chain
.private_key_holder
.generate_nullifier_public_key(),
init_private_accs_keys[1].key_chain.nullifier_public_key
);
assert_eq!(
init_private_accs_keys[1]
.key_chain
.private_key_holder
.generate_viewing_public_key(),
init_private_accs_keys[1].key_chain.viewing_public_key
ViewingSecretKey::new(VSK_D_PRIV_ACC_B, VSK_Z_PRIV_ACC_B)
);
assert_eq!(
@ -453,7 +375,7 @@ mod tests {
assert_eq!(
init_comms[0],
PrivateAccountPublicInitialData {
npk: NullifierPublicKey(NPK_PRIV_ACC_A),
npk: init_private_accs_keys[0].key_chain.nullifier_public_key,
vpk: init_private_accs_keys[0]
.key_chain
.viewing_public_key
@ -470,7 +392,7 @@ mod tests {
assert_eq!(
init_comms[1],
PrivateAccountPublicInitialData {
npk: NullifierPublicKey(NPK_PRIV_ACC_B),
npk: init_private_accs_keys[1].key_chain.nullifier_public_key,
vpk: init_private_accs_keys[1]
.key_chain
.viewing_public_key

View File

@ -550,7 +550,7 @@ fn private_key_tree_acc_preparation(
let from_identifier = from_acc.kind.identifier();
let from_keys = &from_acc.key_chain;
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.nullifier_public_key;
let from_vpk = from_keys.viewing_public_key.clone();

View File

@ -373,7 +373,7 @@ impl WalletCore {
.key_chain()
.shared_private_account(account_id)?;
let keys = self.storage.key_chain().derive_shared_account_keys(entry)?;
let nsk = keys.nullifier_secret_key;
let nsk = keys.nullifier_secret_key();
let npk = keys.generate_nullifier_public_key();
let vpk = keys.generate_viewing_public_key();
let identifier = entry.identifier;
@ -989,7 +989,7 @@ impl WalletCore {
&key_chain.viewing_public_key,
&kind,
);
let nsk = key_chain.private_key_holder.nullifier_secret_key;
let nsk = key_chain.private_key_holder.nullifier_secret_key();
(account_id, kind, res_acc, nsk)
})
})
@ -1028,7 +1028,7 @@ impl WalletCore {
let keys = self.storage.key_chain().derive_shared_account_keys(entry)?;
let npk = keys.generate_nullifier_public_key();
let vpk = keys.generate_viewing_public_key();
let nsk = keys.nullifier_secret_key;
let nsk = keys.nullifier_secret_key();
let vsk = keys.viewing_secret_key;
Some((account_id, npk, vpk, vsk, nsk))
})

View File

@ -365,7 +365,7 @@ impl UserKeyChain {
&found.key_chain.viewing_public_key,
found.kind,
);
let nsk = found.key_chain.private_key_holder.nullifier_secret_key;
let nsk = found.key_chain.private_key_holder.nullifier_secret_key();
index.track(account_id, found.account, &nsk);
}
@ -374,7 +374,7 @@ impl UserKeyChain {
let Some(keys) = self.derive_shared_account_keys(entry) else {
continue;
};
let nsk = keys.nullifier_secret_key;
let nsk = keys.nullifier_secret_key();
index.track(account_id, &entry.account, &nsk);
}
@ -426,14 +426,14 @@ impl UserKeyChain {
&keys.viewing_secret_key.d,
&keys.viewing_secret_key.z,
)?;
(keys.nullifier_secret_key, secret, true)
(keys.nullifier_secret_key(), secret, true)
} else {
let found = self.private_account(account_id)?;
let secret = found
.key_chain
.calculate_shared_secret_receiver(&encrypted.epk)?;
(
found.key_chain.private_key_holder.nullifier_secret_key,
found.key_chain.private_key_holder.nullifier_secret_key(),
secret,
false,
)
@ -459,14 +459,14 @@ impl UserKeyChain {
return Some(NullifierIndex::next_update_nullifier(
account_id,
&entry.account,
&keys.nullifier_secret_key,
&keys.nullifier_secret_key(),
));
}
let acc = self.private_account(account_id)?;
Some(NullifierIndex::next_update_nullifier(
account_id,
acc.account,
&acc.key_chain.private_key_holder.nullifier_secret_key,
&acc.key_chain.private_key_holder.nullifier_secret_key(),
))
}
@ -898,7 +898,7 @@ mod tests {
let mut kc = UserKeyChain::default();
let key_chain = KeyChain::new_os_random();
let nsk = key_chain.private_key_holder.nullifier_secret_key;
let nsk = key_chain.private_key_holder.nullifier_secret_key();
let identifier = 0;
let account_id = AccountId::for_private_account(
&key_chain.nullifier_public_key,
@ -966,7 +966,7 @@ mod tests {
let keys = holder.derive_regular_shared_account_keys_from_identifier(identifier);
let npk = keys.generate_nullifier_public_key();
let vpk = keys.generate_viewing_public_key();
let nsk = keys.nullifier_secret_key;
let nsk = keys.nullifier_secret_key();
let account_id = AccountId::from((&npk, &vpk, identifier));
kc.insert_group_key_holder(label.clone(), holder);
@ -1036,7 +1036,7 @@ mod tests {
let keys = holder.derive_regular_shared_account_keys_from_identifier(identifier);
let npk = keys.generate_nullifier_public_key();
let vpk = keys.generate_viewing_public_key();
let nsk = keys.nullifier_secret_key;
let nsk = keys.nullifier_secret_key();
let account_id = AccountId::from((&npk, &vpk, identifier));
kc.insert_group_key_holder(label.clone(), holder);