Do not panic on wire set twice or generator not run issues (#1611)

* Do not panic on wire set twice or generator not run issues

* No std
This commit is contained in:
Robin Salen 2024-08-07 14:53:14 -04:00 committed by GitHub
parent 0e363e16a3
commit 349beae143
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
46 changed files with 465 additions and 259 deletions

View File

@ -138,7 +138,7 @@ fn dummy_lookup_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
let data = builder.build::<C>(); let data = builder.build::<C>();
let mut inputs = PartialWitness::<F>::new(); let mut inputs = PartialWitness::<F>::new();
inputs.set_target(initial_a, F::ONE); inputs.set_target(initial_a, F::ONE)?;
let mut timing = TimingTree::new("prove with one lookup", Level::Debug); let mut timing = TimingTree::new("prove with one lookup", Level::Debug);
let proof = prove(&data.prover_only, &data.common, inputs, &mut timing)?; let proof = prove(&data.prover_only, &data.common, inputs, &mut timing)?;
timing.print(); timing.print();
@ -189,7 +189,7 @@ fn dummy_many_rows_proof<
builder.register_public_input(output); builder.register_public_input(output);
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::ONE); pw.set_target(initial_a, F::ONE)?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let mut timing = TimingTree::new("prove with many lookups", Level::Debug); let mut timing = TimingTree::new("prove with many lookups", Level::Debug);
let proof = prove(&data.prover_only, &data.common, pw, &mut timing)?; let proof = prove(&data.prover_only, &data.common, pw, &mut timing)?;
@ -235,8 +235,8 @@ where
let data = builder.build::<C>(); let data = builder.build::<C>();
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_proof_with_pis_target(&pt, inner_proof); pw.set_proof_with_pis_target(&pt, inner_proof)?;
pw.set_verifier_data_target(&inner_data, inner_vd); pw.set_verifier_data_target(&inner_data, inner_vd)?;
let mut timing = TimingTree::new("prove", Level::Debug); let mut timing = TimingTree::new("prove", Level::Debug);
let proof = prove::<F, C, D>(&data.prover_only, &data.common, pw, &mut timing)?; let proof = prove::<F, C, D>(&data.prover_only, &data.common, pw, &mut timing)?;

View File

@ -29,7 +29,7 @@ fn main() -> Result<()> {
builder.register_public_input(cur_target); builder.register_public_input(cur_target);
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial, F::ONE); pw.set_target(initial, F::ONE)?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let proof = data.prove(pw)?; let proof = data.prove(pw)?;

View File

@ -34,8 +34,8 @@ fn main() -> Result<()> {
// Provide initial values. // Provide initial values.
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::ZERO); pw.set_target(initial_a, F::ZERO)?;
pw.set_target(initial_b, F::ONE); pw.set_target(initial_b, F::ONE)?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let proof = data.prove(pw)?; let proof = data.prove(pw)?;

View File

@ -37,8 +37,8 @@ fn main() -> Result<()> {
// Provide initial values. // Provide initial values.
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::ZERO); pw.set_target(initial_a, F::ZERO)?;
pw.set_target(initial_b, F::ONE); pw.set_target(initial_b, F::ONE)?;
let data = builder.build::<C>(); let data = builder.build::<C>();

View File

@ -24,7 +24,7 @@ fn main() -> Result<()> {
builder.range_check(value, log_max); builder.range_check(value, log_max);
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(value, F::from_canonical_usize(42)); pw.set_target(value, F::from_canonical_usize(42))?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let proof = data.prove(pw)?; let proof = data.prove(pw)?;

View File

@ -41,13 +41,17 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
vec![self.x_squared] vec![self.x_squared]
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let x_squared = witness.get_target(self.x_squared); let x_squared = witness.get_target(self.x_squared);
let x = x_squared.sqrt().unwrap(); let x = x_squared.sqrt().unwrap();
println!("Square root: {x}"); println!("Square root: {x}");
out_buffer.set_target(self.x, x); out_buffer.set_target(self.x, x)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
@ -121,7 +125,7 @@ fn main() -> Result<()> {
}; };
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(x_squared, x_squared_value); pw.set_target(x_squared, x_squared_value)?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let proof = data.prove(pw.clone())?; let proof = data.prove(pw.clone())?;

View File

@ -599,7 +599,7 @@ mod test {
); );
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
set_fri_proof_target(&mut pw, &fri_proof_target, &proof); set_fri_proof_target(&mut pw, &fri_proof_target, &proof)?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let proof = prove::<F, C, D>(&data.prover_only, &data.common, pw, &mut timing)?; let proof = prove::<F, C, D>(&data.prover_only, &data.common, pw, &mut timing)?;

View File

@ -1,3 +1,4 @@
use anyhow::Result;
use itertools::Itertools; use itertools::Itertools;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
@ -11,12 +12,13 @@ pub fn set_fri_proof_target<F, W, H, const D: usize>(
witness: &mut W, witness: &mut W,
fri_proof_target: &FriProofTarget<D>, fri_proof_target: &FriProofTarget<D>,
fri_proof: &FriProof<F, H, D>, fri_proof: &FriProof<F, H, D>,
) where ) -> Result<()>
where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
W: WitnessWrite<F> + ?Sized, W: WitnessWrite<F> + ?Sized,
H: AlgebraicHasher<F>, H: AlgebraicHasher<F>,
{ {
witness.set_target(fri_proof_target.pow_witness, fri_proof.pow_witness); witness.set_target(fri_proof_target.pow_witness, fri_proof.pow_witness)?;
for (&t, &x) in fri_proof_target for (&t, &x) in fri_proof_target
.final_poly .final_poly
@ -24,7 +26,7 @@ pub fn set_fri_proof_target<F, W, H, const D: usize>(
.iter() .iter()
.zip_eq(&fri_proof.final_poly.coeffs) .zip_eq(&fri_proof.final_poly.coeffs)
{ {
witness.set_extension_target(t, x); witness.set_extension_target(t, x)?;
} }
for (t, x) in fri_proof_target for (t, x) in fri_proof_target
@ -32,7 +34,7 @@ pub fn set_fri_proof_target<F, W, H, const D: usize>(
.iter() .iter()
.zip_eq(&fri_proof.commit_phase_merkle_caps) .zip_eq(&fri_proof.commit_phase_merkle_caps)
{ {
witness.set_cap_target(t, x); witness.set_cap_target(t, x)?;
} }
for (qt, q) in fri_proof_target for (qt, q) in fri_proof_target
@ -47,16 +49,16 @@ pub fn set_fri_proof_target<F, W, H, const D: usize>(
.zip_eq(&q.initial_trees_proof.evals_proofs) .zip_eq(&q.initial_trees_proof.evals_proofs)
{ {
for (&t, &x) in at.0.iter().zip_eq(&a.0) { for (&t, &x) in at.0.iter().zip_eq(&a.0) {
witness.set_target(t, x); witness.set_target(t, x)?;
} }
for (&t, &x) in at.1.siblings.iter().zip_eq(&a.1.siblings) { for (&t, &x) in at.1.siblings.iter().zip_eq(&a.1.siblings) {
witness.set_hash_target(t, x); witness.set_hash_target(t, x)?;
} }
} }
for (st, s) in qt.steps.iter().zip_eq(&q.steps) { for (st, s) in qt.steps.iter().zip_eq(&q.steps) {
for (&t, &x) in st.evals.iter().zip_eq(&s.evals) { for (&t, &x) in st.evals.iter().zip_eq(&s.evals) {
witness.set_extension_target(t, x); witness.set_extension_target(t, x)?;
} }
for (&t, &x) in st for (&t, &x) in st
.merkle_proof .merkle_proof
@ -64,8 +66,10 @@ pub fn set_fri_proof_target<F, W, H, const D: usize>(
.iter() .iter()
.zip_eq(&s.merkle_proof.siblings) .zip_eq(&s.merkle_proof.siblings)
{ {
witness.set_hash_target(t, x); witness.set_hash_target(t, x)?;
} }
} }
} }
Ok(())
} }

View File

@ -6,6 +6,8 @@ use alloc::{
}; };
use core::borrow::Borrow; use core::borrow::Borrow;
use anyhow::Result;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
use crate::field::types::Field64; use crate::field::types::Field64;
use crate::gates::arithmetic_base::ArithmeticGate; use crate::gates::arithmetic_base::ArithmeticGate;
@ -397,14 +399,18 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Equ
vec![self.x, self.y] vec![self.x, self.y]
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let x = witness.get_target(self.x); let x = witness.get_target(self.x);
let y = witness.get_target(self.y); let y = witness.get_target(self.y);
let inv = if x != y { (x - y).inverse() } else { F::ZERO }; let inv = if x != y { (x - y).inverse() } else { F::ZERO };
out_buffer.set_bool_target(self.equal, x == y); out_buffer.set_bool_target(self.equal, x == y)?;
out_buffer.set_target(self.inv, inv); out_buffer.set_target(self.inv, inv)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -6,6 +6,8 @@ use alloc::{
}; };
use core::borrow::Borrow; use core::borrow::Borrow;
use anyhow::Result;
use crate::field::extension::{Extendable, FieldExtension, OEF}; use crate::field::extension::{Extendable, FieldExtension, OEF};
use crate::field::types::{Field, Field64}; use crate::field::types::{Field, Field64};
use crate::gates::arithmetic_extension::ArithmeticExtensionGate; use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
@ -519,7 +521,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
deps deps
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let num = witness.get_extension_target(self.numerator); let num = witness.get_extension_target(self.numerator);
let dem = witness.get_extension_target(self.denominator); let dem = witness.get_extension_target(self.denominator);
let quotient = num / dem; let quotient = num / dem;
@ -621,7 +627,7 @@ mod tests {
let vs = FF::rand_vec(3); let vs = FF::rand_vec(3);
let ts = builder.add_virtual_extension_targets(3); let ts = builder.add_virtual_extension_targets(3);
for (&v, &t) in vs.iter().zip(&ts) { for (&v, &t) in vs.iter().zip(&ts) {
pw.set_extension_target(t, v); pw.set_extension_target(t, v)?;
} }
let mul0 = builder.mul_many_extension(&ts); let mul0 = builder.mul_many_extension(&ts);
let mul1 = { let mul1 = {
@ -696,9 +702,9 @@ mod tests {
let y = ExtensionAlgebra::<FF, D>(FF::rand_array()); let y = ExtensionAlgebra::<FF, D>(FF::rand_array());
let z = x * y; let z = x * y;
for i in 0..D { for i in 0..D {
pw.set_extension_target(xt.0[i], x.0[i]); pw.set_extension_target(xt.0[i], x.0[i])?;
pw.set_extension_target(yt.0[i], y.0[i]); pw.set_extension_target(yt.0[i], y.0[i])?;
pw.set_extension_target(zt.0[i], z.0[i]); pw.set_extension_target(zt.0[i], z.0[i])?;
} }
let data = builder.build::<C>(); let data = builder.build::<C>();

View File

@ -5,6 +5,8 @@ use alloc::{
vec::Vec, vec::Vec,
}; };
use anyhow::Result;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
use crate::hash::hash_types::RichField; use crate::hash::hash_types::RichField;
use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::generator::{GeneratedValues, SimpleGenerator};
@ -74,13 +76,17 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Low
vec![self.integer] vec![self.integer]
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let integer_value = witness.get_target(self.integer).to_canonical_u64(); let integer_value = witness.get_target(self.integer).to_canonical_u64();
let low = integer_value & ((1 << self.n_log) - 1); let low = integer_value & ((1 << self.n_log) - 1);
let high = integer_value >> self.n_log; let high = integer_value >> self.n_log;
out_buffer.set_target(self.low, F::from_canonical_u64(low)); out_buffer.set_target(self.low, F::from_canonical_u64(low))?;
out_buffer.set_target(self.high, F::from_canonical_u64(high)); out_buffer.set_target(self.high, F::from_canonical_u64(high))
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -63,8 +63,8 @@ mod tests {
let truet = builder._true(); let truet = builder._true();
let falset = builder._false(); let falset = builder._false();
pw.set_extension_target(xt, x); pw.set_extension_target(xt, x)?;
pw.set_extension_target(yt, y); pw.set_extension_target(yt, y)?;
let should_be_x = builder.select_ext(truet, xt, yt); let should_be_x = builder.select_ext(truet, xt, yt);
let should_be_y = builder.select_ext(falset, xt, yt); let should_be_y = builder.select_ext(falset, xt, yt);

View File

@ -2,6 +2,7 @@
use alloc::{format, string::String, vec, vec::Vec}; use alloc::{format, string::String, vec, vec::Vec};
use core::borrow::Borrow; use core::borrow::Borrow;
use anyhow::Result;
use itertools::Itertools; use itertools::Itertools;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
@ -97,7 +98,11 @@ impl<F: RichField + Extendable<D>, const B: usize, const D: usize> SimpleGenerat
self.limbs.iter().map(|b| b.target).collect() self.limbs.iter().map(|b| b.target).collect()
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let sum = self let sum = self
.limbs .limbs
.iter() .iter()
@ -107,7 +112,7 @@ impl<F: RichField + Extendable<D>, const B: usize, const D: usize> SimpleGenerat
acc * F::from_canonical_usize(B) + F::from_bool(limb) acc * F::from_canonical_usize(B) + F::from_bool(limb)
}); });
out_buffer.set_target(Target::wire(self.row, BaseSumGate::<B>::WIRE_SUM), sum); out_buffer.set_target(Target::wire(self.row, BaseSumGate::<B>::WIRE_SUM), sum)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -5,6 +5,8 @@ use alloc::{
vec::Vec, vec::Vec,
}; };
use anyhow::Result;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
use crate::gates::base_sum::BaseSumGate; use crate::gates::base_sum::BaseSumGate;
use crate::hash::hash_types::RichField; use crate::hash::hash_types::RichField;
@ -75,12 +77,16 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Spl
vec![self.integer] vec![self.integer]
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let mut integer_value = witness.get_target(self.integer).to_canonical_u64(); let mut integer_value = witness.get_target(self.integer).to_canonical_u64();
for &b in &self.bits { for &b in &self.bits {
let b_value = integer_value & 1; let b_value = integer_value & 1;
out_buffer.set_target(b, F::from_canonical_u64(b_value)); out_buffer.set_target(b, F::from_canonical_u64(b_value))?;
integer_value >>= 1; integer_value >>= 1;
} }
@ -88,6 +94,8 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Spl
integer_value, 0, integer_value, 0,
"Integer too large to fit in given number of bits" "Integer too large to fit in given number of bits"
); );
Ok(())
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
@ -118,7 +126,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Wir
vec![self.integer] vec![self.integer]
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let mut integer_value = witness.get_target(self.integer).to_canonical_u64(); let mut integer_value = witness.get_target(self.integer).to_canonical_u64();
for &gate in &self.gates { for &gate in &self.gates {
@ -134,7 +146,7 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Wir
integer_value = 0; integer_value = 0;
}; };
out_buffer.set_target(sum, F::from_canonical_u64(truncated_value)); out_buffer.set_target(sum, F::from_canonical_u64(truncated_value))?;
} }
debug_assert_eq!( debug_assert_eq!(
@ -143,6 +155,8 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Wir
"Integer too large to fit in {} many `BaseSumGate`s", "Integer too large to fit in {} many `BaseSumGate`s",
self.gates.len() self.gates.len()
); );
Ok(())
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -5,6 +5,8 @@ use alloc::{
vec::Vec, vec::Vec,
}; };
use anyhow::Result;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
use crate::field::packed::PackedField; use crate::field::packed::PackedField;
use crate::gates::gate::Gate; use crate::gates::gate::Gate;
@ -209,7 +211,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
.collect() .collect()
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let get_wire = |wire: usize| -> F { witness.get_target(Target::wire(self.row, wire)) }; let get_wire = |wire: usize| -> F { witness.get_target(Target::wire(self.row, wire)) };
let multiplicand_0 = get_wire(ArithmeticGate::wire_ith_multiplicand_0(self.i)); let multiplicand_0 = get_wire(ArithmeticGate::wire_ith_multiplicand_0(self.i));

