feat: implement private multi chain calls in wallet (nssa)

This commit is contained in:
Daniil Polyakov 2025-12-25 01:49:34 +03:00
parent 847bd1a376
commit ac7b8d418d
12 changed files with 325 additions and 322 deletions

View File

@ -53,7 +53,7 @@ async fn main() {
wallet_core wallet_core
.send_privacy_preserving_tx( .send_privacy_preserving_tx(
accounts, accounts,
&Program::serialize_instruction(greeting).unwrap(), Program::serialize_instruction(greeting).unwrap(),
&program.into(), &program.into(),
) )
.await .await

View File

@ -61,7 +61,7 @@ async fn main() {
wallet_core wallet_core
.send_privacy_preserving_tx( .send_privacy_preserving_tx(
accounts, accounts,
&Program::serialize_instruction(instruction).unwrap(), Program::serialize_instruction(instruction).unwrap(),
&program_with_dependencies, &program_with_dependencies,
) )
.await .await

View File

@ -104,7 +104,7 @@ async fn main() {
wallet_core wallet_core
.send_privacy_preserving_tx( .send_privacy_preserving_tx(
accounts, accounts,
&Program::serialize_instruction(instruction).unwrap(), Program::serialize_instruction(instruction).unwrap(),
&program.into(), &program.into(),
) )
.await .await
@ -145,7 +145,7 @@ async fn main() {
wallet_core wallet_core
.send_privacy_preserving_tx( .send_privacy_preserving_tx(
accounts, accounts,
&Program::serialize_instruction(instruction).unwrap(), Program::serialize_instruction(instruction).unwrap(),
&program.into(), &program.into(),
) )
.await .await

View File

@ -159,16 +159,16 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
]], ]],
); );
let (output, proof) = circuit::execute_and_prove( let (output, proof) = circuit::execute_and_prove(
&[sender_pre, recipient_pre], vec![sender_pre, recipient_pre],
&Program::serialize_instruction(balance_to_move).unwrap(), Program::serialize_instruction(balance_to_move).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
(sender_npk.clone(), sender_ss), (sender_npk.clone(), sender_ss),
(recipient_npk.clone(), recipient_ss), (recipient_npk.clone(), recipient_ss),
], ],
&[sender_nsk], vec![sender_nsk],
&[Some(proof)], vec![Some(proof)],
&program.into(), &program.into(),
) )
.unwrap(); .unwrap();

View File

