diff --git a/artifacts/program_methods/amm.bin b/artifacts/program_methods/amm.bin index a7a8d838..df267d12 100644 Binary files a/artifacts/program_methods/amm.bin and b/artifacts/program_methods/amm.bin differ diff --git a/artifacts/program_methods/associated_token_account.bin b/artifacts/program_methods/associated_token_account.bin index b0a00f1e..6e7a3ce6 100644 Binary files a/artifacts/program_methods/associated_token_account.bin and b/artifacts/program_methods/associated_token_account.bin differ diff --git a/artifacts/program_methods/authenticated_transfer.bin b/artifacts/program_methods/authenticated_transfer.bin index 80a19dbe..68c06d1c 100644 Binary files a/artifacts/program_methods/authenticated_transfer.bin and b/artifacts/program_methods/authenticated_transfer.bin differ diff --git a/artifacts/program_methods/bridge.bin b/artifacts/program_methods/bridge.bin index 8b2ca40c..6eb93a11 100644 Binary files a/artifacts/program_methods/bridge.bin and b/artifacts/program_methods/bridge.bin differ diff --git a/artifacts/program_methods/clock.bin b/artifacts/program_methods/clock.bin index e00f2ccc..7ddfb193 100644 Binary files a/artifacts/program_methods/clock.bin and b/artifacts/program_methods/clock.bin differ diff --git a/artifacts/program_methods/faucet.bin b/artifacts/program_methods/faucet.bin index 11f0554f..006220a5 100644 Binary files a/artifacts/program_methods/faucet.bin and b/artifacts/program_methods/faucet.bin differ diff --git a/artifacts/program_methods/pinata.bin b/artifacts/program_methods/pinata.bin index 113d8c24..2fedd069 100644 Binary files a/artifacts/program_methods/pinata.bin and b/artifacts/program_methods/pinata.bin differ diff --git a/artifacts/program_methods/pinata_token.bin b/artifacts/program_methods/pinata_token.bin index 0be5d96e..4411a3c0 100644 Binary files a/artifacts/program_methods/pinata_token.bin and b/artifacts/program_methods/pinata_token.bin differ diff --git a/artifacts/program_methods/privacy_preserving_circuit.bin b/artifacts/program_methods/privacy_preserving_circuit.bin index 53b64803..256f8fc2 100644 Binary files a/artifacts/program_methods/privacy_preserving_circuit.bin and b/artifacts/program_methods/privacy_preserving_circuit.bin differ diff --git a/artifacts/program_methods/token.bin b/artifacts/program_methods/token.bin index 08ca8e9d..14baf4eb 100644 Binary files a/artifacts/program_methods/token.bin and b/artifacts/program_methods/token.bin differ diff --git a/artifacts/program_methods/vault.bin b/artifacts/program_methods/vault.bin index 5b6cc093..9d97a376 100644 Binary files a/artifacts/program_methods/vault.bin and b/artifacts/program_methods/vault.bin differ diff --git a/artifacts/test_program_methods/auth_asserting_noop.bin b/artifacts/test_program_methods/auth_asserting_noop.bin index f4db3d61..b3694096 100644 Binary files a/artifacts/test_program_methods/auth_asserting_noop.bin and b/artifacts/test_program_methods/auth_asserting_noop.bin differ diff --git a/artifacts/test_program_methods/auth_transfer_proxy.bin b/artifacts/test_program_methods/auth_transfer_proxy.bin index d14e9f95..d7f4c6fe 100644 Binary files a/artifacts/test_program_methods/auth_transfer_proxy.bin and b/artifacts/test_program_methods/auth_transfer_proxy.bin differ diff --git a/artifacts/test_program_methods/burner.bin b/artifacts/test_program_methods/burner.bin index d2101f1e..692a8433 100644 Binary files a/artifacts/test_program_methods/burner.bin and b/artifacts/test_program_methods/burner.bin differ diff --git a/artifacts/test_program_methods/chain_caller.bin b/artifacts/test_program_methods/chain_caller.bin index 36f00dca..f4262dab 100644 Binary files a/artifacts/test_program_methods/chain_caller.bin and b/artifacts/test_program_methods/chain_caller.bin differ diff --git a/artifacts/test_program_methods/changer_claimer.bin b/artifacts/test_program_methods/changer_claimer.bin index 1a3b714c..2acfd6ce 100644 Binary files a/artifacts/test_program_methods/changer_claimer.bin and b/artifacts/test_program_methods/changer_claimer.bin differ diff --git a/artifacts/test_program_methods/claimer.bin b/artifacts/test_program_methods/claimer.bin index 3c888781..ffc41cda 100644 Binary files a/artifacts/test_program_methods/claimer.bin and b/artifacts/test_program_methods/claimer.bin differ diff --git a/artifacts/test_program_methods/clock_chain_caller.bin b/artifacts/test_program_methods/clock_chain_caller.bin index 3d91fa28..e0310830 100644 Binary files a/artifacts/test_program_methods/clock_chain_caller.bin and b/artifacts/test_program_methods/clock_chain_caller.bin differ diff --git a/artifacts/test_program_methods/data_changer.bin b/artifacts/test_program_methods/data_changer.bin index 4e5a5ebe..4a00f11b 100644 Binary files a/artifacts/test_program_methods/data_changer.bin and b/artifacts/test_program_methods/data_changer.bin differ diff --git a/artifacts/test_program_methods/extra_output.bin b/artifacts/test_program_methods/extra_output.bin index 39e000c3..4482e28e 100644 Binary files a/artifacts/test_program_methods/extra_output.bin and b/artifacts/test_program_methods/extra_output.bin differ diff --git a/artifacts/test_program_methods/faucet_chain_caller.bin b/artifacts/test_program_methods/faucet_chain_caller.bin index 2c0c647b..aace5211 100644 Binary files a/artifacts/test_program_methods/faucet_chain_caller.bin and b/artifacts/test_program_methods/faucet_chain_caller.bin differ diff --git a/artifacts/test_program_methods/flash_swap_callback.bin b/artifacts/test_program_methods/flash_swap_callback.bin index fd16b233..881c045c 100644 Binary files a/artifacts/test_program_methods/flash_swap_callback.bin and b/artifacts/test_program_methods/flash_swap_callback.bin differ diff --git a/artifacts/test_program_methods/flash_swap_initiator.bin b/artifacts/test_program_methods/flash_swap_initiator.bin index 4d1f2c59..dab0807d 100644 Binary files a/artifacts/test_program_methods/flash_swap_initiator.bin and b/artifacts/test_program_methods/flash_swap_initiator.bin differ diff --git a/artifacts/test_program_methods/malicious_authorization_changer.bin b/artifacts/test_program_methods/malicious_authorization_changer.bin index 0e1003e3..2421f254 100644 Binary files a/artifacts/test_program_methods/malicious_authorization_changer.bin and b/artifacts/test_program_methods/malicious_authorization_changer.bin differ diff --git a/artifacts/test_program_methods/malicious_caller_program_id.bin b/artifacts/test_program_methods/malicious_caller_program_id.bin index 3d0f38c7..8889a8bb 100644 Binary files a/artifacts/test_program_methods/malicious_caller_program_id.bin and b/artifacts/test_program_methods/malicious_caller_program_id.bin differ diff --git a/artifacts/test_program_methods/malicious_injector.bin b/artifacts/test_program_methods/malicious_injector.bin index fdffa6de..54c9bbd1 100644 Binary files a/artifacts/test_program_methods/malicious_injector.bin and b/artifacts/test_program_methods/malicious_injector.bin differ diff --git a/artifacts/test_program_methods/malicious_launderer.bin b/artifacts/test_program_methods/malicious_launderer.bin index f601b821..e1740d2d 100644 Binary files a/artifacts/test_program_methods/malicious_launderer.bin and b/artifacts/test_program_methods/malicious_launderer.bin differ diff --git a/artifacts/test_program_methods/malicious_self_program_id.bin b/artifacts/test_program_methods/malicious_self_program_id.bin index 3f9767cd..ddb6a012 100644 Binary files a/artifacts/test_program_methods/malicious_self_program_id.bin and b/artifacts/test_program_methods/malicious_self_program_id.bin differ diff --git a/artifacts/test_program_methods/minter.bin b/artifacts/test_program_methods/minter.bin index c54f5c49..fd96b143 100644 Binary files a/artifacts/test_program_methods/minter.bin and b/artifacts/test_program_methods/minter.bin differ diff --git a/artifacts/test_program_methods/missing_output.bin b/artifacts/test_program_methods/missing_output.bin index b3976829..67febaf9 100644 Binary files a/artifacts/test_program_methods/missing_output.bin and b/artifacts/test_program_methods/missing_output.bin differ diff --git a/artifacts/test_program_methods/modified_transfer.bin b/artifacts/test_program_methods/modified_transfer.bin index 2deee157..af1029d1 100644 Binary files a/artifacts/test_program_methods/modified_transfer.bin and b/artifacts/test_program_methods/modified_transfer.bin differ diff --git a/artifacts/test_program_methods/nonce_changer.bin b/artifacts/test_program_methods/nonce_changer.bin index 77ec2fef..5b6e1ce1 100644 Binary files a/artifacts/test_program_methods/nonce_changer.bin and b/artifacts/test_program_methods/nonce_changer.bin differ diff --git a/artifacts/test_program_methods/noop.bin b/artifacts/test_program_methods/noop.bin index 40660c49..9955e3b2 100644 Binary files a/artifacts/test_program_methods/noop.bin and b/artifacts/test_program_methods/noop.bin differ diff --git a/artifacts/test_program_methods/pda_claimer.bin b/artifacts/test_program_methods/pda_claimer.bin index 97414a40..8a8590b9 100644 Binary files a/artifacts/test_program_methods/pda_claimer.bin and b/artifacts/test_program_methods/pda_claimer.bin differ diff --git a/artifacts/test_program_methods/pda_spend_proxy.bin b/artifacts/test_program_methods/pda_spend_proxy.bin index 2da93d71..8458344a 100644 Binary files a/artifacts/test_program_methods/pda_spend_proxy.bin and b/artifacts/test_program_methods/pda_spend_proxy.bin differ diff --git a/artifacts/test_program_methods/pinata_cooldown.bin b/artifacts/test_program_methods/pinata_cooldown.bin index 5987cf31..4e6b953f 100644 Binary files a/artifacts/test_program_methods/pinata_cooldown.bin and b/artifacts/test_program_methods/pinata_cooldown.bin differ diff --git a/artifacts/test_program_methods/private_pda_delegator.bin b/artifacts/test_program_methods/private_pda_delegator.bin index 8f5be9a9..175dc697 100644 Binary files a/artifacts/test_program_methods/private_pda_delegator.bin and b/artifacts/test_program_methods/private_pda_delegator.bin differ diff --git a/artifacts/test_program_methods/program_owner_changer.bin b/artifacts/test_program_methods/program_owner_changer.bin index e0f77e9a..53fcca3e 100644 Binary files a/artifacts/test_program_methods/program_owner_changer.bin and b/artifacts/test_program_methods/program_owner_changer.bin differ diff --git a/artifacts/test_program_methods/simple_balance_transfer.bin b/artifacts/test_program_methods/simple_balance_transfer.bin index 07339bde..ee7165d6 100644 Binary files a/artifacts/test_program_methods/simple_balance_transfer.bin and b/artifacts/test_program_methods/simple_balance_transfer.bin differ diff --git a/artifacts/test_program_methods/time_locked_transfer.bin b/artifacts/test_program_methods/time_locked_transfer.bin index f9eec995..89e8cb69 100644 Binary files a/artifacts/test_program_methods/time_locked_transfer.bin and b/artifacts/test_program_methods/time_locked_transfer.bin differ diff --git a/artifacts/test_program_methods/two_pda_claimer.bin b/artifacts/test_program_methods/two_pda_claimer.bin index 0107ba6a..54a3744e 100644 Binary files a/artifacts/test_program_methods/two_pda_claimer.bin and b/artifacts/test_program_methods/two_pda_claimer.bin differ diff --git a/artifacts/test_program_methods/validity_window.bin b/artifacts/test_program_methods/validity_window.bin index 88201f58..615934f3 100644 Binary files a/artifacts/test_program_methods/validity_window.bin and b/artifacts/test_program_methods/validity_window.bin differ diff --git a/artifacts/test_program_methods/validity_window_chain_caller.bin b/artifacts/test_program_methods/validity_window_chain_caller.bin index 0980448f..dc7a51f3 100644 Binary files a/artifacts/test_program_methods/validity_window_chain_caller.bin and b/artifacts/test_program_methods/validity_window_chain_caller.bin differ diff --git a/integration_tests/tests/auth_transfer/private.rs b/integration_tests/tests/auth_transfer/private.rs index 1e29cbb8..a48bb212 100644 --- a/integration_tests/tests/auth_transfer/private.rs +++ b/integration_tests/tests/auth_transfer/private.rs @@ -710,7 +710,7 @@ async fn ppt_cant_chain_call_faucet() -> Result<()> { InputAccountIdentity::Public, InputAccountIdentity::PrivatePdaInit { vpk, - esk: [0; 32], + os_random: [0; 32], npk, identifier: 1337, seed: None, diff --git a/integration_tests/tests/private_pda.rs b/integration_tests/tests/private_pda.rs index 2cb8de88..90ddb45a 100644 --- a/integration_tests/tests/private_pda.rs +++ b/integration_tests/tests/private_pda.rs @@ -71,7 +71,7 @@ async fn fund_private_pda( InputAccountIdentity::Public, InputAccountIdentity::PrivatePdaInit { vpk, - esk: [0; 32], + os_random: [0; 32], npk, identifier, seed: Some((seed, authority_program_id)), diff --git a/integration_tests/tests/tps.rs b/integration_tests/tests/tps.rs index ae99896c..56facd39 100644 --- a/integration_tests/tests/tps.rs +++ b/integration_tests/tests/tps.rs @@ -293,14 +293,14 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_vpk, - esk: [0; 32], + os_random: [0; 32], nsk: sender_nsk, membership_proof: proof, identifier: 0, }, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_vpk, - esk: [0; 32], + os_random: [0; 32], npk: recipient_npk, identifier: 0, }, diff --git a/lee/state_machine/core/src/circuit_io.rs b/lee/state_machine/core/src/circuit_io.rs index 62b36481..625247e0 100644 --- a/lee/state_machine/core/src/circuit_io.rs +++ b/lee/state_machine/core/src/circuit_io.rs @@ -4,7 +4,7 @@ use crate::{ Commitment, CommitmentSetDigest, Identifier, MembershipProof, Nullifier, NullifierPublicKey, NullifierSecretKey, account::{Account, AccountWithMetadata}, - encryption::{EncryptedAccountData, EphemeralSecretKey, ViewingPublicKey}, + encryption::{EncryptedAccountData, ViewingPublicKey}, program::{BlockValidityWindow, PdaSeed, ProgramId, ProgramOutput, TimestampValidityWindow}, }; @@ -32,7 +32,7 @@ pub enum InputAccountIdentity { /// and matched against `pre_state.account_id`. PrivateAuthorizedInit { vpk: ViewingPublicKey, - esk: EphemeralSecretKey, + os_random: [u8; 32], nsk: NullifierSecretKey, identifier: Identifier, }, @@ -40,7 +40,7 @@ pub enum InputAccountIdentity { /// membership proof. PrivateAuthorizedUpdate { vpk: ViewingPublicKey, - esk: EphemeralSecretKey, + os_random: [u8; 32], nsk: NullifierSecretKey, membership_proof: MembershipProof, identifier: Identifier, @@ -49,7 +49,7 @@ pub enum InputAccountIdentity { /// doesn't yet exist on chain). No `nsk`, no membership proof. PrivateUnauthorized { vpk: ViewingPublicKey, - esk: EphemeralSecretKey, + os_random: [u8; 32], npk: NullifierPublicKey, identifier: Identifier, }, @@ -59,7 +59,7 @@ pub enum InputAccountIdentity { /// as the 4th input. PrivatePdaInit { vpk: ViewingPublicKey, - esk: EphemeralSecretKey, + os_random: [u8; 32], npk: NullifierPublicKey, identifier: Identifier, /// When `Some((seed, authority_program_id))`, the circuit binds this position via the @@ -75,7 +75,7 @@ pub enum InputAccountIdentity { /// previously-seen authorization in a chained call. PrivatePdaUpdate { vpk: ViewingPublicKey, - esk: EphemeralSecretKey, + os_random: [u8; 32], nsk: NullifierSecretKey, membership_proof: MembershipProof, identifier: Identifier, diff --git a/lee/state_machine/core/src/encryption/mod.rs b/lee/state_machine/core/src/encryption/mod.rs index d2d312fe..0d7ccd11 100644 --- a/lee/state_machine/core/src/encryption/mod.rs +++ b/lee/state_machine/core/src/encryption/mod.rs @@ -12,7 +12,30 @@ pub mod shared_key_derivation; pub type Scalar = [u8; 32]; -pub type EphemeralSecretKey = [u8; 32]; +#[derive(Serialize, Deserialize, Clone, Copy)] +pub struct EphemeralSecretKey(pub [u8; 32]); + +impl EphemeralSecretKey { + /// Derives an ephemeral secret key from OS randomness and account-specific values. + /// + /// For updates, `nonce` carries `nsk`-derived entropy, making `esk` strong even + /// with a compromised RNG. For inits, `nonce` is deterministic, so `os_random` + /// is the sole entropy source. + #[must_use] + pub fn new( + account_id: &crate::account::AccountId, + os_random: &[u8; 32], + nonce: &crate::account::Nonce, + ) -> Self { + const PREFIX: &[u8; 14] = b"/LEE/v0.3/esk/"; + let mut input = [0_u8; 14 + 32 + 32 + 16]; + input[0..14].copy_from_slice(PREFIX); + input[14..46].copy_from_slice(account_id.value()); + input[46..78].copy_from_slice(os_random); + input[78..94].copy_from_slice(&nonce.0.to_le_bytes()); + Self(Impl::hash_bytes(&input).as_bytes().try_into().unwrap()) + } +} #[derive(Serialize, Deserialize, Clone, Copy)] pub struct SharedSecretKey(pub [u8; 32]); @@ -237,4 +260,41 @@ mod tests { "wrong shared secret must not produce the correct plaintext" ); } + + #[test] + fn esk_is_deterministic() { + let account_id = AccountId::new([1_u8; 32]); + let os_random = [2_u8; 32]; + let nonce = crate::account::Nonce(42); + let esk1 = EphemeralSecretKey::new(&account_id, &os_random, &nonce); + let esk2 = EphemeralSecretKey::new(&account_id, &os_random, &nonce); + assert_eq!(esk1.0, esk2.0); + } + + #[test] + fn esk_differs_for_different_account_id() { + let os_random = [2_u8; 32]; + let nonce = crate::account::Nonce(42); + let esk_a = EphemeralSecretKey::new(&AccountId::new([0_u8; 32]), &os_random, &nonce); + let esk_b = EphemeralSecretKey::new(&AccountId::new([1_u8; 32]), &os_random, &nonce); + assert_ne!(esk_a.0, esk_b.0); + } + + #[test] + fn esk_differs_for_different_os_random() { + let account_id = AccountId::new([1_u8; 32]); + let nonce = crate::account::Nonce(42); + let esk_a = EphemeralSecretKey::new(&account_id, &[0_u8; 32], &nonce); + let esk_b = EphemeralSecretKey::new(&account_id, &[1_u8; 32], &nonce); + assert_ne!(esk_a.0, esk_b.0); + } + + #[test] + fn esk_differs_for_different_nonce() { + let account_id = AccountId::new([1_u8; 32]); + let os_random = [2_u8; 32]; + let esk_a = EphemeralSecretKey::new(&account_id, &os_random, &crate::account::Nonce(0)); + let esk_b = EphemeralSecretKey::new(&account_id, &os_random, &crate::account::Nonce(1)); + assert_ne!(esk_a.0, esk_b.0); + } } diff --git a/lee/state_machine/core/src/encryption/shared_key_derivation.rs b/lee/state_machine/core/src/encryption/shared_key_derivation.rs index f37edf62..6e51fc67 100644 --- a/lee/state_machine/core/src/encryption/shared_key_derivation.rs +++ b/lee/state_machine/core/src/encryption/shared_key_derivation.rs @@ -80,32 +80,18 @@ impl SharedSecretKey { (Self(ss_bytes), EphemeralPublicKey(ct.to_vec())) } - /// Deterministically encapsulate a shared secret toward `ek` with a given - /// `esk` and `output_index`. + /// Deterministically encapsulate a shared secret toward `ek` using a + /// pre-derived `esk` as the ML-KEM encapsulation randomness. /// - /// This function runs inside the privacy-preserving circuit, generating - /// the shared secret for ciphertext generation. - /// - /// Important: since `ek` is assumed to be public, the uniqueness of the - /// secret is reliant upon the uniqueness of the ephemeral secret key for - /// a note in a given position. It is hence important to generate it - /// with high entropy, for which the prover is responsible. + /// The `esk` must be derived via `derive_esk(account_id, os_random, nonce)` + /// which binds it to the account and incorporates OS entropy. #[must_use] pub fn encapsulate_deterministic( ek: &MlKem768EncapsulationKey, - esk: &[u8; 32], - output_index: u32, + esk: &crate::encryption::EphemeralSecretKey, ) -> (Self, EphemeralPublicKey) { - use risc0_zkvm::sha::{Impl, Sha256 as _}; - - const PREFIX: &[u8; 21] = b"/LEE/v0.3/KDF-ML-KEM/"; - let mut input = [0; 21 + 32 + 4]; - input[0..21].copy_from_slice(PREFIX); - input[21..53].copy_from_slice(esk); - input[53..57].copy_from_slice(&output_index.to_le_bytes()); - let hash = Impl::hash_bytes(&input); - let m: ml_kem::B32 = - ml_kem::array::Array::try_from(hash.as_bytes()).expect("SHA-256 output is 32 bytes"); + let m: ml_kem::B32 = ml_kem::array::Array::try_from(esk.0.as_slice()) + .expect("EphemeralSecretKey is 32 bytes"); let ek_bytes: ml_kem::kem::Key = ek.0.as_slice() diff --git a/lee/state_machine/src/privacy_preserving_transaction/circuit.rs b/lee/state_machine/src/privacy_preserving_transaction/circuit.rs index ce1db3bc..29f2cc95 100644 --- a/lee/state_machine/src/privacy_preserving_transaction/circuit.rs +++ b/lee/state_machine/src/privacy_preserving_transaction/circuit.rs @@ -178,7 +178,7 @@ mod tests { #![expect(clippy::shadow_unrelated, reason = "We don't care about it in tests")] use lee_core::{ - Commitment, DUMMY_COMMITMENT_HASH, EncryptionScheme, Nullifier, + Commitment, DUMMY_COMMITMENT_HASH, EncryptionScheme, EphemeralSecretKey, Nullifier, PrivacyPreservingCircuitOutput, SharedSecretKey, account::{Account, AccountId, AccountWithMetadata, Nonce, data::Data}, program::{PdaSeed, PrivateAccountKind}, @@ -257,8 +257,11 @@ mod tests { let expected_sender_pre = sender.clone(); - let shared_secret = - SharedSecretKey::encapsulate_deterministic(&recipient_keys.vpk(), &[0_u8; 32], 0).0; + let shared_secret = SharedSecretKey::encapsulate_deterministic( + &recipient_keys.vpk(), + &EphemeralSecretKey([0_u8; 32]), + ) + .0; let (output, proof) = execute_and_prove( vec![sender, recipient], @@ -270,7 +273,7 @@ mod tests { InputAccountIdentity::Public, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -357,11 +360,17 @@ mod tests { Commitment::new(&recipient_account_id, &expected_private_account_2), ]; - let shared_secret_1 = - SharedSecretKey::encapsulate_deterministic(&sender_keys.vpk(), &[0_u8; 32], 0).0; + let shared_secret_1 = SharedSecretKey::encapsulate_deterministic( + &sender_keys.vpk(), + &EphemeralSecretKey([0_u8; 32]), + ) + .0; - let shared_secret_2 = - SharedSecretKey::encapsulate_deterministic(&recipient_keys.vpk(), &[0_u8; 32], 1).0; + let shared_secret_2 = SharedSecretKey::encapsulate_deterministic( + &recipient_keys.vpk(), + &EphemeralSecretKey([0_u8; 32]), + ) + .0; let (output, proof) = execute_and_prove( vec![sender_pre, recipient], @@ -372,7 +381,7 @@ mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: commitment_set .get_proof_for(&commitment_sender) @@ -381,7 +390,7 @@ mod tests { }, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -447,7 +456,7 @@ mod tests { instruction, vec![InputAccountIdentity::PrivateUnauthorized { vpk: account_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: account_keys.npk(), identifier: 0, }], @@ -466,8 +475,11 @@ mod tests { let npk = keys.npk(); let seed = PdaSeed::new([42; 32]); let identifier: u128 = 99; - let shared_secret = - SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0; + let shared_secret = SharedSecretKey::encapsulate_deterministic( + &keys.vpk(), + &EphemeralSecretKey([0_u8; 32]), + ) + .0; let account_id = AccountId::for_private_pda(&program.id(), &seed, &npk, &keys.vpk(), identifier); @@ -478,7 +490,7 @@ mod tests { Program::serialize_instruction(seed).unwrap(), vec![InputAccountIdentity::PrivatePdaInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk, identifier, seed: None, @@ -524,7 +536,7 @@ mod tests { instruction, vec![InputAccountIdentity::PrivatePdaInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk, identifier: 0, seed: None, @@ -576,7 +588,7 @@ mod tests { vec![ InputAccountIdentity::PrivatePdaInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk, identifier: 0, seed: None, @@ -633,7 +645,7 @@ mod tests { InputAccountIdentity::Public, InputAccountIdentity::PrivateUnauthorized { vpk: shared_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: shared_npk, identifier: shared_identifier, }, @@ -653,7 +665,11 @@ mod tests { let program = Program::authenticated_transfer_program(); let keys = test_private_account_keys_1(); let identifier: u128 = 99; - let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0; + let ssk = SharedSecretKey::encapsulate_deterministic( + &keys.vpk(), + &EphemeralSecretKey([0_u8; 32]), + ) + .0; let account_id = AccountId::for_regular_private_account(&keys.npk(), &keys.vpk(), identifier); let pre = AccountWithMetadata::new(Account::default(), true, account_id); @@ -664,7 +680,7 @@ mod tests { .unwrap(), vec![InputAccountIdentity::PrivateAuthorizedInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: keys.nsk, identifier, }], @@ -695,7 +711,7 @@ mod tests { .unwrap(), vec![InputAccountIdentity::PrivateAuthorizedInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: keys.nsk, identifier, }], @@ -742,7 +758,7 @@ mod tests { vec![InputAccountIdentity::PrivateAuthorizedInit { // use a different vpk vpk: foreign_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], // but the same nsk nsk: keys.nsk, identifier, @@ -760,7 +776,11 @@ mod tests { let program = Program::authenticated_transfer_program(); let keys = test_private_account_keys_1(); let identifier: u128 = 99; - let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0; + let ssk = SharedSecretKey::encapsulate_deterministic( + &keys.vpk(), + &EphemeralSecretKey([0_u8; 32]), + ) + .0; let sender = AccountWithMetadata::new( Account { @@ -785,7 +805,7 @@ mod tests { InputAccountIdentity::Public, InputAccountIdentity::PrivateUnauthorized { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: keys.npk(), identifier, }, @@ -807,7 +827,11 @@ mod tests { let program = Program::authenticated_transfer_program(); let keys = test_private_account_keys_1(); let identifier: u128 = 99; - let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0; + let ssk = SharedSecretKey::encapsulate_deterministic( + &keys.vpk(), + &EphemeralSecretKey([0_u8; 32]), + ) + .0; let account_id = AccountId::for_regular_private_account(&keys.npk(), &keys.vpk(), identifier); let account = Account { @@ -831,7 +855,7 @@ mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: keys.nsk, membership_proof: commitment_set.get_proof_for(&commitment).unwrap(), identifier, @@ -858,7 +882,11 @@ mod tests { let npk = keys.npk(); let seed = PdaSeed::new([42; 32]); let identifier: u128 = 99; - let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0; + let ssk = SharedSecretKey::encapsulate_deterministic( + &keys.vpk(), + &EphemeralSecretKey([0_u8; 32]), + ) + .0; let auth_transfer_id = auth_transfer.id(); let pda_id = @@ -887,7 +915,7 @@ mod tests { vec![ InputAccountIdentity::PrivatePdaUpdate { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: keys.nsk, membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(), identifier, @@ -923,7 +951,7 @@ mod tests { Program::serialize_instruction(seed).unwrap(), vec![InputAccountIdentity::PrivatePdaInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk, identifier: 99, seed: None, @@ -965,7 +993,7 @@ mod tests { vec![ InputAccountIdentity::PrivatePdaUpdate { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: keys.nsk, membership_proof: commitment_set.get_proof_for(&pda_commitment).unwrap(), identifier: 99, diff --git a/lee/state_machine/src/privacy_preserving_transaction/message.rs b/lee/state_machine/src/privacy_preserving_transaction/message.rs index ae33b71c..73e62021 100644 --- a/lee/state_machine/src/privacy_preserving_transaction/message.rs +++ b/lee/state_machine/src/privacy_preserving_transaction/message.rs @@ -89,8 +89,8 @@ impl Message { #[cfg(test)] pub mod tests { use lee_core::{ - Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, PrivateAccountKind, - SharedSecretKey, + Commitment, EncryptionScheme, EphemeralSecretKey, Nullifier, NullifierPublicKey, + PrivateAccountKind, SharedSecretKey, account::{Account, AccountId, Nonce}, encryption::ViewingPublicKey, program::{BlockValidityWindow, TimestampValidityWindow}, @@ -200,7 +200,8 @@ pub mod tests { let account = Account::default(); let account_id = lee_core::account::AccountId::for_regular_private_account(&npk, &vpk, 0); let commitment = Commitment::new(&account_id, &account); - let (shared_secret, epk) = SharedSecretKey::encapsulate_deterministic(&vpk, &[0_u8; 32], 0); + let (shared_secret, epk) = + SharedSecretKey::encapsulate_deterministic(&vpk, &EphemeralSecretKey([0_u8; 32])); let ciphertext = EncryptionScheme::encrypt( &account, &PrivateAccountKind::Regular(0), diff --git a/lee/state_machine/src/state.rs b/lee/state_machine/src/state.rs index 5bb87f9f..b428663b 100644 --- a/lee/state_machine/src/state.rs +++ b/lee/state_machine/src/state.rs @@ -1419,7 +1419,7 @@ pub mod tests { InputAccountIdentity::Public, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -1470,7 +1470,7 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: state .get_proof_for_commitment(&sender_commitment) @@ -1479,7 +1479,7 @@ pub mod tests { }, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -1526,7 +1526,7 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: state .get_proof_for_commitment(&sender_commitment) @@ -2099,14 +2099,14 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: recipient_keys.nsk, membership_proof: (0, vec![]), identifier: 0, }, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -2147,14 +2147,14 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, }, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -2195,14 +2195,14 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, }, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -2243,14 +2243,14 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, }, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -2291,14 +2291,14 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, }, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -2337,14 +2337,14 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, }, InputAccountIdentity::PrivateUnauthorized { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: recipient_keys.npk(), identifier: 0, }, @@ -2383,7 +2383,7 @@ pub mod tests { InputAccountIdentity::Public, InputAccountIdentity::PrivatePdaInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk, identifier: u128::MAX, seed: None, @@ -2416,7 +2416,7 @@ pub mod tests { Program::serialize_instruction(seed).unwrap(), vec![InputAccountIdentity::PrivatePdaInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk, identifier: u128::MAX, seed: None, @@ -2457,7 +2457,7 @@ pub mod tests { Program::serialize_instruction(seed).unwrap(), vec![InputAccountIdentity::PrivatePdaInit { vpk: keys_b.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: npk_b, identifier: u128::MAX, seed: None, @@ -2494,7 +2494,7 @@ pub mod tests { Program::serialize_instruction((seed, seed, callee_id)).unwrap(), vec![InputAccountIdentity::PrivatePdaInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk, identifier: u128::MAX, seed: None, @@ -2534,7 +2534,7 @@ pub mod tests { Program::serialize_instruction((claim_seed, wrong_delegated_seed, callee_id)).unwrap(), vec![InputAccountIdentity::PrivatePdaInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk, identifier: u128::MAX, seed: None, @@ -2584,14 +2584,14 @@ pub mod tests { vec![ InputAccountIdentity::PrivatePdaInit { vpk: keys_a.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: keys_a.npk(), identifier: u128::MAX, seed: None, }, InputAccountIdentity::PrivatePdaInit { vpk: keys_b.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: keys_b.npk(), identifier: u128::MAX, seed: None, @@ -2633,7 +2633,7 @@ pub mod tests { Program::serialize_instruction(()).unwrap(), vec![InputAccountIdentity::PrivatePdaInit { vpk: keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk, identifier: u128::MAX, seed: None, @@ -2720,14 +2720,14 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: (1, vec![]), identifier: 0, }, InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: (1, vec![]), identifier: 0, @@ -3075,7 +3075,7 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: state .get_proof_for_commitment(&sender_commitment) @@ -3194,7 +3194,7 @@ pub mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: from_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: from_keys.nsk, membership_proof: state .get_proof_for_commitment(&from_commitment) @@ -3203,7 +3203,7 @@ pub mod tests { }, InputAccountIdentity::PrivateAuthorizedUpdate { vpk: to_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: to_keys.nsk, membership_proof: state .get_proof_for_commitment(&to_commitment) @@ -3465,7 +3465,7 @@ pub mod tests { Program::serialize_instruction(instruction).unwrap(), vec![InputAccountIdentity::PrivateAuthorizedInit { vpk: private_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: private_keys.nsk, identifier: 0, }], @@ -3510,7 +3510,7 @@ pub mod tests { Program::serialize_instruction(0_u128).unwrap(), vec![InputAccountIdentity::PrivateUnauthorized { vpk: private_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: private_keys.npk(), identifier: 0, }], @@ -3559,7 +3559,7 @@ pub mod tests { Program::serialize_instruction(instruction).unwrap(), vec![InputAccountIdentity::PrivateAuthorizedInit { vpk: private_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: private_keys.nsk, identifier: 0, }], @@ -3600,7 +3600,7 @@ pub mod tests { Program::serialize_instruction(()).unwrap(), vec![InputAccountIdentity::PrivateAuthorizedInit { vpk: private_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: private_keys.nsk, identifier: 0, }], @@ -3681,7 +3681,7 @@ pub mod tests { Program::serialize_instruction(instruction).unwrap(), vec![InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, @@ -3711,7 +3711,7 @@ pub mod tests { Program::serialize_instruction(instruction).unwrap(), vec![InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.nsk, membership_proof: (0, vec![]), identifier: 0, @@ -3773,7 +3773,7 @@ pub mod tests { InputAccountIdentity::Public, InputAccountIdentity::PrivateAuthorizedUpdate { vpk: recipient_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: recipient_keys.nsk, membership_proof: state .get_proof_for_commitment(&recipient_commitment) @@ -3929,7 +3929,7 @@ pub mod tests { Program::serialize_instruction(instruction).unwrap(), vec![InputAccountIdentity::PrivateUnauthorized { vpk: account_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: account_keys.npk(), identifier: 0, }], @@ -3994,7 +3994,7 @@ pub mod tests { Program::serialize_instruction(instruction).unwrap(), vec![InputAccountIdentity::PrivateUnauthorized { vpk: account_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: account_keys.npk(), identifier: 0, }], @@ -4549,7 +4549,7 @@ pub mod tests { InputAccountIdentity::Public, InputAccountIdentity::PrivatePdaInit { vpk: alice_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: alice_npk, identifier: 0, seed: Some((seed, proxy_id)), @@ -4586,7 +4586,7 @@ pub mod tests { InputAccountIdentity::Public, InputAccountIdentity::PrivatePdaInit { vpk: alice_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], npk: alice_npk, identifier: 1, seed: Some((seed, proxy_id)), @@ -4626,7 +4626,7 @@ pub mod tests { vec![ InputAccountIdentity::PrivatePdaUpdate { vpk: alice_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: alice_keys.nsk, membership_proof: state .get_proof_for_commitment(&commitment_pda_0) @@ -4664,7 +4664,7 @@ pub mod tests { vec![ InputAccountIdentity::PrivatePdaUpdate { vpk: alice_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: alice_keys.nsk, membership_proof: state .get_proof_for_commitment(&commitment_pda_1) @@ -4721,7 +4721,7 @@ pub mod tests { InputAccountIdentity::Public, InputAccountIdentity::PrivatePdaUpdate { vpk: alice_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: alice_keys.nsk, membership_proof: state .get_proof_for_commitment(&commitment_pda_1_after_spend) diff --git a/lee/state_machine/src/validated_state_diff.rs b/lee/state_machine/src/validated_state_diff.rs index 80d9f4ad..ad0591c7 100644 --- a/lee/state_machine/src/validated_state_diff.rs +++ b/lee/state_machine/src/validated_state_diff.rs @@ -660,7 +660,7 @@ mod tests { let account_identities = vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: attacker_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: attacker_keys.nsk, membership_proof, identifier: 0, @@ -817,7 +817,7 @@ mod tests { let account_identities = vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: attacker_keys.vpk(), - esk: [0; 32], + os_random: [0; 32], nsk: attacker_keys.nsk, membership_proof, identifier: 0, diff --git a/lez/sequencer/core/src/lib.rs b/lez/sequencer/core/src/lib.rs index e8cc6d37..3509263b 100644 --- a/lez/sequencer/core/src/lib.rs +++ b/lez/sequencer/core/src/lib.rs @@ -1664,7 +1664,7 @@ mod tests { vec![ InputAccountIdentity::PrivateAuthorizedUpdate { vpk: sender_keys.viewing_public_key, - esk: [0; 32], + os_random: [0; 32], nsk: sender_keys.private_key_holder.nullifier_secret_key, membership_proof: state .get_proof_for_commitment(&sender_commitment) diff --git a/lez/wallet/src/account_manager.rs b/lez/wallet/src/account_manager.rs index 3cab5a23..ef2b51eb 100644 --- a/lez/wallet/src/account_manager.rs +++ b/lez/wallet/src/account_manager.rs @@ -4,8 +4,8 @@ use anyhow::Result; use keycard_wallet::{KeycardWallet, python_path}; use lee::{AccountId, PrivateKey, PublicKey, Signature}; use lee_core::{ - EphemeralSecretKey, Identifier, InputAccountIdentity, MembershipProof, NullifierPublicKey, - NullifierSecretKey, SharedSecretKey, + Identifier, InputAccountIdentity, MembershipProof, NullifierPublicKey, NullifierSecretKey, + SharedSecretKey, account::{AccountWithMetadata, Nonce}, encryption::ViewingPublicKey, }; @@ -262,8 +262,8 @@ impl AccountManager { } => { let acc = lee_core::account::Account::default(); let auth_acc = AccountWithMetadata::new(acc, false, (&npk, &vpk, identifier)); - let mut esk: EphemeralSecretKey = [0; 32]; - OsRng.fill_bytes(&mut esk); + let mut os_random: [u8; 32] = [0; 32]; + OsRng.fill_bytes(&mut os_random); let pre = AccountPreparedData { nsk: None, npk, @@ -271,7 +271,7 @@ impl AccountManager { vpk, pre_state: auth_acc, proof: None, - esk, + os_random, is_pda: false, }; @@ -289,8 +289,8 @@ impl AccountManager { } => { let acc = lee_core::account::Account::default(); let auth_acc = AccountWithMetadata::new(acc, false, account_id); - let mut esk: EphemeralSecretKey = [0; 32]; - OsRng.fill_bytes(&mut esk); + let mut os_random: [u8; 32] = [0; 32]; + OsRng.fill_bytes(&mut os_random); let pre = AccountPreparedData { nsk: None, npk, @@ -298,7 +298,7 @@ impl AccountManager { vpk, pre_state: auth_acc, proof: None, - esk, + os_random, is_pda: true, }; State::Private(pre) @@ -372,14 +372,22 @@ impl AccountManager { State::Private(pre) => Some(pre), State::Public { .. } | State::PublicKeycard { .. } => None, }) - .enumerate() - .map(|(output_index, pre)| PrivateAccountKeys { - ssk: SharedSecretKey::encapsulate_deterministic( - &pre.vpk, - &pre.esk, - u32::try_from(output_index).expect("private output index fits in u32"), - ) - .0, + .map(|pre| { + let nonce = if pre.proof.is_some() { + pre.pre_state.account.nonce.private_account_nonce_increment( + pre.nsk.as_ref().expect("update variant must have nsk"), + ) + } else { + lee_core::account::Nonce::private_account_nonce_init(&pre.pre_state.account_id) + }; + let esk = lee_core::EphemeralSecretKey::new( + &pre.pre_state.account_id, + &pre.os_random, + &nonce, + ); + PrivateAccountKeys { + ssk: SharedSecretKey::encapsulate_deterministic(&pre.vpk, &esk).0, + } }) .collect() } @@ -396,7 +404,7 @@ impl AccountManager { State::Private(pre) if pre.is_pda => match (pre.nsk, pre.proof.clone()) { (Some(nsk), Some(membership_proof)) => InputAccountIdentity::PrivatePdaUpdate { vpk: pre.vpk.clone(), - esk: pre.esk, + os_random: pre.os_random, nsk, membership_proof, identifier: pre.identifier, @@ -404,7 +412,7 @@ impl AccountManager { }, _ => InputAccountIdentity::PrivatePdaInit { vpk: pre.vpk.clone(), - esk: pre.esk, + os_random: pre.os_random, npk: pre.npk, identifier: pre.identifier, seed: None, @@ -414,7 +422,7 @@ impl AccountManager { (Some(nsk), Some(membership_proof)) => { InputAccountIdentity::PrivateAuthorizedUpdate { vpk: pre.vpk.clone(), - esk: pre.esk, + os_random: pre.os_random, nsk, membership_proof, identifier: pre.identifier, @@ -422,13 +430,13 @@ impl AccountManager { } (Some(nsk), None) => InputAccountIdentity::PrivateAuthorizedInit { vpk: pre.vpk.clone(), - esk: pre.esk, + os_random: pre.os_random, nsk, identifier: pre.identifier, }, (None, _) => InputAccountIdentity::PrivateUnauthorized { vpk: pre.vpk.clone(), - esk: pre.esk, + os_random: pre.os_random, npk: pre.npk, identifier: pre.identifier, }, @@ -505,7 +513,7 @@ struct AccountPreparedData { vpk: ViewingPublicKey, pre_state: AccountWithMetadata, proof: Option, - esk: EphemeralSecretKey, + os_random: [u8; 32], /// True when this account is a private PDA (owned or foreign). Used by `account_identities()` /// to select `PrivatePdaInit`/`PrivatePdaUpdate` rather than the standalone private variants. is_pda: bool, @@ -536,8 +544,8 @@ async fn private_key_tree_acc_preparation( // support from that in the wallet. let sender_pre = AccountWithMetadata::new(from_acc.account.clone(), true, account_id); - let mut esk: EphemeralSecretKey = [0; 32]; - OsRng.fill_bytes(&mut esk); + let mut os_random: [u8; 32] = [0; 32]; + OsRng.fill_bytes(&mut os_random); Ok(AccountPreparedData { nsk: Some(nsk), @@ -546,7 +554,7 @@ async fn private_key_tree_acc_preparation( vpk: from_vpk, pre_state: sender_pre, proof, - esk, + os_random, is_pda, }) } @@ -574,8 +582,8 @@ async fn private_shared_acc_preparation( .await .unwrap_or(None); - let mut esk: EphemeralSecretKey = [0; 32]; - OsRng.fill_bytes(&mut esk); + let mut os_random: [u8; 32] = [0; 32]; + OsRng.fill_bytes(&mut os_random); Ok(AccountPreparedData { nsk: Some(nsk), @@ -584,7 +592,7 @@ async fn private_shared_acc_preparation( vpk, pre_state, proof, - esk, + os_random, is_pda, }) } diff --git a/program_methods/guest/src/bin/privacy_preserving_circuit/output.rs b/program_methods/guest/src/bin/privacy_preserving_circuit/output.rs index d9ca92b5..a411a152 100644 --- a/program_methods/guest/src/bin/privacy_preserving_circuit/output.rs +++ b/program_methods/guest/src/bin/privacy_preserving_circuit/output.rs @@ -42,7 +42,7 @@ pub fn compute_circuit_output( } InputAccountIdentity::PrivateAuthorizedInit { vpk, - esk, + os_random, nsk, identifier, } => { @@ -74,14 +74,14 @@ pub fn compute_circuit_output( &PrivateAccountKind::Regular(*identifier), &npk, vpk, - esk, + os_random, new_nullifier, new_nonce, ); } InputAccountIdentity::PrivateAuthorizedUpdate { vpk, - esk, + os_random, nsk, membership_proof, identifier, @@ -111,14 +111,14 @@ pub fn compute_circuit_output( &PrivateAccountKind::Regular(*identifier), &npk, vpk, - esk, + os_random, new_nullifier, new_nonce, ); } InputAccountIdentity::PrivateUnauthorized { vpk, - esk, + os_random, npk, identifier, } => { @@ -149,14 +149,14 @@ pub fn compute_circuit_output( &PrivateAccountKind::Regular(*identifier), npk, vpk, - esk, + os_random, new_nullifier, new_nonce, ); } InputAccountIdentity::PrivatePdaInit { vpk, - esk, + os_random, npk, identifier, seed: _, @@ -199,14 +199,14 @@ pub fn compute_circuit_output( }, npk, vpk, - esk, + os_random, new_nullifier, new_nonce, ); } InputAccountIdentity::PrivatePdaUpdate { vpk, - esk, + os_random, nsk, membership_proof, identifier, @@ -247,7 +247,7 @@ pub fn compute_circuit_output( }, &npk, vpk, - esk, + os_random, new_nullifier, new_nonce, ); @@ -270,7 +270,7 @@ fn emit_private_output( kind: &PrivateAccountKind, npk: &NullifierPublicKey, vpk: &ViewingPublicKey, - esk: &EphemeralSecretKey, + os_random: &[u8; 32], new_nullifier: (Nullifier, CommitmentSetDigest), new_nonce: Nonce, ) { @@ -281,7 +281,8 @@ fn emit_private_output( let commitment_post = Commitment::new(account_id, &post_with_updated_nonce); - let (shared_secret, epk) = SharedSecretKey::encapsulate_deterministic(vpk, esk, *output_index); + let esk = EphemeralSecretKey::new(account_id, os_random, &new_nonce); + let (shared_secret, epk) = SharedSecretKey::encapsulate_deterministic(vpk, &esk); // Currently the view tag is properlty generated for all accounts. // To increase privacy, this will be changed in the later version