From f4f01b3d996c6ec6530141b8a0fc2a0e14b45a3a Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Fri, 18 Jul 2025 17:30:38 -0300 Subject: [PATCH] add docs --- .../examples/happy_path.rs | 23 +++------ .../program_methods/guest/src/bin/outer.rs | 47 ++++++++++++------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/risc0-selective-privacy-poc/examples/happy_path.rs b/risc0-selective-privacy-poc/examples/happy_path.rs index d25abd3..8fdc947 100644 --- a/risc0-selective-privacy-poc/examples/happy_path.rs +++ b/risc0-selective-privacy-poc/examples/happy_path.rs @@ -38,20 +38,14 @@ fn main() { .transfer_private(private_account_user_1, &addresses[2], 8, &mut sequencer) .unwrap(); println!("📝 Balances after shielded execution"); - print_accounts( - &sequencer, - &[&private_account_user_1, &private_account_user_2], - ); + print_accounts(&sequencer, &[&private_account_user_1, &private_account_user_2]); // A deshielded execution of the Transfer Program let private_acount_user_2 = USER_CLIENTS[2] .transfer_deshielded(private_account_user_2, &addresses[0], 1, &mut sequencer) .unwrap(); println!("📝 Balances after deshielded execution"); - print_accounts( - &sequencer, - &[&private_account_user_1, &private_acount_user_2], - ); + print_accounts(&sequencer, &[&private_account_user_1, &private_acount_user_2]); // A public execution of the Piñata program let preimage = bytes_to_words(b"NSSA Selective privacy is great!").to_vec(); @@ -59,10 +53,7 @@ fn main() { .process_public_execution::(&[[0xcafe; 8], addresses[2]], preimage) .unwrap(); println!("📝 Balances after public piñata execution"); - print_accounts( - &sequencer, - &[&private_account_user_1, &private_acount_user_2], - ); + print_accounts(&sequencer, &[&private_account_user_1, &private_acount_user_2]); // A deshielded execution of the Piñata program let private_account_user_0 = { @@ -87,10 +78,8 @@ fn main() { println!("📝 Balances after private piñata execution"); print_accounts( &sequencer, - &[ - &private_account_user_1, - &private_acount_user_2, - &private_account_user_0, - ], + &[&private_account_user_1, &private_acount_user_2, &private_account_user_0], ); + + println!("Ok!"); } diff --git a/risc0-selective-privacy-poc/program_methods/guest/src/bin/outer.rs b/risc0-selective-privacy-poc/program_methods/guest/src/bin/outer.rs index 72f8831..4bbf5f8 100644 --- a/risc0-selective-privacy-poc/program_methods/guest/src/bin/outer.rs +++ b/risc0-selective-privacy-poc/program_methods/guest/src/bin/outer.rs @@ -6,21 +6,28 @@ use core::{ }; use risc0_zkvm::{guest::env, serde::to_vec}; -/// Private execution logic. -/// Circuit for proving correct execution of some program with program id -/// equal to `program_id` (last input). +/// Privacy execution logic. +/// This is the circuit for proving correct off-chain executions of programs. +/// It also verifies that the chain's invariants are not violated. /// -/// Currently only supports private execution of a program with two input accounts, one -/// of which must be a fresh new account (`account_2`) (for example a private transfer function). +/// Inputs: +/// - Vec: The output of the inner program. This is assumed to include the accounts pre and +/// post-states of the execution of the inner program. /// -/// This circuit checks: -/// - That accounts pre states and post states are consistent with the execution of the given `program_id`. -/// - That `account_2` is fresh (meaning, for this toy example, that it has 0 balance). -/// - That `program_id` execution didn't change addresses of the accounts. +/// - Vec: A vector indicating which accounts are private and which are public. /// -/// Outputs: -/// - The nullifier for the only existing input account (account_1) -/// - The commitments for the private accounts post states. +/// - Vec: The vector of nonces to be used for the output accounts. This is assumed to be +/// sampled at random by the host program. +/// +/// - [u32; 8]: The root of the commitment tree. Commitments of used private accounts will be +/// checked against this to prove that they belong to the tree. +/// - ProgamId: The ID of the inner program. +/// +/// Public outputs: +/// - The vector of accounts' pre and post states for the public accounts. +/// - The nullifiers of the used private accounts. +/// - The commitments for the ouput private accounts. +/// - The commitment tree root used for the authentication path verifications. fn main() { let num_inputs: u32 = env::read(); // Read inputs and outputs @@ -35,11 +42,12 @@ fn main() { let output_nonces: Vec = env::read(); assert_eq!(output_nonces.len() as u32, num_inputs); + // Read root and program id. let commitment_tree_root: [u32; 8] = env::read(); let program_id: ProgramId = env::read(); // Verify pre states and post states of accounts are consistent - // with the execution of the `program_id`` program + // with the execution of the `program_id` program env::verify(program_id, &to_vec(&inputs_outputs).unwrap()).unwrap(); // Split inputs_outputs into two separate vectors @@ -57,12 +65,13 @@ fn main() { // Check the input account was created by a previous transaction by checking it belongs to the commitments tree. let commitment = input_account.commitment(); assert!(is_in_tree(commitment, auth_path, commitment_tree_root)); - // Compute nullifier to nullify this private input account. + // Compute the nullifier to nullify this private input account. let nullifier = compute_nullifier(&commitment, private_key); nullifiers.push(nullifier); } InputVisibiility::Private(None) => { // Private accounts without a companion private key are enforced to have default values + // Used for executions that need to create a new private account. assert_eq!(input_account.balance, 0); assert_eq!(input_account.nonce, [0; 8]); } @@ -77,6 +86,11 @@ fn main() { assert_eq!(account_pre.nonce, account_post.nonce); } + // Check that the program preserved the total supply + let total_balance_pre: u128 = inputs.iter().map(|account| account.balance).sum(); + let total_balance_post: u128 = outputs.iter().map(|account| account.balance).sum(); + assert_eq!(total_balance_pre, total_balance_post); + // Insert new nonces in outputs (including public ones (?!)) outputs .iter_mut() @@ -108,10 +122,7 @@ fn main() { } // Compute commitments for every private output - let private_output_commitments: Vec<_> = private_outputs - .iter() - .map(|account| account.commitment()) - .collect(); + let private_output_commitments: Vec<_> = private_outputs.iter().map(|account| account.commitment()).collect(); // Output nullifier of consumed input accounts and commitments of new output private accounts env::commit(&(