@ -1,11 +1,11 @@
use std::collections::HashMap; use std::collections::{HashMap, VecDeque};
use borsh::{BorshDeserialize, BorshSerialize}; use borsh::{BorshDeserialize, BorshSerialize};
use nssa_core::{ use nssa_core::{
MembershipProof, NullifierPublicKey, NullifierSecretKey, PrivacyPreservingCircuitInput, MembershipProof, NullifierPublicKey, NullifierSecretKey, PrivacyPreservingCircuitInput,
PrivacyPreservingCircuitOutput, SharedSecretKey, PrivacyPreservingCircuitOutput, SharedSecretKey,
account::AccountWithMetadata, account::AccountWithMetadata,
program::{InstructionData, ProgramId, ProgramOutput}, program::{ChainedCall, InstructionData, ProgramId, ProgramOutput},
}; };
use risc0_zkvm::{ExecutorEnv, InnerReceipt, Receipt, default_prover}; use risc0_zkvm::{ExecutorEnv, InnerReceipt, Receipt, default_prover};
@ -46,69 +46,72 @@ impl From<Program> for ProgramWithDependencies {
/// circuit /// circuit
#[expect(clippy::too_many_arguments, reason = "TODO: fix later")] #[expect(clippy::too_many_arguments, reason = "TODO: fix later")]
pub fn execute_and_prove( pub fn execute_and_prove(
pre_states: &[AccountWithMetadata], pre_states: Vec<AccountWithMetadata>,
instruction_data: &InstructionData, instruction_data: InstructionData,
visibility_mask: &[u8], visibility_mask: Vec<u8>,
private_account_nonces: &[u128], private_account_nonces: Vec<u128>,
private_account_keys: &[(NullifierPublicKey, SharedSecretKey)], private_account_keys: Vec<(NullifierPublicKey, SharedSecretKey)>,
private_account_nsks: &[NullifierSecretKey], private_account_nsks: Vec<NullifierSecretKey>,
private_account_membership_proofs: &[Option<MembershipProof>], private_account_membership_proofs: Vec<Option<MembershipProof>>,
program_with_dependencies: &ProgramWithDependencies, program_with_dependencies: &ProgramWithDependencies,
) -> Result<(PrivacyPreservingCircuitOutput, Proof), NssaError> { ) -> Result<(PrivacyPreservingCircuitOutput, Proof), NssaError> {
let mut program = &program_with_dependencies.program; let ProgramWithDependencies {
let dependencies = &program_with_dependencies.dependencies; program,
let mut instruction_data = instruction_data.clone(); dependencies,
let mut pre_states = pre_states.to_vec(); } = program_with_dependencies;
let mut env_builder = ExecutorEnv::builder(); let mut env_builder = ExecutorEnv::builder();
let mut program_outputs = Vec::new(); let mut program_outputs = Vec::new();
for _i in 0..MAX_NUMBER_CHAINED_CALLS { let initial_call = ChainedCall {
let inner_receipt = execute_and_prove_program(program, &pre_states, &instruction_data)?; program_id: program.id(),
instruction_data: instruction_data.clone(),
pre_states,
pda_seeds: vec![],
};
let mut chained_calls = VecDeque::from_iter([(initial_call, program)]);
let mut chain_calls_counter = 0;
while let Some((chained_call, program)) = chained_calls.pop_front() {
if chain_calls_counter >= MAX_NUMBER_CHAINED_CALLS {
return Err(NssaError::MaxChainedCallsDepthExceeded);
}
let inner_receipt = execute_and_prove_program(
program,
&chained_call.pre_states,
&chained_call.instruction_data,
)?;
let program_output: ProgramOutput = inner_receipt let program_output: ProgramOutput = inner_receipt
.journal .journal
.decode() .decode()
.map_err(|e| NssaError::ProgramOutputDeserializationError(e.to_string()))?; .map_err(|e| NssaError::ProgramOutputDeserializationError(e.to_string()))?;
// TODO: Why private execution doesn't care about public account authorization?
// TODO: remove clone // TODO: remove clone
program_outputs.push(program_output.clone()); program_outputs.push(program_output.clone());
// Prove circuit. // Prove circuit.
env_builder.add_assumption(inner_receipt); env_builder.add_assumption(inner_receipt);
// TODO: Remove when multi-chain calls are supported in the circuit for new_call in program_output.chained_calls.into_iter().rev() {
assert!(program_output.chained_calls.len() <= 1); let next_program = dependencies
// TODO: Modify when multi-chain calls are supported in the circuit .get(&new_call.program_id)
if let Some(next_call) = program_output.chained_calls.first() {
program = dependencies
.get(&next_call.program_id)
.ok_or(NssaError::InvalidProgramBehavior)?; .ok_or(NssaError::InvalidProgramBehavior)?;
instruction_data = next_call.instruction_data.clone(); chained_calls.push_front((new_call, next_program));
// Build post states with metadata for next call
let mut post_states_with_metadata = Vec::new();
for (pre, post) in program_output
.pre_states
.iter()
.zip(program_output.post_states)
{
let mut post_with_metadata = pre.clone();
post_with_metadata.account = post.account().clone();
post_states_with_metadata.push(post_with_metadata);
}
pre_states = next_call.pre_states.clone();
} else {
break;
} }
chain_calls_counter += 1;
} }
let circuit_input = PrivacyPreservingCircuitInput { let circuit_input = PrivacyPreservingCircuitInput {
program_outputs, program_outputs,
visibility_mask: visibility_mask.to_vec(), visibility_mask,
private_account_nonces: private_account_nonces.to_vec(), private_account_nonces,
private_account_keys: private_account_keys.to_vec(), private_account_keys,
private_account_nsks: private_account_nsks.to_vec(), private_account_nsks,
private_account_membership_proofs: private_account_membership_proofs.to_vec(), private_account_membership_proofs,
program_id: program_with_dependencies.program.id(), program_id: program_with_dependencies.program.id(),
}; };
@ -215,13 +218,13 @@ mod tests {
let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.ivk()); let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.ivk());
let (output, proof) = execute_and_prove( let (output, proof) = execute_and_prove(
&[sender, recipient], vec![sender, recipient],
&Program::serialize_instruction(balance_to_move).unwrap(), Program::serialize_instruction(balance_to_move).unwrap(),
&[0, 2], vec![0, 2],
&[0xdeadbeef], vec![0xdeadbeef],
&[(recipient_keys.npk(), shared_secret)], vec![(recipient_keys.npk(), shared_secret)],
&[], vec![],
&[None], vec![None],
&Program::authenticated_transfer_program().into(), &Program::authenticated_transfer_program().into(),
) )
.unwrap(); .unwrap();
@ -311,16 +314,16 @@ mod tests {
let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.ivk()); let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.ivk());
let (output, proof) = execute_and_prove( let (output, proof) = execute_and_prove(
&[sender_pre.clone(), recipient], vec![sender_pre.clone(), recipient],
&Program::serialize_instruction(balance_to_move).unwrap(), Program::serialize_instruction(balance_to_move).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
(sender_keys.npk(), shared_secret_1), (sender_keys.npk(), shared_secret_1),
(recipient_keys.npk(), shared_secret_2), (recipient_keys.npk(), shared_secret_2),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[commitment_set.get_proof_for(&commitment_sender), None], vec![commitment_set.get_proof_for(&commitment_sender), None],
&program.into(), &program.into(),
) )
.unwrap(); .unwrap();