View File

@ -6,6 +6,8 @@ use alloc::{
}; };
use core::ops::Range; use core::ops::Range;
use anyhow::Result;
use crate::field::extension::{Extendable, FieldExtension}; use crate::field::extension::{Extendable, FieldExtension};
use crate::gates::gate::Gate; use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer; use crate::gates::util::StridedConstraintConsumer;
@ -192,7 +194,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
.collect() .collect()
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let extract_extension = |range: Range<usize>| -> F::Extension { let extract_extension = |range: Range<usize>| -> F::Extension {
let t = ExtensionTarget::from_range(self.row, range); let t = ExtensionTarget::from_range(self.row, range);
witness.get_extension_target(t) witness.get_extension_target(t)

View File

@ -2,6 +2,8 @@
use alloc::{format, string::String, vec, vec::Vec}; use alloc::{format, string::String, vec, vec::Vec};
use core::ops::Range; use core::ops::Range;
use anyhow::Result;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
use crate::field::packed::PackedField; use crate::field::packed::PackedField;
use crate::field::types::{Field, Field64}; use crate::field::types::{Field, Field64};
@ -185,7 +187,11 @@ impl<F: RichField + Extendable<D>, const B: usize, const D: usize> SimpleGenerat
vec![Target::wire(self.row, BaseSumGate::<B>::WIRE_SUM)] vec![Target::wire(self.row, BaseSumGate::<B>::WIRE_SUM)]
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let sum_value = witness let sum_value = witness
.get_target(Target::wire(self.row, BaseSumGate::<B>::WIRE_SUM)) .get_target(Target::wire(self.row, BaseSumGate::<B>::WIRE_SUM))
.to_canonical_u64() as usize; .to_canonical_u64() as usize;
@ -206,8 +212,10 @@ impl<F: RichField + Extendable<D>, const B: usize, const D: usize> SimpleGenerat
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for (b, b_value) in limbs.zip(limbs_value) { for (b, b_value) in limbs.zip(limbs_value) {
out_buffer.set_target(b, b_value); out_buffer.set_target(b, b_value)?;
} }
Ok(())
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -8,6 +8,8 @@ use alloc::{
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ops::Range; use core::ops::Range;
use anyhow::Result;
use crate::field::extension::algebra::ExtensionAlgebra; use crate::field::extension::algebra::ExtensionAlgebra;
use crate::field::extension::{Extendable, FieldExtension, OEF}; use crate::field::extension::{Extendable, FieldExtension, OEF};
use crate::field::interpolation::barycentric_weights; use crate::field::interpolation::barycentric_weights;
@ -442,7 +444,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
deps deps
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let local_wire = |column| Wire { let local_wire = |column| Wire {
row: self.row, row: self.row,
column, column,
@ -465,7 +471,7 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
out_buffer.set_ext_wires( out_buffer.set_ext_wires(
self.gate.wires_shifted_evaluation_point().map(local_wire), self.gate.wires_shifted_evaluation_point().map(local_wire),
shifted_evaluation_point, shifted_evaluation_point,
); )?;
let domain = &self.interpolation_domain; let domain = &self.interpolation_domain;
let values = (0..self.gate.num_points()) let values = (0..self.gate.num_points())
@ -485,8 +491,8 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
for i in 0..self.gate.num_intermediates() { for i in 0..self.gate.num_intermediates() {
let intermediate_eval_wires = self.gate.wires_intermediate_eval(i).map(local_wire); let intermediate_eval_wires = self.gate.wires_intermediate_eval(i).map(local_wire);
let intermediate_prod_wires = self.gate.wires_intermediate_prod(i).map(local_wire); let intermediate_prod_wires = self.gate.wires_intermediate_prod(i).map(local_wire);
out_buffer.set_ext_wires(intermediate_eval_wires, computed_eval); out_buffer.set_ext_wires(intermediate_eval_wires, computed_eval)?;
out_buffer.set_ext_wires(intermediate_prod_wires, computed_prod); out_buffer.set_ext_wires(intermediate_prod_wires, computed_prod)?;
let start_index = 1 + (degree - 1) * (i + 1); let start_index = 1 + (degree - 1) * (i + 1);
let end_index = (start_index + degree - 1).min(self.gate.num_points()); let end_index = (start_index + degree - 1).min(self.gate.num_points());
@ -501,7 +507,7 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
} }
let evaluation_value_wires = self.gate.wires_evaluation_value().map(local_wire); let evaluation_value_wires = self.gate.wires_evaluation_value().map(local_wire);
out_buffer.set_ext_wires(evaluation_value_wires, computed_eval); out_buffer.set_ext_wires(evaluation_value_wires, computed_eval)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -7,6 +7,8 @@ use alloc::{
}; };
use core::marker::PhantomData; use core::marker::PhantomData;
use anyhow::Result;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
use crate::field::ops::Square; use crate::field::ops::Square;
use crate::field::packed::PackedField; use crate::field::packed::PackedField;
@ -265,7 +267,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
deps deps
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let local_wire = |column| Wire { let local_wire = |column| Wire {
row: self.row, row: self.row,
column, column,
@ -292,11 +298,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
for i in 0..num_power_bits { for i in 0..num_power_bits {
let intermediate_value_wire = local_wire(self.gate.wire_intermediate_value(i)); let intermediate_value_wire = local_wire(self.gate.wire_intermediate_value(i));
out_buffer.set_wire(intermediate_value_wire, intermediate_values[i]); out_buffer.set_wire(intermediate_value_wire, intermediate_values[i])?;
} }
let output_wire = local_wire(self.gate.wire_output()); let output_wire = local_wire(self.gate.wire_output());
out_buffer.set_wire(output_wire, intermediate_values[num_power_bits - 1]); out_buffer.set_wire(output_wire, intermediate_values[num_power_bits - 1])
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -137,10 +137,10 @@ pub fn test_eval_fns<
let wires_t = builder.add_virtual_extension_targets(wires.len()); let wires_t = builder.add_virtual_extension_targets(wires.len());
let constants_t = builder.add_virtual_extension_targets(constants.len()); let constants_t = builder.add_virtual_extension_targets(constants.len());
pw.set_extension_targets(&wires_t, &wires); pw.set_extension_targets(&wires_t, &wires)?;
pw.set_extension_targets(&constants_t, &constants); pw.set_extension_targets(&constants_t, &constants)?;
let public_inputs_hash_t = builder.add_virtual_hash(); let public_inputs_hash_t = builder.add_virtual_hash();
pw.set_hash_target(public_inputs_hash_t, public_inputs_hash); pw.set_hash_target(public_inputs_hash_t, public_inputs_hash)?;
let vars = EvaluationVars { let vars = EvaluationVars {
local_constants: &constants, local_constants: &constants,
@ -155,7 +155,7 @@ pub fn test_eval_fns<
public_inputs_hash: &public_inputs_hash_t, public_inputs_hash: &public_inputs_hash_t,
}; };
let evals_t = gate.eval_unfiltered_circuit(&mut builder, vars_t); let evals_t = gate.eval_unfiltered_circuit(&mut builder, vars_t);
pw.set_extension_targets(&evals_t, &evals); pw.set_extension_targets(&evals_t, &evals)?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let proof = data.prove(pw)?; let proof = data.prove(pw)?;

View File

@ -6,6 +6,7 @@ use alloc::{
vec::Vec, vec::Vec,
}; };
use anyhow::{anyhow, Result};
use itertools::Itertools; use itertools::Itertools;
use keccak_hash::keccak; use keccak_hash::keccak;
@ -188,7 +189,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Loo
)] )]
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let get_wire = |wire: usize| -> F { witness.get_target(Target::wire(self.row, wire)) }; let get_wire = |wire: usize| -> F { witness.get_target(Target::wire(self.row, wire)) };
let input_val = get_wire(LookupGate::wire_ith_looking_inp(self.slot_nb)); let input_val = get_wire(LookupGate::wire_ith_looking_inp(self.slot_nb));
@ -197,7 +202,7 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Loo
let output_val = F::from_canonical_u16(output); let output_val = F::from_canonical_u16(output);
let out_wire = Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb)); let out_wire = Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb));
out_buffer.set_target(out_wire, output_val); out_buffer.set_target(out_wire, output_val)
} else { } else {
for (input, output) in self.lut.iter() { for (input, output) in self.lut.iter() {
if input_val == F::from_canonical_u16(*input) { if input_val == F::from_canonical_u16(*input) {
@ -205,12 +210,13 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Loo
let out_wire = let out_wire =
Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb)); Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb));
out_buffer.set_target(out_wire, output_val); out_buffer.set_target(out_wire, output_val)?;
return;
return Ok(());
} }
} }
panic!("Incorrect input value provided"); Err(anyhow!("Incorrect input value provided"))
}; }
} }
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -9,6 +9,7 @@ use alloc::{
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::sync::Arc; use std::sync::Arc;
use anyhow::Result;
use itertools::Itertools; use itertools::Itertools;
use keccak_hash::keccak; use keccak_hash::keccak;
@ -205,7 +206,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Loo
vec![] vec![]
} }
fn run_once(&self, _witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
_witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let first_row = self.last_lut_row + self.lut.len().div_ceil(self.num_slots) - 1; let first_row = self.last_lut_row + self.lut.len().div_ceil(self.num_slots) - 1;
let slot = (first_row - self.row) * self.num_slots + self.slot_nb; let slot = (first_row - self.row) * self.num_slots + self.slot_nb;
@ -216,12 +221,12 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Loo
if slot < self.lut.len() { if slot < self.lut.len() {
let (input, output) = self.lut[slot]; let (input, output) = self.lut[slot];
out_buffer.set_target(slot_input_target, F::from_canonical_usize(input as usize)); out_buffer.set_target(slot_input_target, F::from_canonical_usize(input as usize))?;
out_buffer.set_target(slot_output_target, F::from_canonical_usize(output as usize)); out_buffer.set_target(slot_output_target, F::from_canonical_usize(output as usize))
} else { } else {
// Pad with zeros. // Pad with zeros.
out_buffer.set_target(slot_input_target, F::ZERO); out_buffer.set_target(slot_input_target, F::ZERO)?;
out_buffer.set_target(slot_output_target, F::ZERO); out_buffer.set_target(slot_output_target, F::ZERO)
} }
} }

