diff --git a/src/gadgets/nonnative/bn/big_uint.rs b/src/gadgets/nonnative/bn/big_uint.rs index 72200e65..fb759313 100644 --- a/src/gadgets/nonnative/bn/big_uint.rs +++ b/src/gadgets/nonnative/bn/big_uint.rs @@ -25,7 +25,7 @@ use crate::{ // integer-type, but only a wrapper for // storing a natural number with limbs. #[derive(PartialEq, Debug, Clone)] -pub struct BigUint { +pub struct BigUint { limbs: Vec, width: NonZeroUsize, } diff --git a/src/ivc/cyclefold/mod.rs b/src/ivc/cyclefold/mod.rs index b3aa089a..6ff75137 100644 --- a/src/ivc/cyclefold/mod.rs +++ b/src/ivc/cyclefold/mod.rs @@ -1,6 +1,5 @@ -use std::num::NonZeroUsize; - use halo2_proofs::halo2curves::ff::{FromUniformBytes, PrimeFieldBits}; +use std::num::NonZeroUsize; use crate::{ main_gate::MainGateConfig, diff --git a/src/ivc/cyclefold/sfc/input/assigned.rs b/src/ivc/cyclefold/sfc/input/assigned.rs index d679e6c4..ccc2f122 100644 --- a/src/ivc/cyclefold/sfc/input/assigned.rs +++ b/src/ivc/cyclefold/sfc/input/assigned.rs @@ -1,55 +1,23 @@ use std::iter; use halo2_proofs::halo2curves::ff::PrimeField; +use itertools::Itertools; use crate::{ halo2_proofs::plonk::Error as Halo2PlonkError, - main_gate::{self, AdviceCyclicAssignor, AssignedValue, RegionCtx, WrapValue}, + ivc, + main_gate::{self, AdviceCyclicAssignor, AssignedValue, MainGate, RegionCtx, WrapValue}, }; pub type MainGateConfig = main_gate::MainGateConfig<{ super::super::T_MAIN_GATE }>; -type BigUint = Vec>; +pub type BigUint = Vec; -#[derive(Clone)] -pub struct BigUintPoint { - pub x_limbs: BigUint, - pub y_limbs: BigUint, -} - -impl BigUintPoint { - fn assign_advice_from( - region: &mut RegionCtx<'_, F>, - original: &super::BigUintPoint, - main_gate_config: &MainGateConfig, - ) -> Result { - let super::BigUintPoint { x, y } = original; - let mut assigner = main_gate_config.advice_cycle_assigner(); - - Ok(Self { - x_limbs: assigner.assign_all_advice(region, || "x", x.limbs().iter().copied())?, - y_limbs: assigner.assign_all_advice(region, || "y", y.limbs().iter().copied())?, - }) - } - - fn iter_wrap_values(&self) -> impl '_ + Iterator> { - self.x_limbs - .iter() - .chain(self.y_limbs.iter()) - .cloned() - .map(|l| WrapValue::Assigned(l)) - } -} - -#[derive(Clone)] -pub struct NativePlonkInstance { - pub(crate) W_commitments: Vec>, - pub(crate) instances: Vec>>, - pub(crate) challenges: Vec>, -} +pub type BigUintPoint = ivc::protogalaxy::verify_chip::BigUintPoint; +pub type NativePlonkInstance = ivc::protogalaxy::verify_chip::AssignedPlonkInstance; impl NativePlonkInstance { - fn assign_advice_from( + pub fn assign_advice_from_native( region: &mut RegionCtx<'_, F>, original: &super::NativePlonkInstance, main_gate_config: &MainGateConfig, @@ -62,7 +30,8 @@ impl NativePlonkInstance { let W_commitments = W_commitments .iter() - .map(|p| BigUintPoint::assign_advice_from(region, p, main_gate_config)) + .cloned() + .map(|p| p.assign(region, main_gate_config)) .collect::, _>>()?; let mut assigner = main_gate_config.advice_cycle_assigner(); @@ -83,45 +52,19 @@ impl NativePlonkInstance { challenges, }) } - - fn iter_wrap_values(&self) -> impl '_ + Iterator> { - let Self { - W_commitments, - instances, - challenges, - } = self; - - W_commitments - .iter() - .flat_map(|W_commitment| W_commitment.iter_wrap_values()) - .chain(instances.iter().flat_map(|instance| { - instance - .iter() - .map(|value| WrapValue::Assigned(value.clone())) - })) - .chain( - challenges - .iter() - .map(|cha| WrapValue::Assigned(cha.clone())), - ) - } } -#[derive(Clone)] -pub struct ProtoGalaxyAccumulatorInstance { - pub(crate) ins: NativePlonkInstance, - pub(crate) betas: Box<[AssignedValue]>, - pub(crate) e: AssignedValue, -} +pub type ProtoGalaxyAccumulatorInstance = + ivc::protogalaxy::verify_chip::AssignedAccumulatorInstance; impl ProtoGalaxyAccumulatorInstance { - fn assign_advice_from( + fn assign_advice_from_native( region: &mut RegionCtx<'_, F>, original: &super::ProtoGalaxyAccumulatorInstance, main_gate_config: &MainGateConfig, ) -> Result { let super::ProtoGalaxyAccumulatorInstance { ins, betas, e } = original; - let ins = NativePlonkInstance::assign_advice_from(region, ins, main_gate_config)?; + let ins = NativePlonkInstance::assign_advice_from_native(region, ins, main_gate_config)?; let mut assigner = main_gate_config.advice_cycle_assigner(); Ok(Self { @@ -133,19 +76,39 @@ impl ProtoGalaxyAccumulatorInstance { }) } - fn iter_wrap_values(&self) -> impl '_ + Iterator> { - let Self { ins, betas, e } = self; - ins.iter_wrap_values() - .chain(betas.iter().cloned().map(WrapValue::Assigned)) - .chain(iter::once(WrapValue::Assigned(e.clone()))) + fn conditional_select( + region: &mut RegionCtx<'_, F>, + mg: &MainGate, + lhs: &Self, + rhs: &Self, + cond: &AssignedValue, + ) -> Result { + let Self { + ins: lhs_ins, + betas: lhs_betas, + e: lhs_e, + } = lhs; + + let Self { + ins: rhs_ins, + betas: rhs_betas, + e: rhs_e, + } = rhs; + + Ok(Self { + ins: NativePlonkInstance::conditional_select(region, mg, lhs_ins, rhs_ins, cond)?, + betas: lhs_betas + .iter() + .zip_eq(rhs_betas) + .map(|(l, r)| mg.conditional_select(region, l, r, cond)) + .collect::, _>>()? + .into_boxed_slice(), + e: mg.conditional_select(region, lhs_e, rhs_e, cond)?, + }) } } -#[derive(Debug, Clone)] -pub struct ProtogalaxyProof { - pub poly_F: Vec>, - pub poly_K: Vec>, -} +pub type ProtogalaxyProof = ivc::protogalaxy::verify_chip::AssignedProof; impl ProtogalaxyProof { fn assign_advice_from( @@ -157,8 +120,12 @@ impl ProtogalaxyProof { let super::nifs::protogalaxy::Proof { poly_F, poly_K } = original; Ok(Self { - poly_F: assigner.assign_all_advice(region, || "poly_F", poly_F.iter().cloned())?, - poly_K: assigner.assign_all_advice(region, || "poly_K", poly_K.iter().cloned())?, + poly_F: assigner + .assign_all_advice(region, || "poly_F", poly_F.iter().cloned())? + .into(), + poly_K: assigner + .assign_all_advice(region, || "poly_K", poly_K.iter().cloned())? + .into(), }) } @@ -166,8 +133,9 @@ impl ProtogalaxyProof { let Self { poly_F, poly_K } = self; poly_K + .0 .iter() - .chain(poly_F.iter()) + .chain(poly_F.0.iter()) .cloned() .map(WrapValue::Assigned) } @@ -193,12 +161,16 @@ impl SelfTrace { } = original; Ok(Self { - input_accumulator: ProtoGalaxyAccumulatorInstance::assign_advice_from( + input_accumulator: ProtoGalaxyAccumulatorInstance::assign_advice_from_native( region, input_accumulator, main_gate_config, )?, - incoming: NativePlonkInstance::assign_advice_from(region, incoming, main_gate_config)?, + incoming: NativePlonkInstance::assign_advice_from_native( + region, + incoming, + main_gate_config, + )?, proof: ProtogalaxyProof::assign_advice_from(region, proof, main_gate_config)?, }) } @@ -220,8 +192,8 @@ impl SelfTrace { #[derive(Clone)] pub struct PairedPlonkInstance { pub(crate) W_commitments: Vec<(AssignedValue, AssignedValue)>, - pub(crate) instances: Vec>>, - pub(crate) challenges: Vec>, + pub(crate) instances: Vec>>>, + pub(crate) challenges: Vec>>, } impl PairedPlonkInstance { @@ -303,7 +275,7 @@ impl PairedPlonkInstance { pub struct SangriaAccumulatorInstance { pub(crate) ins: PairedPlonkInstance, pub(crate) E_commitment: (AssignedValue, AssignedValue), - pub(crate) u: BigUint, + pub(crate) u: BigUint>, } impl SangriaAccumulatorInstance { diff --git a/src/ivc/cyclefold/sfc/input/mod.rs b/src/ivc/cyclefold/sfc/input/mod.rs index c5c1d571..13fc0d82 100644 --- a/src/ivc/cyclefold/sfc/input/mod.rs +++ b/src/ivc/cyclefold/sfc/input/mod.rs @@ -1,6 +1,7 @@ use std::array; use super::super::{DEFAULT_LIMBS_COUNT_LIMIT, DEFAULT_LIMB_WIDTH}; +pub use crate::ivc::protogalaxy::verify_chip::BigUintPoint; use crate::{ gadgets::nonnative::bn::big_uint::BigUint, halo2_proofs::halo2curves::{ff::PrimeField, CurveAffine}, @@ -11,39 +12,6 @@ use crate::{ pub mod assigned; -#[derive(Debug, Clone)] -pub struct BigUintPoint { - x: BigUint, - y: BigUint, -} - -impl> AbsorbInRO for BigUintPoint { - fn absorb_into(&self, ro: &mut RO) { - ro.absorb_field_iter(self.x.limbs().iter().chain(self.y.limbs().iter()).cloned()); - } -} - -impl From<&C> for BigUintPoint { - fn from(value: &C) -> Self { - let c = value.coordinates().unwrap(); - Self { - x: BigUint::from_different_field(c.x(), DEFAULT_LIMB_WIDTH, DEFAULT_LIMBS_COUNT_LIMIT) - .unwrap(), - y: BigUint::from_different_field(c.y(), DEFAULT_LIMB_WIDTH, DEFAULT_LIMBS_COUNT_LIMIT) - .unwrap(), - } - } -} - -impl BigUintPoint { - fn identity() -> Self { - Self { - x: BigUint::zero(DEFAULT_LIMB_WIDTH), - y: BigUint::zero(DEFAULT_LIMB_WIDTH), - } - } -} - #[derive(Debug, Clone)] pub struct NativePlonkInstance { pub(crate) W_commitments: Vec>, @@ -88,7 +56,12 @@ impl> AbsorbInRO for PairedPlonkInstance impl From> for NativePlonkInstance { fn from(value: plonk::PlonkInstance) -> Self { Self { - W_commitments: value.W_commitments.iter().map(BigUintPoint::from).collect(), + W_commitments: value + .W_commitments + .iter() + .map(BigUintPoint::new) + .collect::, _>>() + .unwrap(), instances: value.instances, challenges: value.challenges, } @@ -148,7 +121,7 @@ impl SelfTrace { }; let ins = NativePlonkInstance:: { - W_commitments: vec![BigUintPoint::identity(); W_commitments_len], + W_commitments: vec![BigUintPoint::::identity(); W_commitments_len], instances: native_plonk_structure .num_io .iter() @@ -335,8 +308,8 @@ impl Input { input_accumulator: ProtoGalaxyAccumulatorInstance { ins: NativePlonkInstance { W_commitments: vec![BigUintPoint { - x: random_big_uint(&mut gen), - y: random_big_uint(&mut gen), + x: random_big_uint(&mut gen).limbs().to_vec(), + y: random_big_uint(&mut gen).limbs().to_vec(), }], instances: vec![ vec![gen.next().unwrap(); 10]; // 5 instances each with 10 field elements @@ -349,8 +322,8 @@ impl Input { }, incoming: NativePlonkInstance { W_commitments: vec![BigUintPoint { - x: random_big_uint(&mut gen), - y: random_big_uint(&mut gen), + x: random_big_uint(&mut gen).limbs().to_vec(), + y: random_big_uint(&mut gen).limbs().to_vec(), }], instances: vec![ vec![gen.next().unwrap(); 10]; // 10 instances each with 10 field elements diff --git a/src/ivc/cyclefold/sfc/mod.rs b/src/ivc/cyclefold/sfc/mod.rs index 4fa7af61..09da5083 100644 --- a/src/ivc/cyclefold/sfc/mod.rs +++ b/src/ivc/cyclefold/sfc/mod.rs @@ -15,7 +15,6 @@ use crate::{ StepCircuit, }, main_gate::{MainGate, MainGateConfig, RegionCtx}, - polynomial::univariate::UnivariatePoly, poseidon::ROTrait, }; @@ -114,28 +113,29 @@ where Halo2PlonkError::Synthesis })?; - let _self_acc_out = layouter.assign_region( - || "sfc protogalaxy", - |region| { - let mut region = RegionCtx::new(region, 0); - - protogalaxy::verify_chip::verify( - &mut region, - config.mg.clone(), - ro_chip(config.mg.clone()), - verify_chip::AssignedVerifierParam { - pp_digest: input.pp_digest.clone(), - }, - input.self_trace.input_accumulator.clone().into(), - &[input.self_trace.incoming.clone().into()], - input.self_trace.proof.clone().into(), - ) - .map_err(|err| { - error!("while protogalaxy::verify: {err:?}"); - Halo2PlonkError::Synthesis - }) - }, - )?; + let _self_acc_out: input::assigned::ProtoGalaxyAccumulatorInstance = layouter + .assign_region( + || "sfc protogalaxy", + |region| { + let mut region = RegionCtx::new(region, 0); + + protogalaxy::verify_chip::verify( + &mut region, + config.mg.clone(), + ro_chip(config.mg.clone()), + verify_chip::AssignedVerifierParam { + pp_digest: input.pp_digest.clone(), + }, + input.self_trace.input_accumulator.clone(), + &[input.self_trace.incoming.clone()], + input.self_trace.proof.clone(), + ) + .map_err(|err| { + error!("while protogalaxy::verify: {err:?}"); + Halo2PlonkError::Synthesis + }) + }, + )?; layouter.assign_region( || "sfc out", @@ -163,67 +163,3 @@ where todo!() } } - -impl From> - for verify_chip::AssignedAccumulatorInstance -{ - fn from(value: input::assigned::ProtoGalaxyAccumulatorInstance) -> Self { - use self::input::assigned::{NativePlonkInstance, ProtoGalaxyAccumulatorInstance}; - - let ProtoGalaxyAccumulatorInstance { - ins: - NativePlonkInstance { - W_commitments, - instances, - challenges, - }, - betas, - e, - } = value; - - Self { - betas, - e, - ins: verify_chip::AssignedPlonkInstance { - instances, - challenges, - W_commitments: W_commitments - .into_iter() - .map(|W_commitment| (W_commitment.x_limbs, W_commitment.y_limbs)) - .collect(), - }, - } - } -} - -impl From> for verify_chip::AssignedProof { - fn from(value: input::assigned::ProtogalaxyProof) -> Self { - let input::assigned::ProtogalaxyProof { poly_F, poly_K } = value; - - verify_chip::AssignedProof { - poly_F: verify_chip::AssignedUnivariatePoly(UnivariatePoly(poly_F.into_boxed_slice())), - poly_K: verify_chip::AssignedUnivariatePoly(UnivariatePoly(poly_K.into_boxed_slice())), - } - } -} - -impl From> - for verify_chip::AssignedPlonkInstance -{ - fn from(value: input::assigned::NativePlonkInstance) -> Self { - let input::assigned::NativePlonkInstance { - W_commitments, - instances, - challenges, - } = value; - - Self { - instances, - challenges, - W_commitments: W_commitments - .into_iter() - .map(|W_commitment| (W_commitment.x_limbs, W_commitment.y_limbs)) - .collect(), - } - } -} diff --git a/src/ivc/protogalaxy/mod.rs b/src/ivc/protogalaxy/mod.rs index 913ae5d5..4ab020c4 100644 --- a/src/ivc/protogalaxy/mod.rs +++ b/src/ivc/protogalaxy/mod.rs @@ -22,9 +22,9 @@ pub mod verify_chip { self, poly::{PolyChallenges, PolyContext}, }, - plonk::PlonkInstance, + plonk, polynomial::{lagrange::iter_cyclic_subgroup, univariate::UnivariatePoly}, - poseidon::ROCircuitTrait, + poseidon::{AbsorbInRO, ROCircuitTrait, ROTrait}, prelude::DEFAULT_LIMB_WIDTH, util, }; @@ -58,91 +58,216 @@ pub mod verify_chip { } pub type BigUint = Vec; - pub type BigUintPoint = (BigUint, BigUint); - /// Assigned version of [`crate::plonk::PlonkInstance`] - pub struct AssignedPlonkInstance { - pub W_commitments: Vec>>, - pub instances: Vec>>, - pub challenges: Vec>, + #[derive(Debug, Clone)] + pub struct BigUintPoint { + pub x: BigUint, + pub y: BigUint, } - fn to_bn(v: &C) -> Result, big_uint::Error> { - let coordinates = v.coordinates().unwrap(); + impl BigUintPoint { + fn x_limbs(&self) -> impl Iterator { + self.x.iter() + } - let x = big_uint::BigUint::::from_different_field::( - coordinates.x(), - DEFAULT_LIMB_WIDTH, - DEFAULT_LIMBS_COUNT_LIMIT, - )?; + fn y_limbs(&self) -> impl Iterator { + self.y.iter() + } + } - let y = big_uint::BigUint::::from_different_field::( - coordinates.y(), - DEFAULT_LIMB_WIDTH, - DEFAULT_LIMBS_COUNT_LIMIT, - )?; + impl> AbsorbInRO for BigUintPoint { + fn absorb_into(&self, ro: &mut RO) { + ro.absorb_field_iter(self.x.iter().chain(self.y.iter()).cloned()); + } + } - Ok((x.limbs().to_vec(), y.limbs().to_vec())) + impl BigUintPoint> { + pub fn iter_wrap_values(&self) -> impl '_ + Iterator> { + let Self { x, y } = self; + x.iter() + .chain(y.iter()) + .map(|v| WrapValue::Assigned(v.clone())) + } + + fn conditional_select( + region: &mut RegionCtx<'_, F>, + mg: &MainGate, + lhs: &Self, + rhs: &Self, + cond: &AssignedValue, + ) -> Result { + let Self { x: lhs_x, y: lhs_y } = lhs; + let Self { x: rhs_x, y: rhs_y } = rhs; + + let x = lhs_x + .iter() + .zip_eq(rhs_x.iter()) + .map(|(l, r)| mg.conditional_select(region, l, r, cond)) + .collect::, _>>()?; + + let y = lhs_y + .iter() + .zip_eq(rhs_y.iter()) + .map(|(l, r)| mg.conditional_select(region, l, r, cond)) + .collect::, _>>()?; + + Ok(Self { x, y }) + } + } + + impl BigUintPoint { + pub fn new>(v: &C) -> Result { + let coordinates = v.coordinates().unwrap(); + + let x = big_uint::BigUint::::from_different_field::( + coordinates.x(), + DEFAULT_LIMB_WIDTH, + DEFAULT_LIMBS_COUNT_LIMIT, + )?; + + let y = big_uint::BigUint::::from_different_field::( + coordinates.y(), + DEFAULT_LIMB_WIDTH, + DEFAULT_LIMBS_COUNT_LIMIT, + )?; + + Ok(Self { + x: x.limbs().to_vec(), + y: y.limbs().to_vec(), + }) + } + + pub fn assign( + self, + region: &mut RegionCtx, + main_gate_config: &MainGateConfig, + ) -> Result>, Halo2PlonkError> { + let mut assigner = main_gate_config.advice_cycle_assigner(); + + Ok(BigUintPoint { + x: assigner.assign_all_advice(region, || "x", self.x.into_iter())?, + y: assigner.assign_all_advice(region, || "y", self.y.into_iter())?, + }) + } + } + + impl BigUintPoint { + pub fn identity() -> Self { + Self { + x: big_uint::BigUint::zero(DEFAULT_LIMB_WIDTH).limbs().to_vec(), + y: big_uint::BigUint::zero(DEFAULT_LIMB_WIDTH).limbs().to_vec(), + } + } + } + + /// Assigned version of [`crate::plonk::PlonkInstance`] + #[derive(Clone)] + pub struct AssignedPlonkInstance { + pub W_commitments: Vec>>, + pub instances: Vec>>, + pub challenges: Vec>, } impl AssignedPlonkInstance { pub fn assign_advice_from>( region: &mut RegionCtx, + original: plonk::PlonkInstance, main_gate_config: MainGateConfig, - original: PlonkInstance, ) -> Result { - let PlonkInstance { + let plonk::PlonkInstance { W_commitments, instances, challenges, } = original; - let mut assigner = main_gate_config.advice_cycle_assigner(); - let W_commitments = W_commitments .iter() - .enumerate() - .map(|(i, W_commitment)| { - let (x, y) = to_bn(W_commitment).unwrap(); - - Ok(( - assigner.assign_all_advice( - region, - || format!("W_commitments[{i}]"), - x.into_iter(), - )?, - assigner.assign_all_advice( - region, - || format!("W_commitments[{i}]"), - y.into_iter(), - )?, - )) + .map(|W_commitment| { + BigUintPoint::new(W_commitment) + .expect("TODO") + .assign(region, &main_gate_config) }) - .collect::, _>>(); + .collect::, _>>() + .map_err(|err| Error::Assign { + annotation: "W_commitments", + err, + })?; - let instances = instances - .iter() - .map(|instance| { - assigner.assign_all_advice(region, || "instance", instance.iter().cloned()) - }) - .collect::, _>>(); + let mut assigner = main_gate_config.advice_cycle_assigner(); - let challenges = - assigner.assign_all_advice(region, || "challenges", challenges.iter().cloned()); + Ok(Self { + W_commitments, + instances: instances + .into_iter() + .map(|instance| { + assigner.assign_all_advice(region, || "instance", instance.into_iter()) + }) + .collect::, _>>() + .map_err(|err| Error::Assign { + annotation: "instances", + err, + })?, + challenges: assigner + .assign_all_advice(region, || "challenges", challenges.into_iter()) + .map_err(|err| Error::Assign { + annotation: "challenges", + err, + })?, + }) + } - let map_err = |err| Error::Assign { - annotation: "PlonkInstance", - err, - }; + pub fn conditional_select( + region: &mut RegionCtx<'_, F>, + mg: &MainGate, + lhs: &Self, + rhs: &Self, + cond: &AssignedValue, + ) -> Result { + let Self { + W_commitments: lhs_W_commitments, + instances: lhs_instances, + challenges: lhs_challenges, + } = lhs; + let Self { + W_commitments: rhs_W_commitments, + instances: rhs_instances, + challenges: rhs_challenges, + } = rhs; Ok(Self { - W_commitments: W_commitments.map_err(map_err)?, - instances: instances.map_err(map_err)?, - challenges: challenges.map_err(map_err)?, + W_commitments: lhs_W_commitments + .iter() + .zip_eq(rhs_W_commitments.iter()) + .map(|(lhs_W_commitment, rhs_W_commitment)| { + BigUintPoint::conditional_select( + region, + mg, + lhs_W_commitment, + rhs_W_commitment, + cond, + ) + }) + .collect::, _>>()?, + instances: lhs_instances + .iter() + .zip_eq(rhs_instances.iter()) + .map(|(l_instance, r_instance)| { + l_instance + .iter() + .zip_eq(r_instance.iter()) + .map(|(l, r)| mg.conditional_select(region, l, r, cond)) + .collect::, _>>() + }) + .collect::>, _>>()?, + challenges: lhs_challenges + .iter() + .zip_eq(rhs_challenges.iter()) + .map(|(l, r)| mg.conditional_select(region, l, r, cond)) + .collect::, _>>()?, }) } - pub fn iter_wrap_value(&self) -> impl '_ + Iterator> { + pub fn iter_wrap_values(&self) -> impl '_ + Iterator> { let Self { W_commitments, instances, @@ -151,21 +276,22 @@ pub mod verify_chip { W_commitments .iter() - .flat_map(|(W_commitment_x, W_commitment_y)| { - W_commitment_x.iter().chain(W_commitment_y.iter()).cloned() - }) + .flat_map(|W_commitment| W_commitment.iter_wrap_values()) + .chain(instances.iter().flat_map(|instance| { + instance + .iter() + .map(|value| WrapValue::Assigned(value.clone())) + })) .chain( - instances + challenges .iter() - .flat_map(|instance| instance.iter()) - .cloned(), + .map(|cha| WrapValue::Assigned(cha.clone())), ) - .chain(challenges.iter().cloned()) - .map(|value| WrapValue::Assigned(value)) } } /// Assigned version of [`crate::nifs::protogalaxy::accumulator::AccumulatorInstance`] + #[derive(Clone)] pub struct AssignedAccumulatorInstance { pub ins: AssignedPlonkInstance, pub betas: Box<[AssignedValue]>, @@ -173,7 +299,7 @@ pub mod verify_chip { } impl AssignedAccumulatorInstance { - pub fn assign>( + pub fn assign_advice_from>( region: &mut RegionCtx, main_gate_config: MainGateConfig, acc: protogalaxy::AccumulatorInstance, @@ -181,7 +307,7 @@ pub mod verify_chip { let protogalaxy::AccumulatorInstance { ins, betas, e } = acc; let ins = - AssignedPlonkInstance::assign_advice_from(region, main_gate_config.clone(), ins)?; + AssignedPlonkInstance::assign_advice_from(region, ins, main_gate_config.clone())?; let mut assigner = main_gate_config.advice_cycle_assigner(); @@ -207,10 +333,10 @@ pub mod verify_chip { Ok(Self { ins, betas, e }) } - pub fn iter_wrap_value(&self) -> impl '_ + Iterator> { + pub fn iter_wrap_values(&self) -> impl '_ + Iterator> { let Self { ins, betas, e } = self; - ins.iter_wrap_value() + ins.iter_wrap_values() .chain(betas.iter().map(|beta| WrapValue::Assigned(beta.clone()))) .chain(iter::once(WrapValue::Assigned(e.clone()))) } @@ -275,9 +401,32 @@ pub mod verify_chip { } /// Assigned version of [`crate::polynomial::univariate::UnivariatePoly`] + #[derive(Clone)] pub struct AssignedUnivariatePoly(pub UnivariatePoly>); + impl From>> for AssignedUnivariatePoly { + fn from(value: UnivariatePoly>) -> Self { + Self(value) + } + } + + impl From>> for AssignedUnivariatePoly { + fn from(value: Vec>) -> Self { + Self(UnivariatePoly(value.into_boxed_slice())) + } + } + + impl FromIterator> for AssignedUnivariatePoly { + fn from_iter>>(iter: T) -> Self { + Self(UnivariatePoly::from_iter(iter)) + } + } + impl AssignedUnivariatePoly { + pub fn new(coeff: Box<[AssignedValue]>) -> Self { + Self(UnivariatePoly(coeff)) + } + pub fn assign( region: &mut RegionCtx, main_gate_config: MainGateConfig, @@ -405,6 +554,7 @@ pub mod verify_chip { } /// Assigned version of [`crate::nifs::protogalaxy::Proof] + #[derive(Clone)] pub struct AssignedProof { pub poly_F: AssignedUnivariatePoly, pub poly_K: AssignedUnivariatePoly, @@ -511,8 +661,8 @@ pub mod verify_chip { { let delta = ro_circuit .absorb_iter(vp.iter_wrap_value()) - .absorb_iter(accumulator.iter_wrap_value()) - .absorb_iter(incoming.iter().flat_map(|tr| tr.iter_wrap_value())) + .absorb_iter(accumulator.iter_wrap_values()) + .absorb_iter(incoming.iter().flat_map(|tr| tr.iter_wrap_values())) .squeeze(region)?; let alpha = ro_circuit @@ -758,10 +908,9 @@ pub mod verify_chip { ro_circuit.absorb_iter(pi.instances.iter().flat_map(|inst| inst.iter())); for (W_commitment, challenge) in pi.W_commitments.iter().zip_eq(pi.challenges.iter()) { - let (W_commitment_x, W_commitment_y) = W_commitment; let expected = ro_circuit - .absorb_iter(W_commitment_x.iter()) - .absorb_iter(W_commitment_y.iter()) + .absorb_iter(W_commitment.x_limbs()) + .absorb_iter(W_commitment.y_limbs()) .squeeze(region)?; region.constrain_equal(expected.cell(), challenge.cell())?; @@ -883,6 +1032,7 @@ pub mod verify_chip { self, protogalaxy::{AccumulatorArgs, VerifierParam}, }, + plonk::PlonkInstance, polynomial, table::WitnessCollector, }; @@ -968,7 +1118,7 @@ pub mod verify_chip { params, ) .unwrap(); - let acc = AssignedAccumulatorInstance::assign( + let acc = AssignedAccumulatorInstance::assign_advice_from( &mut region, config.clone(), acc.clone().into(),