View File

@ -865,13 +865,13 @@ pub mod tests {
let epk = EphemeralPublicKey::from_scalar(esk); let epk = EphemeralPublicKey::from_scalar(esk);
let (output, proof) = circuit::execute_and_prove( let (output, proof) = circuit::execute_and_prove(
&[sender, recipient], vec![sender, recipient],
&Program::serialize_instruction(balance_to_move).unwrap(), Program::serialize_instruction(balance_to_move).unwrap(),
&[0, 2], vec![0, 2],
&[0xdeadbeef], vec![0xdeadbeef],
&[(recipient_keys.npk(), shared_secret)], vec![(recipient_keys.npk(), shared_secret)],
&[], vec![],
&[None], vec![None],
&Program::authenticated_transfer_program().into(), &Program::authenticated_transfer_program().into(),
) )
.unwrap(); .unwrap();
@ -912,16 +912,16 @@ pub mod tests {
let epk_2 = EphemeralPublicKey::from_scalar(esk_2); let epk_2 = EphemeralPublicKey::from_scalar(esk_2);
let (output, proof) = circuit::execute_and_prove( let (output, proof) = circuit::execute_and_prove(
&[sender_pre, recipient_pre], vec![sender_pre, recipient_pre],
&Program::serialize_instruction(balance_to_move).unwrap(), Program::serialize_instruction(balance_to_move).unwrap(),
&[1, 2], vec![1, 2],
&new_nonces, new_nonces.to_vec(),
&[ vec![
(sender_keys.npk(), shared_secret_1), (sender_keys.npk(), shared_secret_1),
(recipient_keys.npk(), shared_secret_2), (recipient_keys.npk(), shared_secret_2),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[state.get_proof_for_commitment(&sender_commitment), None], vec![state.get_proof_for_commitment(&sender_commitment), None],
&program.into(), &program.into(),
) )
.unwrap(); .unwrap();
@ -965,13 +965,13 @@ pub mod tests {
let epk = EphemeralPublicKey::from_scalar(esk); let epk = EphemeralPublicKey::from_scalar(esk);
let (output, proof) = circuit::execute_and_prove( let (output, proof) = circuit::execute_and_prove(
&[sender_pre, recipient_pre], vec![sender_pre, recipient_pre],
&Program::serialize_instruction(balance_to_move).unwrap(), Program::serialize_instruction(balance_to_move).unwrap(),
&[1, 0], vec![1, 0],
&[new_nonce], vec![new_nonce],
&[(sender_keys.npk(), shared_secret)], vec![(sender_keys.npk(), shared_secret)],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[state.get_proof_for_commitment(&sender_commitment)], vec![state.get_proof_for_commitment(&sender_commitment)],
&program.into(), &program.into(),
) )
.unwrap(); .unwrap();
@ -1179,13 +1179,13 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[public_account], vec![public_account],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[0], vec![0],
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1206,13 +1206,13 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[public_account], vec![public_account],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[0], vec![0],
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1233,13 +1233,13 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[public_account], vec![public_account],
&Program::serialize_instruction(()).unwrap(), Program::serialize_instruction(()).unwrap(),
&[0], vec![0],
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1260,13 +1260,13 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[public_account], vec![public_account],
&Program::serialize_instruction(vec![0]).unwrap(), Program::serialize_instruction(vec![0]).unwrap(),
&[0], vec![0],
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1289,13 +1289,13 @@ pub mod tests {
let large_data: Vec<u8> = vec![0; nssa_core::account::data::DATA_MAX_LENGTH_IN_BYTES + 1]; let large_data: Vec<u8> = vec![0; nssa_core::account::data::DATA_MAX_LENGTH_IN_BYTES + 1];
let result = execute_and_prove( let result = execute_and_prove(
&[public_account], vec![public_account],
&Program::serialize_instruction(large_data).unwrap(), Program::serialize_instruction(large_data).unwrap(),
&[0], vec![0],
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.to_owned().into(), &program.to_owned().into(),
); );
@ -1316,13 +1316,13 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[public_account], vec![public_account],
&Program::serialize_instruction(()).unwrap(), Program::serialize_instruction(()).unwrap(),
&[0], vec![0],
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1352,13 +1352,13 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[public_account_1, public_account_2], vec![public_account_1, public_account_2],
&Program::serialize_instruction(()).unwrap(), Program::serialize_instruction(()).unwrap(),
&[0, 0], vec![0, 0],
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1379,13 +1379,13 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[public_account], vec![public_account],
&Program::serialize_instruction(()).unwrap(), Program::serialize_instruction(()).unwrap(),
&[0], vec![0],
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1415,13 +1415,13 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[public_account_1, public_account_2], vec![public_account_1, public_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[0, 0], vec![0, 0],
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1453,13 +1453,13 @@ pub mod tests {
// Setting only one visibility mask for a circuit execution with two pre_state accounts. // Setting only one visibility mask for a circuit execution with two pre_state accounts.
let visibility_mask = [0]; let visibility_mask = [0];
let result = execute_and_prove( let result = execute_and_prove(
&[public_account_1, public_account_2], vec![public_account_1, public_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&visibility_mask, visibility_mask.to_vec(),
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1486,11 +1486,11 @@ pub mod tests {
// Setting only one nonce for an execution with two private accounts. // Setting only one nonce for an execution with two private accounts.
let private_account_nonces = [0xdeadbeef1]; let private_account_nonces = [0xdeadbeef1];
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&private_account_nonces, private_account_nonces.to_vec(),
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -1500,8 +1500,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[Some((0, vec![]))], vec![Some((0, vec![]))],
&program.into(), &program.into(),
); );
@ -1530,13 +1530,13 @@ pub mod tests {
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
)]; )];
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&private_account_keys, private_account_keys.to_vec(),
&[sender_keys.nsk], vec![sender_keys.nsk],
&[Some((0, vec![]))], vec![Some((0, vec![]))],
&program.into(), &program.into(),
); );
@ -1563,11 +1563,11 @@ pub mod tests {
// Setting no second commitment proof. // Setting no second commitment proof.
let private_account_membership_proofs = [Some((0, vec![]))]; let private_account_membership_proofs = [Some((0, vec![]))];
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -1577,8 +1577,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&private_account_membership_proofs, private_account_membership_proofs.to_vec(),
&program.into(), &program.into(),
); );
@ -1605,11 +1605,11 @@ pub mod tests {
// Setting no auth key for an execution with one non default private accounts. // Setting no auth key for an execution with one non default private accounts.
let private_account_nsks = []; let private_account_nsks = [];
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -1619,8 +1619,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&private_account_nsks, private_account_nsks.to_vec(),
&[], vec![],
&program.into(), &program.into(),
); );
@ -1663,13 +1663,13 @@ pub mod tests {
let private_account_nsks = [recipient_keys.nsk]; let private_account_nsks = [recipient_keys.nsk];
let private_account_membership_proofs = [Some((0, vec![]))]; let private_account_membership_proofs = [Some((0, vec![]))];
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&private_account_keys, private_account_keys.to_vec(),
&private_account_nsks, private_account_nsks.to_vec(),
&private_account_membership_proofs, private_account_membership_proofs.to_vec(),
&program.into(), &program.into(),
); );
@ -1701,11 +1701,11 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -1715,8 +1715,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[Some((0, vec![]))], vec![Some((0, vec![]))],
&program.into(), &program.into(),
); );
@ -1749,11 +1749,11 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -1763,8 +1763,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[Some((0, vec![]))], vec![Some((0, vec![]))],
&program.into(), &program.into(),
); );
@ -1796,11 +1796,11 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -1810,8 +1810,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[Some((0, vec![]))], vec![Some((0, vec![]))],
&program.into(), &program.into(),
); );
@ -1843,11 +1843,11 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -1857,8 +1857,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[Some((0, vec![]))], vec![Some((0, vec![]))],
&program.into(), &program.into(),
); );
@ -1888,11 +1888,11 @@ pub mod tests {
); );
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -1902,8 +1902,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[Some((0, vec![]))], vec![Some((0, vec![]))],
&program.into(), &program.into(),
); );
@ -1927,13 +1927,13 @@ pub mod tests {
let visibility_mask = [0, 3]; let visibility_mask = [0, 3];
let result = execute_and_prove( let result = execute_and_prove(
&[public_account_1, public_account_2], vec![public_account_1, public_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&visibility_mask, visibility_mask.to_vec(),
&[], vec![],
&[], vec![],
&[], vec![],
&[], vec![],
&program.into(), &program.into(),
); );
@ -1961,11 +1961,11 @@ pub mod tests {
// accounts. // accounts.
let private_account_nonces = [0xdeadbeef1, 0xdeadbeef2, 0xdeadbeef3]; let private_account_nonces = [0xdeadbeef1, 0xdeadbeef2, 0xdeadbeef3];
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&private_account_nonces, private_account_nonces.to_vec(),
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -1975,8 +1975,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&[sender_keys.nsk], vec![sender_keys.nsk],
&[Some((0, vec![]))], vec![Some((0, vec![]))],
&program.into(), &program.into(),
); );
@ -2017,13 +2017,13 @@ pub mod tests {
), ),
]; ];
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&[1, 2], vec![1, 2],
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&private_account_keys, private_account_keys.to_vec(),
&[sender_keys.nsk], vec![sender_keys.nsk],
&[Some((0, vec![]))], vec![Some((0, vec![]))],
&program.into(), &program.into(),
); );
@ -2053,11 +2053,11 @@ pub mod tests {
let private_account_nsks = [sender_keys.nsk, recipient_keys.nsk]; let private_account_nsks = [sender_keys.nsk, recipient_keys.nsk];
let private_account_membership_proofs = [Some((0, vec![])), Some((1, vec![]))]; let private_account_membership_proofs = [Some((0, vec![])), Some((1, vec![]))];
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1, private_account_2], vec![private_account_1, private_account_2],
&Program::serialize_instruction(10u128).unwrap(), Program::serialize_instruction(10u128).unwrap(),
&visibility_mask, visibility_mask.to_vec(),
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
( (
sender_keys.npk(), sender_keys.npk(),
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()), SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
@ -2067,8 +2067,8 @@ pub mod tests {
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()), SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
), ),
], ],
&private_account_nsks, private_account_nsks.to_vec(),
&private_account_membership_proofs, private_account_membership_proofs.to_vec(),
&program.into(), &program.into(),
); );
@ -2149,16 +2149,16 @@ pub mod tests {
let private_account_membership_proofs = [Some((1, vec![])), Some((1, vec![]))]; let private_account_membership_proofs = [Some((1, vec![])), Some((1, vec![]))];
let shared_secret = SharedSecretKey::new(&[55; 32], &sender_keys.ivk()); let shared_secret = SharedSecretKey::new(&[55; 32], &sender_keys.ivk());
let result = execute_and_prove( let result = execute_and_prove(
&[private_account_1.clone(), private_account_1], vec![private_account_1.clone(), private_account_1],
&Program::serialize_instruction(100u128).unwrap(), Program::serialize_instruction(100u128).unwrap(),
&visibility_mask, visibility_mask.to_vec(),
&[0xdeadbeef1, 0xdeadbeef2], vec![0xdeadbeef1, 0xdeadbeef2],
&[ vec![
(sender_keys.npk(), shared_secret), (sender_keys.npk(), shared_secret),
(sender_keys.npk(), shared_secret), (sender_keys.npk(), shared_secret),
], ],
&private_account_nsks, private_account_nsks.to_vec(),
&private_account_membership_proofs, private_account_membership_proofs.to_vec(),
&program.into(), &program.into(),
); );
@ -4014,13 +4014,13 @@ pub mod tests {
// Act // Act
let (output, proof) = execute_and_prove( let (output, proof) = execute_and_prove(
&[to_account, from_account], vec![to_account, from_account],
&Program::serialize_instruction(instruction).unwrap(), Program::serialize_instruction(instruction).unwrap(),
&[1, 1], vec![1, 1],
&[from_new_nonce, to_new_nonce], vec![from_new_nonce, to_new_nonce],
&[(from_keys.npk(), to_ss), (to_keys.npk(), from_ss)], vec![(from_keys.npk(), to_ss), (to_keys.npk(), from_ss)],
&[from_keys.nsk, to_keys.nsk], vec![from_keys.nsk, to_keys.nsk],
&[ vec![
state.get_proof_for_commitment(&from_commitment), state.get_proof_for_commitment(&from_commitment),
state.get_proof_for_commitment(&to_commitment), state.get_proof_for_commitment(&to_commitment),
], ],
@ -4255,13 +4255,13 @@ pub mod tests {
// Execute and prove the circuit with the authorized account but no commitment proof // Execute and prove the circuit with the authorized account but no commitment proof
let (output, proof) = execute_and_prove( let (output, proof) = execute_and_prove(
std::slice::from_ref(&authorized_account), vec![authorized_account],
&Program::serialize_instruction(balance).unwrap(), Program::serialize_instruction(balance).unwrap(),
&[1], vec![1],
&[nonce], vec![nonce],
&[(private_keys.npk(), shared_secret)], vec![(private_keys.npk(), shared_secret)],
&[private_keys.nsk], vec![private_keys.nsk],
&[None], vec![None],
&program.into(), &program.into(),
) )
.unwrap(); .unwrap();
@ -4308,13 +4308,13 @@ pub mod tests {
// Step 2: Execute claimer program to claim the account with authentication // Step 2: Execute claimer program to claim the account with authentication
let (output, proof) = execute_and_prove( let (output, proof) = execute_and_prove(
std::slice::from_ref(&authorized_account), vec![authorized_account.clone()],
&Program::serialize_instruction(balance).unwrap(), Program::serialize_instruction(balance).unwrap(),
&[1], vec![1],
&[nonce], vec![nonce],
&[(private_keys.npk(), shared_secret)], vec![(private_keys.npk(), shared_secret)],
&[private_keys.nsk], vec![private_keys.nsk],
&[None], vec![None],
&claimer_program.into(), &claimer_program.into(),
) )
.unwrap(); .unwrap();
@ -4356,13 +4356,13 @@ pub mod tests {
// Step 3: Try to execute noop program with authentication but without initialization // Step 3: Try to execute noop program with authentication but without initialization
let res = execute_and_prove( let res = execute_and_prove(
std::slice::from_ref(&account_metadata), vec![account_metadata],
&Program::serialize_instruction(()).unwrap(), Program::serialize_instruction(()).unwrap(),
&[1], vec![1],
&[nonce2], vec![nonce2],
&[(private_keys.npk(), shared_secret2)], vec![(private_keys.npk(), shared_secret2)],
&[private_keys.nsk], vec![private_keys.nsk],
&[None], vec![None],
&noop_program.into(), &noop_program.into(),
); );

View File

@ -335,7 +335,7 @@ impl WalletCore {
pub async fn send_privacy_preserving_tx( pub async fn send_privacy_preserving_tx(
&self, &self,
accounts: Vec<PrivacyPreservingAccount>, accounts: Vec<PrivacyPreservingAccount>,
instruction_data: &InstructionData, instruction_data: InstructionData,
program: &ProgramWithDependencies, program: &ProgramWithDependencies,
) -> Result<(SendTxResponse, Vec<SharedSecretKey>), ExecutionFailureKind> { ) -> Result<(SendTxResponse, Vec<SharedSecretKey>), ExecutionFailureKind> {
self.send_privacy_preserving_tx_with_pre_check(accounts, instruction_data, program, |_| { self.send_privacy_preserving_tx_with_pre_check(accounts, instruction_data, program, |_| {
@ -347,7 +347,7 @@ impl WalletCore {
pub async fn send_privacy_preserving_tx_with_pre_check( pub async fn send_privacy_preserving_tx_with_pre_check(
&self, &self,
accounts: Vec<PrivacyPreservingAccount>, accounts: Vec<PrivacyPreservingAccount>,
instruction_data: &InstructionData, instruction_data: InstructionData,
program: &ProgramWithDependencies, program: &ProgramWithDependencies,
tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>, tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
) -> Result<(SendTxResponse, Vec<SharedSecretKey>), ExecutionFailureKind> { ) -> Result<(SendTxResponse, Vec<SharedSecretKey>), ExecutionFailureKind> {
@ -363,16 +363,16 @@ impl WalletCore {
let private_account_keys = acc_manager.private_account_keys(); let private_account_keys = acc_manager.private_account_keys();
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove( let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove(
&pre_states, pre_states,
instruction_data, instruction_data,
acc_manager.visibility_mask(), acc_manager.visibility_mask().to_vec(),
&produce_random_nonces(private_account_keys.len()), produce_random_nonces(private_account_keys.len()),
&private_account_keys private_account_keys
.iter() .iter()
.map(|keys| (keys.npk.clone(), keys.ssk)) .map(|keys| (keys.npk.clone(), keys.ssk))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
&acc_manager.private_account_auth(), acc_manager.private_account_auth(),
&acc_manager.private_account_membership_proofs(), acc_manager.private_account_membership_proofs(),
&program.to_owned(), &program.to_owned(),
) )
.unwrap(); .unwrap();

View File

@ -19,7 +19,7 @@ impl NativeTokenTransfer<'_> {
PrivacyPreservingAccount::PrivateOwned(from), PrivacyPreservingAccount::PrivateOwned(from),
PrivacyPreservingAccount::Public(to), PrivacyPreservingAccount::Public(to),
], ],
&instruction_data, instruction_data,
&program.into(), &program.into(),
tx_pre_check, tx_pre_check,
) )

View File

@ -17,7 +17,7 @@ impl NativeTokenTransfer<'_> {
self.0 self.0
.send_privacy_preserving_tx_with_pre_check( .send_privacy_preserving_tx_with_pre_check(
vec![PrivacyPreservingAccount::PrivateOwned(from)], vec![PrivacyPreservingAccount::PrivateOwned(from)],
&Program::serialize_instruction(instruction).unwrap(), Program::serialize_instruction(instruction).unwrap(),
&Program::authenticated_transfer_program().into(), &Program::authenticated_transfer_program().into(),
|_| Ok(()), |_| Ok(()),
) )
@ -47,7 +47,7 @@ impl NativeTokenTransfer<'_> {
ipk: to_ipk, ipk: to_ipk,
}, },
], ],
&instruction_data, instruction_data,
&program.into(), &program.into(),
tx_pre_check, tx_pre_check,
) )
@ -74,7 +74,7 @@ impl NativeTokenTransfer<'_> {
PrivacyPreservingAccount::PrivateOwned(from), PrivacyPreservingAccount::PrivateOwned(from),
PrivacyPreservingAccount::PrivateOwned(to), PrivacyPreservingAccount::PrivateOwned(to),
], ],
&instruction_data, instruction_data,
&program.into(), &program.into(),
tx_pre_check, tx_pre_check,
) )

View File

@ -20,7 +20,7 @@ impl NativeTokenTransfer<'_> {
PrivacyPreservingAccount::Public(from), PrivacyPreservingAccount::Public(from),
PrivacyPreservingAccount::PrivateOwned(to), PrivacyPreservingAccount::PrivateOwned(to),
], ],
&instruction_data, instruction_data,
&program.into(), &program.into(),
tx_pre_check, tx_pre_check,
) )
@ -52,7 +52,7 @@ impl NativeTokenTransfer<'_> {
ipk: to_ipk, ipk: to_ipk,
}, },
], ],
&instruction_data, instruction_data,
&program.into(), &program.into(),
tx_pre_check, tx_pre_check,
) )

