diff --git a/artifacts/program_methods/amm.bin b/artifacts/program_methods/amm.bin index 31e0bd7b..002de9c4 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 ddbfff47..93fa5293 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 c343394d..8571c878 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 983bd43e..6053f4e9 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 7557bfc5..0e68bd74 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 04dd51c6..ccd0dfd6 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 57cda10b..66ca147c 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 9664737c..ccb8abde 100644 Binary files a/artifacts/program_methods/token.bin and b/artifacts/program_methods/token.bin differ diff --git a/artifacts/test_program_methods/auth_asserting_noop.bin b/artifacts/test_program_methods/auth_asserting_noop.bin index b4252de3..b4d78f9a 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/burner.bin b/artifacts/test_program_methods/burner.bin index 69828f5f..db1f91fc 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 35cd9b76..51552977 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 c16d1bf4..fa3f10f7 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 d0e869ca..164fc2e1 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 eb3849ba..17cf28a9 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 3df1213b..27a808d3 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 d8e9453b..997d783b 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 8096c5d5..bd1b0fb7 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 0c06e900..751cea31 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/group_pda_spender.bin b/artifacts/test_program_methods/group_pda_spender.bin new file mode 100644 index 00000000..16efb8a4 Binary files /dev/null and b/artifacts/test_program_methods/group_pda_spender.bin differ diff --git a/artifacts/test_program_methods/malicious_authorization_changer.bin b/artifacts/test_program_methods/malicious_authorization_changer.bin index 7db291f8..1d9e261d 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 4f2f2fe6..d8f2fab7 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 da80c542..bf6f94fe 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 d5fcf65e..8d230657 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 f1258f73..9ffdad4d 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 e719836f..c95729cd 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 c548c76b..b5b9f2d0 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 d9e00f30..d35aae8d 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 916ddaef..3d3a949e 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/pinata_cooldown.bin b/artifacts/test_program_methods/pinata_cooldown.bin index c5d22535..269a9323 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 a00de630..b991dccc 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 18a5019d..2e4d8463 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 bfa38005..5775494e 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 d1050b1c..7f06ad7f 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 6c8d7a5d..7cbb3249 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 8f36964a..6c436b2f 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 f936dbe8..a8f7cf41 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/src/privacy_preserving_transaction/message.rs b/nssa/src/privacy_preserving_transaction/message.rs index 697f66ac..8256ab7c 100644 --- a/nssa/src/privacy_preserving_transaction/message.rs +++ b/nssa/src/privacy_preserving_transaction/message.rs @@ -140,7 +140,8 @@ impl Message { #[cfg(test)] pub mod tests { use nssa_core::{ - Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, SharedSecretKey, + Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, PrivateAccountKind, + SharedSecretKey, account::{Account, AccountId, Nonce}, encryption::{EphemeralPublicKey, ViewingPublicKey}, program::{BlockValidityWindow, TimestampValidityWindow}, @@ -252,7 +253,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, 0, &shared_secret, &commitment, 2); + let ciphertext = EncryptionScheme::encrypt(&account, &PrivateAccountKind::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 13101b0b..3d16fdbb 100644 --- a/program_methods/guest/src/bin/privacy_preserving_circuit.rs +++ b/program_methods/guest/src/bin/privacy_preserving_circuit.rs @@ -35,7 +35,7 @@ struct ExecutionState { /// claims a private PDA and then delegates it to a callee), and the set uses `contains`, /// not `assert!(insert)`. After the main loop, every mask-3 position must appear in this /// set; otherwise the npk is unbound and the circuit rejects. - private_pda_bound_positions: HashMap, + private_pda_bound_positions: HashMap, /// Across the whole transaction, each `(program_id, seed)` pair may resolve to at most one /// `AccountId`. A seed under a program can derive a family of accounts, one public PDA and /// one private PDA per distinct npk. Without this check, a single `pda_seeds: [S]` entry in @@ -372,7 +372,7 @@ impl ExecutionState { pre_account_id, pda, "Invalid private PDA claim for account {pre_account_id}" ); - self.private_pda_bound_positions.insert(pre_state_position, seed); + self.private_pda_bound_positions.insert(pre_state_position, (program_id, seed)); assert_family_binding( &mut self.pda_family_binding, program_id, @@ -453,7 +453,7 @@ fn assert_family_binding( )] fn resolve_authorization_and_record_bindings( pda_family_binding: &mut HashMap<(ProgramId, PdaSeed), AccountId>, - private_pda_bound_positions: &mut HashMap, + private_pda_bound_positions: &mut HashMap, private_pda_npk_by_position: &HashMap, pre_account_id: AccountId, pre_state_position: usize, @@ -479,7 +479,7 @@ fn resolve_authorization_and_record_bindings( if let Some((seed, is_private_form, caller)) = matched_caller_seed { assert_family_binding(pda_family_binding, caller, seed, pre_account_id); if is_private_form { - private_pda_bound_positions.insert(pre_state_position, seed); + private_pda_bound_positions.insert(pre_state_position, (caller, seed)); } } @@ -487,7 +487,7 @@ fn resolve_authorization_and_record_bindings( } fn compute_circuit_output( - execution_state: ExecutionState, + mut execution_state: ExecutionState, visibility_mask: &[u8], private_account_keys: &[(NullifierPublicKey, Identifier, SharedSecretKey)], private_account_nsks: &[NullifierSecretKey], @@ -503,6 +503,7 @@ fn compute_circuit_output( timestamp_validity_window: execution_state.timestamp_validity_window, }; + let pda_seed_by_position = std::mem::take(&mut execution_state.private_pda_bound_positions); let states_iter = execution_state.into_states_iter(); assert_eq!( visibility_mask.len(), @@ -515,8 +516,8 @@ fn compute_circuit_output( let mut private_membership_proofs_iter = private_account_membership_proofs.iter(); let mut output_index = 0; - for (account_visibility_mask, (pre_state, post_state)) in - visibility_mask.iter().copied().zip(states_iter) + for (pos, (account_visibility_mask, (pre_state, post_state))) in + visibility_mask.iter().copied().zip(states_iter).enumerate() { match account_visibility_mask { 0 => { @@ -689,9 +690,16 @@ fn compute_circuit_output( let commitment_post = Commitment::new(&pre_state.account_id, &post_with_updated_nonce); + let (pda_program_id, seed) = pda_seed_by_position + .get(&pos) + .expect("mask-3 position must be in pda_seed_by_position"); let encrypted_account = EncryptionScheme::encrypt( &post_with_updated_nonce, - &PrivateAccountKind::Account(*identifier), + &PrivateAccountKind::Pda { + program_id: *pda_program_id, + seed: *seed, + identifier: *identifier, + }, shared_secret, &commitment_post, output_index,