From 0add69ba434d6624caf7d9b4ff6f92af95556de2 Mon Sep 17 00:00:00 2001 From: Chris T Date: Fri, 26 Apr 2024 16:25:45 -0700 Subject: [PATCH] fix: deferred proofs + cleanup hash_vkey (#615) --- core/src/stark/machine.rs | 40 ---------- core/src/utils/config.rs | 21 +---- primitives/src/lib.rs | 2 +- prover/src/lib.rs | 66 +++++++--------- prover/src/types.rs | 27 ++++++- recursion/compiler/src/ir/builder.rs | 23 +++++- recursion/compiler/src/ir/types.rs | 72 +++++++++--------- recursion/core/src/runtime/mod.rs | 1 + recursion/program/src/reduce.rs | 13 +++- recursion/program/src/utils.rs | 4 +- tests/verify-proof/Cargo.lock | 61 +++++++-------- .../elf/riscv32im-succinct-zkvm-elf | Bin 180672 -> 179396 bytes 12 files changed, 152 insertions(+), 178 deletions(-) diff --git a/core/src/stark/machine.rs b/core/src/stark/machine.rs index 8eaa04f5c9..44e13de5db 100644 --- a/core/src/stark/machine.rs +++ b/core/src/stark/machine.rs @@ -4,22 +4,18 @@ use std::fmt::Debug; use itertools::Itertools; use p3_air::Air; -use p3_baby_bear::BabyBear; use p3_challenger::CanObserve; use p3_challenger::FieldChallenger; use p3_commit::Pcs; -use p3_commit::TwoAdicMultiplicativeCoset; use p3_field::AbstractField; use p3_field::Field; use p3_field::PrimeField32; -use p3_field::TwoAdicField; use p3_matrix::dense::RowMajorMatrix; use p3_matrix::Dimensions; use p3_matrix::Matrix; use p3_maybe_rayon::prelude::*; use serde::Deserialize; use serde::Serialize; -use sp1_primitives::poseidon2_hash; use super::debug_constraints; use super::Dom; @@ -34,7 +30,6 @@ use crate::stark::DebugConstraintBuilder; use crate::stark::ProverConstraintFolder; use crate::stark::ShardProof; use crate::stark::VerifierConstraintFolder; -use crate::utils::DIGEST_SIZE; use super::Chip; use super::Com; @@ -107,41 +102,6 @@ impl Debug for StarkVerifyingKey { } } -impl< - SC: StarkGenericConfig>, - A: MachineAir, - > StarkMachine -where - >::Commitment: AsRef<[BabyBear; DIGEST_SIZE]>, -{ - /// Hash the verifying key, producing a single commitment that uniquely identifies the program - /// being proven. - /// - /// poseidon2( commit[0..8] || pc_start || prep_domains[N].{log_n, .size, .shift, .g} ) - pub fn hash_vkey(&self, vkey: &StarkVerifyingKey) -> [BabyBear; DIGEST_SIZE] { - // TODO: this should live in SP1VerifyingKey - let prep_domains = self.preprocessed_chip_ids().into_iter().map(|chip_idx| { - let name = self.chips[chip_idx].name().clone(); - let prep_sorted_idx = vkey.chip_ordering[&name]; - vkey.chip_information[prep_sorted_idx].1 - }); - let num_inputs = DIGEST_SIZE + 1 + (4 * prep_domains.len()); - let mut inputs = Vec::with_capacity(num_inputs); - inputs.extend(vkey.commit.as_ref()); - inputs.push(vkey.pc_start); - for domain in prep_domains { - inputs.push(BabyBear::from_canonical_usize(domain.log_n)); - let size = 1 << domain.log_n; - inputs.push(BabyBear::from_canonical_usize(size)); - let g = BabyBear::two_adic_generator(domain.log_n); - inputs.push(domain.shift); - inputs.push(g); - } - - poseidon2_hash(inputs) - } -} - impl>> StarkMachine { /// Get an array containing a `ChipRef` for all the chips of this RISC-V STARK machine. pub fn chips(&self) -> &[MachineChip] { diff --git a/core/src/utils/config.rs b/core/src/utils/config.rs index c6f90ad6db..9cb3583683 100644 --- a/core/src/utils/config.rs +++ b/core/src/utils/config.rs @@ -15,7 +15,7 @@ use p3_symmetric::Hash; use p3_symmetric::{PaddingFreeSponge, TruncatedPermutation}; use serde::Deserialize; use serde::Serialize; -use sp1_primitives::RC_16_30; +use sp1_primitives::poseidon2_init; pub const DIGEST_SIZE: usize = 8; @@ -48,24 +48,7 @@ pub type InnerPcsProof = /// The permutation for inner recursion. pub fn inner_perm() -> InnerPerm { - const ROUNDS_F: usize = 8; - const ROUNDS_P: usize = 13; - let mut round_constants = RC_16_30.to_vec(); - let internal_start = ROUNDS_F / 2; - let internal_end = (ROUNDS_F / 2) + ROUNDS_P; - let internal_round_constants = round_constants - .drain(internal_start..internal_end) - .map(|vec| vec[0]) - .collect::>(); - let external_round_constants = round_constants; - InnerPerm::new( - ROUNDS_F, - external_round_constants, - Poseidon2ExternalMatrixGeneral, - ROUNDS_P, - internal_round_constants, - DiffusionMatrixBabyBear, - ) + poseidon2_init() } /// The FRI config for sp1 proofs. diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index f6613cb593..97a074cdc3 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -1102,7 +1102,7 @@ lazy_static! { pub fn poseidon2_init( ) -> Poseidon2 { const ROUNDS_F: usize = 8; - const ROUNDS_P: usize = 22; + const ROUNDS_P: usize = 13; let mut round_constants = RC_16_30.to_vec(); let internal_start = ROUNDS_F / 2; let internal_end = (ROUNDS_F / 2) + ROUNDS_P; diff --git a/prover/src/lib.rs b/prover/src/lib.rs index 681ec41721..d3294ae05a 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -154,17 +154,15 @@ impl SP1Prover { pub fn setup(&self, elf: &[u8]) -> (SP1ProvingKey, SP1VerifyingKey) { let program = Program::from(elf); let (pk, vk) = self.core_machine.setup(&program); - let pk = SP1ProvingKey { pk, program }; let vk = SP1VerifyingKey { vk }; + let pk = SP1ProvingKey { + pk, + program, + vk: vk.clone(), + }; (pk, vk) } - /// Hash a verifying key, producing a single commitment that uniquely identifies the program - /// being proven. - pub fn hash_vkey(&self, vk: &StarkVerifyingKey) -> [Val; 8] { - self.core_machine.hash_vkey(vk) - } - /// Accumulate deferred proofs into a single digest. pub fn hash_deferred_proofs( prev_digest: [Val; 8], @@ -485,6 +483,10 @@ impl SP1Prover { indices }) .collect(); + let deferred_chip_quotient_data: Vec> = deferred_proofs + .iter() + .map(|p| get_chip_quotient_data(&self.reduce_machine, p)) + .collect(); // Convert the inputs into a witness stream. let mut witness_stream = Vec::new(); @@ -518,6 +520,7 @@ impl SP1Prover { } } } + witness_stream.extend(deferred_chip_quotient_data.write()); witness_stream.extend(deferred_sorted_indices.write()); witness_stream.extend(deferred_proofs.to_vec().write()); let is_complete = if is_complete { 1usize } else { 0 }; @@ -755,15 +758,18 @@ mod tests { prover.wrap_groth16(wrapped_bn254_proof, PathBuf::from("build")); } + /// This test ensures that a proof can be deferred in the core vm and verified in recursion. #[test] - #[ignore] fn test_deferred_verify() { setup_logger(); std::env::set_var("RECONSTRUCT_COMMITMENTS", "false"); + std::env::set_var("FRI_QUERIES", "1"); + std::env::set_var("SHARD_SIZE", "262144"); + std::env::set_var("MAX_RECURSION_PROGRAM_SIZE", "1"); - // Generate SP1 proof + // keccak program which proves keccak of various inputs let keccak_elf = include_bytes!("../../tests/keccak256/elf/riscv32im-succinct-zkvm-elf"); - + // verify program which verifies proofs of a vkey and a list of committed inputs let verify_elf = include_bytes!("../../tests/verify-proof/elf/riscv32im-succinct-zkvm-elf"); tracing::info!("initializing prover"); @@ -773,21 +779,12 @@ mod tests { let (keccak_pk, keccak_vk) = prover.setup(keccak_elf); let (verify_pk, verify_vk) = prover.setup(verify_elf); + // Prove keccak of various inputs tracing::info!("prove subproof 1"); let mut stdin = SP1Stdin::new(); stdin.write(&1usize); stdin.write(&vec![0u8, 0, 0]); - // Read proof from p1.bin if exists - let p1_file = std::fs::File::open("p1.bin"); - let deferred_proof_1 = match p1_file { - Ok(file) => bincode::deserialize_from(file).unwrap(), - Err(_) => { - let deferred_proof_1 = prover.prove_core(&keccak_pk, &stdin); - let file = std::fs::File::create("p1.bin").unwrap(); - bincode::serialize_into(file, &deferred_proof_1).unwrap(); - deferred_proof_1 - } - }; + let deferred_proof_1 = prover.prove_core(&keccak_pk, &stdin); let pv_1 = deferred_proof_1.public_values.buffer.data.clone(); println!("proof 1 pv: {:?}", hex::encode(pv_1.clone())); let pv_digest_1 = deferred_proof_1.shard_proofs[0].public_values[..32] @@ -796,23 +793,14 @@ mod tests { .collect::>(); println!("proof 1 pv_digest: {:?}", hex::encode(pv_digest_1.clone())); + // Generate a second proof of keccak of various inputs tracing::info!("prove subproof 2"); let mut stdin = SP1Stdin::new(); stdin.write(&3usize); stdin.write(&vec![0u8, 1, 2]); stdin.write(&vec![2, 3, 4]); stdin.write(&vec![5, 6, 7]); - // Read proof from p2.bin if exists - let p2_file = std::fs::File::open("p2.bin"); - let deferred_proof_2 = match p2_file { - Ok(file) => bincode::deserialize_from(file).unwrap(), - Err(_) => { - let deferred_proof_2 = prover.prove_core(&keccak_pk, &stdin); - let file = std::fs::File::create("p2.bin").unwrap(); - bincode::serialize_into(file, &deferred_proof_2).unwrap(); - deferred_proof_2 - } - }; + let deferred_proof_2 = prover.prove_core(&keccak_pk, &stdin); let pv_2 = deferred_proof_2.public_values.buffer.data.clone(); println!("proof 2 pv: {:?}", hex::encode(pv_2.clone())); let pv_digest_2 = deferred_proof_2.shard_proofs[0].public_values[..32] @@ -821,14 +809,17 @@ mod tests { .collect::>(); println!("proof 2 pv_digest: {:?}", hex::encode(pv_digest_2.clone())); + // Generate recursive proof of first subproof println!("reduce subproof 1"); let deferred_reduce_1 = prover.reduce(&keccak_vk, deferred_proof_1, vec![]); + // Generate recursive proof of second subproof println!("reduce subproof 2"); let deferred_reduce_2 = prover.reduce(&keccak_vk, deferred_proof_2, vec![]); + // Run verify program with keccak vkey, subproofs, and their committed values let mut stdin = SP1Stdin::new(); - let vkey_digest = &prover.core_machine.hash_vkey(&keccak_vk.vk); + let vkey_digest = keccak_vk.hash(); let vkey_digest: [u32; 8] = vkey_digest .iter() .map(|n| n.as_canonical_u32()) @@ -841,6 +832,7 @@ mod tests { stdin.write_proof(deferred_reduce_2.proof.clone(), keccak_vk.vk.clone()); stdin.write_proof(deferred_reduce_2.proof.clone(), keccak_vk.vk.clone()); + // Prove verify program println!("proving verify program (core)"); let verify_proof = prover.prove_core(&verify_pk, &stdin); let pv = PublicValues::, BabyBear>::from_vec( @@ -849,6 +841,7 @@ mod tests { println!("deferred_hash: {:?}", pv.deferred_proofs_digest); + // Generate recursive proof of verify program println!("proving verify program (recursion)"); let verify_reduce = prover.reduce( &verify_vk, @@ -863,10 +856,7 @@ mod tests { println!("deferred_hash: {:?}", reduce_pv.deferred_proofs_digest); println!("complete: {:?}", reduce_pv.is_complete); - println!("wrap"); - let wrapped = prover.wrap_bn254(&verify_vk, verify_reduce); - - tracing::info!("groth16"); - prover.wrap_groth16(wrapped, PathBuf::from("build")); + // TODO: verify verify_reduce proof once shard transition logic is moved out of machine.verify + // prover.reduce_machine.verify(vk, proof, challenger) } } diff --git a/prover/src/types.rs b/prover/src/types.rs index 89db785b2c..cc757328cd 100644 --- a/prover/src/types.rs +++ b/prover/src/types.rs @@ -1,12 +1,14 @@ use p3_baby_bear::BabyBear; -use p3_field::AbstractField; +use p3_field::{AbstractField, TwoAdicField}; use serde::{Deserialize, Serialize}; use sp1_core::{ air::{PublicValues, Word, POSEIDON_NUM_WORDS, PV_DIGEST_NUM_WORDS}, io::{SP1PublicValues, SP1Stdin}, runtime::Program, stark::{ShardProof, StarkGenericConfig, StarkProvingKey, StarkVerifyingKey, Val}, + utils::DIGEST_SIZE, }; +use sp1_primitives::poseidon2_hash; use sp1_recursion_core::air::RecursionPublicValues; use crate::{CoreSC, InnerSC}; @@ -15,13 +17,36 @@ use crate::{CoreSC, InnerSC}; pub struct SP1ProvingKey { pub pk: StarkProvingKey, pub program: Program, + /// Verifying key is also included as we need it for recursion + pub vk: SP1VerifyingKey, } /// The information necessary to verify a proof for a given RISC-V program. +#[derive(Clone)] pub struct SP1VerifyingKey { pub vk: StarkVerifyingKey, } +impl SP1VerifyingKey { + pub fn hash(&self) -> [BabyBear; 8] { + let prep_domains = self.vk.chip_information.iter().map(|(_, domain, _)| domain); + let num_inputs = DIGEST_SIZE + 1 + (4 * prep_domains.len()); + let mut inputs = Vec::with_capacity(num_inputs); + inputs.extend(self.vk.commit.as_ref()); + inputs.push(self.vk.pc_start); + for domain in prep_domains { + inputs.push(BabyBear::from_canonical_usize(domain.log_n)); + let size = 1 << domain.log_n; + inputs.push(BabyBear::from_canonical_usize(size)); + let g = BabyBear::two_adic_generator(domain.log_n); + inputs.push(domain.shift); + inputs.push(g); + } + + poseidon2_hash(inputs) + } +} + /// A proof of a RISC-V execution with given inputs and outputs composed of multiple shard proofs. #[derive(Serialize, Deserialize, Clone)] pub struct SP1CoreProof { diff --git a/recursion/compiler/src/ir/builder.rs b/recursion/compiler/src/ir/builder.rs index e608880e35..e8d1fd45a7 100644 --- a/recursion/compiler/src/ir/builder.rs +++ b/recursion/compiler/src/ir/builder.rs @@ -42,11 +42,21 @@ impl TracedVec { pub fn push(&mut self, value: T) { self.vec.push(value); - match std::env::var("SP1_DEBUG") { - Ok(_) => { + self.traces.push(None); + } + + /// Pushes a value to the vector and records a backtrace if SP1_DEBUG is enabled + pub fn trace_push(&mut self, value: T) { + self.vec.push(value); + match std::env::var("SP1_DEBUG") + .unwrap_or("false".to_string()) + .to_lowercase() + .as_str() + { + "true" => { self.traces.push(Some(Backtrace::new_unresolved())); } - Err(_) => { + _ => { self.traces.push(None); } }; @@ -123,6 +133,11 @@ impl Builder { self.operations.push(op); } + /// Pushes an operation to the builder and records a trace if SP1_DEBUG. + pub fn trace_push(&mut self, op: DslIr) { + self.operations.trace_push(op); + } + /// Creates an uninitialized variable. pub fn uninit>(&mut self) -> V { V::uninit(self) @@ -394,7 +409,7 @@ impl Builder { /// Throws an error. pub fn error(&mut self) { - self.operations.push(DslIr::Error()); + self.operations.trace_push(DslIr::Error()); } /// Materializes a usize into a variable. diff --git a/recursion/compiler/src/ir/types.rs b/recursion/compiler/src/ir/types.rs index 5aec6fa97d..989dd0b428 100644 --- a/recursion/compiler/src/ir/types.rs +++ b/recursion/compiler/src/ir/types.rs @@ -423,30 +423,30 @@ impl Variable for Var { assert_eq!(lhs, rhs, "Assertion failed at compile time"); } (SymbolicVar::Const(lhs, _), SymbolicVar::Val(rhs, _)) => { - builder.push(DslIr::AssertEqVI(rhs, lhs)); + builder.trace_push(DslIr::AssertEqVI(rhs, lhs)); } (SymbolicVar::Const(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertEqVI(rhs_value, lhs)); + builder.trace_push(DslIr::AssertEqVI(rhs_value, lhs)); } (SymbolicVar::Val(lhs, _), SymbolicVar::Const(rhs, _)) => { - builder.push(DslIr::AssertEqVI(lhs, rhs)); + builder.trace_push(DslIr::AssertEqVI(lhs, rhs)); } (SymbolicVar::Val(lhs, _), SymbolicVar::Val(rhs, _)) => { - builder.push(DslIr::AssertEqV(lhs, rhs)); + builder.trace_push(DslIr::AssertEqV(lhs, rhs)); } (SymbolicVar::Val(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertEqV(lhs, rhs_value)); + builder.trace_push(DslIr::AssertEqV(lhs, rhs_value)); } (lhs, rhs) => { let lhs_value = Self::uninit(builder); lhs_value.assign(lhs, builder); let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertEqV(lhs_value, rhs_value)); + builder.trace_push(DslIr::AssertEqV(lhs_value, rhs_value)); } } } @@ -464,30 +464,30 @@ impl Variable for Var { assert_ne!(lhs, rhs, "Assertion failed at compile time"); } (SymbolicVar::Const(lhs, _), SymbolicVar::Val(rhs, _)) => { - builder.push(DslIr::AssertNeVI(rhs, lhs)); + builder.trace_push(DslIr::AssertNeVI(rhs, lhs)); } (SymbolicVar::Const(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertNeVI(rhs_value, lhs)); + builder.trace_push(DslIr::AssertNeVI(rhs_value, lhs)); } (SymbolicVar::Val(lhs, _), SymbolicVar::Const(rhs, _)) => { - builder.push(DslIr::AssertNeVI(lhs, rhs)); + builder.trace_push(DslIr::AssertNeVI(lhs, rhs)); } (SymbolicVar::Val(lhs, _), SymbolicVar::Val(rhs, _)) => { - builder.push(DslIr::AssertNeV(lhs, rhs)); + builder.trace_push(DslIr::AssertNeV(lhs, rhs)); } (SymbolicVar::Val(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertNeV(lhs, rhs_value)); + builder.trace_push(DslIr::AssertNeV(lhs, rhs_value)); } (lhs, rhs) => { let lhs_value = Self::uninit(builder); lhs_value.assign(lhs, builder); let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertNeV(lhs_value, rhs_value)); + builder.trace_push(DslIr::AssertNeV(lhs_value, rhs_value)); } } } @@ -766,30 +766,30 @@ impl Variable for Felt { assert_eq!(lhs, rhs, "Assertion failed at compile time"); } (SymbolicFelt::Const(lhs, _), SymbolicFelt::Val(rhs, _)) => { - builder.push(DslIr::AssertEqFI(rhs, lhs)); + builder.trace_push(DslIr::AssertEqFI(rhs, lhs)); } (SymbolicFelt::Const(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertEqFI(rhs_value, lhs)); + builder.trace_push(DslIr::AssertEqFI(rhs_value, lhs)); } (SymbolicFelt::Val(lhs, _), SymbolicFelt::Const(rhs, _)) => { - builder.push(DslIr::AssertEqFI(lhs, rhs)); + builder.trace_push(DslIr::AssertEqFI(lhs, rhs)); } (SymbolicFelt::Val(lhs, _), SymbolicFelt::Val(rhs, _)) => { - builder.push(DslIr::AssertEqF(lhs, rhs)); + builder.trace_push(DslIr::AssertEqF(lhs, rhs)); } (SymbolicFelt::Val(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertEqF(lhs, rhs_value)); + builder.trace_push(DslIr::AssertEqF(lhs, rhs_value)); } (lhs, rhs) => { let lhs_value = Self::uninit(builder); lhs_value.assign(lhs, builder); let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertEqF(lhs_value, rhs_value)); + builder.trace_push(DslIr::AssertEqF(lhs_value, rhs_value)); } } } @@ -807,30 +807,30 @@ impl Variable for Felt { assert_ne!(lhs, rhs, "Assertion failed at compile time"); } (SymbolicFelt::Const(lhs, _), SymbolicFelt::Val(rhs, _)) => { - builder.push(DslIr::AssertNeFI(rhs, lhs)); + builder.trace_push(DslIr::AssertNeFI(rhs, lhs)); } (SymbolicFelt::Const(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertNeFI(rhs_value, lhs)); + builder.trace_push(DslIr::AssertNeFI(rhs_value, lhs)); } (SymbolicFelt::Val(lhs, _), SymbolicFelt::Const(rhs, _)) => { - builder.push(DslIr::AssertNeFI(lhs, rhs)); + builder.trace_push(DslIr::AssertNeFI(lhs, rhs)); } (SymbolicFelt::Val(lhs, _), SymbolicFelt::Val(rhs, _)) => { - builder.push(DslIr::AssertNeF(lhs, rhs)); + builder.trace_push(DslIr::AssertNeF(lhs, rhs)); } (SymbolicFelt::Val(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertNeF(lhs, rhs_value)); + builder.trace_push(DslIr::AssertNeF(lhs, rhs_value)); } (lhs, rhs) => { let lhs_value = Self::uninit(builder); lhs_value.assign(lhs, builder); let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertNeF(lhs_value, rhs_value)); + builder.trace_push(DslIr::AssertNeF(lhs_value, rhs_value)); } } } @@ -1161,30 +1161,30 @@ impl Variable for Ext { assert_eq!(lhs, rhs, "Assertion failed at compile time"); } (SymbolicExt::Const(lhs, _), SymbolicExt::Val(rhs, _)) => { - builder.push(DslIr::AssertEqEI(rhs, lhs)); + builder.trace_push(DslIr::AssertEqEI(rhs, lhs)); } (SymbolicExt::Const(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertEqEI(rhs_value, lhs)); + builder.trace_push(DslIr::AssertEqEI(rhs_value, lhs)); } (SymbolicExt::Val(lhs, _), SymbolicExt::Const(rhs, _)) => { - builder.push(DslIr::AssertEqEI(lhs, rhs)); + builder.trace_push(DslIr::AssertEqEI(lhs, rhs)); } (SymbolicExt::Val(lhs, _), SymbolicExt::Val(rhs, _)) => { - builder.push(DslIr::AssertEqE(lhs, rhs)); + builder.trace_push(DslIr::AssertEqE(lhs, rhs)); } (SymbolicExt::Val(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertEqE(lhs, rhs_value)); + builder.trace_push(DslIr::AssertEqE(lhs, rhs_value)); } (lhs, rhs) => { let lhs_value = Self::uninit(builder); lhs_value.assign(lhs, builder); let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertEqE(lhs_value, rhs_value)); + builder.trace_push(DslIr::AssertEqE(lhs_value, rhs_value)); } } } @@ -1202,30 +1202,30 @@ impl Variable for Ext { assert_ne!(lhs, rhs, "Assertion failed at compile time"); } (SymbolicExt::Const(lhs, _), SymbolicExt::Val(rhs, _)) => { - builder.push(DslIr::AssertNeEI(rhs, lhs)); + builder.trace_push(DslIr::AssertNeEI(rhs, lhs)); } (SymbolicExt::Const(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertNeEI(rhs_value, lhs)); + builder.trace_push(DslIr::AssertNeEI(rhs_value, lhs)); } (SymbolicExt::Val(lhs, _), SymbolicExt::Const(rhs, _)) => { - builder.push(DslIr::AssertNeEI(lhs, rhs)); + builder.trace_push(DslIr::AssertNeEI(lhs, rhs)); } (SymbolicExt::Val(lhs, _), SymbolicExt::Val(rhs, _)) => { - builder.push(DslIr::AssertNeE(lhs, rhs)); + builder.trace_push(DslIr::AssertNeE(lhs, rhs)); } (SymbolicExt::Val(lhs, _), rhs) => { let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertNeE(lhs, rhs_value)); + builder.trace_push(DslIr::AssertNeE(lhs, rhs_value)); } (lhs, rhs) => { let lhs_value = Self::uninit(builder); lhs_value.assign(lhs, builder); let rhs_value = Self::uninit(builder); rhs_value.assign(rhs, builder); - builder.push(DslIr::AssertNeE(lhs_value, rhs_value)); + builder.trace_push(DslIr::AssertNeE(lhs_value, rhs_value)); } } } diff --git a/recursion/core/src/runtime/mod.rs b/recursion/core/src/runtime/mod.rs index ab6df22e44..10e30a38cf 100644 --- a/recursion/core/src/runtime/mod.rs +++ b/recursion/core/src/runtime/mod.rs @@ -582,6 +582,7 @@ where "TRAP encountered at pc={}. Nearest trace at pc={}: {:?}", trap_pc, nearby_pc, trace ); + exit(1); } } eprintln!("TRAP encountered. No backtrace available"); diff --git a/recursion/program/src/reduce.rs b/recursion/program/src/reduce.rs index 424ee215ed..474006197c 100644 --- a/recursion/program/src/reduce.rs +++ b/recursion/program/src/reduce.rs @@ -122,6 +122,7 @@ impl ReduceProgram { let initial_start_shard: Felt<_> = builder.uninit(); let mut reconstruct_deferred_digest: DigestVariable<_> = builder.uninit(); let proofs: Array<_, ShardProofVariable<_>> = builder.uninit(); + let deferred_chip_quotient_data: Array<_, Array<_, QuotientData<_>>> = builder.uninit(); let deferred_sorted_indices: Array<_, Array<_, Var<_>>> = builder.uninit(); let num_deferred_proofs: Var<_> = builder.uninit(); let deferred_proofs: Array<_, ShardProofVariable<_>> = builder.uninit(); @@ -171,6 +172,7 @@ impl ReduceProgram { }); builder.assign(proofs.clone(), proofs_target); + Vec::>::witness(&deferred_chip_quotient_data, &mut builder); Vec::>::witness(&deferred_sorted_indices, &mut builder); Vec::>::witness(&deferred_proofs, &mut builder); let num_deferred_proofs_var = deferred_proofs.len(); @@ -198,8 +200,13 @@ impl ReduceProgram { builder.cycle_tracker("stage-b-setup-recursion-challenger"); // Hash vkey + pc_start + prep_domains into a single digest. - let sp1_vk_digest = hash_vkey(&mut builder, &sp1_vk, &prep_domains); - let recursion_vk_digest = hash_vkey(&mut builder, &reduce_vk, &reduce_prep_domains); + let sp1_vk_digest = hash_vkey(&mut builder, &sp1_vk, &prep_domains, &prep_sorted_indices); + let recursion_vk_digest = hash_vkey( + &mut builder, + &reduce_vk, + &reduce_prep_domains, + &reduce_prep_sorted_indices, + ); // Global variables that will be commmitted to at the end. let global_committed_values_digest: Sha256DigestVariable<_> = @@ -518,7 +525,7 @@ impl ReduceProgram { .for_each(|i, builder| { let proof = builder.get(&deferred_proofs, i); let sorted_indices = builder.get(&deferred_sorted_indices, i); - let chip_quotient_data = builder.get(&chip_quotient_data, i); + let chip_quotient_data = builder.get(&deferred_chip_quotient_data, i); let mut challenger = recursion_challenger.copy(builder); for j in 0..DIGEST_SIZE { let element = builder.get(&proof.commitment.main_commit, j); diff --git a/recursion/program/src/utils.rs b/recursion/program/src/utils.rs index c7c131f990..550b9e0e43 100644 --- a/recursion/program/src/utils.rs +++ b/recursion/program/src/utils.rs @@ -171,6 +171,7 @@ pub fn hash_vkey( builder: &mut Builder, vk: &VerifyingKeyVariable, prep_domains: &Array>, + prep_sorted_indices: &Array>, ) -> Array> { let domain_slots: Var<_> = builder.eval(prep_domains.len() * 4); let vkey_slots: Var<_> = builder.constant(C::N::from_canonical_usize(DIGEST_SIZE + 1)); @@ -184,8 +185,9 @@ pub fn hash_vkey( let four: Var<_> = builder.constant(C::N::from_canonical_usize(4)); let one: Var<_> = builder.constant(C::N::one()); builder.range(0, prep_domains.len()).for_each(|i, builder| { + let sorted_index = builder.get(prep_sorted_indices, i); let domain = builder.get(prep_domains, i); - let log_n_index: Var<_> = builder.eval(vkey_slots + i * four); + let log_n_index: Var<_> = builder.eval(vkey_slots + sorted_index * four); let size_index: Var<_> = builder.eval(log_n_index + one); let shift_index: Var<_> = builder.eval(size_index + one); let g_index: Var<_> = builder.eval(shift_index + one); diff --git a/tests/verify-proof/Cargo.lock b/tests/verify-proof/Cargo.lock index fb37065a5f..4467585731 100644 --- a/tests/verify-proof/Cargo.lock +++ b/tests/verify-proof/Cargo.lock @@ -160,9 +160,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "elliptic-curve" @@ -294,15 +294,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.12.1" @@ -434,7 +425,7 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "p3-baby-bear" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#056f328a5096049b2b308fb6dc3497249e81d354" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#aef4f8f03f960925f7088d757aeeb956a7f4b30c" dependencies = [ "num-bigint", "p3-field", @@ -448,7 +439,7 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#056f328a5096049b2b308fb6dc3497249e81d354" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#aef4f8f03f960925f7088d757aeeb956a7f4b30c" dependencies = [ "p3-field", "p3-matrix", @@ -460,9 +451,9 @@ dependencies = [ [[package]] name = "p3-field" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#056f328a5096049b2b308fb6dc3497249e81d354" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#aef4f8f03f960925f7088d757aeeb956a7f4b30c" dependencies = [ - "itertools 0.12.1", + "itertools", "num-bigint", "num-traits", "p3-util", @@ -473,9 +464,9 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#056f328a5096049b2b308fb6dc3497249e81d354" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#aef4f8f03f960925f7088d757aeeb956a7f4b30c" dependencies = [ - "itertools 0.12.1", + "itertools", "p3-field", "p3-maybe-rayon", "p3-util", @@ -487,14 +478,14 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#056f328a5096049b2b308fb6dc3497249e81d354" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#aef4f8f03f960925f7088d757aeeb956a7f4b30c" [[package]] name = "p3-mds" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#056f328a5096049b2b308fb6dc3497249e81d354" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#aef4f8f03f960925f7088d757aeeb956a7f4b30c" dependencies = [ - "itertools 0.11.0", + "itertools", "p3-dft", "p3-field", "p3-matrix", @@ -506,7 +497,7 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#056f328a5096049b2b308fb6dc3497249e81d354" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#aef4f8f03f960925f7088d757aeeb956a7f4b30c" dependencies = [ "gcd", "p3-field", @@ -518,9 +509,9 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#056f328a5096049b2b308fb6dc3497249e81d354" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#aef4f8f03f960925f7088d757aeeb956a7f4b30c" dependencies = [ - "itertools 0.12.1", + "itertools", "p3-field", "serde", ] @@ -528,7 +519,7 @@ dependencies = [ [[package]] name = "p3-util" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#056f328a5096049b2b308fb6dc3497249e81d354" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#aef4f8f03f960925f7088d757aeeb956a7f4b30c" dependencies = [ "serde", ] @@ -601,9 +592,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -703,22 +694,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -772,7 +763,7 @@ dependencies = [ name = "sp1-primitives" version = "0.1.0" dependencies = [ - "itertools 0.12.1", + "itertools", "lazy_static", "p3-baby-bear", "p3-field", @@ -828,9 +819,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -890,7 +881,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] diff --git a/tests/verify-proof/elf/riscv32im-succinct-zkvm-elf b/tests/verify-proof/elf/riscv32im-succinct-zkvm-elf index 63c211e27fda183a846439b732fc46df4459aae0..bce15a863acb9747046088fb9d33823a0a196ea8 100755 GIT binary patch delta 55018 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%0ALxfyUPUq9{^Cn+saYtmak#If)|Ek6xixuzk=tl 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