mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-03 22:03:06 +00:00
Merge pull request #108 from vacp2p/schouhy/add-privacy-preserving-circuit-tests
Add privacy preserving circuit tests
This commit is contained in:
commit
b7c2e8a3ec
@ -32,11 +32,13 @@ fn main() {
|
||||
|
||||
// Check that the program is well behaved.
|
||||
// See the # Programs section for the definition of the `validate_execution` method.
|
||||
validate_execution(&pre_states, &post_states, program_id);
|
||||
if !validate_execution(&pre_states, &post_states, program_id) {
|
||||
panic!("Bad behaved program");
|
||||
}
|
||||
|
||||
let n_accounts = pre_states.len();
|
||||
if visibility_mask.len() != n_accounts {
|
||||
panic!();
|
||||
panic!("Invalid visibility mask length");
|
||||
}
|
||||
|
||||
// These lists will be the public outputs of this circuit
|
||||
@ -59,7 +61,9 @@ fn main() {
|
||||
public_pre_states.push(pre_states[i].clone());
|
||||
|
||||
let mut post = post_states[i].clone();
|
||||
post.nonce += 1;
|
||||
if pre_states[i].is_authorized {
|
||||
post.nonce += 1;
|
||||
}
|
||||
if post.program_owner == DEFAULT_PROGRAM_ID {
|
||||
// Claim account
|
||||
post.program_owner = program_id;
|
||||
@ -136,7 +140,7 @@ fn main() {
|
||||
}
|
||||
|
||||
if private_keys_iter.next().is_some() {
|
||||
panic!("Too many private accounts keys.");
|
||||
panic!("Too many private account keys.");
|
||||
}
|
||||
|
||||
if private_auth_iter.next().is_some() {
|
||||
|
||||
@ -45,4 +45,7 @@ pub enum NssaError {
|
||||
|
||||
#[error("Invalid privacy preserving execution circuit proof")]
|
||||
InvalidPrivacyPreservingProof,
|
||||
|
||||
#[error("Circuit proving error")]
|
||||
CircuitProvingError(String),
|
||||
}
|
||||
|
||||
@ -47,7 +47,9 @@ pub fn execute_and_prove(
|
||||
env_builder.write(&circuit_input).unwrap();
|
||||
let env = env_builder.build().unwrap();
|
||||
let prover = default_prover();
|
||||
let prove_info = prover.prove(env, PRIVACY_PRESERVING_CIRCUIT_ELF).unwrap();
|
||||
let prove_info = prover
|
||||
.prove(env, PRIVACY_PRESERVING_CIRCUIT_ELF)
|
||||
.map_err(|e| NssaError::CircuitProvingError(e.to_string()))?;
|
||||
|
||||
let proof = Proof(borsh::to_vec(&prove_info.receipt.inner)?);
|
||||
|
||||
@ -109,6 +111,7 @@ mod tests {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let sender = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
@ -175,11 +178,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn prove_privacy_preserving_execution_circuit_fully_private() {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let sender_pre = AccountWithMetadata {
|
||||
account: Account {
|
||||
balance: 100,
|
||||
nonce: 0xdeadbeef,
|
||||
..Account::default()
|
||||
program_owner: program.id(),
|
||||
data: vec![],
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
@ -145,12 +145,6 @@ impl V01State {
|
||||
*current_account = post;
|
||||
}
|
||||
|
||||
// // 5. Increment nonces
|
||||
for address in tx.signer_addresses() {
|
||||
let current_account = self.get_account_by_address_mut(address);
|
||||
current_account.nonce += 1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -219,6 +213,7 @@ pub mod tests {
|
||||
use crate::{
|
||||
Address, PublicKey, PublicTransaction, V01State,
|
||||
error::NssaError,
|
||||
execute_and_prove,
|
||||
privacy_preserving_transaction::{
|
||||
PrivacyPreservingTransaction, circuit, message::Message, witness_set::WitnessSet,
|
||||
},
|
||||
@ -941,6 +936,13 @@ pub mod tests {
|
||||
&state,
|
||||
);
|
||||
|
||||
let expected_sender_post = {
|
||||
let mut this = state.get_account_by_address(&sender_keys.address());
|
||||
this.balance -= balance_to_move;
|
||||
this.nonce += 1;
|
||||
this
|
||||
};
|
||||
|
||||
let [expected_new_commitment] = tx.message().new_commitments.clone().try_into().unwrap();
|
||||
assert!(!state.private_state.0.contains(&expected_new_commitment));
|
||||
|
||||
@ -948,6 +950,8 @@ pub mod tests {
|
||||
.transition_from_privacy_preserving_transaction(&tx)
|
||||
.unwrap();
|
||||
|
||||
let sender_post = state.get_account_by_address(&sender_keys.address());
|
||||
assert_eq!(sender_post, expected_sender_post);
|
||||
assert!(state.private_state.0.contains(&expected_new_commitment));
|
||||
|
||||
assert_eq!(
|
||||
@ -1040,6 +1044,12 @@ pub mod tests {
|
||||
|
||||
let balance_to_move = 37;
|
||||
|
||||
let expected_recipient_post = {
|
||||
let mut this = state.get_account_by_address(&recipient_keys.address());
|
||||
this.balance += balance_to_move;
|
||||
this
|
||||
};
|
||||
|
||||
let tx = deshielded_balance_transfer_for_tests(
|
||||
&sender_keys,
|
||||
&sender_private_account,
|
||||
@ -1070,6 +1080,8 @@ pub mod tests {
|
||||
.transition_from_privacy_preserving_transaction(&tx)
|
||||
.unwrap();
|
||||
|
||||
let recipient_post = state.get_account_by_address(&recipient_keys.address());
|
||||
assert_eq!(recipient_post, expected_recipient_post);
|
||||
assert!(state.private_state.0.contains(&sender_pre_commitment));
|
||||
assert!(state.private_state.0.contains(&expected_new_commitment));
|
||||
assert!(state.private_state.1.contains(&expected_new_nullifier));
|
||||
@ -1080,4 +1092,809 @@ pub mod tests {
|
||||
recipient_initial_balance + balance_to_move
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_burner_program_should_fail_in_privacy_preserving_circuit() {
|
||||
let program = Program::burner();
|
||||
let public_account = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[public_account],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[0],
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_minter_program_should_fail_in_privacy_preserving_circuit() {
|
||||
let program = Program::minter();
|
||||
let public_account = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 0,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[public_account],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[0],
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nonce_changer_program_should_fail_in_privacy_preserving_circuit() {
|
||||
let program = Program::nonce_changer_program();
|
||||
let public_account = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 0,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[public_account],
|
||||
&Program::serialize_instruction(()).unwrap(),
|
||||
&[0],
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_data_changer_program_should_fail_for_non_owned_account_in_privacy_preserving_circuit() {
|
||||
let program = Program::data_changer();
|
||||
let public_account = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: [0, 1, 2, 3, 4, 5, 6, 7],
|
||||
balance: 0,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[public_account],
|
||||
&Program::serialize_instruction(()).unwrap(),
|
||||
&[0],
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extra_output_program_should_fail_in_privacy_preserving_circuit() {
|
||||
let program = Program::extra_output_program();
|
||||
let public_account = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 0,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[public_account],
|
||||
&Program::serialize_instruction(()).unwrap(),
|
||||
&[0],
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_missing_output_program_should_fail_in_privacy_preserving_circuit() {
|
||||
let program = Program::missing_output_program();
|
||||
let public_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 0,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let public_account_2 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 0,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[public_account_1, public_account_2],
|
||||
&Program::serialize_instruction(()).unwrap(),
|
||||
&[0, 0],
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_program_owner_changer_should_fail_in_privacy_preserving_circuit() {
|
||||
let program = Program::program_owner_changer();
|
||||
let public_account = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 0,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[public_account],
|
||||
&Program::serialize_instruction(()).unwrap(),
|
||||
&[0],
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transfer_from_non_owned_account_should_fail_in_privacy_preserving_circuit() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let public_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: [0, 1, 2, 3, 4, 5, 6, 7],
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let public_account_2 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 0,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[public_account_1, public_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[0, 0],
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_fails_if_visibility_masks_have_incorrect_lenght() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let public_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let public_account_2 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 0,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
// Setting only one visibility mask for a circuit execution with two pre_state accounts.
|
||||
let visibility_mask = [0];
|
||||
let result = execute_and_prove(
|
||||
&[public_account_1, public_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&visibility_mask,
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_fails_if_insufficient_nonces_are_provided() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
// Setting only one nonce for an execution with two private accounts.
|
||||
let private_account_nonces = [0xdeadbeef1];
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&private_account_nonces,
|
||||
&[
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
],
|
||||
&[(sender_keys.nsk, (0, vec![]))],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_fails_if_insufficient_keys_are_provided() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
// Setting only one key for an execution with two private accounts.
|
||||
let private_account_keys = [(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
)];
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&private_account_keys,
|
||||
&[(sender_keys.nsk, (0, vec![]))],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_fails_if_insufficient_auth_keys_are_provided() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
// Setting no auth key for an execution with one non default private accounts.
|
||||
let private_account_auth = [];
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&[
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
],
|
||||
&private_account_auth,
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_fails_if_invalid_auth_keys_are_provided() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
let private_account_keys = [
|
||||
// First private account is the sender
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
// Second private account is the recipient
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
];
|
||||
let private_account_auth = [
|
||||
// Setting the recipient key to authorize the sender.
|
||||
// This should be set to the sender private account in
|
||||
// a normal circumstance. The recipient can't authorize this.
|
||||
(recipient_keys.nsk, (0, vec![])),
|
||||
];
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&private_account_keys,
|
||||
&private_account_auth,
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_should_fail_if_new_private_account_with_non_default_balance_is_provided() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account {
|
||||
// Non default balance
|
||||
balance: 1,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&[
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
],
|
||||
&[(sender_keys.nsk, (0, vec![]))],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_should_fail_if_new_private_account_with_non_default_program_owner_is_provided()
|
||||
{
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account {
|
||||
// Non default program_owner
|
||||
program_owner: [0, 1, 2, 3, 4, 5, 6, 7],
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&[
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
],
|
||||
&[(sender_keys.nsk, (0, vec![]))],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_should_fail_if_new_private_account_with_non_default_data_is_provided() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account {
|
||||
// Non default data
|
||||
data: b"hola mundo".to_vec(),
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&[
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
],
|
||||
&[(sender_keys.nsk, (0, vec![]))],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_should_fail_if_new_private_account_with_non_default_nonce_is_provided() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account {
|
||||
// Non default nonce
|
||||
nonce: 0xdeadbeef,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&[
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
],
|
||||
&[(sender_keys.nsk, (0, vec![]))],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_should_fail_if_new_private_account_is_provided_with_default_values_but_marked_as_authorized()
|
||||
{
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
// This should be set to false in normal circumstances
|
||||
is_authorized: true,
|
||||
};
|
||||
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&[
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
],
|
||||
&[(sender_keys.nsk, (0, vec![]))],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_should_fail_with_invalid_visibility_mask_value() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let public_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let public_account_2 = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
let visibility_mask = [0, 3];
|
||||
let result = execute_and_prove(
|
||||
&[public_account_1, public_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&visibility_mask,
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_should_fail_with_too_many_nonces() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
// Setting three new private account nonces for a circuit execution with only two private
|
||||
// accounts.
|
||||
let private_account_nonces = [0xdeadbeef1, 0xdeadbeef2, 0xdeadbeef3];
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&private_account_nonces,
|
||||
&[
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
],
|
||||
&[(sender_keys.nsk, (0, vec![]))],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_should_fail_with_too_many_private_account_keys() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
// Setting three private account keys for a circuit execution with only two private
|
||||
// accounts.
|
||||
let private_account_keys = [
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[57; 32], &sender_keys.ivk()),
|
||||
),
|
||||
];
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&[1, 2],
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&private_account_keys,
|
||||
&[(sender_keys.nsk, (0, vec![]))],
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_should_fail_with_too_many_private_account_auth_keys() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
let private_account_1 = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: program.id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
},
|
||||
is_authorized: true,
|
||||
};
|
||||
let private_account_2 = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: false,
|
||||
};
|
||||
|
||||
// Setting two private account keys for a circuit execution with only one non default
|
||||
// private account (visibility mask equal to 1 means that auth keys are expected).
|
||||
let visibility_mask = [1, 2];
|
||||
let private_account_auth = [
|
||||
(sender_keys.nsk, (0, vec![])),
|
||||
(recipient_keys.nsk, (1, vec![])),
|
||||
];
|
||||
let result = execute_and_prove(
|
||||
&[private_account_1, private_account_2],
|
||||
&Program::serialize_instruction(10u128).unwrap(),
|
||||
&visibility_mask,
|
||||
&[0xdeadbeef1, 0xdeadbeef2],
|
||||
&[
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
),
|
||||
],
|
||||
&private_account_auth,
|
||||
&program,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,12 +5,12 @@ type Instruction = ();
|
||||
fn main() {
|
||||
let ProgramInput { pre_states, .. } = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [pre1, _] = match pre_states.try_into() {
|
||||
let [pre1, pre2] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let account_pre1 = pre1.account.clone();
|
||||
|
||||
write_nssa_outputs(vec![pre1], vec![account_pre1]);
|
||||
write_nssa_outputs(vec![pre1, pre2], vec![account_pre1]);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user