diff --git a/halo2_gadgets/src/ecc.rs b/halo2_gadgets/src/ecc.rs index 5d99d1807..635bfe9ef 100644 --- a/halo2_gadgets/src/ecc.rs +++ b/halo2_gadgets/src/ecc.rs @@ -15,7 +15,7 @@ pub mod utilities; /// The set of circuit instructions required to use the ECC gadgets. pub trait EccInstructions: - Chip + UtilitiesInstructions + Clone + Debug + Eq + Chip + UtilitiesInstructions + Debug { /// Variable representing a scalar used in variable-base scalar /// mul. Internally both scalar-field scalars and base-field @@ -295,7 +295,7 @@ pub struct NonIdentityPoint> { inner: EccChip::NonIdentityPoint, } -impl> NonIdentityPoint { +impl + Eq + Clone> NonIdentityPoint { /// Constructs a new point with the given value. pub fn new( chip: EccChip, @@ -524,12 +524,12 @@ pub struct FixedPointBaseField> { /// Precomputed multiples of a fixed point, for short signed scalar multiplication. #[derive(Clone, Debug)] -pub struct FixedPointShort> { +pub struct FixedPointShort + Eq> { chip: EccChip, inner: >::ShortScalar, } -impl> FixedPoint { +impl + Eq + Clone> FixedPoint { #[allow(clippy::type_complexity)] /// Returns `[by] self`. pub fn mul( @@ -563,7 +563,7 @@ impl> FixedPoint { } } -impl> FixedPointBaseField { +impl + Eq + Clone> FixedPointBaseField { #[allow(clippy::type_complexity)] /// Returns `[by] self`. pub fn mul( @@ -588,7 +588,7 @@ impl> FixedPointBaseField> FixedPointShort { +impl + Eq + Clone> FixedPointShort { #[allow(clippy::type_complexity)] /// Returns `[by] self`. pub fn mul( diff --git a/halo2_gadgets/src/lib.rs b/halo2_gadgets/src/lib.rs index 8cdc9c293..8896d284b 100644 --- a/halo2_gadgets/src/lib.rs +++ b/halo2_gadgets/src/lib.rs @@ -26,6 +26,8 @@ pub mod ecc; pub mod endoscale; pub mod poseidon; +pub mod recursive_chip; +pub mod recursive_circuits; #[cfg(feature = "unstable")] #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))] pub mod sha256; diff --git a/halo2_gadgets/src/recursive_chip.rs b/halo2_gadgets/src/recursive_chip.rs new file mode 100644 index 000000000..dd65436d9 --- /dev/null +++ b/halo2_gadgets/src/recursive_chip.rs @@ -0,0 +1,474 @@ +//! Chip for recursive proof verification + +use halo2_proofs::{ + circuit::{AssignedCell, Chip, Layouter, Value}, + plonk::{Advice, Assigned, Column, ConstraintSystem, Error, Fixed, Instance, TableColumn}, + poseidon::{duplex::DuplexDomain, P128Pow5T3}, +}; +use halo2curves::{pasta, CurveAffine}; +use std::{fmt::Debug, io::Read}; + +use crate::{ + ecc::{ + chip::{BaseFieldElem, EccChip, FixedPoint, FullScalar, ShortScalar}, + EccInstructions, FixedPoints, + }, + endoscale::{ + chip::{CurveEndoscale, EndoscaleChip}, + EndoscaleInstructions, + }, + poseidon::Pow5Chip, + recursive_circuits::RecurseCurve, + transcript::{ + chip::{TranscriptChip, TranscriptChipP128Pow5T3}, + read_chip::TranscriptReaderChip, + TranscriptInstructions, TranscriptReadInstructions, + }, + utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions}, +}; + +/// Configuration for [`RecursiveChip`] +pub struct RecursiveChipConfig< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, +> { + ecc_config: Ecc::Config, + endo_config: Endo::Config, + transcript_config: T::Config, +} + +impl< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, + > Debug for RecursiveChipConfig +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("RecursiveChipConfig") + .field("ecc_config", &self.ecc_config) + .field("endo_config", &self.endo_config) + .field("transcript_config", &self.transcript_config) + .finish() + } +} + +impl< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, + > Clone for RecursiveChipConfig +{ + fn clone(&self) -> Self { + Self { + ecc_config: self.ecc_config.clone(), + endo_config: self.endo_config.clone(), + transcript_config: self.transcript_config.clone(), + } + } +} + +/// Wrapper chip designed to be used for recursive Halo2 proof verification. +#[derive(Clone, Debug)] +pub struct RecursiveChip< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, +> { + ecc_chip: Ecc, + endo_chip: Endo, + transcript_chip: T, + config: RecursiveChipConfig, +} + +type C = pasta::pallas::Affine; // Limitation of `EccChip` (will be generalized later) +const K: usize = 0; // We won't be using Algorithm 2 yet, so no reason to have this table +const MAX_BITSTRING_LENGTH: usize = ::MAX_BITSTRING_LENGTH; + +type Endo = EndoscaleChip; +type P = Pow5Chip<::Base, { P128Pow5T3::WIDTH }, { P128Pow5T3::RATE }>; +type TR = + TranscriptReaderChip, TranscriptChipP128Pow5T3, R>; + +/// [`RecursiveChip`] instantiated with [`EndoscaleChip`], [`Pow5Chip`], and [`TranscriptReaderChip`] +pub type DefaultRecursiveChip = + RecursiveChip, Endo, TR>; + +impl< + // C: CurveAffine, -- will be generalized once `EccChip` is ready + FP, + D, + R, + const L: usize, + > DefaultRecursiveChip +where + FP: FixedPoints, + >::Base: FixedPoint, + >::FullScalar: FixedPoint, + >::ShortScalar: FixedPoint, + D: DuplexDomain<::Base, { P128Pow5T3::RATE }, L>, + R: Read + Debug, +{ + /// Construct a [`RecursiveChip`] using internal ecc, endoscaling, and transcript chips as well as its configuration. + pub fn init( + mut layouter: impl Layouter<::Base>, + config: RecursiveChipConfig, Endo, TR>, + proof: Value, + ) -> Result { + let ecc_chip = EccChip::construct(config.ecc_config.clone()); + let endo_chip = EndoscaleChip::construct(config.endo_config.clone()); + + let pow5 = Pow5Chip::construct(config.transcript_config.inner_transcript_config().clone()); + let transcript_chip = + TranscriptChip::init_with_poseidon(layouter.namespace(|| "init poseidon"), pow5)?; + + let transcript_chip = TranscriptReaderChip::construct( + transcript_chip, + ecc_chip.clone(), + proof, + config.transcript_config.clone(), + ); + + ecc_chip.config().lookup_config.load(&mut layouter)?; + + Ok(Self { + ecc_chip, + endo_chip, + transcript_chip, + config, + }) + } + + /// Build the configuration for a [`RecursiveChip`] given sufficient columns. + pub fn configure( + meta: &mut ConstraintSystem<::Base>, + advice: [Column; 10], + fixed: [Column; 8], + instance: [Column; 1], + lookup_range_check_table_idx: TableColumn, + ) -> RecursiveChipConfig, Endo, TR> { + // Shared fixed column for loading constants + let constants = meta.fixed_column(); + meta.enable_constant(constants); + + let lookup_config = + LookupRangeCheckConfig::configure(meta, advice[9], lookup_range_check_table_idx); + let ecc_config = EccChip::configure(meta, advice, fixed, lookup_config); + let endo_advice = advice[0..8].try_into().expect("unreachable"); + let endo_config = EndoscaleChip::configure(meta, endo_advice, advice[9], instance[0]); + let transcript_state = advice[0..3].try_into().expect("unreachable"); + let transcript_rc_a = fixed[0..3].try_into().expect("unreachable"); + let transcript_rc_b = fixed[3..6].try_into().expect("unreachable"); + let transcript_config = Pow5Chip::configure::( + meta, + transcript_state, + advice[3], + transcript_rc_a, + transcript_rc_b, + ); + let transcript_reader_config = + TranscriptReaderChip::configure(ecc_config.clone(), transcript_config); + + RecursiveChipConfig { + ecc_config, + endo_config, + transcript_config: transcript_reader_config, + } + } +} + +impl< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, + > Chip for RecursiveChip +{ + type Config = RecursiveChipConfig; + type Loaded = (); + + fn config(&self) -> &Self::Config { + &self.config + } + + fn loaded(&self) -> &Self::Loaded { + &() + } +} + +impl< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, + > TranscriptInstructions for RecursiveChip +{ + type DecompScalar = T::DecompScalar; + type NonIdentityEccPoint = T::NonIdentityEccPoint; + + fn squeeze_challenge( + &mut self, + layouter: impl Layouter, + ) -> Result, Error> { + self.transcript_chip.squeeze_challenge(layouter) + } + + fn common_scalar( + &mut self, + layouter: impl Layouter, + scalar: Self::DecompScalar, + ) -> Result<(), Error> { + self.transcript_chip.common_scalar(layouter, scalar) + } + + fn common_point( + &mut self, + layouter: impl Layouter, + point: Self::NonIdentityEccPoint, + ) -> Result<(), Error> { + self.transcript_chip.common_point(layouter, point) + } +} + +impl< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, + > TranscriptReadInstructions for RecursiveChip +{ + fn read_point( + &mut self, + layouter: impl Layouter, + ) -> Result { + self.transcript_chip.read_point(layouter) + } + + fn read_scalar(&mut self, layouter: impl Layouter) -> Result { + self.transcript_chip.read_scalar(layouter) + } +} + +impl< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, + > EndoscaleInstructions for RecursiveChip +{ + type NonIdentityPoint = Endo::NonIdentityPoint; + type Bitstring = Endo::Bitstring; + type FixedBases = Endo::FixedBases; + const MAX_BITSTRING_LENGTH: usize = Endo::MAX_BITSTRING_LENGTH; + const NUM_FIXED_BASES: usize = Endo::NUM_FIXED_BASES; + + fn witness_bitstring( + &self, + layouter: &mut impl Layouter, + bits: &[Value], + for_base: bool, + ) -> Result, Error> { + self.endo_chip.witness_bitstring(layouter, bits, for_base) + } + + fn convert_to_bitstring( + &self, + layouter: &mut impl Layouter, + challenge: &AssignedCell, + ) -> Result { + self.endo_chip.convert_to_bitstring(layouter, challenge) + } + + fn endoscale_fixed_base( + &self, + layouter: &mut impl Layouter, + bitstring: Vec, + bases: Vec, + ) -> Result, Error> { + self.endo_chip + .endoscale_fixed_base(layouter, bitstring, bases) + } + + fn endoscale_var_base( + &self, + layouter: &mut impl Layouter, + bitstring: Vec, + bases: Vec, + ) -> Result, Error> { + self.endo_chip + .endoscale_var_base(layouter, bitstring, bases) + } + + fn compute_endoscalar( + &self, + layouter: &mut impl Layouter, + bitstring: &Self::Bitstring, + ) -> Result, C::Base>, Error> { + self.endo_chip.compute_endoscalar(layouter, bitstring) + } + + fn constrain_bitstring( + &self, + layouter: &mut impl Layouter, + bitstring: &Self::Bitstring, + pub_input_rows: Vec, + ) -> Result<(), Error> { + self.endo_chip + .constrain_bitstring(layouter, bitstring, pub_input_rows) + } +} + +impl< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, + > UtilitiesInstructions for RecursiveChip +{ + type Var = Ecc::Var; +} + +impl< + C: RecurseCurve, + Ecc: EccInstructions, + Endo: EndoscaleInstructions, + T: TranscriptReadInstructions, + > EccInstructions for RecursiveChip +{ + type ScalarVar = Ecc::ScalarVar; + type ScalarFixed = Ecc::ScalarFixed; + type ScalarFixedShort = Ecc::ScalarFixedShort; + type Point = Ecc::Point; + type NonIdentityPoint = Ecc::NonIdentityPoint; + type X = Ecc::X; + type FixedPoints = Ecc::FixedPoints; + + fn constrain_equal( + &self, + layouter: &mut impl Layouter, + a: &Self::Point, + b: &Self::Point, + ) -> Result<(), Error> { + self.ecc_chip.constrain_equal(layouter, a, b) + } + + fn ensure_non_id( + &self, + layouter: &mut impl Layouter, + point: &Self::Point, + ) -> Result { + self.ecc_chip.ensure_non_id(layouter, point) + } + + fn witness_point( + &self, + layouter: &mut impl Layouter, + value: Value, + ) -> Result { + self.ecc_chip.witness_point(layouter, value) + } + + fn witness_point_non_id( + &self, + layouter: &mut impl Layouter, + value: Value, + ) -> Result { + self.ecc_chip.witness_point_non_id(layouter, value) + } + + fn witness_scalar_var( + &self, + layouter: &mut impl Layouter, + value: Value, + ) -> Result { + self.ecc_chip.witness_scalar_var(layouter, value) + } + + fn witness_scalar_fixed( + &self, + layouter: &mut impl Layouter, + value: Value, + ) -> Result { + self.ecc_chip.witness_scalar_fixed(layouter, value) + } + + fn scalar_fixed_from_signed_short( + &self, + layouter: &mut impl Layouter, + magnitude_sign: (Self::Var, Self::Var), + ) -> Result { + self.ecc_chip + .scalar_fixed_from_signed_short(layouter, magnitude_sign) + } + + fn extract_p + Clone>(point: &Point) -> Self::X { + Ecc::extract_p(point) + } + + fn add_incomplete( + &self, + layouter: &mut impl Layouter, + a: &Self::NonIdentityPoint, + b: &Self::NonIdentityPoint, + ) -> Result { + self.ecc_chip.add_incomplete(layouter, a, b) + } + + fn add + Clone, B: Into + Clone>( + &self, + layouter: &mut impl Layouter, + a: &A, + b: &B, + ) -> Result { + self.ecc_chip.add(layouter, a, b) + } + + fn mul( + &self, + layouter: &mut impl Layouter, + scalar: &Self::ScalarVar, + base: &Self::NonIdentityPoint, + ) -> Result<(Self::Point, Self::ScalarVar), Error> { + self.ecc_chip.mul(layouter, scalar, base) + } + + fn mul_fixed( + &self, + layouter: &mut impl Layouter, + scalar: &Self::ScalarFixed, + base: &>::FullScalar, + ) -> Result<(Self::Point, Self::ScalarFixed), Error> { + self.ecc_chip.mul_fixed(layouter, scalar, base) + } + + fn mul_fixed_short( + &self, + layouter: &mut impl Layouter, + scalar: &Self::ScalarFixedShort, + base: &>::ShortScalar, + ) -> Result<(Self::Point, Self::ScalarFixedShort), Error> { + self.ecc_chip.mul_fixed_short(layouter, scalar, base) + } + + fn mul_fixed_base_field_elem( + &self, + layouter: &mut impl Layouter, + base_field_elem: Self::Var, + base: &>::Base, + ) -> Result { + self.ecc_chip + .mul_fixed_base_field_elem(layouter, base_field_elem, base) + } + + fn double( + &self, + layouter: &mut impl Layouter, + p: &Self::NonIdentityPoint, + ) -> Result { + self.ecc_chip.double(layouter, p) + } +} diff --git a/halo2_gadgets/src/recursive_circuits.rs b/halo2_gadgets/src/recursive_circuits.rs new file mode 100644 index 000000000..b5da049f3 --- /dev/null +++ b/halo2_gadgets/src/recursive_circuits.rs @@ -0,0 +1,5 @@ +//! Implementation of recrusive verification circuit subroutines + +mod recursive_gadgets; + +pub use recursive_gadgets::{RecurseChip, RecurseCurve}; diff --git a/halo2_gadgets/src/recursive_circuits/recursive_gadgets.rs b/halo2_gadgets/src/recursive_circuits/recursive_gadgets.rs new file mode 100644 index 000000000..b4f6fe0f4 --- /dev/null +++ b/halo2_gadgets/src/recursive_circuits/recursive_gadgets.rs @@ -0,0 +1,54 @@ +use crate::utilities::high_low_decomp; +use halo2curves::CurveAffine; + +use crate::{ + ecc::{chip::ScalarVar, EccInstructions}, + endoscale::EndoscaleInstructions, + transcript::TranscriptReadInstructions, +}; + +/// Curve alias +pub trait RecurseCurve: CurveAffine::NativeField> { + /// The native field must implement [`ff::PrimeFieldBits`] to support endoscaling + type NativeField: ff::PrimeFieldBits; +} + +impl RecurseCurve for C +where + C::Base: ff::PrimeFieldBits, +{ + type NativeField = C::Base; +} + +/// Chip alias +pub trait RecurseChip: + TranscriptReadInstructions< + C, + DecompScalar = Self::ScalarVar, + NonIdentityEccPoint = >::NonIdentityPoint, + > + EccInstructions> + + EndoscaleInstructions< + C, + FixedBases = C, + NonIdentityPoint = >::NonIdentityPoint, + > +where + ::ScalarExt: high_low_decomp::ScalarOrBase, +{ +} + +impl RecurseChip for Chip +where + Chip: TranscriptReadInstructions< + C, + DecompScalar = Self::ScalarVar, + NonIdentityEccPoint = >::NonIdentityPoint, + > + EccInstructions> + + EndoscaleInstructions< + C, + FixedBases = C, + NonIdentityPoint = >::NonIdentityPoint, + >, + ::ScalarExt: high_low_decomp::ScalarOrBase, +{ +} diff --git a/halo2_gadgets/src/transcript.rs b/halo2_gadgets/src/transcript.rs index 65de4d14e..b2ccd13c5 100644 --- a/halo2_gadgets/src/transcript.rs +++ b/halo2_gadgets/src/transcript.rs @@ -32,7 +32,7 @@ pub trait TranscriptInstructions: Chip + Debug { type DecompScalar: Clone + Debug; /// The representation of a witnessed elliptic curve point - type EccPoint: Clone + Debug; + type NonIdentityEccPoint: Clone + Debug; /// Emit a challenge from the transcript. fn squeeze_challenge( @@ -43,7 +43,7 @@ pub trait TranscriptInstructions: Chip + Debug { fn common_point( &mut self, layouter: impl Layouter, - point: Self::EccPoint, + point: Self::NonIdentityEccPoint, ) -> Result<(), Error>; /// Absorb a scalar element into the transcript. fn common_scalar( @@ -61,7 +61,10 @@ pub trait TranscriptReadInstructions: TranscriptInstructions /// /// Note: The implementer is responsible for passing the read value into [`TranscriptInstructions::common_point`] /// in order to correctly implement Fiat-Shamir - fn read_point(&mut self, layouter: impl Layouter) -> Result; + fn read_point( + &mut self, + layouter: impl Layouter, + ) -> Result; /// Read a scalar from the transcript /// diff --git a/halo2_gadgets/src/transcript/chip.rs b/halo2_gadgets/src/transcript/chip.rs index 573e635d5..af7de75b5 100644 --- a/halo2_gadgets/src/transcript/chip.rs +++ b/halo2_gadgets/src/transcript/chip.rs @@ -97,7 +97,7 @@ where C::Scalar: ScalarOrBase, { type DecompScalar = ScalarVar; - type EccPoint = NonIdentityEccPoint; + type NonIdentityEccPoint = NonIdentityEccPoint; fn squeeze_challenge( &mut self, @@ -265,7 +265,7 @@ mod transcript_chip_tests { fn transcript_chip_absorb_squeeze>( mut layouter: impl Layouter, transcript: &mut T, - point: T::EccPoint, + point: T::NonIdentityEccPoint, scalar: T::DecompScalar, config: &BaseConfig, ) -> Result<(), Error> diff --git a/halo2_gadgets/src/transcript/read_chip.rs b/halo2_gadgets/src/transcript/read_chip.rs index 82d09186b..0f24a65d1 100644 --- a/halo2_gadgets/src/transcript/read_chip.rs +++ b/halo2_gadgets/src/transcript/read_chip.rs @@ -3,6 +3,7 @@ use std::{ fmt::Debug, io::{self, ErrorKind, Read}, + marker::PhantomData, }; use super::TranscriptReadInstructions; @@ -31,7 +32,7 @@ where ecc_chip: ECC, transcript_chip: T, proof: Value, - config: TranscriptReaderConfig, + config: TranscriptReaderConfig, } /// Circuit configuration used in [`TranscriptReaderChip`] @@ -39,7 +40,7 @@ where /// Chip uses an internal [`TranscriptInstructions`] for Fiat-Shamir style hashing of points/scalars /// and [`EccInstructions`] for witnessing points/scalars parsed from a reader. #[derive(Debug)] -pub struct TranscriptReaderConfig +pub struct TranscriptReaderConfig where C: CurveAffine, ECC: EccInstructions, @@ -47,13 +48,31 @@ where { ecc_config: ECC::Config, transcript_config: T::Config, + phantom: PhantomData, +} + +impl TranscriptReaderConfig +where + C: CurveAffine, + ECC: EccInstructions, + T: TranscriptInstructions, +{ + /// Retrieves `Config` of inner `EccChip` + pub fn inner_ecc_config(&self) -> &ECC::Config { + &self.ecc_config + } + + /// Retrieves `Config` of inner `TranscriptChip` + pub fn inner_transcript_config(&self) -> &T::Config { + &self.transcript_config + } } // We implement this manually due to a limitation of derive() that requires all generics to // implement `Clone` instead of just needing a `Clone`-able `ECC::Config` and `T::Config`. // // For more information see: https://github.com/rust-lang/lang-team/issues/152 -impl Clone for TranscriptReaderConfig +impl Clone for TranscriptReaderConfig where C: CurveAffine, ECC: EccInstructions, @@ -63,6 +82,7 @@ where Self { ecc_config: self.ecc_config.clone(), transcript_config: self.transcript_config.clone(), + phantom: PhantomData, } } } @@ -70,11 +90,11 @@ where impl Chip for TranscriptReaderChip where C: CurveAffine, - ECC: EccInstructions, + ECC: EccInstructions, T: TranscriptInstructions, R: Read + Debug, { - type Config = TranscriptReaderConfig; + type Config = TranscriptReaderConfig; type Loaded = (); @@ -90,17 +110,18 @@ where impl TranscriptReaderChip where C: CurveAffine, - ECC: EccInstructions, + ECC: EccInstructions, T: TranscriptInstructions, R: Read + Debug, { /// Instantiate [`TranscriptReaderChip`] using internal [`crate::ecc`] and [`crate::transcript`] chips, /// as well as a bytestream which it will parse scalars/points from. - pub fn construct(transcript_chip: T, ecc_chip: ECC, proof: Value) -> Self { - let config = TranscriptReaderConfig { - ecc_config: ecc_chip.config().clone(), - transcript_config: transcript_chip.config().clone(), - }; + pub fn construct( + transcript_chip: T, + ecc_chip: ECC, + proof: Value, + config: TranscriptReaderConfig, + ) -> Self { Self { ecc_chip, transcript_chip, @@ -108,16 +129,29 @@ where config, } } + + /// Construct the configuration [`TranscriptReaderConfig`] given [`crate::ecc`] and + /// [`crate::transcript`] configurations. + pub fn configure( + ecc_config: ECC::Config, + transcript_config: T::Config, + ) -> TranscriptReaderConfig { + TranscriptReaderConfig { + ecc_config, + transcript_config, + phantom: PhantomData, + } + } } impl TranscriptInstructions for TranscriptReaderChip where C: CurveAffine, - ECC: EccInstructions, + ECC: EccInstructions, T: TranscriptInstructions, R: Read + Debug, { - type EccPoint = T::EccPoint; + type NonIdentityEccPoint = T::NonIdentityEccPoint; type DecompScalar = T::DecompScalar; fn squeeze_challenge( @@ -130,7 +164,7 @@ where fn common_point( &mut self, layouter: impl Layouter, - point: T::EccPoint, + point: T::NonIdentityEccPoint, ) -> Result<(), Error> { self.transcript_chip.common_point(layouter, point) } @@ -147,16 +181,23 @@ where impl TranscriptReadInstructions for TranscriptReaderChip where C: CurveAffine, - ECC: EccInstructions, + ECC: EccInstructions, T: TranscriptInstructions, R: Read + Debug, { - fn read_point(&mut self, mut layouter: impl Layouter) -> Result { + fn read_point( + &mut self, + mut layouter: impl Layouter, + ) -> Result { let mut compressed = Value::known(C::Repr::default()); self.proof .as_mut() .zip(compressed.as_mut()) - .map(|(proof, compressed)| proof.read_exact(compressed.as_mut())); + .map(|(proof, compressed)| { + proof + .read_exact(compressed.as_mut()) + .expect("Couldn't read this much!") + }); let point = compressed.map(|compressed| Option::from(C::from_bytes(&compressed))); @@ -212,7 +253,7 @@ mod transcript_read { use ff::Field; use group::{Curve, Group}; use halo2_proofs::{ - circuit::{Layouter, SimpleFloorPlanner, Value}, + circuit::{Chip, Layouter, SimpleFloorPlanner, Value}, dev::MockProver, generate_default_duplex_domain, plonk::{Circuit, Column, ConstraintSystem, Error, Instance}, @@ -345,8 +386,16 @@ mod transcript_read { )?; let ecc_chip = EccChip::construct(config.ecc_config.clone()); - let mut transcript = - TranscriptReaderChip::construct(transcript_chip, ecc_chip, self.proof.clone()); + let transcript_reader_config = TranscriptReaderChip::configure( + ecc_chip.config().clone(), + transcript_chip.config().clone(), + ); + let mut transcript = TranscriptReaderChip::construct( + transcript_chip, + ecc_chip, + self.proof.clone(), + transcript_reader_config, + ); transcript.read_point(layouter.namespace(|| "Read point"))?; transcript.read_scalar(layouter.namespace(|| "Read scalar"))?;