View File

@ -6,6 +6,8 @@ use alloc::{
}; };
use core::ops::Range; use core::ops::Range;
use anyhow::Result;
use crate::field::extension::{Extendable, FieldExtension}; use crate::field::extension::{Extendable, FieldExtension};
use crate::gates::gate::Gate; use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer; use crate::gates::util::StridedConstraintConsumer;
@ -175,7 +177,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
.collect() .collect()
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let extract_extension = |range: Range<usize>| -> F::Extension { let extract_extension = |range: Range<usize>| -> F::Extension {
let t = ExtensionTarget::from_range(self.row, range); let t = ExtensionTarget::from_range(self.row, range);
witness.get_extension_target(t) witness.get_extension_target(t)

View File

@ -7,6 +7,8 @@ use alloc::{
}; };
use core::marker::PhantomData; use core::marker::PhantomData;
use anyhow::Result;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
use crate::field::types::Field; use crate::field::types::Field;
use crate::gates::gate::Gate; use crate::gates::gate::Gate;
@ -439,7 +441,11 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F,
.collect() .collect()
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let local_wire = |column| Wire { let local_wire = |column| Wire {
row: self.row, row: self.row,
column, column,
@ -454,7 +460,7 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F,
for i in 0..4 { for i in 0..4 {
let delta_i = swap_value * (state[i + 4] - state[i]); let delta_i = swap_value * (state[i + 4] - state[i]);
out_buffer.set_wire(local_wire(PoseidonGate::<F, D>::wire_delta(i)), delta_i); out_buffer.set_wire(local_wire(PoseidonGate::<F, D>::wire_delta(i)), delta_i)?;
} }
if swap_value == F::ONE { if swap_value == F::ONE {
@ -473,7 +479,7 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F,
out_buffer.set_wire( out_buffer.set_wire(
local_wire(PoseidonGate::<F, D>::wire_full_sbox_0(r, i)), local_wire(PoseidonGate::<F, D>::wire_full_sbox_0(r, i)),
state[i], state[i],
); )?;
} }
} }
<F as Poseidon>::sbox_layer_field(&mut state); <F as Poseidon>::sbox_layer_field(&mut state);
@ -487,7 +493,7 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F,
out_buffer.set_wire( out_buffer.set_wire(
local_wire(PoseidonGate::<F, D>::wire_partial_sbox(r)), local_wire(PoseidonGate::<F, D>::wire_partial_sbox(r)),
state[0], state[0],
); )?;
state[0] = <F as Poseidon>::sbox_monomial(state[0]); state[0] = <F as Poseidon>::sbox_monomial(state[0]);
state[0] += F::from_canonical_u64(<F as Poseidon>::FAST_PARTIAL_ROUND_CONSTANTS[r]); state[0] += F::from_canonical_u64(<F as Poseidon>::FAST_PARTIAL_ROUND_CONSTANTS[r]);
state = <F as Poseidon>::mds_partial_layer_fast_field(&state, r); state = <F as Poseidon>::mds_partial_layer_fast_field(&state, r);
@ -497,7 +503,7 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F,
poseidon::N_PARTIAL_ROUNDS - 1, poseidon::N_PARTIAL_ROUNDS - 1,
)), )),
state[0], state[0],
); )?;
state[0] = <F as Poseidon>::sbox_monomial(state[0]); state[0] = <F as Poseidon>::sbox_monomial(state[0]);
state = state =
<F as Poseidon>::mds_partial_layer_fast_field(&state, poseidon::N_PARTIAL_ROUNDS - 1); <F as Poseidon>::mds_partial_layer_fast_field(&state, poseidon::N_PARTIAL_ROUNDS - 1);
@ -509,7 +515,7 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F,
out_buffer.set_wire( out_buffer.set_wire(
local_wire(PoseidonGate::<F, D>::wire_full_sbox_1(r, i)), local_wire(PoseidonGate::<F, D>::wire_full_sbox_1(r, i)),
state[i], state[i],
); )?;
} }
<F as Poseidon>::sbox_layer_field(&mut state); <F as Poseidon>::sbox_layer_field(&mut state);
state = <F as Poseidon>::mds_layer_field(&state); state = <F as Poseidon>::mds_layer_field(&state);
@ -517,8 +523,10 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F,
} }
for i in 0..SPONGE_WIDTH { for i in 0..SPONGE_WIDTH {
out_buffer.set_wire(local_wire(PoseidonGate::<F, D>::wire_output(i)), state[i]); out_buffer.set_wire(local_wire(PoseidonGate::<F, D>::wire_output(i)), state[i])?
} }
Ok(())
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
@ -589,24 +597,29 @@ mod tests {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut inputs = PartialWitness::new(); let mut inputs = PartialWitness::new();
inputs.set_wire( inputs
Wire { .set_wire(
row,
column: Gate::WIRE_SWAP,
},
F::ZERO,
);
for i in 0..SPONGE_WIDTH {
inputs.set_wire(
Wire { Wire {
row, row,
column: Gate::wire_input(i), column: Gate::WIRE_SWAP,
}, },
permutation_inputs[i], F::ZERO,
); )
.unwrap();
for i in 0..SPONGE_WIDTH {
inputs
.set_wire(
Wire {
row,
column: Gate::wire_input(i),
},
permutation_inputs[i],
)
.unwrap();
} }
let witness = generate_partial_witness(inputs, &circuit.prover_only, &circuit.common); let witness =
generate_partial_witness(inputs, &circuit.prover_only, &circuit.common).unwrap();
let expected_outputs: [F; SPONGE_WIDTH] = let expected_outputs: [F; SPONGE_WIDTH] =
F::poseidon(permutation_inputs.try_into().unwrap()); F::poseidon(permutation_inputs.try_into().unwrap());

View File

@ -8,6 +8,8 @@ use alloc::{
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ops::Range; use core::ops::Range;
use anyhow::Result;
use crate::field::extension::algebra::ExtensionAlgebra; use crate::field::extension::algebra::ExtensionAlgebra;
use crate::field::extension::{Extendable, FieldExtension}; use crate::field::extension::{Extendable, FieldExtension};
use crate::field::types::Field; use crate::field::types::Field;
@ -238,7 +240,11 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F,
.collect() .collect()
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let get_local_get_target = |wire_range| ExtensionTarget::from_range(self.row, wire_range); let get_local_get_target = |wire_range| ExtensionTarget::from_range(self.row, wire_range);
let get_local_ext = let get_local_ext =
|wire_range| witness.get_extension_target(get_local_get_target(wire_range)); |wire_range| witness.get_extension_target(get_local_get_target(wire_range));
@ -255,8 +261,10 @@ impl<F: RichField + Extendable<D> + Poseidon, const D: usize> SimpleGenerator<F,
out_buffer.set_extension_target( out_buffer.set_extension_target(
get_local_get_target(PoseidonMdsGate::<F, D>::wires_output(i)), get_local_get_target(PoseidonMdsGate::<F, D>::wires_output(i)),
out, out,
); )?;
} }
Ok(())
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -7,6 +7,7 @@ use alloc::{
}; };
use core::marker::PhantomData; use core::marker::PhantomData;
use anyhow::Result;
use itertools::Itertools; use itertools::Itertools;
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
@ -366,7 +367,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
deps deps
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let local_wire = |column| Wire { let local_wire = |column| Wire {
row: self.row, row: self.row,
column, column,
@ -390,12 +395,14 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
set_local_wire( set_local_wire(
self.gate.wire_claimed_element(copy), self.gate.wire_claimed_element(copy),
get_local_wire(self.gate.wire_list_item(access_index, copy)), get_local_wire(self.gate.wire_list_item(access_index, copy)),
); )?;
for i in 0..self.gate.bits { for i in 0..self.gate.bits {
let bit = F::from_bool(((access_index >> i) & 1) != 0); let bit = F::from_bool(((access_index >> i) & 1) != 0);
set_local_wire(self.gate.wire_bit(i, copy), bit); set_local_wire(self.gate.wire_bit(i, copy), bit)?;
} }
Ok(())
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -7,6 +7,8 @@ use alloc::{
}; };
use core::ops::Range; use core::ops::Range;
use anyhow::Result;
use crate::field::extension::{Extendable, FieldExtension}; use crate::field::extension::{Extendable, FieldExtension};
use crate::gates::gate::Gate; use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer; use crate::gates::util::StridedConstraintConsumer;
@ -201,7 +203,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Red
.collect() .collect()
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let extract_extension = |range: Range<usize>| -> F::Extension { let extract_extension = |range: Range<usize>| -> F::Extension {
let t = ExtensionTarget::from_range(self.row, range); let t = ExtensionTarget::from_range(self.row, range);
witness.get_extension_target(t) witness.get_extension_target(t)
@ -224,10 +230,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Red
let mut acc = old_acc; let mut acc = old_acc;
for i in 0..self.gate.num_coeffs { for i in 0..self.gate.num_coeffs {
let computed_acc = acc * alpha + coeffs[i].into(); let computed_acc = acc * alpha + coeffs[i].into();
out_buffer.set_extension_target(accs[i], computed_acc); out_buffer.set_extension_target(accs[i], computed_acc)?;
acc = computed_acc; acc = computed_acc;
} }
out_buffer.set_extension_target(output, acc);
out_buffer.set_extension_target(output, acc)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -7,6 +7,8 @@ use alloc::{
}; };
use core::ops::Range; use core::ops::Range;
use anyhow::Result;
use crate::field::extension::{Extendable, FieldExtension}; use crate::field::extension::{Extendable, FieldExtension};
use crate::gates::gate::Gate; use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer; use crate::gates::util::StridedConstraintConsumer;
@ -201,7 +203,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Red
.collect() .collect()
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let local_extension = |range: Range<usize>| -> F::Extension { let local_extension = |range: Range<usize>| -> F::Extension {
let t = ExtensionTarget::from_range(self.row, range); let t = ExtensionTarget::from_range(self.row, range);
witness.get_extension_target(t) witness.get_extension_target(t)
@ -219,9 +225,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Red
let mut acc = old_acc; let mut acc = old_acc;
for i in 0..self.gate.num_coeffs { for i in 0..self.gate.num_coeffs {
let computed_acc = acc * alpha + coeffs[i]; let computed_acc = acc * alpha + coeffs[i];
out_buffer.set_extension_target(accs[i], computed_acc); out_buffer.set_extension_target(accs[i], computed_acc)?;
acc = computed_acc; acc = computed_acc;
} }
Ok(())
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -292,18 +292,18 @@ mod tests {
siblings: builder.add_virtual_hashes(proof.siblings.len()), siblings: builder.add_virtual_hashes(proof.siblings.len()),
}; };
for i in 0..proof.siblings.len() { for i in 0..proof.siblings.len() {
pw.set_hash_target(proof_t.siblings[i], proof.siblings[i]); pw.set_hash_target(proof_t.siblings[i], proof.siblings[i])?;
} }
let cap_t = builder.add_virtual_cap(cap_height); let cap_t = builder.add_virtual_cap(cap_height);
pw.set_cap_target(&cap_t, &tree.cap); pw.set_cap_target(&cap_t, &tree.cap)?;
let i_c = builder.constant(F::from_canonical_usize(i)); let i_c = builder.constant(F::from_canonical_usize(i));
let i_bits = builder.split_le(i_c, log_n); let i_bits = builder.split_le(i_c, log_n);
let data = builder.add_virtual_targets(tree.leaves[i].len()); let data = builder.add_virtual_targets(tree.leaves[i].len());
for j in 0..data.len() { for j in 0..data.len() {
pw.set_target(data[j], tree.leaves[i][j]); pw.set_target(data[j], tree.leaves[i][j])?;
} }
builder.verify_merkle_proof_to_cap::<<C as GenericConfig<D>>::InnerHasher>( builder.verify_merkle_proof_to_cap::<<C as GenericConfig<D>>::InnerHasher>(

View File

@ -365,7 +365,8 @@ mod tests {
} }
let circuit = builder.build::<C>(); let circuit = builder.build::<C>();
let inputs = PartialWitness::new(); let inputs = PartialWitness::new();
let witness = generate_partial_witness(inputs, &circuit.prover_only, &circuit.common); let witness =
generate_partial_witness(inputs, &circuit.prover_only, &circuit.common).unwrap();
let recursive_output_values_per_round: Vec<Vec<F>> = recursive_outputs_per_round let recursive_output_values_per_round: Vec<Vec<F>> = recursive_outputs_per_round
.iter() .iter()
.map(|outputs| witness.get_targets(outputs)) .map(|outputs| witness.get_targets(outputs))

View File

@ -8,6 +8,8 @@ use alloc::{
use core::fmt::Debug; use core::fmt::Debug;
use core::marker::PhantomData; use core::marker::PhantomData;
use anyhow::{anyhow, Result};
use crate::field::extension::Extendable; use crate::field::extension::Extendable;
use crate::field::types::Field; use crate::field::types::Field;
use crate::hash::hash_types::RichField; use crate::hash::hash_types::RichField;
@ -30,7 +32,7 @@ pub fn generate_partial_witness<
inputs: PartialWitness<F>, inputs: PartialWitness<F>,
prover_data: &'a ProverOnlyCircuitData<F, C, D>, prover_data: &'a ProverOnlyCircuitData<F, C, D>,
common_data: &'a CommonCircuitData<F, D>, common_data: &'a CommonCircuitData<F, D>,
) -> PartitionWitness<'a, F> { ) -> Result<PartitionWitness<'a, F>> {
let config = &common_data.config; let config = &common_data.config;
let generators = &prover_data.generators; let generators = &prover_data.generators;
let generator_indices_by_watches = &prover_data.generator_indices_by_watches; let generator_indices_by_watches = &prover_data.generator_indices_by_watches;
@ -42,7 +44,7 @@ pub fn generate_partial_witness<
); );
for (t, v) in inputs.target_values.into_iter() { for (t, v) in inputs.target_values.into_iter() {
witness.set_target(t, v); witness.set_target(t, v)?;
} }
// Build a list of "pending" generators which are queued to be run. Initially, all generators // Build a list of "pending" generators which are queued to be run. Initially, all generators
@ -72,10 +74,11 @@ pub fn generate_partial_witness<
// Merge any generated values into our witness, and get a list of newly-populated // Merge any generated values into our witness, and get a list of newly-populated
// targets' representatives. // targets' representatives.
let new_target_reps = buffer let mut new_target_reps = Vec::with_capacity(buffer.target_values.len());
.target_values for (t, v) in buffer.target_values.drain(..) {
.drain(..) let reps = witness.set_target_returning_rep(t, v)?;
.flat_map(|(t, v)| witness.set_target_returning_rep(t, v)); new_target_reps.extend(reps);
}
// Enqueue unfinished generators that were watching one of the newly populated targets. // Enqueue unfinished generators that were watching one of the newly populated targets.
for watch in new_target_reps { for watch in new_target_reps {
@ -93,13 +96,11 @@ pub fn generate_partial_witness<
pending_generator_indices = next_pending_generator_indices; pending_generator_indices = next_pending_generator_indices;
} }
assert_eq!( if remaining_generators != 0 {
remaining_generators, 0, return Err(anyhow!("{} generators weren't run", remaining_generators));
"{} generators weren't run", }
remaining_generators,
);
witness Ok(witness)
} }
/// A generator participates in the generation of the witness. /// A generator participates in the generation of the witness.
@ -163,8 +164,10 @@ impl<F: Field> From<Vec<(Target, F)>> for GeneratedValues<F> {
} }
impl<F: Field> WitnessWrite<F> for GeneratedValues<F> { impl<F: Field> WitnessWrite<F> for GeneratedValues<F> {
fn set_target(&mut self, target: Target, value: F) { fn set_target(&mut self, target: Target, value: F) -> Result<()> {
self.target_values.push((target, value)); self.target_values.push((target, value));
Ok(())
} }
} }
@ -188,13 +191,14 @@ impl<F: Field> GeneratedValues<F> {
pub fn singleton_extension_target<const D: usize>( pub fn singleton_extension_target<const D: usize>(
et: ExtensionTarget<D>, et: ExtensionTarget<D>,
value: F::Extension, value: F::Extension,
) -> Self ) -> Result<Self>
where where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
{ {
let mut witness = Self::with_capacity(D); let mut witness = Self::with_capacity(D);
witness.set_extension_target(et, value); witness.set_extension_target(et, value)?;
witness
Ok(witness)
} }
} }
@ -206,7 +210,11 @@ pub trait SimpleGenerator<F: RichField + Extendable<D>, const D: usize>:
fn dependencies(&self) -> Vec<Target>; fn dependencies(&self) -> Vec<Target>;
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>); fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()>;
fn adapter(self) -> SimpleGeneratorAdapter<F, Self, D> fn adapter(self) -> SimpleGeneratorAdapter<F, Self, D>
where where
@ -248,8 +256,7 @@ impl<F: RichField + Extendable<D>, SG: SimpleGenerator<F, D>, const D: usize> Wi
fn run(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool { fn run(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) -> bool {
if witness.contains_all(&self.inner.dependencies()) { if witness.contains_all(&self.inner.dependencies()) {
self.inner.run_once(witness, out_buffer); self.inner.run_once(witness, out_buffer).is_ok()
true
} else { } else {
false false
} }
@ -283,9 +290,13 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Cop
vec![self.src] vec![self.src]
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let value = witness.get_target(self.src); let value = witness.get_target(self.src);
out_buffer.set_target(self.dst, value); out_buffer.set_target(self.dst, value)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
@ -315,9 +326,13 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Ran
Vec::new() Vec::new()
} }
fn run_once(&self, _witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
_witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let random_value = F::rand(); let random_value = F::rand();
out_buffer.set_target(self.target, random_value); out_buffer.set_target(self.target, random_value)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
@ -346,7 +361,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Non
vec![self.to_test] vec![self.to_test]
} }
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
&self,
witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
let to_test_value = witness.get_target(self.to_test); let to_test_value = witness.get_target(self.to_test);
let dummy_value = if to_test_value == F::ZERO { let dummy_value = if to_test_value == F::ZERO {
@ -355,7 +374,7 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Non
to_test_value.inverse() to_test_value.inverse()
}; };
out_buffer.set_target(self.dummy, dummy_value); out_buffer.set_target(self.dummy, dummy_value)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
@ -394,8 +413,12 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Con
vec![] vec![]
} }
fn run_once(&self, _witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
out_buffer.set_target(Target::wire(self.row, self.wire_index), self.constant); &self,
_witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
out_buffer.set_target(Target::wire(self.row, self.wire_index), self.constant)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -1,6 +1,8 @@
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec}; use alloc::{vec, vec::Vec};
use core::iter::zip;
use anyhow::{anyhow, Result};
use hashbrown::HashMap; use hashbrown::HashMap;
use itertools::{zip_eq, Itertools}; use itertools::{zip_eq, Itertools};
@ -18,52 +20,67 @@ use crate::plonk::config::{AlgebraicHasher, GenericConfig};
use crate::plonk::proof::{Proof, ProofTarget, ProofWithPublicInputs, ProofWithPublicInputsTarget}; use crate::plonk::proof::{Proof, ProofTarget, ProofWithPublicInputs, ProofWithPublicInputsTarget};
pub trait WitnessWrite<F: Field> { pub trait WitnessWrite<F: Field> {
fn set_target(&mut self, target: Target, value: F); fn set_target(&mut self, target: Target, value: F) -> Result<()>;
fn set_hash_target(&mut self, ht: HashOutTarget, value: HashOut<F>) { fn set_hash_target(&mut self, ht: HashOutTarget, value: HashOut<F>) -> Result<()> {
ht.elements for (t, x) in zip(ht.elements, value.elements) {
.iter() self.set_target(t, x)?;
.zip(value.elements) }
.for_each(|(&t, x)| self.set_target(t, x));
Ok(())
} }
fn set_cap_target<H: AlgebraicHasher<F>>( fn set_cap_target<H: AlgebraicHasher<F>>(
&mut self, &mut self,
ct: &MerkleCapTarget, ct: &MerkleCapTarget,
value: &MerkleCap<F, H>, value: &MerkleCap<F, H>,
) where ) -> Result<()>
where
F: RichField, F: RichField,
{ {
for (ht, h) in ct.0.iter().zip(&value.0) { for (ht, h) in ct.0.iter().zip(&value.0) {
self.set_hash_target(*ht, *h); self.set_hash_target(*ht, *h)?;
} }
Ok(())
} }
fn set_extension_target<const D: usize>(&mut self, et: ExtensionTarget<D>, value: F::Extension) fn set_extension_target<const D: usize>(
&mut self,
et: ExtensionTarget<D>,
value: F::Extension,
) -> Result<()>
where where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
{ {
self.set_target_arr(&et.0, &value.to_basefield_array()); self.set_target_arr(&et.0, &value.to_basefield_array())
} }
fn set_target_arr(&mut self, targets: &[Target], values: &[F]) { fn set_target_arr(&mut self, targets: &[Target], values: &[F]) -> Result<()> {
zip_eq(targets, values).for_each(|(&target, &value)| self.set_target(target, value)); for (&target, &value) in zip_eq(targets, values) {
self.set_target(target, value)?;
}
Ok(())
} }
fn set_extension_targets<const D: usize>( fn set_extension_targets<const D: usize>(
&mut self, &mut self,
ets: &[ExtensionTarget<D>], ets: &[ExtensionTarget<D>],
values: &[F::Extension], values: &[F::Extension],
) where ) -> Result<()>
where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
{ {
debug_assert_eq!(ets.len(), values.len()); debug_assert_eq!(ets.len(), values.len());
ets.iter() for (&et, &v) in zip(ets, values) {
.zip(values) self.set_extension_target(et, v)?;
.for_each(|(&et, &v)| self.set_extension_target(et, v)); }
Ok(())
} }
fn set_bool_target(&mut self, target: BoolTarget, value: bool) { fn set_bool_target(&mut self, target: BoolTarget, value: bool) -> Result<()> {
self.set_target(target.target, F::from_bool(value)) self.set_target(target.target, F::from_bool(value))
} }
@ -73,7 +90,8 @@ pub trait WitnessWrite<F: Field> {
&mut self, &mut self,
proof_with_pis_target: &ProofWithPublicInputsTarget<D>, proof_with_pis_target: &ProofWithPublicInputsTarget<D>,
proof_with_pis: &ProofWithPublicInputs<F, C, D>, proof_with_pis: &ProofWithPublicInputs<F, C, D>,
) where ) -> Result<()>
where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
C::Hasher: AlgebraicHasher<F>, C::Hasher: AlgebraicHasher<F>,
{ {
@ -88,10 +106,10 @@ pub trait WitnessWrite<F: Field> {
// Set public inputs. // Set public inputs.
for (&pi_t, &pi) in pi_targets.iter().zip_eq(public_inputs) { for (&pi_t, &pi) in pi_targets.iter().zip_eq(public_inputs) {
self.set_target(pi_t, pi); self.set_target(pi_t, pi)?;
} }
self.set_proof_target(pt, proof); self.set_proof_target(pt, proof)
} }
/// Set the targets in a `ProofTarget` to their corresponding values in a `Proof`. /// Set the targets in a `ProofTarget` to their corresponding values in a `Proof`.
@ -99,30 +117,32 @@ pub trait WitnessWrite<F: Field> {
&mut self, &mut self,
proof_target: &ProofTarget<D>, proof_target: &ProofTarget<D>,
proof: &Proof<F, C, D>, proof: &Proof<F, C, D>,
) where ) -> Result<()>
where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
C::Hasher: AlgebraicHasher<F>, C::Hasher: AlgebraicHasher<F>,
{ {
self.set_cap_target(&proof_target.wires_cap, &proof.wires_cap); self.set_cap_target(&proof_target.wires_cap, &proof.wires_cap)?;
self.set_cap_target( self.set_cap_target(
&proof_target.plonk_zs_partial_products_cap, &proof_target.plonk_zs_partial_products_cap,
&proof.plonk_zs_partial_products_cap, &proof.plonk_zs_partial_products_cap,
); )?;
self.set_cap_target(&proof_target.quotient_polys_cap, &proof.quotient_polys_cap); self.set_cap_target(&proof_target.quotient_polys_cap, &proof.quotient_polys_cap)?;
self.set_fri_openings( self.set_fri_openings(
&proof_target.openings.to_fri_openings(), &proof_target.openings.to_fri_openings(),
&proof.openings.to_fri_openings(), &proof.openings.to_fri_openings(),
); )?;
set_fri_proof_target(self, &proof_target.opening_proof, &proof.opening_proof); set_fri_proof_target(self, &proof_target.opening_proof, &proof.opening_proof)
} }
fn set_fri_openings<const D: usize>( fn set_fri_openings<const D: usize>(
&mut self, &mut self,
fri_openings_target: &FriOpeningsTarget<D>, fri_openings_target: &FriOpeningsTarget<D>,
fri_openings: &FriOpenings<F, D>, fri_openings: &FriOpenings<F, D>,
) where ) -> Result<()>
where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
{ {
for (batch_target, batch) in fri_openings_target for (batch_target, batch) in fri_openings_target
@ -130,48 +150,55 @@ pub trait WitnessWrite<F: Field> {
.iter() .iter()
.zip_eq(&fri_openings.batches) .zip_eq(&fri_openings.batches)
{ {
self.set_extension_targets(&batch_target.values, &batch.values); self.set_extension_targets(&batch_target.values, &batch.values)?;
} }
Ok(())
} }
fn set_verifier_data_target<C: GenericConfig<D, F = F>, const D: usize>( fn set_verifier_data_target<C: GenericConfig<D, F = F>, const D: usize>(
&mut self, &mut self,
vdt: &VerifierCircuitTarget, vdt: &VerifierCircuitTarget,
vd: &VerifierOnlyCircuitData<C, D>, vd: &VerifierOnlyCircuitData<C, D>,
) where ) -> Result<()>
where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
C::Hasher: AlgebraicHasher<F>, C::Hasher: AlgebraicHasher<F>,
{ {
self.set_cap_target(&vdt.constants_sigmas_cap, &vd.constants_sigmas_cap); self.set_cap_target(&vdt.constants_sigmas_cap, &vd.constants_sigmas_cap)?;
self.set_hash_target(vdt.circuit_digest, vd.circuit_digest); self.set_hash_target(vdt.circuit_digest, vd.circuit_digest)
} }
fn set_wire(&mut self, wire: Wire, value: F) { fn set_wire(&mut self, wire: Wire, value: F) -> Result<()> {
self.set_target(Target::Wire(wire), value) self.set_target(Target::Wire(wire), value)
} }
fn set_wires<W>(&mut self, wires: W, values: &[F]) fn set_wires<W>(&mut self, wires: W, values: &[F]) -> Result<()>
where where
W: IntoIterator<Item = Wire>, W: IntoIterator<Item = Wire>,
{ {
// If we used itertools, we could use zip_eq for extra safety. // If we used itertools, we could use zip_eq for extra safety.
for (wire, &value) in wires.into_iter().zip(values) { for (wire, &value) in wires.into_iter().zip(values) {
self.set_wire(wire, value); self.set_wire(wire, value)?;
} }
Ok(())
} }
fn set_ext_wires<W, const D: usize>(&mut self, wires: W, value: F::Extension) fn set_ext_wires<W, const D: usize>(&mut self, wires: W, value: F::Extension) -> Result<()>
where where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
W: IntoIterator<Item = Wire>, W: IntoIterator<Item = Wire>,
{ {
self.set_wires(wires, &value.to_basefield_array()); self.set_wires(wires, &value.to_basefield_array())
} }
fn extend<I: Iterator<Item = (Target, F)>>(&mut self, pairs: I) { fn extend<I: Iterator<Item = (Target, F)>>(&mut self, pairs: I) -> Result<()> {
for (t, v) in pairs { for (t, v) in pairs {
self.set_target(t, v); self.set_target(t, v)?;
} }
Ok(())
} }
} }
@ -277,15 +304,20 @@ impl<F: Field> PartialWitness<F> {
} }
impl<F: Field> WitnessWrite<F> for PartialWitness<F> { impl<F: Field> WitnessWrite<F> for PartialWitness<F> {
fn set_target(&mut self, target: Target, value: F) { fn set_target(&mut self, target: Target, value: F) -> Result<()> {
let opt_old_value = self.target_values.insert(target, value); let opt_old_value = self.target_values.insert(target, value);
if let Some(old_value) = opt_old_value { if let Some(old_value) = opt_old_value {
assert_eq!( if value != old_value {
value, old_value, return Err(anyhow!(
"Target {:?} was set twice with different values: {} != {}", "Target {:?} was set twice with different values: {} != {}",
target, old_value, value target,
); old_value,
value
));
}
} }
Ok(())
} }
} }
@ -317,19 +349,23 @@ impl<'a, F: Field> PartitionWitness<'a, F> {
/// Set a `Target`. On success, returns the representative index of the newly-set target. If the /// Set a `Target`. On success, returns the representative index of the newly-set target. If the
/// target was already set, returns `None`. /// target was already set, returns `None`.
pub fn set_target_returning_rep(&mut self, target: Target, value: F) -> Option<usize> { pub fn set_target_returning_rep(&mut self, target: Target, value: F) -> Result<Option<usize>> {
let rep_index = self.representative_map[self.target_index(target)]; let rep_index = self.representative_map[self.target_index(target)];
let rep_value = &mut self.values[rep_index]; let rep_value = &mut self.values[rep_index];
if let Some(old_value) = *rep_value { if let Some(old_value) = *rep_value {
assert_eq!( if value != old_value {
value, old_value, return Err(anyhow!(
"Partition containing {:?} was set twice with different values: {} != {}", "Partition containing {:?} was set twice with different values: {} != {}",
target, old_value, value target,
); old_value,
None value
));
}
Ok(None)
} else { } else {
*rep_value = Some(value); *rep_value = Some(value);
Some(rep_index) Ok(Some(rep_index))
} }
} }
@ -353,8 +389,8 @@ impl<'a, F: Field> PartitionWitness<'a, F> {
} }
impl<'a, F: Field> WitnessWrite<F> for PartitionWitness<'a, F> { impl<'a, F: Field> WitnessWrite<F> for PartitionWitness<'a, F> {
fn set_target(&mut self, target: Target, value: F) { fn set_target(&mut self, target: Target, value: F) -> Result<()> {
self.set_target_returning_rep(target, value); self.set_target_returning_rep(target, value).map(|_| ())
} }
} }

