diff --git a/risc0-selective-privacy-poc/examples/private_execution.rs b/risc0-selective-privacy-poc/examples/private_execution.rs index c580c78..a19b5bb 100644 --- a/risc0-selective-privacy-poc/examples/private_execution.rs +++ b/risc0-selective-privacy-poc/examples/private_execution.rs @@ -11,7 +11,7 @@ use toy_example_core::{ types::{Address, AuthenticationPath, Commitment, Nonce, Nullifier}, }; use transfer_methods::{TRANSFER_ELF, TRANSFER_ID}; -use tuki::program::{prove_privacy_execution, Program}; +use tuki::{prove_privacy_execution, Program}; fn mint_fresh_account(address: Address) -> Account { let nonce = [0; 8]; diff --git a/risc0-selective-privacy-poc/examples/programs/mod.rs b/risc0-selective-privacy-poc/examples/programs/mod.rs index 1bb7219..b61b7ba 100644 --- a/risc0-selective-privacy-poc/examples/programs/mod.rs +++ b/risc0-selective-privacy-poc/examples/programs/mod.rs @@ -1,5 +1,5 @@ use transfer_methods::{TRANSFER_ELF, TRANSFER_ID}; -use tuki::program::Program; +use tuki::Program; pub struct TransferProgram; diff --git a/risc0-selective-privacy-poc/examples/public_execution.rs b/risc0-selective-privacy-poc/examples/public_execution.rs index c7cb566..9ede169 100644 --- a/risc0-selective-privacy-poc/examples/public_execution.rs +++ b/risc0-selective-privacy-poc/examples/public_execution.rs @@ -4,7 +4,7 @@ use risc0_zkvm::{default_executor, ExecutorEnv}; use toy_example_core::account::Account; use transfer_methods::TRANSFER_ELF; -use tuki::program::{execute, Program}; +use tuki::{execute, Program}; use crate::programs::TransferProgram; diff --git a/risc0-selective-privacy-poc/src/lib.rs b/risc0-selective-privacy-poc/src/lib.rs index 5dc5d07..d83813a 100644 --- a/risc0-selective-privacy-poc/src/lib.rs +++ b/risc0-selective-privacy-poc/src/lib.rs @@ -1,2 +1,99 @@ -pub mod program; +use outer_methods::OUTER_ELF; +use rand::{rngs::OsRng, Rng}; +use risc0_zkvm::{ + default_executor, default_prover, ExecutorEnv, ExecutorEnvBuilder, ProveInfo, Receipt, +}; +use serde::{Deserialize, Serialize}; +use toy_example_core::{account::Account, input::InputVisibiility, types::Nonce}; +pub fn new_random_nonce() -> Nonce { + let mut rng = OsRng; + std::array::from_fn(|_| rng.gen()) +} + +pub trait Program { + const PROGRAM_ID: [u32; 8]; + const PROGRAM_ELF: &[u8]; + type InstructionData: Serialize + for<'de> Deserialize<'de>; +} + +pub(crate) fn write_inputs( + input_accounts: &[Account], + instruction_data: &P::InstructionData, + env_builder: &mut ExecutorEnvBuilder, +) -> Result<(), ()> { + for account in input_accounts { + env_builder.write(&account).map_err(|_| ())?; + } + env_builder.write(&instruction_data).map_err(|_| ())?; + Ok(()) +} + +pub(crate) fn execute_and_prove( + input_accounts: &[Account], + instruction_data: &P::InstructionData, +) -> Result<(Receipt, Vec), ()> { + // Write inputs to the program + let mut env_builder = ExecutorEnv::builder(); + write_inputs::

(input_accounts, instruction_data, &mut env_builder)?; + let env = env_builder.build().unwrap(); + + // Prove the program + let prover = default_prover(); + let prove_info = prover.prove(env, P::PROGRAM_ELF).map_err(|_| ())?; + let receipt = prove_info.receipt; + + // Get proof and (inputs and) outputs + let inputs_outputs: Vec = receipt.journal.decode().map_err(|_| ())?; + + Ok((receipt, inputs_outputs)) +} + +pub fn execute( + input_accounts: &[Account], + instruction_data: &P::InstructionData, +) -> Result, ()> { + // Write inputs to the program + let mut env_builder = ExecutorEnv::builder(); + write_inputs::

(input_accounts, instruction_data, &mut env_builder)?; + let env = env_builder.build().unwrap(); + + // Execute the program (without proving) + let executor = default_executor(); + let session_info = executor.execute(env, P::PROGRAM_ELF).map_err(|_| ())?; + + // Get proof and (inputs and) outputs + let inputs_outputs: Vec = session_info.journal.decode().map_err(|_| ())?; + + Ok(inputs_outputs) +} + +pub fn prove_privacy_execution( + inputs: &[Account], + instruction_data: &P::InstructionData, + visibilities: &[InputVisibiility], + commitment_tree_root: [u32; 8], +) -> Result { + // Prove inner program and get post state of the accounts + let num_inputs = inputs.len(); + let (inner_receipt, inputs_outputs) = execute_and_prove::

(inputs, instruction_data)?; + + // Sample fresh random nonces for the outputs of this execution + let output_nonces: Vec<_> = (0..num_inputs).map(|_| new_random_nonce()).collect(); + + // Prove outer program. + // This computes the nullifiers for the input accounts and commitments for the output accounts. + let mut env_builder = ExecutorEnv::builder(); + env_builder.add_assumption(inner_receipt); + env_builder.write(&(num_inputs as u32)).unwrap(); + env_builder.write(&inputs_outputs).unwrap(); + env_builder.write(&visibilities).unwrap(); + env_builder.write(&output_nonces).unwrap(); + env_builder.write(&commitment_tree_root).unwrap(); + env_builder.write(&P::PROGRAM_ID).unwrap(); + let env = env_builder.build().unwrap(); + + let prover = default_prover(); + let prove_info = prover.prove(env, OUTER_ELF).unwrap(); + Ok(prove_info) +} diff --git a/risc0-selective-privacy-poc/src/program.rs b/risc0-selective-privacy-poc/src/program.rs index d83813a..e69de29 100644 --- a/risc0-selective-privacy-poc/src/program.rs +++ b/risc0-selective-privacy-poc/src/program.rs @@ -1,99 +0,0 @@ -use outer_methods::OUTER_ELF; -use rand::{rngs::OsRng, Rng}; -use risc0_zkvm::{ - default_executor, default_prover, ExecutorEnv, ExecutorEnvBuilder, ProveInfo, Receipt, -}; -use serde::{Deserialize, Serialize}; -use toy_example_core::{account::Account, input::InputVisibiility, types::Nonce}; - -pub fn new_random_nonce() -> Nonce { - let mut rng = OsRng; - std::array::from_fn(|_| rng.gen()) -} - -pub trait Program { - const PROGRAM_ID: [u32; 8]; - const PROGRAM_ELF: &[u8]; - type InstructionData: Serialize + for<'de> Deserialize<'de>; -} - -pub(crate) fn write_inputs( - input_accounts: &[Account], - instruction_data: &P::InstructionData, - env_builder: &mut ExecutorEnvBuilder, -) -> Result<(), ()> { - for account in input_accounts { - env_builder.write(&account).map_err(|_| ())?; - } - env_builder.write(&instruction_data).map_err(|_| ())?; - Ok(()) -} - -pub(crate) fn execute_and_prove( - input_accounts: &[Account], - instruction_data: &P::InstructionData, -) -> Result<(Receipt, Vec), ()> { - // Write inputs to the program - let mut env_builder = ExecutorEnv::builder(); - write_inputs::

(input_accounts, instruction_data, &mut env_builder)?; - let env = env_builder.build().unwrap(); - - // Prove the program - let prover = default_prover(); - let prove_info = prover.prove(env, P::PROGRAM_ELF).map_err(|_| ())?; - let receipt = prove_info.receipt; - - // Get proof and (inputs and) outputs - let inputs_outputs: Vec = receipt.journal.decode().map_err(|_| ())?; - - Ok((receipt, inputs_outputs)) -} - -pub fn execute( - input_accounts: &[Account], - instruction_data: &P::InstructionData, -) -> Result, ()> { - // Write inputs to the program - let mut env_builder = ExecutorEnv::builder(); - write_inputs::

(input_accounts, instruction_data, &mut env_builder)?; - let env = env_builder.build().unwrap(); - - // Execute the program (without proving) - let executor = default_executor(); - let session_info = executor.execute(env, P::PROGRAM_ELF).map_err(|_| ())?; - - // Get proof and (inputs and) outputs - let inputs_outputs: Vec = session_info.journal.decode().map_err(|_| ())?; - - Ok(inputs_outputs) -} - -pub fn prove_privacy_execution( - inputs: &[Account], - instruction_data: &P::InstructionData, - visibilities: &[InputVisibiility], - commitment_tree_root: [u32; 8], -) -> Result { - // Prove inner program and get post state of the accounts - let num_inputs = inputs.len(); - let (inner_receipt, inputs_outputs) = execute_and_prove::

(inputs, instruction_data)?; - - // Sample fresh random nonces for the outputs of this execution - let output_nonces: Vec<_> = (0..num_inputs).map(|_| new_random_nonce()).collect(); - - // Prove outer program. - // This computes the nullifiers for the input accounts and commitments for the output accounts. - let mut env_builder = ExecutorEnv::builder(); - env_builder.add_assumption(inner_receipt); - env_builder.write(&(num_inputs as u32)).unwrap(); - env_builder.write(&inputs_outputs).unwrap(); - env_builder.write(&visibilities).unwrap(); - env_builder.write(&output_nonces).unwrap(); - env_builder.write(&commitment_tree_root).unwrap(); - env_builder.write(&P::PROGRAM_ID).unwrap(); - let env = env_builder.build().unwrap(); - - let prover = default_prover(); - let prove_info = prover.prove(env, OUTER_ELF).unwrap(); - Ok(prove_info) -}