mirror of
https://github.com/logos-blockchain/lssa-zkvm-testing.git
synced 2026-01-05 06:43:12 +00:00
add program trait
This commit is contained in:
parent
c322f93775
commit
b6bec23ac2
6
risc0-selective-privacy-poc/core/src/types.rs
Normal file
6
risc0-selective-privacy-poc/core/src/types.rs
Normal file
@ -0,0 +1,6 @@
|
||||
pub type Commitment = u32;
|
||||
pub type Nullifier = [u32; 8];
|
||||
pub type Address = [u32; 8];
|
||||
pub type Nonce = [u32; 8];
|
||||
pub type Key = [u32; 8];
|
||||
pub type AuthenticationPath = [[u32; 8]; 32];
|
||||
@ -49,11 +49,9 @@ fn main() {
|
||||
for (visibility, input_account) in input_visibilities.iter().zip(inputs.iter()) {
|
||||
match visibility {
|
||||
InputVisibiility::Private(Some((private_key, auth_path))) => {
|
||||
// Prove ownership of input accounts by proving
|
||||
// knowledge of the pre-image of their addresses.
|
||||
// Prove ownership of input accounts by proving knowledge of the pre-image of their addresses.
|
||||
assert_eq!(hash(private_key), input_account.address);
|
||||
// Check the input account was created by a previous transaction
|
||||
// by checking it belongs to the commitments tree.
|
||||
// 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.
|
||||
@ -61,18 +59,19 @@ fn main() {
|
||||
nullifiers.push(nullifier);
|
||||
}
|
||||
InputVisibiility::Private(None) => {
|
||||
// Private accounts without a companion private key are
|
||||
// enforced to have default values
|
||||
// Private accounts without a companion private key are enforced to have default values
|
||||
assert_eq!(input_account.balance, 0);
|
||||
assert_eq!(input_account.nonce, [0; 8]);
|
||||
}
|
||||
// No checks on public accounts
|
||||
InputVisibiility::Public => continue,
|
||||
}
|
||||
}
|
||||
|
||||
// Assert `program_id` program didn't modify address fields
|
||||
// Assert `program_id` program didn't modify address fields or nonces
|
||||
for (account_pre, account_post) in inputs.iter().zip(outputs.iter()) {
|
||||
assert_eq!(account_pre.address, account_post.address);
|
||||
assert_eq!(account_pre.nonce, account_post.nonce);
|
||||
}
|
||||
|
||||
// Insert new nonces in outputs (including public ones (?!))
|
||||
|
||||
@ -1,2 +1,17 @@
|
||||
mod private_execution;
|
||||
mod program;
|
||||
mod public_execution;
|
||||
|
||||
use program::Program;
|
||||
use transfer_methods::{TRANSFER_ELF, TRANSFER_ID};
|
||||
|
||||
struct TransferProgram;
|
||||
|
||||
impl Program for TransferProgram {
|
||||
const PROGRAM_ID: [u32; 8] = TRANSFER_ID;
|
||||
|
||||
const PROGRAM_ELF: &[u8] = TRANSFER_ELF;
|
||||
|
||||
// Amount to transfer
|
||||
type InstructionData = u128;
|
||||
}
|
||||
|
||||
@ -10,13 +10,16 @@ use toy_example_core::{
|
||||
};
|
||||
use transfer_methods::{TRANSFER_ELF, TRANSFER_ID};
|
||||
|
||||
use crate::program::Program;
|
||||
use crate::TransferProgram;
|
||||
|
||||
pub fn new_random_nonce() -> Nonce {
|
||||
let mut rng = OsRng;
|
||||
std::array::from_fn(|_| rng.gen())
|
||||
}
|
||||
|
||||
fn mint_fresh_account(address: Address) -> Account {
|
||||
let nonce = new_random_nonce();
|
||||
let nonce = [0; 8];
|
||||
Account::new(address, nonce)
|
||||
}
|
||||
|
||||
@ -45,13 +48,13 @@ fn run_private_execution_of_transfer_program() {
|
||||
|
||||
let balance_to_move: u128 = 3;
|
||||
|
||||
// This is the new private account (UTXO) being minted by this private execution.
|
||||
// (The `receiver_address` would be <Npk> in UTXO's terminology)
|
||||
// This is the new private account (UTXO) being minted by this private execution. (The `receiver_address` would be <Npk> in UTXO's terminology)
|
||||
let receiver_address = [99; 8];
|
||||
let receiver = mint_fresh_account(receiver_address);
|
||||
|
||||
// Prove inner program and get post state of the accounts
|
||||
let (inner_receipt, inputs_outputs) = prove_inner(&sender, &receiver, balance_to_move);
|
||||
let (inner_receipt, inputs_outputs) =
|
||||
TransferProgram::execute_and_prove(&[sender, receiver], &balance_to_move).unwrap();
|
||||
|
||||
let visibilities = vec![
|
||||
InputVisibiility::Private(Some((sender_private_key, auth_path))),
|
||||
@ -65,8 +68,7 @@ fn run_private_execution_of_transfer_program() {
|
||||
println!("output nonces {output_nonces:?}");
|
||||
|
||||
// Prove outer program.
|
||||
// This computes the nullifier for the input account
|
||||
// and commitments for the accounts post states.
|
||||
// This computes the nullifier for the input account and commitments for the accounts post states.
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
env_builder.add_assumption(inner_receipt);
|
||||
env_builder.write(&num_inputs).unwrap();
|
||||
@ -91,40 +93,6 @@ fn run_private_execution_of_transfer_program() {
|
||||
println!("commitments: {:?}", output.2);
|
||||
}
|
||||
|
||||
fn prove_inner(
|
||||
sender: &Account,
|
||||
receiver: &Account,
|
||||
balance_to_move: u128,
|
||||
) -> (Receipt, Vec<Account>) {
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
env_builder.write(&sender).unwrap();
|
||||
env_builder.write(&receiver).unwrap();
|
||||
env_builder.write(&balance_to_move).unwrap();
|
||||
let env = env_builder.build().unwrap();
|
||||
|
||||
let prover = default_prover();
|
||||
let prove_info = prover.prove(env, TRANSFER_ELF).unwrap();
|
||||
|
||||
let receipt = prove_info.receipt;
|
||||
|
||||
let inputs_outputs: Vec<Account> = receipt.journal.decode().unwrap();
|
||||
assert_eq!(inputs_outputs.len(), 4);
|
||||
|
||||
println!(
|
||||
"sender_before: {:?}, sender_after: {:?}",
|
||||
inputs_outputs[0], inputs_outputs[2]
|
||||
);
|
||||
println!(
|
||||
"receiver_before: {:?}, receiver_after: {:?}",
|
||||
inputs_outputs[1], inputs_outputs[3]
|
||||
);
|
||||
|
||||
// Sanity check
|
||||
receipt.verify(TRANSFER_ID).unwrap();
|
||||
|
||||
(receipt, inputs_outputs)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
60
risc0-selective-privacy-poc/src/program.rs
Normal file
60
risc0-selective-privacy-poc/src/program.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use risc0_zkvm::{default_executor, default_prover, ExecutorEnv, ExecutorEnvBuilder, Receipt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use toy_example_core::account::Account;
|
||||
|
||||
pub(crate) trait Program {
|
||||
const PROGRAM_ID: [u32; 8];
|
||||
const PROGRAM_ELF: &[u8];
|
||||
type InstructionData: Serialize + for<'de> Deserialize<'de>;
|
||||
|
||||
fn write_inputs(
|
||||
input_accounts: &[Account],
|
||||
instruction_data: &Self::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(())
|
||||
}
|
||||
|
||||
fn execute_and_prove(
|
||||
input_accounts: &[Account],
|
||||
instruction_data: &Self::InstructionData,
|
||||
) -> Result<(Receipt, Vec<Account>), ()> {
|
||||
// Write inputs to the program
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
Self::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, Self::PROGRAM_ELF).map_err(|_| ())?;
|
||||
let receipt = prove_info.receipt;
|
||||
|
||||
// Get proof and (inputs and) outputs
|
||||
let inputs_outputs: Vec<Account> = receipt.journal.decode().map_err(|_| ())?;
|
||||
|
||||
Ok((receipt, inputs_outputs))
|
||||
}
|
||||
|
||||
fn execute(
|
||||
input_accounts: &[Account],
|
||||
instruction_data: &Self::InstructionData,
|
||||
) -> Result<Vec<Account>, ()> {
|
||||
// Write inputs to the program
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
Self::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, Self::PROGRAM_ELF).map_err(|_| ())?;
|
||||
|
||||
// Get proof and (inputs and) outputs
|
||||
let inputs_outputs: Vec<Account> = session_info.journal.decode().map_err(|_| ())?;
|
||||
|
||||
Ok(inputs_outputs)
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,8 @@ use risc0_zkvm::{default_executor, ExecutorEnv};
|
||||
use toy_example_core::account::Account;
|
||||
use transfer_methods::TRANSFER_ELF;
|
||||
|
||||
use crate::{program::Program, TransferProgram};
|
||||
|
||||
/// A public execution.
|
||||
/// This would be executed by the runtime after checking that
|
||||
/// the initiating transaction includes the sender's signature.
|
||||
@ -22,19 +24,7 @@ pub fn run_public_execution_of_transfer_program() {
|
||||
|
||||
let balance_to_move: u128 = 3;
|
||||
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
env_builder.write(&sender).unwrap();
|
||||
env_builder.write(&receiver).unwrap();
|
||||
env_builder.write(&balance_to_move).unwrap();
|
||||
let env = env_builder.build().unwrap();
|
||||
|
||||
let executor = default_executor();
|
||||
let inputs_outputs: Vec<Account> = executor
|
||||
.execute(env, TRANSFER_ELF)
|
||||
.unwrap()
|
||||
.journal
|
||||
.decode()
|
||||
.unwrap();
|
||||
let inputs_outputs = TransferProgram::execute(&[sender, receiver], &balance_to_move).unwrap();
|
||||
|
||||
println!(
|
||||
"sender_before: {:?}, sender_after: {:?}",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user