View File

@ -37,7 +37,7 @@ impl Pinata<'_> {
PrivacyPreservingAccount::Public(pinata_account_id), PrivacyPreservingAccount::Public(pinata_account_id),
PrivacyPreservingAccount::PrivateOwned(winner_account_id), PrivacyPreservingAccount::PrivateOwned(winner_account_id),
], ],
&nssa::program::Program::serialize_instruction(solution).unwrap(), nssa::program::Program::serialize_instruction(solution).unwrap(),
&nssa::program::Program::pinata().into(), &nssa::program::Program::pinata().into(),
) )
.await .await

View File

@ -52,7 +52,7 @@ impl Token<'_> {
PrivacyPreservingAccount::Public(definition_account_id), PrivacyPreservingAccount::Public(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(supply_account_id), PrivacyPreservingAccount::PrivateOwned(supply_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -82,7 +82,7 @@ impl Token<'_> {
PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::Public(supply_account_id), PrivacyPreservingAccount::Public(supply_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -112,7 +112,7 @@ impl Token<'_> {
PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(supply_account_id), PrivacyPreservingAccount::PrivateOwned(supply_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -180,7 +180,7 @@ impl Token<'_> {
PrivacyPreservingAccount::PrivateOwned(sender_account_id), PrivacyPreservingAccount::PrivateOwned(sender_account_id),
PrivacyPreservingAccount::PrivateOwned(recipient_account_id), PrivacyPreservingAccount::PrivateOwned(recipient_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -212,7 +212,7 @@ impl Token<'_> {
ipk: recipient_ipk, ipk: recipient_ipk,
}, },
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -240,7 +240,7 @@ impl Token<'_> {
PrivacyPreservingAccount::PrivateOwned(sender_account_id), PrivacyPreservingAccount::PrivateOwned(sender_account_id),
PrivacyPreservingAccount::Public(recipient_account_id), PrivacyPreservingAccount::Public(recipient_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -269,7 +269,7 @@ impl Token<'_> {
PrivacyPreservingAccount::Public(sender_account_id), PrivacyPreservingAccount::Public(sender_account_id),
PrivacyPreservingAccount::PrivateOwned(recipient_account_id), PrivacyPreservingAccount::PrivateOwned(recipient_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -302,7 +302,7 @@ impl Token<'_> {
ipk: recipient_ipk, ipk: recipient_ipk,
}, },
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -365,7 +365,7 @@ impl Token<'_> {
PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(holder_account_id), PrivacyPreservingAccount::PrivateOwned(holder_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -393,7 +393,7 @@ impl Token<'_> {
PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::Public(holder_account_id), PrivacyPreservingAccount::Public(holder_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -422,7 +422,7 @@ impl Token<'_> {
PrivacyPreservingAccount::Public(definition_account_id), PrivacyPreservingAccount::Public(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(holder_account_id), PrivacyPreservingAccount::PrivateOwned(holder_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -491,7 +491,7 @@ impl Token<'_> {
PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(holder_account_id), PrivacyPreservingAccount::PrivateOwned(holder_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -523,7 +523,7 @@ impl Token<'_> {
ipk: holder_ipk, ipk: holder_ipk,
}, },
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -551,7 +551,7 @@ impl Token<'_> {
PrivacyPreservingAccount::PrivateOwned(definition_account_id), PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::Public(holder_account_id), PrivacyPreservingAccount::Public(holder_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -580,7 +580,7 @@ impl Token<'_> {
PrivacyPreservingAccount::Public(definition_account_id), PrivacyPreservingAccount::Public(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(holder_account_id), PrivacyPreservingAccount::PrivateOwned(holder_account_id),
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await
@ -613,7 +613,7 @@ impl Token<'_> {
ipk: holder_ipk, ipk: holder_ipk,
}, },
], ],
&instruction_data, instruction_data,
&Program::token().into(), &Program::token().into(),
) )
.await .await