Skip to content

Commit

Permalink
fix committed public values
Browse files Browse the repository at this point in the history
  • Loading branch information
PayneJoe committed Nov 30, 2024
1 parent c7df573 commit a9eb454
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 52 deletions.
Binary file added examples/recursive/lib/src/.lib.rs.swp
Binary file not shown.
25 changes: 20 additions & 5 deletions examples/recursive/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,32 @@ use crate::utils::sha256_hash;
pub struct CircuitInput {
pub public_input_merkle_root: [u8; 32],
pub public_value: u32,
pub private_value: u32,
pub witness: Vec<u32>,
}

/// A toy example of cubic computation
pub fn cubic(n: u32) -> u32 {
n.wrapping_mul(n).wrapping_mul(n)
impl CircuitInput {
pub fn new(public_input_merkle_root: [u8; 32], public_value: u32, private_value: u32, witness: Vec<u32>) -> Self {
Self {
public_input_merkle_root,
public_value,
private_value,
witness,
}
}
}

/// A toy example of accumulation of cubic
pub fn acc_cubic(public_value: u32, private_value: u32) -> u32 {
private_value.wrapping_add(public_value.wrapping_mul(public_value).wrapping_mul(public_value))
}

/// Verify last prover's proof
pub fn verify_proof(vkey_hash: &[u32; 8], public_input_merkle_root: &[u8; 32]) {
sp1_zkvm::lib::verify::verify_sp1_proof(vkey_hash, &sha256_hash(public_input_merkle_root));
pub fn verify_proof(vkey_hash: &[u32; 8], public_input_merkle_root: &[u8; 32], private_value: u32) {
let mut bytes = Vec::with_capacity(36);
bytes.extend_from_slice(public_input_merkle_root);
bytes.extend_from_slice(&private_value.to_le_bytes());
sp1_zkvm::lib::verify::verify_sp1_proof(vkey_hash, &sha256_hash(&bytes));
}

/// Construct a merkle tree for all public inputs avoiding commit these public inputs directly
Expand Down
6 changes: 3 additions & 3 deletions examples/recursive/program/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#![no_main]
sp1_zkvm::entrypoint!(main);

use recursive_lib::{cubic, verify_proof, merkle_tree_public_input, CircuitInput};
use recursive_lib::{acc_cubic, verify_proof, merkle_tree_public_input, CircuitInput};

pub fn main() {
// Read prover's sequence number
Expand All @@ -18,10 +18,10 @@ pub fn main() {
let circuit_input = sp1_zkvm::io::read::<CircuitInput>();

// Do cubic computation
let result = cubic(circuit_input.public_value);
let result = acc_cubic(circuit_input.public_value, circuit_input.private_value);
// Verify proof output by last prover
if seq != 0 {
verify_proof(&vkey_u32_hash, &circuit_input.public_input_merkle_root);
verify_proof(&vkey_u32_hash, &circuit_input.public_input_merkle_root, circuit_input.private_value);
}
// Construct a merkle root of all public inputs
let merkle_root = merkle_tree_public_input(
Expand Down
108 changes: 64 additions & 44 deletions examples/recursive/script/src/bin/recursive_prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
//! RUST_LOG=info cargo run --release -- --prove
//! ```
use alloy_sol_types::SolType;
use clap::Parser;
use fibonacci_lib::PublicValuesStruct;
use sp1_sdk::{include_elf, ProverClient, SP1Stdin};
use recursive_lib::CircuitInput;
use sp1_sdk::SP1Proof;
use sp1_sdk::HashableKey;

/// The ELF (executable and linkable format) file for the Succinct RISC-V zkVM.
pub const FIBONACCI_ELF: &[u8] = include_elf!("fibonacci-program");
pub const RECURSIVE_ELF: &[u8] = include_elf!("recursive-program");

/// The arguments for the command.
#[derive(Parser, Debug)]
Expand All @@ -43,49 +44,68 @@ fn main() {
eprintln!("Error: You must specify either --execute or --prove");
std::process::exit(1);
}

// Setup the prover client.
let client = ProverClient::new();

// Setup the inputs.
let mut stdin = SP1Stdin::new();
stdin.write(&args.n);

println!("n: {}", args.n);
assert_eq!(args.n > 0, true, "n must be greater than 0");
let test_public_values = (0..args.n).map(|i| 100 + i).collect::<Vec<_>>();

if args.execute {
// Execute the program
let (output, report) = client.execute(FIBONACCI_ELF, stdin).run().unwrap();
println!("Program executed successfully.");

// Read the output.
let decoded = PublicValuesStruct::abi_decode(output.as_slice(), true).unwrap();
let PublicValuesStruct { n, a, b } = decoded;
println!("n: {}", n);
println!("a: {}", a);
println!("b: {}", b);

let (expected_a, expected_b) = fibonacci_lib::fibonacci(n);
assert_eq!(a, expected_a);
assert_eq!(b, expected_b);
println!("Values are correct!");

// Record the number of cycles executed.
println!("Number of cycles: {}", report.total_instruction_count());
} else {
// Setup the program for proving.
let (pk, vk) = client.setup(FIBONACCI_ELF);

// Generate the proof
let proof = client
.prove(&pk, stdin)
let client = ProverClient::new();
let (recursive_prover_pk, recursive_prover_vk) = client.setup(RECURSIVE_ELF);

// For the very first prover
// initialized public and private values for the very first prover
let mut vkey_hash = [0u32; 8];
let mut public_input_merkle_root = [0u8; 32];
let mut public_value = test_public_values[0];
let mut private_value = 0u32;
let mut witness: Vec<u32> = vec![];
let mut circuit_input = CircuitInput::new(public_input_merkle_root, public_value, private_value, witness);

// just fill in STDIN
let mut stdin = SP1Stdin::new();
// write sequence number
stdin.write(&(0 as u32));
// write vkey u32 hash
stdin.write(&vkey_hash);
// write circuit input
stdin.write(&circuit_input);
// generate proof for the very first prover
let mut last_prover_proof = client
.prove(&recursive_prover_pk, stdin)
.compressed()
.run()
.expect("failed to generate proof");

println!("Successfully generated proof!");

// Verify the proof.
client.verify(&proof, &vk).expect("failed to verify proof");
println!("Successfully verified proof!");
.expect("proving failed");
println!("## Generating proof for the very first prover succeeds!");

// For the rest of the provers
for seq in 1..args.n {
// public and private values for the rest of provers
vkey_hash = recursive_prover_vk.hash_u32();
public_input_merkle_root = last_prover_proof.public_values.read::<[u8; 32]>();
private_value = last_prover_proof.public_values.read::<u32>();
public_value = test_public_values[seq as usize];
witness = test_public_values[..seq as usize].to_vec();
circuit_input = CircuitInput::new(public_input_merkle_root, public_value, private_value, witness);

// just fill in STDIN
stdin = SP1Stdin::new();
stdin.write(&(seq as u32));
stdin.write(&vkey_hash);
stdin.write(&circuit_input);
let SP1Proof::Compressed(proof) = last_prover_proof.proof else {
panic!()
};
// write proof and vkey as private value
stdin.write_proof(*proof, recursive_prover_vk.vk.clone());
last_prover_proof = client
.prove(&recursive_prover_pk, stdin)
.compressed()
.run()
.expect("proving failed");
println!("## Generating proof for one of the rest provers succeeds!");
}


} else {
unimplemented!();
}
}

0 comments on commit a9eb454

Please sign in to comment.