diff --git a/artifacts/program_methods/amm.bin b/artifacts/program_methods/amm.bin index a6007fb8..4488ad4e 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 9740bdf9..4d883d87 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 57782b67..1b6174b9 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/clock.bin b/artifacts/program_methods/clock.bin index b7137200..a02f649f 100644 Binary files a/artifacts/program_methods/clock.bin and b/artifacts/program_methods/clock.bin differ diff --git a/artifacts/program_methods/pinata.bin b/artifacts/program_methods/pinata.bin index dd2f01f0..37f42b7d 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 b1eba309..c01259f6 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 da616104..7b499637 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 d840d9dc..bd93e510 100644 Binary files a/artifacts/program_methods/token.bin and b/artifacts/program_methods/token.bin differ diff --git a/artifacts/test_program_methods/burner.bin b/artifacts/test_program_methods/burner.bin index c5ec313d..8405f775 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 753a3617..73442a8e 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 e107b543..a4afbcef 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 d6ec5541..2781a824 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 68911f91..534bc190 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 dc345618..53d4eb79 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 6e3885b6..ca0e9442 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/flash_swap_callback.bin b/artifacts/test_program_methods/flash_swap_callback.bin index 74aebf6d..aa0a6db0 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 3fd8f0dd..601e1585 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 d28c2c06..affadf14 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 f8490f21..c214f0f7 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_self_program_id.bin b/artifacts/test_program_methods/malicious_self_program_id.bin index 0508f3fd..778d3ca7 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 89c6185c..bf345a92 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 4f6d61aa..01fd3c11 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 0b2d16de..24ffce83 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 b1c5b542..0b380d2a 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 de36834a..32cb2534 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/pinata_cooldown.bin b/artifacts/test_program_methods/pinata_cooldown.bin index c735b1df..06bb0527 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/program_owner_changer.bin b/artifacts/test_program_methods/program_owner_changer.bin index d25c24c4..9166ac3f 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 8e78ac7d..c1e1497b 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 800893f6..75f23020 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/validity_window.bin b/artifacts/test_program_methods/validity_window.bin index a2ba8b5d..6ee0e41a 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 c02c355f..41fd2a3d 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/nssa/core/src/encryption/mod.rs b/nssa/core/src/encryption/mod.rs index 400fb331..80d62f30 100644 --- a/nssa/core/src/encryption/mod.rs +++ b/nssa/core/src/encryption/mod.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "host")] pub use shared_key_derivation::{EphemeralPublicKey, EphemeralSecretKey, ViewingPublicKey}; -use crate::{Commitment, account::Account}; +use crate::{Commitment, Identifier, account::Account}; #[cfg(feature = "host")] pub mod shared_key_derivation; @@ -40,11 +40,14 @@ impl EncryptionScheme { #[must_use] pub fn encrypt( account: &Account, + identifier: Identifier, shared_secret: &SharedSecretKey, commitment: &Commitment, output_index: u32, ) -> Ciphertext { - let mut buffer = account.to_bytes(); + // Plaintext: identifier (16 bytes, little-endian) || account bytes + let mut buffer = identifier.to_le_bytes().to_vec(); + buffer.extend_from_slice(&account.to_bytes()); Self::symmetric_transform(&mut buffer, shared_secret, commitment, output_index); Ciphertext(buffer) } @@ -86,12 +89,17 @@ impl EncryptionScheme { shared_secret: &SharedSecretKey, commitment: &Commitment, output_index: u32, - ) -> Option { + ) -> Option<(Identifier, Account)> { use std::io::Cursor; let mut buffer = ciphertext.0.clone(); Self::symmetric_transform(&mut buffer, shared_secret, commitment, output_index); - let mut cursor = Cursor::new(buffer.as_slice()); + if buffer.len() < 16 { + return None; + } + let identifier = Identifier::from_le_bytes(buffer[..16].try_into().unwrap()); + + let mut cursor = Cursor::new(&buffer[16..]); Account::from_cursor(&mut cursor) .inspect_err(|err| { println!( @@ -104,5 +112,6 @@ impl EncryptionScheme { ); }) .ok() + .map(|account| (identifier, account)) } } diff --git a/nssa/src/privacy_preserving_transaction/circuit.rs b/nssa/src/privacy_preserving_transaction/circuit.rs index fc6bd521..70d26568 100644 --- a/nssa/src/privacy_preserving_transaction/circuit.rs +++ b/nssa/src/privacy_preserving_transaction/circuit.rs @@ -259,7 +259,7 @@ mod tests { assert_eq!(output.new_nullifiers.len(), 1); assert_eq!(output.ciphertexts.len(), 1); - let recipient_post = EncryptionScheme::decrypt( + let (_identifier, recipient_post) = EncryptionScheme::decrypt( &output.ciphertexts[0], &shared_secret, &output.new_commitments[0], @@ -357,7 +357,7 @@ mod tests { assert_eq!(output.new_nullifiers, expected_new_nullifiers); assert_eq!(output.ciphertexts.len(), 2); - let sender_post = EncryptionScheme::decrypt( + let (_identifier, sender_post) = EncryptionScheme::decrypt( &output.ciphertexts[0], &shared_secret_1, &expected_new_commitments[0], @@ -366,7 +366,7 @@ mod tests { .unwrap(); assert_eq!(sender_post, expected_private_account_1); - let recipient_post = EncryptionScheme::decrypt( + let (_identifier, recipient_post) = EncryptionScheme::decrypt( &output.ciphertexts[1], &shared_secret_2, &expected_new_commitments[1], diff --git a/nssa/src/privacy_preserving_transaction/message.rs b/nssa/src/privacy_preserving_transaction/message.rs index a46ddf07..ee46d0b3 100644 --- a/nssa/src/privacy_preserving_transaction/message.rs +++ b/nssa/src/privacy_preserving_transaction/message.rs @@ -186,7 +186,7 @@ pub mod tests { let esk = [3; 32]; let shared_secret = SharedSecretKey::new(&esk, &vpk); let epk = EphemeralPublicKey::from_scalar(esk); - let ciphertext = EncryptionScheme::encrypt(&account, &shared_secret, &commitment, 2); + let ciphertext = EncryptionScheme::encrypt(&account, 0, &shared_secret, &commitment, 2); let encrypted_account_data = EncryptedAccountData::new(ciphertext.clone(), &npk, &vpk, epk.clone()); diff --git a/program_methods/guest/src/bin/privacy_preserving_circuit.rs b/program_methods/guest/src/bin/privacy_preserving_circuit.rs index ad3d4f95..d950f2af 100644 --- a/program_methods/guest/src/bin/privacy_preserving_circuit.rs +++ b/program_methods/guest/src/bin/privacy_preserving_circuit.rs @@ -425,6 +425,7 @@ fn compute_circuit_output( // Encrypt and push post state let encrypted_account = EncryptionScheme::encrypt( &post_with_updated_nonce, + *identifier, shared_secret, &commitment_post, output_index, diff --git a/wallet/src/chain_storage.rs b/wallet/src/chain_storage.rs index 30f312fa..b8038d09 100644 --- a/wallet/src/chain_storage.rs +++ b/wallet/src/chain_storage.rs @@ -175,6 +175,7 @@ impl WalletChainStore { pub fn insert_private_account_data( &mut self, account_id: nssa::AccountId, + identifier: nssa_core::Identifier, account: nssa_core::account::Account, ) { debug!("inserting at address {account_id}, this account {account:?}"); @@ -204,8 +205,6 @@ impl WalletChainStore { } // Otherwise update the private key tree - // Identifier is hardcoded to 0 until ciphertexts carry the identifier - let identifier: nssa_core::Identifier = 0; // Find the node by iterating all tree nodes for this account_id let chain_index = self diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 7cd481a9..b2458390 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -335,7 +335,7 @@ impl WalletCore { let acc_ead = tx.message.encrypted_private_post_states[output_index].clone(); let acc_comm = tx.message.new_commitments[output_index].clone(); - let res_acc = nssa_core::EncryptionScheme::decrypt( + let (identifier, res_acc) = nssa_core::EncryptionScheme::decrypt( &acc_ead.ciphertext, secret, &acc_comm, @@ -348,7 +348,7 @@ impl WalletCore { println!("Received new acc {res_acc:#?}"); self.storage - .insert_private_account_data(*acc_account_id, res_acc); + .insert_private_account_data(*acc_account_id, identifier, res_acc); } AccDecodeData::Skip => {} } @@ -484,35 +484,28 @@ impl WalletCore { .storage .user_data .default_user_private_accounts - .iter() - .map(|(acc_account_id, (key_chain, _))| (*acc_account_id, key_chain, None)) + .values() + .map(|(key_chain, _)| (key_chain, None)) .chain(self.storage.user_data.private_key_tree.key_map.iter().map( - |(chain_index, keys_node)| { - // Use identifier=0 as the expected first account for this node. - // The actual identifier will be confirmed once the account is synced. - let account_id = nssa::AccountId::from(( - &keys_node.value.0.nullifier_public_key, - 0_u128, - )); - (account_id, &keys_node.value.0, chain_index.index()) - }, + |(chain_index, keys_node)| (&keys_node.value.0, chain_index.index()), )); let affected_accounts = private_account_key_chains - .flat_map(|(acc_account_id, key_chain, index)| { + .flat_map(|(key_chain, index)| { let view_tag = EncryptedAccountData::compute_view_tag( &key_chain.nullifier_public_key, &key_chain.viewing_public_key, ); + let new_commitments = &tx.message.new_commitments; tx.message() .encrypted_private_post_states .iter() .enumerate() .filter(move |(_, encrypted_data)| encrypted_data.view_tag == view_tag) - .filter_map(|(ciph_id, encrypted_data)| { + .filter_map(move |(ciph_id, encrypted_data)| { let ciphertext = &encrypted_data.ciphertext; - let commitment = &tx.message.new_commitments[ciph_id]; + let commitment = &new_commitments[ciph_id]; let shared_secret = key_chain.calculate_shared_secret_receiver(&encrypted_data.epk, index); @@ -524,18 +517,24 @@ impl WalletCore { .try_into() .expect("Ciphertext ID is expected to fit in u32"), ) + .map(|(identifier, res_acc)| { + let account_id = nssa::AccountId::from(( + &key_chain.nullifier_public_key, + identifier, + )); + (account_id, identifier, res_acc) + }) }) - .map(move |res_acc| (acc_account_id, res_acc)) .collect::>() }) .collect::>(); - for (affected_account_id, new_acc) in affected_accounts { + for (affected_account_id, identifier, new_acc) in affected_accounts { info!( "Received new account for account_id {affected_account_id:#?} with account object {new_acc:#?}" ); self.storage - .insert_private_account_data(affected_account_id, new_acc); + .insert_private_account_data(affected_account_id, identifier, new_acc); } }