View File

@ -103,8 +103,8 @@ fn test_one_lookup() -> anyhow::Result<()> {
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::from_canonical_usize(look_val_a)); pw.set_target(initial_a, F::from_canonical_usize(look_val_a))?;
pw.set_target(initial_b, F::from_canonical_usize(look_val_b)); pw.set_target(initial_b, F::from_canonical_usize(look_val_b))?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let mut timing = TimingTree::new("prove one lookup", Level::Debug); let mut timing = TimingTree::new("prove one lookup", Level::Debug);
@ -171,8 +171,8 @@ fn test_two_luts() -> anyhow::Result<()> {
builder.register_public_input(output_final); builder.register_public_input(output_final);
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::from_canonical_usize(look_val_a)); pw.set_target(initial_a, F::from_canonical_usize(look_val_a))?;
pw.set_target(initial_b, F::from_canonical_usize(look_val_b)); pw.set_target(initial_b, F::from_canonical_usize(look_val_b))?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let mut timing = TimingTree::new("prove two_luts", Level::Debug); let mut timing = TimingTree::new("prove two_luts", Level::Debug);
let proof = prove(&data.prover_only, &data.common, pw, &mut timing)?; let proof = prove(&data.prover_only, &data.common, pw, &mut timing)?;
@ -241,8 +241,8 @@ fn test_different_inputs() -> anyhow::Result<()> {
let look_val_a = table[init_a].0; let look_val_a = table[init_a].0;
let look_val_b = table[init_b].0; let look_val_b = table[init_b].0;
pw.set_target(initial_a, F::from_canonical_u16(look_val_a)); pw.set_target(initial_a, F::from_canonical_u16(look_val_a))?;
pw.set_target(initial_b, F::from_canonical_u16(look_val_b)); pw.set_target(initial_b, F::from_canonical_u16(look_val_b))?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let mut timing = TimingTree::new("prove different lookups", Level::Debug); let mut timing = TimingTree::new("prove different lookups", Level::Debug);
@ -327,8 +327,8 @@ fn test_many_lookups() -> anyhow::Result<()> {
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::from_canonical_usize(look_val_a)); pw.set_target(initial_a, F::from_canonical_usize(look_val_a))?;
pw.set_target(initial_b, F::from_canonical_usize(look_val_b)); pw.set_target(initial_b, F::from_canonical_usize(look_val_b))?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let mut timing = TimingTree::new("prove different lookups", Level::Debug); let mut timing = TimingTree::new("prove different lookups", Level::Debug);
@ -404,8 +404,8 @@ fn test_same_luts() -> anyhow::Result<()> {
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::from_canonical_usize(look_val_a)); pw.set_target(initial_a, F::from_canonical_usize(look_val_a))?;
pw.set_target(initial_b, F::from_canonical_usize(look_val_b)); pw.set_target(initial_b, F::from_canonical_usize(look_val_b))?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let mut timing = TimingTree::new("prove two_luts", Level::Debug); let mut timing = TimingTree::new("prove two_luts", Level::Debug);
@ -443,8 +443,8 @@ fn test_big_lut() -> anyhow::Result<()> {
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::from_canonical_u16(look_val_a)); pw.set_target(initial_a, F::from_canonical_u16(look_val_a))?;
pw.set_target(initial_b, F::from_canonical_u16(look_val_b)); pw.set_target(initial_b, F::from_canonical_u16(look_val_b))?;
let proof = data.prove(pw)?; let proof = data.prove(pw)?;
assert_eq!( assert_eq!(
@ -494,12 +494,11 @@ fn test_many_lookups_on_big_lut() -> anyhow::Result<()> {
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
inputs for (i, t) in inputs.into_iter().enumerate() {
.into_iter() pw.set_target(t, F::from_canonical_usize(i))?
.enumerate() }
.for_each(|(i, t)| pw.set_target(t, F::from_canonical_usize(i))); pw.set_target(initial_a, F::from_canonical_u16(look_val_a))?;
pw.set_target(initial_a, F::from_canonical_u16(look_val_a)); pw.set_target(initial_b, F::from_canonical_u16(look_val_b))?;
pw.set_target(initial_b, F::from_canonical_u16(look_val_b));
let proof = data.prove(pw)?; let proof = data.prove(pw)?;
assert_eq!( assert_eq!(

View File

@ -152,7 +152,7 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
MockCircuitData<F, C, D> MockCircuitData<F, C, D>
{ {
pub fn generate_witness(&self, inputs: PartialWitness<F>) -> PartitionWitness<F> { pub fn generate_witness(&self, inputs: PartialWitness<F>) -> PartitionWitness<F> {
generate_partial_witness::<F, C, D>(inputs, &self.prover_only, &self.common) generate_partial_witness::<F, C, D>(inputs, &self.prover_only, &self.common).unwrap()
} }
} }

View File

@ -46,7 +46,7 @@ pub fn set_lookup_wires<
prover_data: &ProverOnlyCircuitData<F, C, D>, prover_data: &ProverOnlyCircuitData<F, C, D>,
common_data: &CommonCircuitData<F, D>, common_data: &CommonCircuitData<F, D>,
pw: &mut PartitionWitness<F>, pw: &mut PartitionWitness<F>,
) { ) -> Result<()> {
for ( for (
lut_index, lut_index,
&LookupWire { &LookupWire {
@ -88,8 +88,8 @@ pub fn set_lookup_wires<
Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_inp(slot)); Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_inp(slot));
let out_target = let out_target =
Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_out(slot)); Target::wire(last_lut_gate - 1, LookupGate::wire_ith_looking_out(slot));
pw.set_target(inp_target, F::from_canonical_u16(first_inp_value)); pw.set_target(inp_target, F::from_canonical_u16(first_inp_value))?;
pw.set_target(out_target, F::from_canonical_u16(first_out_value)); pw.set_target(out_target, F::from_canonical_u16(first_out_value))?;
multiplicities[0] += 1; multiplicities[0] += 1;
} }
@ -104,9 +104,11 @@ pub fn set_lookup_wires<
pw.set_target( pw.set_target(
mul_target, mul_target,
F::from_canonical_usize(multiplicities[lut_entry]), F::from_canonical_usize(multiplicities[lut_entry]),
); )?;
} }
} }
Ok(())
} }
pub fn prove<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>( pub fn prove<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
@ -122,7 +124,7 @@ where
let partition_witness = timed!( let partition_witness = timed!(
timing, timing,
&format!("run {} generators", prover_data.generators.len()), &format!("run {} generators", prover_data.generators.len()),
generate_partial_witness(inputs, prover_data, common_data) generate_partial_witness(inputs, prover_data, common_data)?
); );
prove_with_partition_witness(prover_data, common_data, partition_witness, timing) prove_with_partition_witness(prover_data, common_data, partition_witness, timing)
@ -148,7 +150,7 @@ where
let quotient_degree = common_data.quotient_degree(); let quotient_degree = common_data.quotient_degree();
let degree = common_data.degree(); let degree = common_data.degree();
set_lookup_wires(prover_data, common_data, &mut partition_witness); set_lookup_wires(prover_data, common_data, &mut partition_witness)?;
let public_inputs = partition_witness.get_targets(&prover_data.public_inputs); let public_inputs = partition_witness.get_targets(&prover_data.public_inputs);
let public_inputs_hash = C::InnerHasher::hash_no_pad(&public_inputs); let public_inputs_hash = C::InnerHasher::hash_no_pad(&public_inputs);

View File

@ -370,7 +370,7 @@ mod tests {
let mut builder = CircuitBuilder::<F, D>::new(config.clone()); let mut builder = CircuitBuilder::<F, D>::new(config.clone());
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
let t = builder.add_virtual_target(); let t = builder.add_virtual_target();
pw.set_target(t, F::rand()); pw.set_target(t, F::rand())?;
builder.register_public_input(t); builder.register_public_input(t);
let _t2 = builder.square(t); let _t2 = builder.square(t);
for _ in 0..64 { for _ in 0..64 {
@ -388,15 +388,15 @@ mod tests {
let mut builder = CircuitBuilder::<F, D>::new(config); let mut builder = CircuitBuilder::<F, D>::new(config);
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
let pt = builder.add_virtual_proof_with_pis(&data.common); let pt = builder.add_virtual_proof_with_pis(&data.common);
pw.set_proof_with_pis_target(&pt, &proof); pw.set_proof_with_pis_target(&pt, &proof)?;
let dummy_pt = builder.add_virtual_proof_with_pis(&data.common); let dummy_pt = builder.add_virtual_proof_with_pis(&data.common);
pw.set_proof_with_pis_target::<C, D>(&dummy_pt, &dummy_proof); pw.set_proof_with_pis_target::<C, D>(&dummy_pt, &dummy_proof)?;
let inner_data = let inner_data =
builder.add_virtual_verifier_data(data.common.config.fri_config.cap_height); builder.add_virtual_verifier_data(data.common.config.fri_config.cap_height);
pw.set_verifier_data_target(&inner_data, &data.verifier_only); pw.set_verifier_data_target(&inner_data, &data.verifier_only)?;
let dummy_inner_data = let dummy_inner_data =
builder.add_virtual_verifier_data(data.common.config.fri_config.cap_height); builder.add_virtual_verifier_data(data.common.config.fri_config.cap_height);
pw.set_verifier_data_target(&dummy_inner_data, &dummy_data.verifier_only); pw.set_verifier_data_target(&dummy_inner_data, &dummy_data.verifier_only)?;
let b = builder.constant_bool(F::rand().0 % 2 == 0); let b = builder.constant_bool(F::rand().0 % 2 == 0);
builder.conditionally_verify_proof::<C>( builder.conditionally_verify_proof::<C>(
b, b,

View File

@ -312,7 +312,7 @@ mod tests {
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
let initial_hash = [F::ZERO, F::ONE, F::TWO, F::from_canonical_usize(3)]; let initial_hash = [F::ZERO, F::ONE, F::TWO, F::from_canonical_usize(3)];
let initial_hash_pis = initial_hash.into_iter().enumerate().collect(); let initial_hash_pis = initial_hash.into_iter().enumerate().collect();
pw.set_bool_target(condition, false); pw.set_bool_target(condition, false)?;
pw.set_proof_with_pis_target::<C, D>( pw.set_proof_with_pis_target::<C, D>(
&inner_cyclic_proof_with_pis, &inner_cyclic_proof_with_pis,
&cyclic_base_proof( &cyclic_base_proof(
@ -320,8 +320,8 @@ mod tests {
&cyclic_circuit_data.verifier_only, &cyclic_circuit_data.verifier_only,
initial_hash_pis, initial_hash_pis,
), ),
); )?;
pw.set_verifier_data_target(&verifier_data_target, &cyclic_circuit_data.verifier_only); pw.set_verifier_data_target(&verifier_data_target, &cyclic_circuit_data.verifier_only)?;
let proof = cyclic_circuit_data.prove(pw)?; let proof = cyclic_circuit_data.prove(pw)?;
check_cyclic_proof_verifier_data( check_cyclic_proof_verifier_data(
&proof, &proof,
@ -332,9 +332,9 @@ mod tests {
// 1st recursive layer. // 1st recursive layer.
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_bool_target(condition, true); pw.set_bool_target(condition, true)?;
pw.set_proof_with_pis_target(&inner_cyclic_proof_with_pis, &proof); pw.set_proof_with_pis_target(&inner_cyclic_proof_with_pis, &proof)?;
pw.set_verifier_data_target(&verifier_data_target, &cyclic_circuit_data.verifier_only); pw.set_verifier_data_target(&verifier_data_target, &cyclic_circuit_data.verifier_only)?;
let proof = cyclic_circuit_data.prove(pw)?; let proof = cyclic_circuit_data.prove(pw)?;
check_cyclic_proof_verifier_data( check_cyclic_proof_verifier_data(
&proof, &proof,
@ -345,9 +345,9 @@ mod tests {
// 2nd recursive layer. // 2nd recursive layer.
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_bool_target(condition, true); pw.set_bool_target(condition, true)?;
pw.set_proof_with_pis_target(&inner_cyclic_proof_with_pis, &proof); pw.set_proof_with_pis_target(&inner_cyclic_proof_with_pis, &proof)?;
pw.set_verifier_data_target(&verifier_data_target, &cyclic_circuit_data.verifier_only); pw.set_verifier_data_target(&verifier_data_target, &cyclic_circuit_data.verifier_only)?;
let proof = cyclic_circuit_data.prove(pw)?; let proof = cyclic_circuit_data.prove(pw)?;
check_cyclic_proof_verifier_data( check_cyclic_proof_verifier_data(
&proof, &proof,

View File

@ -5,6 +5,7 @@ use alloc::{
vec::Vec, vec::Vec,
}; };
use anyhow::Result;
use hashbrown::HashMap; use hashbrown::HashMap;
use plonky2_field::extension::Extendable; use plonky2_field::extension::Extendable;
use plonky2_field::polynomial::PolynomialCoeffs; use plonky2_field::polynomial::PolynomialCoeffs;
@ -76,7 +77,7 @@ where
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
for i in 0..circuit.common.num_public_inputs { for i in 0..circuit.common.num_public_inputs {
let pi = nonzero_public_inputs.get(&i).copied().unwrap_or_default(); let pi = nonzero_public_inputs.get(&i).copied().unwrap_or_default();
pw.set_target(circuit.prover_only.public_inputs[i], pi); pw.set_target(circuit.prover_only.public_inputs[i], pi)?;
} }
circuit.prove(pw) circuit.prove(pw)
} }
@ -238,9 +239,13 @@ where
vec![] vec![]
} }
fn run_once(&self, _witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) { fn run_once(
out_buffer.set_proof_with_pis_target(&self.proof_with_pis_target, &self.proof_with_pis); &self,
out_buffer.set_verifier_data_target(&self.verifier_data_target, &self.verifier_data); _witness: &PartitionWitness<F>,
out_buffer: &mut GeneratedValues<F>,
) -> Result<()> {
out_buffer.set_proof_with_pis_target(&self.proof_with_pis_target, &self.proof_with_pis)?;
out_buffer.set_verifier_data_target(&self.verifier_data_target, &self.verifier_data)
} }
fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> { fn serialize(&self, dst: &mut Vec<u8>, _common_data: &CommonCircuitData<F, D>) -> IoResult<()> {

View File

@ -473,8 +473,8 @@ mod tests {
let data = builder.build::<C>(); let data = builder.build::<C>();
let mut inputs = PartialWitness::new(); let mut inputs = PartialWitness::new();
inputs.set_target(initial_a, F::from_canonical_usize(look_val_a)); inputs.set_target(initial_a, F::from_canonical_usize(look_val_a))?;
inputs.set_target(initial_b, F::from_canonical_usize(look_val_b)); inputs.set_target(initial_b, F::from_canonical_usize(look_val_b))?;
let proof = data.prove(inputs)?; let proof = data.prove(inputs)?;
data.verify(proof.clone())?; data.verify(proof.clone())?;
@ -540,8 +540,8 @@ mod tests {
builder.register_public_input(output_final); builder.register_public_input(output_final);
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::ONE); pw.set_target(initial_a, F::ONE)?;
pw.set_target(initial_b, F::TWO); pw.set_target(initial_b, F::TWO)?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let proof = data.prove(pw)?; let proof = data.prove(pw)?;
@ -606,8 +606,8 @@ mod tests {
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
pw.set_target(initial_a, F::from_canonical_usize(look_val_a)); pw.set_target(initial_a, F::from_canonical_usize(look_val_a))?;
pw.set_target(initial_b, F::from_canonical_usize(look_val_b)); pw.set_target(initial_b, F::from_canonical_usize(look_val_b))?;
let data = builder.build::<C>(); let data = builder.build::<C>();
let proof = data.prove(pw)?; let proof = data.prove(pw)?;
@ -646,14 +646,14 @@ mod tests {
let mut builder = CircuitBuilder::<F, D>::new(config.clone()); let mut builder = CircuitBuilder::<F, D>::new(config.clone());
let mut pw = PartialWitness::new(); let mut pw = PartialWitness::new();
let pt = builder.add_virtual_proof_with_pis(&inner_cd); let pt = builder.add_virtual_proof_with_pis(&inner_cd);
pw.set_proof_with_pis_target(&pt, &inner_proof); pw.set_proof_with_pis_target(&pt, &inner_proof)?;
let inner_data = builder.add_virtual_verifier_data(inner_cd.config.fri_config.cap_height); let inner_data = builder.add_virtual_verifier_data(inner_cd.config.fri_config.cap_height);
pw.set_cap_target( pw.set_cap_target(
&inner_data.constants_sigmas_cap, &inner_data.constants_sigmas_cap,
&inner_vd.constants_sigmas_cap, &inner_vd.constants_sigmas_cap,
); )?;
pw.set_hash_target(inner_data.circuit_digest, inner_vd.circuit_digest); pw.set_hash_target(inner_data.circuit_digest, inner_vd.circuit_digest)?;
builder.verify_proof::<InnerC>(&pt, &inner_data, &inner_cd); builder.verify_proof::<InnerC>(&pt, &inner_data, &inner_cd);

View File

@ -303,7 +303,7 @@ mod tests {
let mut alpha_t = ReducingFactorTarget::new(builder.constant_extension(alpha)); let mut alpha_t = ReducingFactorTarget::new(builder.constant_extension(alpha));
let vs_t = builder.add_virtual_targets(vs.len()); let vs_t = builder.add_virtual_targets(vs.len());
for (&v, &v_t) in vs.iter().zip(&vs_t) { for (&v, &v_t) in vs.iter().zip(&vs_t) {
pw.set_target(v_t, v); pw.set_target(v_t, v)?;
} }
let circuit_reduce = alpha_t.reduce_base(&vs_t, &mut builder); let circuit_reduce = alpha_t.reduce_base(&vs_t, &mut builder);
@ -334,7 +334,7 @@ mod tests {
let mut alpha_t = ReducingFactorTarget::new(builder.constant_extension(alpha)); let mut alpha_t = ReducingFactorTarget::new(builder.constant_extension(alpha));
let vs_t = builder.add_virtual_extension_targets(vs.len()); let vs_t = builder.add_virtual_extension_targets(vs.len());
pw.set_extension_targets(&vs_t, &vs); pw.set_extension_targets(&vs_t, &vs)?;
let circuit_reduce = alpha_t.reduce(&vs_t, &mut builder); let circuit_reduce = alpha_t.reduce(&vs_t, &mut builder);
builder.connect_extension(manual_reduce, circuit_reduce); builder.connect_extension(manual_reduce, circuit_reduce);

View File

@ -3,7 +3,7 @@
//! to highlight the use of the permutation argument with logUp. //! to highlight the use of the permutation argument with logUp.
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec}; use alloc::vec::Vec;
use core::marker::PhantomData; use core::marker::PhantomData;
use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::extension::{Extendable, FieldExtension};
@ -255,7 +255,7 @@ mod tests {
let degree_bits = inner_proof.proof.recover_degree_bits(inner_config); let degree_bits = inner_proof.proof.recover_degree_bits(inner_config);
let pt = let pt =
add_virtual_stark_proof_with_pis(&mut builder, &stark, inner_config, degree_bits, 0, 0); add_virtual_stark_proof_with_pis(&mut builder, &stark, inner_config, degree_bits, 0, 0);
set_stark_proof_with_pis_target(&mut pw, &pt, &inner_proof, builder.zero()); set_stark_proof_with_pis_target(&mut pw, &pt, &inner_proof, builder.zero())?;
verify_stark_proof_circuit::<F, InnerC, S, D>(&mut builder, stark, pt, inner_config); verify_stark_proof_circuit::<F, InnerC, S, D>(&mut builder, stark, pt, inner_config);

View File

@ -7,6 +7,7 @@ use core::borrow::Borrow;
use core::fmt::Debug; use core::fmt::Debug;
use core::iter::repeat; use core::iter::repeat;
#[cfg(feature = "std")]
use itertools::Itertools; use itertools::Itertools;
use num_bigint::BigUint; use num_bigint::BigUint;
use plonky2::field::batch_util::{batch_add_inplace, batch_multiply_inplace}; use plonky2::field::batch_util::{batch_add_inplace, batch_multiply_inplace};

View File

@ -217,7 +217,7 @@ mod tests {
let degree_bits = inner_proof.proof.recover_degree_bits(inner_config); let degree_bits = inner_proof.proof.recover_degree_bits(inner_config);
let pt = let pt =
add_virtual_stark_proof_with_pis(&mut builder, &stark, inner_config, degree_bits, 0, 0); add_virtual_stark_proof_with_pis(&mut builder, &stark, inner_config, degree_bits, 0, 0);
set_stark_proof_with_pis_target(&mut pw, &pt, &inner_proof, builder.zero()); set_stark_proof_with_pis_target(&mut pw, &pt, &inner_proof, builder.zero())?;
verify_stark_proof_circuit::<F, InnerC, S, D>(&mut builder, stark, pt, inner_config); verify_stark_proof_circuit::<F, InnerC, S, D>(&mut builder, stark, pt, inner_config);

View File

@ -325,7 +325,8 @@ pub fn set_stark_proof_with_pis_target<F, C: GenericConfig<D, F = F>, W, const D
stark_proof_with_pis_target: &StarkProofWithPublicInputsTarget<D>, stark_proof_with_pis_target: &StarkProofWithPublicInputsTarget<D>,
stark_proof_with_pis: &StarkProofWithPublicInputs<F, C, D>, stark_proof_with_pis: &StarkProofWithPublicInputs<F, C, D>,
zero: Target, zero: Target,
) where ) -> Result<()>
where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
C::Hasher: AlgebraicHasher<F>, C::Hasher: AlgebraicHasher<F>,
W: WitnessWrite<F>, W: WitnessWrite<F>,
@ -341,10 +342,10 @@ pub fn set_stark_proof_with_pis_target<F, C: GenericConfig<D, F = F>, W, const D
// Set public inputs. // Set public inputs.
for (&pi_t, &pi) in pi_targets.iter().zip_eq(public_inputs) { for (&pi_t, &pi) in pi_targets.iter().zip_eq(public_inputs) {
witness.set_target(pi_t, pi); witness.set_target(pi_t, pi)?;
} }
set_stark_proof_target(witness, pt, proof, zero); set_stark_proof_target(witness, pt, proof, zero)
} }
/// Set the targets in a [`StarkProofTarget`] to their corresponding values in a /// Set the targets in a [`StarkProofTarget`] to their corresponding values in a
@ -354,31 +355,32 @@ pub fn set_stark_proof_target<F, C: GenericConfig<D, F = F>, W, const D: usize>(
proof_target: &StarkProofTarget<D>, proof_target: &StarkProofTarget<D>,
proof: &StarkProof<F, C, D>, proof: &StarkProof<F, C, D>,
zero: Target, zero: Target,
) where ) -> Result<()>
where
F: RichField + Extendable<D>, F: RichField + Extendable<D>,
C::Hasher: AlgebraicHasher<F>, C::Hasher: AlgebraicHasher<F>,
W: WitnessWrite<F>, W: WitnessWrite<F>,
{ {
witness.set_cap_target(&proof_target.trace_cap, &proof.trace_cap); witness.set_cap_target(&proof_target.trace_cap, &proof.trace_cap)?;
if let (Some(quotient_polys_cap_target), Some(quotient_polys_cap)) = if let (Some(quotient_polys_cap_target), Some(quotient_polys_cap)) =
(&proof_target.quotient_polys_cap, &proof.quotient_polys_cap) (&proof_target.quotient_polys_cap, &proof.quotient_polys_cap)
{ {
witness.set_cap_target(quotient_polys_cap_target, quotient_polys_cap); witness.set_cap_target(quotient_polys_cap_target, quotient_polys_cap)?;
} }
witness.set_fri_openings( witness.set_fri_openings(
&proof_target.openings.to_fri_openings(zero), &proof_target.openings.to_fri_openings(zero),
&proof.openings.to_fri_openings(), &proof.openings.to_fri_openings(),
); )?;
if let (Some(auxiliary_polys_cap_target), Some(auxiliary_polys_cap)) = ( if let (Some(auxiliary_polys_cap_target), Some(auxiliary_polys_cap)) = (
&proof_target.auxiliary_polys_cap, &proof_target.auxiliary_polys_cap,
&proof.auxiliary_polys_cap, &proof.auxiliary_polys_cap,
) { ) {
witness.set_cap_target(auxiliary_polys_cap_target, auxiliary_polys_cap); witness.set_cap_target(auxiliary_polys_cap_target, auxiliary_polys_cap)?;
} }
set_fri_proof_target(witness, &proof_target.opening_proof, &proof.opening_proof); set_fri_proof_target(witness, &proof_target.opening_proof, &proof.opening_proof)
} }
/// Utility function to check that all lookups data wrapped in `Option`s are `Some` iff /// Utility function to check that all lookups data wrapped in `Option`s are `Some` iff

View File

@ -109,19 +109,19 @@ pub fn test_stark_circuit_constraints<
let mut pw = PartialWitness::<F>::new(); let mut pw = PartialWitness::<F>::new();
let locals_t = builder.add_virtual_extension_targets(S::COLUMNS); let locals_t = builder.add_virtual_extension_targets(S::COLUMNS);
pw.set_extension_targets(&locals_t, vars.get_local_values()); pw.set_extension_targets(&locals_t, vars.get_local_values())?;
let nexts_t = builder.add_virtual_extension_targets(S::COLUMNS); let nexts_t = builder.add_virtual_extension_targets(S::COLUMNS);
pw.set_extension_targets(&nexts_t, vars.get_next_values()); pw.set_extension_targets(&nexts_t, vars.get_next_values())?;
let pis_t = builder.add_virtual_extension_targets(S::PUBLIC_INPUTS); let pis_t = builder.add_virtual_extension_targets(S::PUBLIC_INPUTS);
pw.set_extension_targets(&pis_t, vars.get_public_inputs()); pw.set_extension_targets(&pis_t, vars.get_public_inputs())?;
let alphas_t = builder.add_virtual_targets(1); let alphas_t = builder.add_virtual_targets(1);
pw.set_target(alphas_t[0], alphas[0]); pw.set_target(alphas_t[0], alphas[0])?;
let z_last_t = builder.add_virtual_extension_target(); let z_last_t = builder.add_virtual_extension_target();
pw.set_extension_target(z_last_t, z_last); pw.set_extension_target(z_last_t, z_last)?;
let lagrange_first_t = builder.add_virtual_extension_target(); let lagrange_first_t = builder.add_virtual_extension_target();
pw.set_extension_target(lagrange_first_t, lagrange_first); pw.set_extension_target(lagrange_first_t, lagrange_first)?;
let lagrange_last_t = builder.add_virtual_extension_target(); let lagrange_last_t = builder.add_virtual_extension_target();
pw.set_extension_target(lagrange_last_t, lagrange_last); pw.set_extension_target(lagrange_last_t, lagrange_last)?;
let vars = S::EvaluationFrameTarget::from_values(&locals_t, &nexts_t, &pis_t); let vars = S::EvaluationFrameTarget::from_values(&locals_t, &nexts_t, &pis_t);
let mut consumer = RecursiveConstraintConsumer::<F, D>::new( let mut consumer = RecursiveConstraintConsumer::<F, D>::new(

View File

@ -2,7 +2,7 @@
//! a proof of knowledge of the trace) //! a proof of knowledge of the trace)
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec}; use alloc::vec::Vec;
use core::marker::PhantomData; use core::marker::PhantomData;
use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::extension::{Extendable, FieldExtension};
@ -182,7 +182,7 @@ mod tests {
let degree_bits = inner_proof.proof.recover_degree_bits(inner_config); let degree_bits = inner_proof.proof.recover_degree_bits(inner_config);
let pt = let pt =
add_virtual_stark_proof_with_pis(&mut builder, &stark, inner_config, degree_bits, 0, 0); add_virtual_stark_proof_with_pis(&mut builder, &stark, inner_config, degree_bits, 0, 0);
set_stark_proof_with_pis_target(&mut pw, &pt, &inner_proof, builder.zero()); set_stark_proof_with_pis_target(&mut pw, &pt, &inner_proof, builder.zero())?;
verify_stark_proof_circuit::<F, InnerC, S, D>(&mut builder, stark, pt, inner_config); verify_stark_proof_circuit::<F, InnerC, S, D>(&mut builder, stark, pt, inner_config);