Merge branch 'main' into schouhy/implement-privacy-preserving-tail-calls

This commit is contained in:
Sergio Chouhy
2025-11-07 19:32:42 -03:00
3 changed files with 79 additions and 509 deletions
@@ -3,7 +3,12 @@ use std::collections::HashSet;
use risc0_zkvm::{guest::env, serde::to_vec};
use nssa_core::{
account::{Account, AccountId, AccountWithMetadata}, compute_digest_for_path, encryption::Ciphertext, program::{validate_execution, ProgramId, ProgramOutput, DEFAULT_PROGRAM_ID}, Commitment, CommitmentSetDigest, EncryptionScheme, Nullifier, NullifierPublicKey, PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput, DUMMY_COMMITMENT_HASH
Commitment, CommitmentSetDigest, DUMMY_COMMITMENT_HASH, EncryptionScheme,
Nullifier, NullifierPublicKey, PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput,
account::{Account, AccountId, AccountWithMetadata},
compute_digest_for_path,
encryption::Ciphertext,
program::{DEFAULT_PROGRAM_ID, ProgramOutput, validate_execution},
};
fn main() {
@@ -16,43 +21,12 @@ fn main() {
program_id,
} = env::read();
// These lists will be the public outputs of this circuit
// and will be populated next.
let mut public_pre_states: Vec<AccountWithMetadata> = Vec::new();
let mut public_post_states: Vec<Account> = Vec::new();
let mut ciphertexts: Vec<Ciphertext> = Vec::new();
let mut new_commitments: Vec<Commitment> = Vec::new();
let mut new_nullifiers: Vec<(Nullifier, CommitmentSetDigest)> = Vec::new();
// TODO: WIP
let program_output = program_outputs[0].clone();
for program_output in program_outputs.iter() {
// Check that `program_output` is consistent with the execution of the corresponding program.
env::verify(program_id, &to_vec(program_output).unwrap()).unwrap();
}
// Check that `program_output` is consistent with the execution of the corresponding program.
env::verify(program_id, &to_vec(&program_output).unwrap()).unwrap();
if private_nonces_iter.next().is_some() {
panic!("Too many nonces.");
}
if private_keys_iter.next().is_some() {
panic!("Too many private account keys.");
}
if private_auth_iter.next().is_some() {
panic!("Too many private account authentication keys.");
}
let output = PrivacyPreservingCircuitOutput {
public_pre_states,
public_post_states,
ciphertexts,
new_commitments,
new_nullifiers,
};
env::commit(&output);
}
fn validate_program_execution(program_output: &ProgramOutput, program_id: ProgramId) {
let ProgramOutput {
pre_states,
post_states,
@@ -64,11 +38,6 @@ fn validate_program_execution(program_output: &ProgramOutput, program_id: Progra
panic!("Privacy preserving transactions do not support yet chained calls.")
}
// Check that there are no repeated account ids
if !validate_uniqueness_of_account_ids(&pre_states) {
panic!("Repeated account ids found")
}
// Check that the program is well behaved.
// See the # Programs section for the definition of the `validate_execution` method.
if !validate_execution(&pre_states, &post_states, program_id) {
@@ -80,6 +49,14 @@ fn validate_program_execution(program_output: &ProgramOutput, program_id: Progra
panic!("Invalid visibility mask length");
}
// These lists will be the public outputs of this circuit
// and will be populated next.
let mut public_pre_states: Vec<AccountWithMetadata> = Vec::new();
let mut public_post_states: Vec<Account> = Vec::new();
let mut ciphertexts: Vec<Ciphertext> = Vec::new();
let mut new_commitments: Vec<Commitment> = Vec::new();
let mut new_nullifiers: Vec<(Nullifier, CommitmentSetDigest)> = Vec::new();
let mut private_nonces_iter = private_account_nonces.iter();
let mut private_keys_iter = private_account_keys.iter();
let mut private_auth_iter = private_account_auth.iter();
@@ -173,15 +150,26 @@ fn validate_program_execution(program_output: &ProgramOutput, program_id: Progra
_ => panic!("Invalid visibility mask value"),
}
}
}
fn validate_uniqueness_of_account_ids(pre_states: &[AccountWithMetadata]) -> bool {
let number_of_accounts = pre_states.len();
let number_of_account_ids = pre_states
.iter()
.map(|account| account.account_id.clone())
.collect::<HashSet<_>>()
.len();
if private_nonces_iter.next().is_some() {
panic!("Too many nonces.");
}
number_of_accounts == number_of_account_ids
if private_keys_iter.next().is_some() {
panic!("Too many private account keys.");
}
if private_auth_iter.next().is_some() {
panic!("Too many private account authentication keys.");
}
let output = PrivacyPreservingCircuitOutput {
public_pre_states,
public_post_states,
ciphertexts,
new_commitments,
new_nullifiers,
};
env::commit(&output);
}