diff --git a/halo2_gadgets/Cargo.toml b/halo2_gadgets/Cargo.toml index 6025ef7297..136ef63a16 100644 --- a/halo2_gadgets/Cargo.toml +++ b/halo2_gadgets/Cargo.toml @@ -24,11 +24,11 @@ rustdoc-args = ["--cfg", "docsrs", "--html-in-header", "katex-header.html"] [dependencies] arrayvec = "0.7.0" bitvec = "1" -ff = "0.12" -group = "0.12" +ff = { version = "0.13", features = ["bits"] } +group = "0.13" halo2_proofs = { version = "0.2", path = "../halo2_proofs" } lazy_static = "1" -halo2curves = { git = 'https://github.com/privacy-scaling-explorations/halo2curves', tag = '0.3.0' } +halo2curves = { git = 'https://github.com/privacy-scaling-explorations/halo2curves', tag = "0.3.2" } proptest = { version = "1.0.0", optional = true } rand = "0.8" subtle = "2.3" diff --git a/halo2_gadgets/benches/poseidon.rs b/halo2_gadgets/benches/poseidon.rs index e8cfa08714..4494e77a0f 100644 --- a/halo2_gadgets/benches/poseidon.rs +++ b/halo2_gadgets/benches/poseidon.rs @@ -21,7 +21,7 @@ use halo2_proofs::{ use halo2curves::pasta::{pallas, vesta, EqAffine, Fp}; use halo2_gadgets::poseidon::{ - primitives::{self as poseidon, ConstantLength, Spec}, + primitives::{self as poseidon, generate_constants, ConstantLength, Mds, Spec}, Hash, Pow5Chip, Pow5Config, }; use std::convert::TryInto; @@ -139,6 +139,10 @@ impl Spec for MySpec usize { 0 } + + fn constants() -> (Vec<[Fp; WIDTH]>, Mds, Mds) { + generate_constants::<_, Self, WIDTH, RATE>() + } } const K: u32 = 7; diff --git a/halo2_gadgets/src/ecc/chip/add.rs b/halo2_gadgets/src/ecc/chip/add.rs index 9f24d0d7dd..11661d51e2 100644 --- a/halo2_gadgets/src/ecc/chip/add.rs +++ b/halo2_gadgets/src/ecc/chip/add.rs @@ -1,10 +1,11 @@ use super::EccPoint; +use ff::PrimeField; use halo2_proofs::{ circuit::Region, plonk::{Advice, Assigned, Column, ConstraintSystem, Constraints, Error, Expression, Selector}, poly::Rotation, }; -use halo2curves::{pasta::pallas, FieldExt}; +use halo2curves::pasta::pallas; use std::collections::HashSet; #[derive(Clone, Copy, Debug, Eq, PartialEq)] diff --git a/halo2_gadgets/src/ecc/chip/constants.rs b/halo2_gadgets/src/ecc/chip/constants.rs index cecbbae99a..6296165464 100644 --- a/halo2_gadgets/src/ecc/chip/constants.rs +++ b/halo2_gadgets/src/ecc/chip/constants.rs @@ -6,7 +6,7 @@ use group::{ Curve, }; use halo2_proofs::arithmetic::lagrange_interpolate; -use halo2curves::{pasta::pallas, CurveAffine, FieldExt}; +use halo2curves::{pasta::pallas, CurveAffine}; /// Window size for fixed-base scalar multiplication pub const FIXED_BASE_WINDOW_SIZE: usize = 3; @@ -61,7 +61,7 @@ fn compute_window_table(base: C, num_windows: usize) -> Vec<[C; // Generate window table entries for the last window, w = `num_windows - 1`. // For the last window, we compute [k * (2^3)^w - sum]B, where sum is defined // as sum = \sum_{j = 0}^{`num_windows - 2`} 2^{3j+1} - let sum = (0..(num_windows - 1)).fold(C::Scalar::zero(), |acc, j| { + let sum = (0..(num_windows - 1)).fold(C::Scalar::ZERO, |acc, j| { acc + C::Scalar::from(2).pow(&[FIXED_BASE_WINDOW_SIZE as u64 * j as u64 + 1, 0, 0, 0]) }); window_table.push( @@ -181,7 +181,7 @@ pub fn test_lagrange_coeffs(base: C, num_windows: usize) { .rev() .cloned() .reduce(|acc, coeff| acc * x + coeff) - .unwrap_or_else(C::Base::zero) + .unwrap_or(C::Base::ZERO) } let lagrange_coeffs = compute_lagrange_coeffs(base, num_windows); @@ -213,7 +213,7 @@ pub fn test_lagrange_coeffs(base: C, num_windows: usize) { // Compute the actual x-coordinate of the multiple [k * (8^84) - offset]B, // where offset = \sum_{j = 0}^{83} 2^{3j+1} - let offset = (0..(num_windows - 1)).fold(C::Scalar::zero(), |acc, w| { + let offset = (0..(num_windows - 1)).fold(C::Scalar::ZERO, |acc, w| { acc + C::Scalar::from(2).pow(&[FIXED_BASE_WINDOW_SIZE as u64 * w as u64 + 1, 0, 0, 0]) }); let scalar = C::Scalar::from(bits as u64) @@ -229,8 +229,9 @@ pub fn test_lagrange_coeffs(base: C, num_windows: usize) { #[cfg(test)] mod tests { + use ff::FromUniformBytes; use group::{ff::Field, Curve, Group}; - use halo2curves::{pasta::pallas, CurveAffine, FieldExt}; + use halo2curves::{pasta::pallas, CurveAffine}; use proptest::prelude::*; use super::{compute_window_table, find_zs_and_us, test_lagrange_coeffs, H, NUM_WINDOWS}; @@ -241,7 +242,7 @@ mod tests { // Instead of rejecting out-of-range bytes, let's reduce them. let mut buf = [0; 64]; buf[..32].copy_from_slice(&bytes); - let scalar = pallas::Scalar::from_bytes_wide(&buf); + let scalar = pallas::Scalar::from_uniform_bytes(&buf); pallas::Point::generator() * scalar } } diff --git a/halo2_gadgets/src/ecc/chip/mul.rs b/halo2_gadgets/src/ecc/chip/mul.rs index 26c705a17c..7896bf58bd 100644 --- a/halo2_gadgets/src/ecc/chip/mul.rs +++ b/halo2_gadgets/src/ecc/chip/mul.rs @@ -8,16 +8,15 @@ use std::{ ops::{Deref, Range}, }; -use ff::PrimeField; use halo2_proofs::{ - arithmetic::FieldExt, + arithmetic::Field, circuit::{AssignedCell, Layouter, Region, Value}, plonk::{Advice, Assigned, Column, ConstraintSystem, Constraints, Error, Selector}, poly::Rotation, }; -use uint::construct_uint; - +use halo2curves::group::ff::PrimeField; use halo2curves::pasta::pallas; +use uint::construct_uint; mod complete; pub(super) mod incomplete; @@ -389,8 +388,8 @@ impl Config { #[derive(Clone, Debug)] // `x`-coordinate of the accumulator. -struct X(AssignedCell, F>); -impl Deref for X { +struct X(AssignedCell, F>); +impl Deref for X { type Target = AssignedCell, F>; fn deref(&self) -> &Self::Target { @@ -400,8 +399,8 @@ impl Deref for X { #[derive(Clone, Debug)] // `y`-coordinate of the accumulator. -struct Y(AssignedCell, F>); -impl Deref for Y { +struct Y(AssignedCell, F>); +impl Deref for Y { type Target = AssignedCell, F>; fn deref(&self) -> &Self::Target { @@ -411,8 +410,8 @@ impl Deref for Y { #[derive(Clone, Debug)] // Cumulative sum `z` used to decompose the scalar. -struct Z(AssignedCell); -impl Deref for Z { +struct Z(AssignedCell); +impl Deref for Z { type Target = AssignedCell; fn deref(&self) -> &Self::Target { diff --git a/halo2_gadgets/src/ecc/chip/mul/incomplete.rs b/halo2_gadgets/src/ecc/chip/mul/incomplete.rs index bfe51c7e2e..9b1d7494e6 100644 --- a/halo2_gadgets/src/ecc/chip/mul/incomplete.rs +++ b/halo2_gadgets/src/ecc/chip/mul/incomplete.rs @@ -1,6 +1,7 @@ use super::super::NonIdentityEccPoint; use super::{X, Y, Z}; use crate::utilities::bool_check; +use ff::PrimeField; use halo2_proofs::{ circuit::{Region, Value}, plonk::{ @@ -8,7 +9,7 @@ use halo2_proofs::{ }, poly::Rotation, }; -use halo2curves::{pasta::pallas, FieldExt}; +use halo2curves::pasta::pallas; /// A helper struct for implementing single-row double-and-add using incomplete addition. #[derive(Copy, Clone, Debug, Eq, PartialEq)] diff --git a/halo2_gadgets/src/ecc/chip/mul/overflow.rs b/halo2_gadgets/src/ecc/chip/mul/overflow.rs index 0d7bd69692..3625ff73db 100644 --- a/halo2_gadgets/src/ecc/chip/mul/overflow.rs +++ b/halo2_gadgets/src/ecc/chip/mul/overflow.rs @@ -9,8 +9,8 @@ use halo2_proofs::{ plonk::{Advice, Assigned, Column, ConstraintSystem, Constraints, Error, Expression, Selector}, poly::Rotation, }; - -use halo2curves::{pasta::pallas, FieldExt}; +use halo2curves::group::ff::PrimeField; +use halo2curves::pasta::pallas; use std::iter; diff --git a/halo2_gadgets/src/ecc/chip/mul_fixed.rs b/halo2_gadgets/src/ecc/chip/mul_fixed.rs index 909dd171d3..0005a108bb 100644 --- a/halo2_gadgets/src/ecc/chip/mul_fixed.rs +++ b/halo2_gadgets/src/ecc/chip/mul_fixed.rs @@ -7,7 +7,7 @@ use crate::utilities::decompose_running_sum::RunningSumConfig; use std::marker::PhantomData; use group::{ - ff::{PrimeField, PrimeFieldBits}, + ff::{Field, PrimeField, PrimeFieldBits}, Curve, }; use halo2_proofs::{ @@ -18,7 +18,7 @@ use halo2_proofs::{ }, poly::Rotation, }; -use halo2curves::{pasta::pallas, CurveAffine, FieldExt}; +use halo2curves::{pasta::pallas, CurveAffine}; use lazy_static::lazy_static; pub mod base_field_elem; diff --git a/halo2_gadgets/src/ecc/chip/mul_fixed/base_field_elem.rs b/halo2_gadgets/src/ecc/chip/mul_fixed/base_field_elem.rs index 08fd34e313..91671847a2 100644 --- a/halo2_gadgets/src/ecc/chip/mul_fixed/base_field_elem.rs +++ b/halo2_gadgets/src/ecc/chip/mul_fixed/base_field_elem.rs @@ -13,7 +13,7 @@ use halo2_proofs::{ plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Expression, Selector}, poly::Rotation, }; -use halo2curves::{pasta::pallas, FieldExt}; +use halo2curves::pasta::pallas; use std::convert::TryInto; diff --git a/halo2_gadgets/src/ecc/chip/mul_fixed/full_width.rs b/halo2_gadgets/src/ecc/chip/mul_fixed/full_width.rs index b82620c283..607c51e534 100644 --- a/halo2_gadgets/src/ecc/chip/mul_fixed/full_width.rs +++ b/halo2_gadgets/src/ecc/chip/mul_fixed/full_width.rs @@ -295,7 +295,7 @@ pub mod tests { // [-1]B is the largest scalar field element. { - let scalar_fixed = -pallas::Scalar::one(); + let scalar_fixed = -pallas::Scalar::ONE; let neg_1 = ScalarFixed::new( chip.clone(), layouter.namespace(|| "-1"), diff --git a/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs b/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs index 844d88d134..4c92becb86 100644 --- a/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs +++ b/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs @@ -209,6 +209,7 @@ impl> Config { // tested at the circuit-level. { use super::super::FixedPoint; + use ff::Field; use group::{ff::PrimeField, Curve}; scalar @@ -228,9 +229,9 @@ impl> Config { let magnitude = pallas::Scalar::from_repr(magnitude.to_repr()).unwrap(); let sign = if sign == &&pallas::Base::one() { - pallas::Scalar::one() + pallas::Scalar::ONE } else { - -pallas::Scalar::one() + -pallas::Scalar::ONE }; magnitude * sign @@ -248,13 +249,16 @@ impl> Config { #[cfg(test)] pub mod tests { - use group::{ff::PrimeField, Curve}; + use group::{ + ff::{Field, PrimeField}, + Curve, + }; use halo2_proofs::{ arithmetic::CurveAffine, circuit::{AssignedCell, Chip, Layouter, Value}, plonk::{Any, Error}, }; - use halo2curves::{pasta::pallas, FieldExt}; + use halo2curves::pasta::pallas; use crate::{ ecc::{ @@ -359,9 +363,9 @@ pub mod tests { let scalar = { let magnitude = pallas::Scalar::from_repr(magnitude.to_repr()).unwrap(); let sign = if *sign == pallas::Base::one() { - pallas::Scalar::one() + pallas::Scalar::ONE } else { - -pallas::Scalar::one() + -pallas::Scalar::ONE }; magnitude * sign }; diff --git a/halo2_gadgets/src/poseidon.rs b/halo2_gadgets/src/poseidon.rs index 1350075146..ffd745ad6d 100644 --- a/halo2_gadgets/src/poseidon.rs +++ b/halo2_gadgets/src/poseidon.rs @@ -4,9 +4,9 @@ use std::convert::TryInto; use std::fmt; use std::marker::PhantomData; +use ff::PrimeField; use group::ff::Field; use halo2_proofs::{ - arithmetic::FieldExt, circuit::{AssignedCell, Chip, Layouter}, plonk::Error, }; @@ -27,7 +27,7 @@ pub enum PaddedWord { } /// The set of circuit instructions required to use the Poseidon permutation. -pub trait PoseidonInstructions, const T: usize, const RATE: usize>: +pub trait PoseidonInstructions, const T: usize, const RATE: usize>: Chip { /// Variable representing the word over which the Poseidon permutation operates. @@ -45,7 +45,7 @@ pub trait PoseidonInstructions, const T: usize, /// /// [`Hash`]: self::Hash pub trait PoseidonSpongeInstructions< - F: FieldExt, + F: Field, S: Spec, D: Domain, const T: usize, @@ -71,7 +71,7 @@ pub trait PoseidonSpongeInstructions< /// A word over which the Poseidon permutation operates. #[derive(Debug)] pub struct Word< - F: FieldExt, + F: Field, PoseidonChip: PoseidonInstructions, S: Spec, const T: usize, @@ -81,7 +81,7 @@ pub struct Word< } impl< - F: FieldExt, + F: Field, PoseidonChip: PoseidonInstructions, S: Spec, const T: usize, @@ -100,7 +100,7 @@ impl< } fn poseidon_sponge< - F: FieldExt, + F: Field, PoseidonChip: PoseidonSpongeInstructions, S: Spec, D: Domain, @@ -122,7 +122,7 @@ fn poseidon_sponge< /// A Poseidon sponge. #[derive(Debug)] pub struct Sponge< - F: FieldExt, + F: Field, PoseidonChip: PoseidonSpongeInstructions, S: Spec, M: SpongeMode, @@ -137,7 +137,7 @@ pub struct Sponge< } impl< - F: FieldExt, + F: Field, PoseidonChip: PoseidonSpongeInstructions, S: Spec, D: Domain, @@ -210,7 +210,7 @@ impl< } impl< - F: FieldExt, + F: Field, PoseidonChip: PoseidonSpongeInstructions, S: Spec, D: Domain, @@ -241,7 +241,7 @@ impl< /// A Poseidon hash function, built around a sponge. #[derive(Debug)] pub struct Hash< - F: FieldExt, + F: Field, PoseidonChip: PoseidonSpongeInstructions, S: Spec, D: Domain, @@ -252,7 +252,7 @@ pub struct Hash< } impl< - F: FieldExt, + F: Field, PoseidonChip: PoseidonSpongeInstructions, S: Spec, D: Domain, @@ -267,7 +267,7 @@ impl< } impl< - F: FieldExt, + F: PrimeField, PoseidonChip: PoseidonSpongeInstructions, T, RATE>, S: Spec, const T: usize, diff --git a/halo2_gadgets/src/poseidon/pow5.rs b/halo2_gadgets/src/poseidon/pow5.rs index 7b9862e5b6..52b0d27312 100644 --- a/halo2_gadgets/src/poseidon/pow5.rs +++ b/halo2_gadgets/src/poseidon/pow5.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; use std::iter; use halo2_proofs::{ - arithmetic::FieldExt, + arithmetic::Field, circuit::{AssignedCell, Cell, Chip, Layouter, Region, Value}, plonk::{ Advice, Any, Column, ConstraintSystem, Constraints, Error, Expression, Fixed, Selector, @@ -18,7 +18,7 @@ use crate::utilities::Var; /// Configuration for a [`Pow5Chip`]. #[derive(Clone, Debug)] -pub struct Pow5Config { +pub struct Pow5Config { pub(crate) state: [Column; WIDTH], partial_sbox: Column, rc_a: [Column; WIDTH], @@ -40,11 +40,11 @@ pub struct Pow5Config { /// The chip is implemented using a single round per row for full rounds, and two rounds /// per row for partial rounds. #[derive(Debug)] -pub struct Pow5Chip { +pub struct Pow5Chip { config: Pow5Config, } -impl Pow5Chip { +impl Pow5Chip { /// Configures this chip for use in a circuit. /// /// # Side-effects @@ -209,7 +209,7 @@ impl Pow5Chip Chip for Pow5Chip { +impl Chip for Pow5Chip { type Config = Pow5Config; type Loaded = (); @@ -222,7 +222,7 @@ impl Chip for Pow5Chip, const WIDTH: usize, const RATE: usize> +impl, const WIDTH: usize, const RATE: usize> PoseidonInstructions for Pow5Chip { type Word = StateWord; @@ -273,7 +273,7 @@ impl, const WIDTH: usize, const RATE: usize } impl< - F: FieldExt, + F: Field, S: Spec, D: Domain, const WIDTH: usize, @@ -302,7 +302,7 @@ impl< }; for i in 0..RATE { - load_state_word(i, F::zero())?; + load_state_word(i, F::ZERO)?; } load_state_word(RATE, D::initial_capacity_element())?; @@ -372,7 +372,7 @@ impl< .get(i) .map(|word| word.0.value().cloned()) // The capacity element is never altered by the input. - .unwrap_or_else(|| Value::known(F::zero())); + .unwrap_or_else(|| Value::known(F::ZERO)); region .assign_advice( || format!("load output_{}", i), @@ -403,21 +403,21 @@ impl< /// A word in the Poseidon state. #[derive(Clone, Debug)] -pub struct StateWord(AssignedCell); +pub struct StateWord(AssignedCell); -impl From> for AssignedCell { +impl From> for AssignedCell { fn from(state_word: StateWord) -> AssignedCell { state_word.0 } } -impl From> for StateWord { +impl From> for StateWord { fn from(cell_value: AssignedCell) -> StateWord { StateWord(cell_value) } } -impl Var for StateWord { +impl Var for StateWord { fn cell(&self) -> Cell { self.0.cell() } @@ -428,9 +428,9 @@ impl Var for StateWord { } #[derive(Debug)] -struct Pow5State([StateWord; WIDTH]); +struct Pow5State([StateWord; WIDTH]); -impl Pow5State { +impl Pow5State { fn full_round( self, region: &mut Region, @@ -450,7 +450,7 @@ impl Pow5State { r.as_ref().map(|r| { r.iter() .enumerate() - .fold(F::zero(), |acc, (j, r_j)| acc + m_i[j] * r_j) + .fold(F::ZERO, |acc, (j, r_j)| acc + m_i[j] * r_j) }) }); @@ -491,7 +491,7 @@ impl Pow5State { r.as_ref().map(|r| { m_i.iter() .zip(r.iter()) - .fold(F::zero(), |acc, (m_ij, r_j)| acc + *m_ij * r_j) + .fold(F::ZERO, |acc, (m_ij, r_j)| acc + *m_ij * r_j) }) }) .collect(); @@ -524,7 +524,7 @@ impl Pow5State { r_mid.as_ref().map(|r| { m_i.iter() .zip(r.iter()) - .fold(F::zero(), |acc, (m_ij, r_j)| acc + *m_ij * r_j) + .fold(F::ZERO, |acc, (m_ij, r_j)| acc + *m_ij * r_j) }) }) .collect(); diff --git a/halo2_gadgets/src/poseidon/primitives.rs b/halo2_gadgets/src/poseidon/primitives.rs index 4d7d5b038a..a8662a00e8 100644 --- a/halo2_gadgets/src/poseidon/primitives.rs +++ b/halo2_gadgets/src/poseidon/primitives.rs @@ -5,7 +5,9 @@ use std::fmt; use std::iter; use std::marker::PhantomData; -use halo2_proofs::arithmetic::FieldExt; +use ff::FromUniformBytes; +use ff::PrimeField; +use halo2_proofs::arithmetic::Field; pub(crate) mod fp; pub(crate) mod fq; @@ -27,10 +29,10 @@ pub(crate) type State = [F; T]; pub(crate) type SpongeRate = [Option; RATE]; /// The type used to hold the MDS matrix and its inverse. -pub(crate) type Mds = [[F; T]; T]; +pub type Mds = [[F; T]; T]; /// A specification for a Poseidon permutation. -pub trait Spec: fmt::Debug { +pub trait Spec: fmt::Debug { /// The number of full rounds for this specification. /// /// This must be an even number. @@ -50,33 +52,41 @@ pub trait Spec: fmt::Debug { fn secure_mds() -> usize; /// Generates `(round_constants, mds, mds^-1)` corresponding to this specification. - fn constants() -> (Vec<[F; T]>, Mds, Mds) { - let r_f = Self::full_rounds(); - let r_p = Self::partial_rounds(); - - let mut grain = grain::Grain::new(SboxType::Pow, T as u16, r_f as u16, r_p as u16); - - let round_constants = (0..(r_f + r_p)) - .map(|_| { - let mut rc_row = [F::zero(); T]; - for (rc, value) in rc_row - .iter_mut() - .zip((0..T).map(|_| grain.next_field_element())) - { - *rc = value; - } - rc_row - }) - .collect(); + fn constants() -> (Vec<[F; T]>, Mds, Mds); +} + +/// Generates `(round_constants, mds, mds^-1)` corresponding to this specification. +pub fn generate_constants< + F: FromUniformBytes<64> + Ord, + S: Spec, + const T: usize, + const RATE: usize, +>() -> (Vec<[F; T]>, Mds, Mds) { + let r_f = S::full_rounds(); + let r_p = S::partial_rounds(); - let (mds, mds_inv) = mds::generate_mds::(&mut grain, Self::secure_mds()); + let mut grain = grain::Grain::new(SboxType::Pow, T as u16, r_f as u16, r_p as u16); - (round_constants, mds, mds_inv) - } + let round_constants = (0..(r_f + r_p)) + .map(|_| { + let mut rc_row = [F::ZERO; T]; + for (rc, value) in rc_row + .iter_mut() + .zip((0..T).map(|_| grain.next_field_element())) + { + *rc = value; + } + rc_row + }) + .collect(); + + let (mds, mds_inv) = mds::generate_mds::(&mut grain, S::secure_mds()); + + (round_constants, mds, mds_inv) } /// Runs the Poseidon permutation on the given state. -pub(crate) fn permute, const T: usize, const RATE: usize>( +pub(crate) fn permute, const T: usize, const RATE: usize>( state: &mut State, mds: &Mds, round_constants: &[[F; T]], @@ -85,7 +95,7 @@ pub(crate) fn permute, const T: usize, const RA let r_p = S::partial_rounds(); let apply_mds = |state: &mut State| { - let mut new_state = [F::zero(); T]; + let mut new_state = [F::ZERO; T]; // Matrix multiplication #[allow(clippy::needless_range_loop)] for i in 0..T { @@ -123,7 +133,7 @@ pub(crate) fn permute, const T: usize, const RA }); } -fn poseidon_sponge, const T: usize, const RATE: usize>( +fn poseidon_sponge, const T: usize, const RATE: usize>( state: &mut State, input: Option<&Absorbing>, mds_matrix: &Mds, @@ -180,7 +190,7 @@ impl Absorbing { /// A Poseidon sponge. pub(crate) struct Sponge< - F: FieldExt, + F: Field, S: Spec, M: SpongeMode, const T: usize, @@ -193,7 +203,7 @@ pub(crate) struct Sponge< _marker: PhantomData, } -impl, const T: usize, const RATE: usize> +impl, const T: usize, const RATE: usize> Sponge, T, RATE> { /// Constructs a new sponge for the given Poseidon specification. @@ -201,7 +211,7 @@ impl, const T: usize, const RATE: usize> let (round_constants, mds_matrix, _) = S::constants(); let mode = Absorbing([None; RATE]); - let mut state = [F::zero(); T]; + let mut state = [F::ZERO; T]; state[RATE] = initial_capacity_element; Sponge { @@ -251,7 +261,7 @@ impl, const T: usize, const RATE: usize> } } -impl, const T: usize, const RATE: usize> +impl, const T: usize, const RATE: usize> Sponge, T, RATE> { /// Squeezes an element from the sponge. @@ -275,7 +285,7 @@ impl, const T: usize, const RATE: usize> } /// A domain in which a Poseidon hash function is being used. -pub trait Domain { +pub trait Domain { /// Iterator that outputs padding field elements. type Padding: IntoIterator; @@ -295,7 +305,7 @@ pub trait Domain { #[derive(Clone, Copy, Debug)] pub struct ConstantLength; -impl Domain for ConstantLength { +impl Domain for ConstantLength { type Padding = iter::Take>; fn name() -> String { @@ -315,13 +325,13 @@ impl Domain for Constan // Poseidon authors encode the constant length into the capacity element, ensuring // that inputs of different lengths do not share the same permutation. let k = (L + RATE - 1) / RATE; - iter::repeat(F::zero()).take(k * RATE - L) + iter::repeat(F::ZERO).take(k * RATE - L) } } /// A Poseidon hash function, built around a sponge. pub struct Hash< - F: FieldExt, + F: Field, S: Spec, D: Domain, const T: usize, @@ -331,7 +341,7 @@ pub struct Hash< _domain: PhantomData, } -impl, D: Domain, const T: usize, const RATE: usize> +impl, D: Domain, const T: usize, const RATE: usize> fmt::Debug for Hash { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -345,7 +355,7 @@ impl, D: Domain, const T: usize, const } } -impl, D: Domain, const T: usize, const RATE: usize> +impl, D: Domain, const T: usize, const RATE: usize> Hash { /// Initializes a new hasher. @@ -357,7 +367,7 @@ impl, D: Domain, const T: usize, const } } -impl, const T: usize, const RATE: usize, const L: usize> +impl, const T: usize, const RATE: usize, const L: usize> Hash, T, RATE> { /// Hashes the given input. @@ -374,9 +384,9 @@ impl, const T: usize, const RATE: usize, const #[cfg(test)] mod tests { - use halo2curves::{pasta::pallas, FieldExt}; - use super::{permute, ConstantLength, Hash, P128Pow5T3 as OrchardNullifier, Spec}; + use ff::PrimeField; + use halo2curves::pasta::pallas; #[test] fn orchard_spec_equivalence() { diff --git a/halo2_gadgets/src/poseidon/primitives/grain.rs b/halo2_gadgets/src/poseidon/primitives/grain.rs index f3cf94f761..99711f97f3 100644 --- a/halo2_gadgets/src/poseidon/primitives/grain.rs +++ b/halo2_gadgets/src/poseidon/primitives/grain.rs @@ -3,7 +3,8 @@ use std::marker::PhantomData; use bitvec::prelude::*; -use halo2_proofs::arithmetic::FieldExt; +use ff::{FromUniformBytes, PrimeField}; +use halo2_proofs::arithmetic::Field; const STATE: usize = 80; @@ -43,13 +44,13 @@ impl SboxType { } } -pub(super) struct Grain { +pub(super) struct Grain { state: BitArr!(for 80, in u8, Msb0), next_bit: usize, _field: PhantomData, } -impl Grain { +impl Grain { pub(super) fn new(sbox: SboxType, t: u16, r_f: u16, r_p: u16) -> Self { // Initialize the LFSR state. let mut state = bitarr![u8, Msb0; 1; STATE]; @@ -135,7 +136,9 @@ impl Grain { } } } +} +impl> Grain { /// Returns the next field element from this Grain instantiation, without using /// rejection sampling. pub(super) fn next_field_element_without_rejection(&mut self) -> F { @@ -161,11 +164,11 @@ impl Grain { view[i / 8] |= if bit { 1 << (i % 8) } else { 0 }; } - F::from_bytes_wide(&bytes) + F::from_uniform_bytes(&bytes) } } -impl Iterator for Grain { +impl Iterator for Grain { type Item = bool; fn next(&mut self) -> Option { diff --git a/halo2_gadgets/src/poseidon/primitives/mds.rs b/halo2_gadgets/src/poseidon/primitives/mds.rs index fb809e3a79..892ee11f6b 100644 --- a/halo2_gadgets/src/poseidon/primitives/mds.rs +++ b/halo2_gadgets/src/poseidon/primitives/mds.rs @@ -1,8 +1,8 @@ -use halo2_proofs::arithmetic::FieldExt; +use ff::FromUniformBytes; use super::{grain::Grain, Mds}; -pub(super) fn generate_mds( +pub(super) fn generate_mds + Ord, const T: usize>( grain: &mut Grain, mut select: usize, ) -> (Mds, Mds) { @@ -48,7 +48,7 @@ pub(super) fn generate_mds( // However, the Poseidon paper and reference impl use the positive formulation, // and we want to rely on the reference impl for MDS security, so we use the same // formulation. - let mut mds = [[F::zero(); T]; T]; + let mut mds = [[F::ZERO; T]; T]; #[allow(clippy::needless_range_loop)] for i in 0..T { for j in 0..T { @@ -74,10 +74,10 @@ pub(super) fn generate_mds( // where A_i(x) and B_i(x) are the Lagrange polynomials for xs and ys respectively. // // We adapt this to the positive Cauchy formulation by negating ys. - let mut mds_inv = [[F::zero(); T]; T]; + let mut mds_inv = [[F::ZERO; T]; T]; let l = |xs: &[F], j, x: F| { let x_j = xs[j]; - xs.iter().enumerate().fold(F::one(), |acc, (m, x_m)| { + xs.iter().enumerate().fold(F::ONE, |acc, (m, x_m)| { if m == j { acc } else { diff --git a/halo2_gadgets/src/poseidon/primitives/p128pow5t3.rs b/halo2_gadgets/src/poseidon/primitives/p128pow5t3.rs index 379c399b4e..c8d54d9afd 100644 --- a/halo2_gadgets/src/poseidon/primitives/p128pow5t3.rs +++ b/halo2_gadgets/src/poseidon/primitives/p128pow5t3.rs @@ -66,29 +66,31 @@ impl Spec for P128Pow5T3 { #[cfg(test)] mod tests { - use ff::PrimeField; - use std::marker::PhantomData; - - use halo2curves::FieldExt; - use super::{ super::{fp, fq}, Fp, Fq, }; - use crate::poseidon::primitives::{permute, ConstantLength, Hash, Spec}; + use crate::poseidon::primitives::{ + generate_constants, permute, ConstantLength, Hash, Mds, Spec, + }; + use ff::PrimeField; + use ff::{Field, FromUniformBytes}; + use std::marker::PhantomData; /// The same Poseidon specification as poseidon::P128Pow5T3, but constructed /// such that its constants will be generated at runtime. #[derive(Debug)] - pub struct P128Pow5T3Gen(PhantomData); + pub struct P128Pow5T3Gen(PhantomData); - impl P128Pow5T3Gen { + impl P128Pow5T3Gen { pub fn new() -> Self { P128Pow5T3Gen(PhantomData::default()) } } - impl Spec for P128Pow5T3Gen { + impl + Ord, const SECURE_MDS: usize> Spec + for P128Pow5T3Gen + { fn full_rounds() -> usize { 8 } @@ -98,17 +100,21 @@ mod tests { } fn sbox(val: F) -> F { - val.pow_vartime(&[5]) + val.pow_vartime([5]) } fn secure_mds() -> usize { SECURE_MDS } + + fn constants() -> (Vec<[F; 3]>, Mds, Mds) { + generate_constants::<_, Self, 3, 2>() + } } #[test] fn verify_constants() { - fn verify_constants_helper( + fn verify_constants_helper + Ord>( expected_round_constants: [[F; 3]; 64], expected_mds: [[F; 3]; 3], expected_mds_inv: [[F; 3]; 3], diff --git a/halo2_gadgets/src/sha256.rs b/halo2_gadgets/src/sha256.rs index 19a658df3a..391020a3d3 100644 --- a/halo2_gadgets/src/sha256.rs +++ b/halo2_gadgets/src/sha256.rs @@ -7,7 +7,7 @@ use std::convert::TryInto; use std::fmt; use halo2_proofs::{ - arithmetic::FieldExt, + arithmetic::Field, circuit::{Chip, Layouter}, plonk::Error, }; @@ -22,7 +22,7 @@ pub const BLOCK_SIZE: usize = 16; const DIGEST_SIZE: usize = 8; /// The set of circuit instructions required to use the [`Sha256`] gadget. -pub trait Sha256Instructions: Chip { +pub trait Sha256Instructions: Chip { /// Variable representing the SHA-256 internal state. type State: Clone + fmt::Debug; /// Variable representing a 32-bit word of the input block to the SHA-256 compression @@ -63,14 +63,14 @@ pub struct Sha256Digest([BlockWord; DIGEST_SIZE]); /// A gadget that constrains a SHA-256 invocation. It supports input at a granularity of /// 32 bits. #[derive(Debug)] -pub struct Sha256> { +pub struct Sha256> { chip: CS, state: CS::State, cur_block: Vec, length: usize, } -impl> Sha256 { +impl> Sha256 { /// Create a new hasher instance. pub fn new(chip: Sha256Chip, mut layouter: impl Layouter) -> Result { let state = chip.initialization_vector(&mut layouter)?; diff --git a/halo2_gadgets/src/sha256/table16/compression/compression_gates.rs b/halo2_gadgets/src/sha256/table16/compression/compression_gates.rs index e22a10210c..1cf6a605d7 100644 --- a/halo2_gadgets/src/sha256/table16/compression/compression_gates.rs +++ b/halo2_gadgets/src/sha256/table16/compression/compression_gates.rs @@ -1,15 +1,13 @@ use super::super::{util::*, Gate}; -use halo2_proofs::{ - arithmetic::FieldExt, - plonk::{Constraint, Constraints, Expression}, -}; +use ff::PrimeField; +use halo2_proofs::plonk::{Constraint, Constraints, Expression}; use std::marker::PhantomData; -pub struct CompressionGate(PhantomData); +pub struct CompressionGate(PhantomData); -impl CompressionGate { +impl CompressionGate { fn ones() -> Expression { - Expression::Constant(F::one()) + Expression::Constant(F::ONE) } // Decompose `A,B,C,D` words @@ -59,16 +57,16 @@ impl CompressionGate { + c_mid * F::from(1 << 16) + c_hi * F::from(1 << 19) + d * F::from(1 << 22) - + word_lo * (-F::one()) - + word_hi * F::from(1 << 16) * (-F::one()); + + word_lo * (-F::ONE) + + word_hi * F::from(1 << 16) * (-F::ONE); let spread_check = spread_a + spread_b * F::from(1 << 4) + spread_c_lo * F::from(1 << 26) + spread_c_mid * F::from(1 << 32) + spread_c_hi * F::from(1 << 38) + spread_d * F::from(1 << 44) - + spread_word_lo * (-F::one()) - + spread_word_hi * F::from(1 << 32) * (-F::one()); + + spread_word_lo * (-F::ONE) + + spread_word_hi * F::from(1 << 32) * (-F::ONE); Constraints::with_selector( s_decompose_abcd, @@ -130,16 +128,16 @@ impl CompressionGate { + b_hi * F::from(1 << 8) + c * F::from(1 << 11) + d * F::from(1 << 25) - + word_lo * (-F::one()) - + word_hi * F::from(1 << 16) * (-F::one()); + + word_lo * (-F::ONE) + + word_hi * F::from(1 << 16) * (-F::ONE); let spread_check = spread_a_lo + spread_a_hi * F::from(1 << 6) + spread_b_lo * F::from(1 << 12) + spread_b_hi * F::from(1 << 16) + spread_c * F::from(1 << 22) + spread_d * F::from(1 << 50) - + spread_word_lo * (-F::one()) - + spread_word_hi * F::from(1 << 32) * (-F::one()); + + spread_word_lo * (-F::ONE) + + spread_word_hi * F::from(1 << 32) * (-F::ONE); Constraints::with_selector( s_decompose_efgh, @@ -189,7 +187,7 @@ impl CompressionGate { + spread_c_mid * F::from(1 << 52) + spread_c_hi * F::from(1 << 58); let xor = xor_0 + xor_1 + xor_2; - let check = spread_witness + (xor * -F::one()); + let check = spread_witness + (xor * -F::ONE); Some(("s_upper_sigma_0", s_upper_sigma_0 * check)) } @@ -233,7 +231,7 @@ impl CompressionGate { + spread_b_hi * F::from(1 << 30) + spread_c * F::from(1 << 36); let xor = xor_0 + xor_1 + xor_2; - let check = spread_witness + (xor * -F::one()); + let check = spread_witness + (xor * -F::ONE); Some(("s_upper_sigma_1", s_upper_sigma_1 * check)) } @@ -259,7 +257,7 @@ impl CompressionGate { let rhs_odd = spread_p0_odd + spread_p1_odd * F::from(1 << 32); let rhs = rhs_even + rhs_odd * F::from(2); - let check = lhs + rhs * -F::one(); + let check = lhs + rhs * -F::ONE; Some(("s_ch", s_ch * check)) } @@ -286,9 +284,9 @@ impl CompressionGate { let neg_check = { let evens = Self::ones() * F::from(MASK_EVEN_32 as u64); // evens - spread_e_lo = spread_e_neg_lo - let lo_check = spread_e_neg_lo.clone() + spread_e_lo + (evens.clone() * (-F::one())); + let lo_check = spread_e_neg_lo.clone() + spread_e_lo + (evens.clone() * (-F::ONE)); // evens - spread_e_hi = spread_e_neg_hi - let hi_check = spread_e_neg_hi.clone() + spread_e_hi + (evens * (-F::one())); + let hi_check = spread_e_neg_hi.clone() + spread_e_hi + (evens * (-F::ONE)); std::iter::empty() .chain(Some(("lo_check", lo_check))) diff --git a/halo2_gadgets/src/sha256/table16/gates.rs b/halo2_gadgets/src/sha256/table16/gates.rs index 4f268092db..d5f3840a57 100644 --- a/halo2_gadgets/src/sha256/table16/gates.rs +++ b/halo2_gadgets/src/sha256/table16/gates.rs @@ -1,10 +1,11 @@ -use halo2_proofs::{arithmetic::FieldExt, plonk::Expression}; +use ff::PrimeField; +use halo2_proofs::{arithmetic::Field, plonk::Expression}; -pub struct Gate(pub Expression); +pub struct Gate(pub Expression); -impl Gate { +impl Gate { fn ones() -> Expression { - Expression::Constant(F::one()) + Expression::Constant(F::ONE) } // Helper gates @@ -32,7 +33,7 @@ impl Gate { for i in 0..deg { let i = i as u64; if i != idx { - expr = expr * (Self::ones() * (-F::one()) * F::from(i) + var.clone()); + expr = expr * (Self::ones() * (-F::ONE) * F::from(i) + var.clone()); } } expr * F::from(u64::from(eval)) @@ -46,13 +47,13 @@ impl Gate { } } if denom < 0 { - -F::one() * F::from(factor / (-denom as u64)) + -F::ONE * F::from(factor / (-denom as u64)) } else { F::from(factor / (denom as u64)) } }; - let mut expr = Self::ones() * F::zero(); + let mut expr = Self::ones() * F::ZERO; for ((idx, _), eval) in points.iter().enumerate().zip(evals.iter()) { expr = expr + numerator(var.clone(), *eval, idx as u64) * denominator(idx as i32) } @@ -63,7 +64,7 @@ impl Gate { pub fn range_check(value: Expression, lower_range: u64, upper_range: u64) -> Expression { let mut expr = Self::ones(); for i in lower_range..(upper_range + 1) { - expr = expr * (Self::ones() * (-F::one()) * F::from(i) + value.clone()) + expr = expr * (Self::ones() * (-F::ONE) * F::from(i) + value.clone()) } expr } diff --git a/halo2_gadgets/src/sha256/table16/message_schedule/schedule_gates.rs b/halo2_gadgets/src/sha256/table16/message_schedule/schedule_gates.rs index fab51bd373..cf6a917261 100644 --- a/halo2_gadgets/src/sha256/table16/message_schedule/schedule_gates.rs +++ b/halo2_gadgets/src/sha256/table16/message_schedule/schedule_gates.rs @@ -1,10 +1,11 @@ use super::super::Gate; -use halo2_proofs::{arithmetic::FieldExt, plonk::Expression}; +use ff::PrimeField; +use halo2_proofs::plonk::Expression; use std::marker::PhantomData; -pub struct ScheduleGate(PhantomData); +pub struct ScheduleGate(PhantomData); -impl ScheduleGate { +impl ScheduleGate { /// s_word for W_16 to W_63 #[allow(clippy::too_many_arguments)] pub fn s_word( @@ -25,8 +26,8 @@ impl ScheduleGate { let word_check = lo + hi * F::from(1 << 16) - + (carry.clone() * F::from(1 << 32) * (-F::one())) - + (word * (-F::one())); + + (carry.clone() * F::from(1 << 32) * (-F::ONE)) + + (word * (-F::ONE)); let carry_check = Gate::range_check(carry, 0, 3); [("word_check", word_check), ("carry_check", carry_check)] @@ -58,11 +59,8 @@ impl ScheduleGate { tag_d: Expression, word: Expression, ) -> impl Iterator)> { - let decompose_check = a - + b * F::from(1 << 3) - + c * F::from(1 << 7) - + d * F::from(1 << 18) - + word * (-F::one()); + let decompose_check = + a + b * F::from(1 << 3) + c * F::from(1 << 7) + d * F::from(1 << 18) + word * (-F::ONE); let range_check_tag_c = Gate::range_check(tag_c, 0, 2); let range_check_tag_d = Gate::range_check(tag_d, 0, 4); @@ -99,7 +97,7 @@ impl ScheduleGate { + e * F::from(1 << 17) + f * F::from(1 << 18) + g * F::from(1 << 19) - + word * (-F::one()); + + word * (-F::ONE); let range_check_tag_d = Gate::range_check(tag_d, 0, 0); let range_check_tag_g = Gate::range_check(tag_g, 0, 3); @@ -129,7 +127,7 @@ impl ScheduleGate { + b * F::from(1 << 10) + c * F::from(1 << 17) + d * F::from(1 << 19) - + word * (-F::one()); + + word * (-F::ONE); let range_check_tag_a = Gate::range_check(tag_a, 0, 1); let range_check_tag_d = Gate::range_check(tag_d, 0, 3); diff --git a/halo2_gadgets/src/sha256/table16/spread_table.rs b/halo2_gadgets/src/sha256/table16/spread_table.rs index 3e1488e9ac..031f088084 100644 --- a/halo2_gadgets/src/sha256/table16/spread_table.rs +++ b/halo2_gadgets/src/sha256/table16/spread_table.rs @@ -1,6 +1,7 @@ use super::{util::*, AssignedBits}; +use ff::PrimeField; use halo2_proofs::{ - arithmetic::FieldExt, + arithmetic::Field, circuit::{Chip, Layouter, Region, Value}, plonk::{Advice, Column, ConstraintSystem, Error, TableColumn}, poly::Rotation, @@ -153,12 +154,12 @@ pub(super) struct SpreadTableConfig { } #[derive(Clone, Debug)] -pub(super) struct SpreadTableChip { +pub(super) struct SpreadTableChip { config: SpreadTableConfig, _marker: PhantomData, } -impl Chip for SpreadTableChip { +impl Chip for SpreadTableChip { type Config = SpreadTableConfig; type Loaded = (); @@ -171,7 +172,7 @@ impl Chip for SpreadTableChip { } } -impl SpreadTableChip { +impl SpreadTableChip { pub fn configure( meta: &mut ConstraintSystem, input_tag: Column, @@ -250,45 +251,42 @@ impl SpreadTableChip { } impl SpreadTableConfig { - fn generate() -> impl Iterator { - (1..=(1 << 16)).scan( - (F::zero(), F::zero(), F::zero()), - |(tag, dense, spread), i| { - // We computed this table row in the previous iteration. - let res = (*tag, *dense, *spread); - - // i holds the zero-indexed row number for the next table row. - match i { - BITS_7 | BITS_10 | BITS_11 | BITS_13 | BITS_14 => *tag += F::one(), - _ => (), - } - *dense += F::one(); - if i & 1 == 0 { - // On even-numbered rows we recompute the spread. - *spread = F::zero(); - for b in 0..16 { - if (i >> b) & 1 != 0 { - *spread += F::from(1 << (2 * b)); - } + fn generate() -> impl Iterator { + (1..=(1 << 16)).scan((F::ZERO, F::ZERO, F::ZERO), |(tag, dense, spread), i| { + // We computed this table row in the previous iteration. + let res = (*tag, *dense, *spread); + + // i holds the zero-indexed row number for the next table row. + match i { + BITS_7 | BITS_10 | BITS_11 | BITS_13 | BITS_14 => *tag += F::ONE, + _ => (), + } + *dense += F::ONE; + if i & 1 == 0 { + // On even-numbered rows we recompute the spread. + *spread = F::ZERO; + for b in 0..16 { + if (i >> b) & 1 != 0 { + *spread += F::from(1 << (2 * b)); } - } else { - // On odd-numbered rows we add one. - *spread += F::one(); } + } else { + // On odd-numbered rows we add one. + *spread += F::ONE; + } - Some(res) - }, - ) + Some(res) + }) } } #[cfg(test)] mod tests { use super::{get_tag, SpreadTableChip, SpreadTableConfig}; + use ff::PrimeField; use rand::Rng; use halo2_proofs::{ - arithmetic::FieldExt, circuit::{Layouter, SimpleFloorPlanner, Value}, dev::MockProver, plonk::{Advice, Circuit, Column, ConstraintSystem, Error}, @@ -303,7 +301,7 @@ mod tests { struct MyCircuit {} - impl Circuit for MyCircuit { + impl Circuit for MyCircuit { type Config = SpreadTableConfig; type FloorPlanner = SimpleFloorPlanner; @@ -354,20 +352,20 @@ mod tests { }; // Test the first few small values. - add_row(F::zero(), F::from(0b000), F::from(0b000000))?; - add_row(F::zero(), F::from(0b001), F::from(0b000001))?; - add_row(F::zero(), F::from(0b010), F::from(0b000100))?; - add_row(F::zero(), F::from(0b011), F::from(0b000101))?; - add_row(F::zero(), F::from(0b100), F::from(0b010000))?; - add_row(F::zero(), F::from(0b101), F::from(0b010001))?; + add_row(F::ZERO, F::from(0b000), F::from(0b000000))?; + add_row(F::ZERO, F::from(0b001), F::from(0b000001))?; + add_row(F::ZERO, F::from(0b010), F::from(0b000100))?; + add_row(F::ZERO, F::from(0b011), F::from(0b000101))?; + add_row(F::ZERO, F::from(0b100), F::from(0b010000))?; + add_row(F::ZERO, F::from(0b101), F::from(0b010001))?; // Test the tag boundaries: // 7-bit - add_row(F::zero(), F::from(0b1111111), F::from(0b01010101010101))?; - add_row(F::one(), F::from(0b10000000), F::from(0b0100000000000000))?; + add_row(F::ZERO, F::from(0b1111111), F::from(0b01010101010101))?; + add_row(F::ONE, F::from(0b10000000), F::from(0b0100000000000000))?; // - 10-bit add_row( - F::one(), + F::ONE, F::from(0b1111111111), F::from(0b01010101010101010101), )?; diff --git a/halo2_gadgets/src/sinsemilla.rs b/halo2_gadgets/src/sinsemilla.rs index 3cec450ea1..2670529229 100644 --- a/halo2_gadgets/src/sinsemilla.rs +++ b/halo2_gadgets/src/sinsemilla.rs @@ -203,9 +203,9 @@ where let to_base_field = |bits: &[Value]| -> Value { let bits: Value> = bits.iter().cloned().collect(); bits.map(|bits| { - bits.into_iter().rev().fold(C::Base::zero(), |acc, bit| { + bits.into_iter().rev().fold(C::Base::ZERO, |acc, bit| { if bit { - acc.double() + C::Base::one() + acc.double() + C::Base::ONE } else { acc.double() } @@ -243,7 +243,7 @@ where subpieces: impl IntoIterator>>, ) -> Result { let (field_elem, total_bits) = subpieces.into_iter().fold( - (Value::known(C::Base::zero()), 0), + (Value::known(C::Base::ZERO), 0), |(acc, bits), subpiece| { assert!(bits < 64); let subpiece_shifted = subpiece diff --git a/halo2_gadgets/src/sinsemilla/chip/generator_table.rs b/halo2_gadgets/src/sinsemilla/chip/generator_table.rs index a653c13b35..a50a687e88 100644 --- a/halo2_gadgets/src/sinsemilla/chip/generator_table.rs +++ b/halo2_gadgets/src/sinsemilla/chip/generator_table.rs @@ -6,7 +6,8 @@ use halo2_proofs::{ use super::{CommitDomains, FixedPoints, HashDomains}; use crate::sinsemilla::primitives::{self as sinsemilla, SINSEMILLA_S}; -use halo2curves::{pasta::pallas, FieldExt}; +use ff::PrimeField; +use halo2curves::pasta::pallas; /// Table containing independent generators S[0..2^k] #[derive(Eq, PartialEq, Copy, Clone, Debug)] diff --git a/halo2_gadgets/src/sinsemilla/chip/hash_to_point.rs b/halo2_gadgets/src/sinsemilla/chip/hash_to_point.rs index 70eab6b86d..9c15dd111a 100644 --- a/halo2_gadgets/src/sinsemilla/chip/hash_to_point.rs +++ b/halo2_gadgets/src/sinsemilla/chip/hash_to_point.rs @@ -10,8 +10,8 @@ use halo2_proofs::{ plonk::{Assigned, Error}, }; -use group::ff::{PrimeField, PrimeFieldBits}; -use halo2curves::{pasta::pallas, CurveAffine, FieldExt}; +use group::ff::{Field, PrimeField, PrimeFieldBits}; +use halo2curves::{pasta::pallas, CurveAffine}; use std::ops::Deref; @@ -376,15 +376,15 @@ where } /// The x-coordinate of the accumulator in a Sinsemilla hash instance. -struct X(AssignedCell, F>); +struct X(AssignedCell, F>); -impl From, F>> for X { +impl From, F>> for X { fn from(cell_value: AssignedCell, F>) -> Self { X(cell_value) } } -impl Deref for X { +impl Deref for X { type Target = AssignedCell, F>; fn deref(&self) -> &AssignedCell, F> { @@ -397,15 +397,15 @@ impl Deref for X { /// This is never actually witnessed until the last round, since it /// can be derived from other variables. Thus it only exists as a field /// element, not a `CellValue`. -struct Y(Value>); +struct Y(Value>); -impl From>> for Y { +impl From>> for Y { fn from(value: Value>) -> Self { Y(value) } } -impl Deref for Y { +impl Deref for Y { type Target = Value>; fn deref(&self) -> &Value> { diff --git a/halo2_gadgets/src/sinsemilla/merkle/chip.rs b/halo2_gadgets/src/sinsemilla/merkle/chip.rs index 97da766d0c..bb042a5aee 100644 --- a/halo2_gadgets/src/sinsemilla/merkle/chip.rs +++ b/halo2_gadgets/src/sinsemilla/merkle/chip.rs @@ -5,7 +5,7 @@ use halo2_proofs::{ plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Selector}, poly::Rotation, }; -use halo2curves::{pasta::pallas, FieldExt}; +use halo2curves::pasta::pallas; use super::MerkleInstructions; diff --git a/halo2_gadgets/src/sinsemilla/message.rs b/halo2_gadgets/src/sinsemilla/message.rs index 6bb72e2f1e..62696834ab 100644 --- a/halo2_gadgets/src/sinsemilla/message.rs +++ b/halo2_gadgets/src/sinsemilla/message.rs @@ -1,17 +1,17 @@ //! Gadget and chips for the Sinsemilla hash function. use ff::PrimeFieldBits; use halo2_proofs::{ - arithmetic::FieldExt, + arithmetic::Field, circuit::{AssignedCell, Cell, Value}, }; use std::fmt::Debug; /// A [`Message`] composed of several [`MessagePiece`]s. #[derive(Clone, Debug)] -pub struct Message(Vec>); +pub struct Message(Vec>); -impl - From>> for Message +impl From>> + for Message { fn from(pieces: Vec>) -> Self { // A message cannot contain more than `MAX_WORDS` words. @@ -20,7 +20,7 @@ impl } } -impl std::ops::Deref +impl std::ops::Deref for Message { type Target = [MessagePiece]; @@ -35,13 +35,13 @@ impl std:: /// The piece must fit within a base field element, which means its length /// cannot exceed the base field's `NUM_BITS`. #[derive(Clone, Debug)] -pub struct MessagePiece { +pub struct MessagePiece { cell_value: AssignedCell, /// The number of K-bit words in this message piece. num_words: usize, } -impl MessagePiece { +impl MessagePiece { pub fn new(cell_value: AssignedCell, num_words: usize) -> Self { assert!(num_words * K < F::NUM_BITS as usize); Self { diff --git a/halo2_gadgets/src/utilities.rs b/halo2_gadgets/src/utilities.rs index fa50f7e8e8..683a553b7e 100644 --- a/halo2_gadgets/src/utilities.rs +++ b/halo2_gadgets/src/utilities.rs @@ -1,11 +1,10 @@ //! Utility gadgets. -use ff::{Field, PrimeFieldBits}; +use ff::{Field, PrimeField, PrimeFieldBits}; use halo2_proofs::{ circuit::{AssignedCell, Cell, Layouter, Value}, plonk::{Advice, Column, Error, Expression}, }; -use halo2curves::FieldExt; use std::marker::PhantomData; use std::ops::Range; @@ -32,7 +31,7 @@ impl FieldValue for AssignedCell { } /// Trait for a variable in the circuit. -pub trait Var: Clone + std::fmt::Debug + From> { +pub trait Var: Clone + std::fmt::Debug + From> { /// The cell at which this variable was allocated. fn cell(&self) -> Cell; @@ -40,7 +39,7 @@ pub trait Var: Clone + std::fmt::Debug + From> { fn value(&self) -> Value; } -impl Var for AssignedCell { +impl Var for AssignedCell { fn cell(&self) -> Cell { self.cell() } @@ -51,7 +50,7 @@ impl Var for AssignedCell { } /// Trait for utilities used across circuits. -pub trait UtilitiesInstructions { +pub trait UtilitiesInstructions { /// Variable in the circuit. type Var: Var; @@ -130,15 +129,15 @@ impl RangeConstrained> { } /// Checks that an expression is either 1 or 0. -pub fn bool_check(value: Expression) -> Expression { +pub fn bool_check(value: Expression) -> Expression { range_check(value, 2) } /// If `a` then `b`, else `c`. Returns (a * b) + (1 - a) * c. /// /// `a` must be a boolean-constrained expression. -pub fn ternary(a: Expression, b: Expression, c: Expression) -> Expression { - let one_minus_a = Expression::Constant(F::one()) - a.clone(); +pub fn ternary(a: Expression, b: Expression, c: Expression) -> Expression { + let one_minus_a = Expression::Constant(F::ONE) - a.clone(); a * b + one_minus_a * c } @@ -156,9 +155,9 @@ pub fn bitrange_subset(field_elem: &F, bitrange: Range .skip(bitrange.start) .take(bitrange.end - bitrange.start) .rev() - .fold(F::zero(), |acc, bit| { + .fold(F::ZERO, |acc, bit| { if bit { - acc.double() + F::one() + acc.double() + F::ONE } else { acc.double() } @@ -167,7 +166,7 @@ pub fn bitrange_subset(field_elem: &F, bitrange: Range /// Check that an expression is in the small range [0..range), /// i.e. 0 ≤ word < range. -pub fn range_check(word: Expression, range: usize) -> Expression { +pub fn range_check(word: Expression, range: usize) -> Expression { (1..range).fold(word.clone(), |acc, i| { acc * (Expression::Constant(F::from(i as u64)) - word.clone()) }) @@ -240,6 +239,7 @@ pub fn i2lebsp(int: u64) -> [bool; NUM_BITS] { #[cfg(test)] mod tests { use super::*; + use ff::FromUniformBytes; use group::ff::{Field, PrimeField}; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner}, @@ -247,7 +247,7 @@ mod tests { plonk::{Any, Circuit, ConstraintSystem, Constraints, Error, Selector}, poly::Rotation, }; - use halo2curves::{pasta::pallas, FieldExt}; + use halo2curves::pasta::pallas; use proptest::prelude::*; use rand::rngs::OsRng; use std::convert::TryInto; @@ -420,7 +420,7 @@ mod tests { // Instead of rejecting out-of-range bytes, let's reduce them. let mut buf = [0; 64]; buf[..32].copy_from_slice(&bytes); - pallas::Scalar::from_bytes_wide(&buf) + pallas::Scalar::from_uniform_bytes(&buf) } } diff --git a/halo2_gadgets/src/utilities/cond_swap.rs b/halo2_gadgets/src/utilities/cond_swap.rs index 9dc1afa3ef..2dc96d5904 100644 --- a/halo2_gadgets/src/utilities/cond_swap.rs +++ b/halo2_gadgets/src/utilities/cond_swap.rs @@ -1,16 +1,16 @@ //! Gadget and chip for a conditional swap utility. use super::{bool_check, ternary, UtilitiesInstructions}; +use ff::{Field, PrimeField}; use halo2_proofs::{ circuit::{AssignedCell, Chip, Layouter, Value}, plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Selector}, poly::Rotation, }; -use halo2curves::FieldExt; use std::marker::PhantomData; /// Instructions for a conditional swap gadget. -pub trait CondSwapInstructions: UtilitiesInstructions { +pub trait CondSwapInstructions: UtilitiesInstructions { #[allow(clippy::type_complexity)] /// Given an input pair (a,b) and a `swap` boolean flag, returns /// (b,a) if `swap` is set, else (a,b) if `swap` is not set. @@ -32,7 +32,7 @@ pub struct CondSwapChip { _marker: PhantomData, } -impl Chip for CondSwapChip { +impl Chip for CondSwapChip { type Config = CondSwapConfig; type Loaded = (); @@ -63,11 +63,11 @@ impl CondSwapConfig { } } -impl UtilitiesInstructions for CondSwapChip { +impl UtilitiesInstructions for CondSwapChip { type Var = AssignedCell; } -impl CondSwapInstructions for CondSwapChip { +impl CondSwapInstructions for CondSwapChip { #[allow(clippy::type_complexity)] fn swap( &self, @@ -122,7 +122,7 @@ impl CondSwapInstructions for CondSwapChip { } } -impl CondSwapChip { +impl CondSwapChip { /// Configures this chip for use in a circuit. /// /// # Side-effects @@ -195,25 +195,26 @@ impl CondSwapChip { mod tests { use super::super::UtilitiesInstructions; use super::{CondSwapChip, CondSwapConfig, CondSwapInstructions}; + use ff::PrimeField; use group::ff::Field; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner, Value}, dev::MockProver, plonk::{Circuit, ConstraintSystem, Error}, }; - use halo2curves::{pasta::pallas::Base, FieldExt}; + use halo2curves::pasta::pallas::Base; use rand::rngs::OsRng; #[test] fn cond_swap() { #[derive(Default)] - struct MyCircuit { + struct MyCircuit { a: Value, b: Value, swap: Value, } - impl Circuit for MyCircuit { + impl Circuit for MyCircuit { type Config = CondSwapConfig; type FloorPlanner = SimpleFloorPlanner; diff --git a/halo2_gadgets/src/utilities/decompose_running_sum.rs b/halo2_gadgets/src/utilities/decompose_running_sum.rs index 89508f176c..96fd279942 100644 --- a/halo2_gadgets/src/utilities/decompose_running_sum.rs +++ b/halo2_gadgets/src/utilities/decompose_running_sum.rs @@ -30,13 +30,12 @@ use halo2_proofs::{ }; use super::range_check; -use halo2curves::FieldExt; use std::marker::PhantomData; /// The running sum $[z_0, ..., z_W]$. If created in strict mode, $z_W = 0$. #[derive(Debug)] -pub struct RunningSum(Vec>); -impl std::ops::Deref for RunningSum { +pub struct RunningSum(Vec>); +impl std::ops::Deref for RunningSum { type Target = Vec>; fn deref(&self) -> &Vec> { @@ -46,15 +45,13 @@ impl std::ops::Deref for RunningSum { /// Configuration that provides methods for running sum decomposition. #[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub struct RunningSumConfig { +pub struct RunningSumConfig { q_range_check: Selector, z: Column, _marker: PhantomData, } -impl - RunningSumConfig -{ +impl RunningSumConfig { /// Returns the q_range_check selector of this [`RunningSumConfig`]. pub(crate) fn q_range_check(&self) -> Selector { self.q_range_check @@ -200,7 +197,7 @@ impl if strict { // Constrain the final running sum output to be zero. - region.constrain_constant(zs.last().unwrap().cell(), F::zero())?; + region.constrain_constant(zs.last().unwrap().cell(), F::ZERO)?; } Ok(RunningSum(zs)) @@ -216,7 +213,7 @@ mod tests { dev::{FailureLocation, MockProver, VerifyFailure}, plonk::{Any, Circuit, ConstraintSystem, Error}, }; - use halo2curves::{pasta::pallas, FieldExt}; + use halo2curves::pasta::pallas; use rand::rngs::OsRng; use crate::ecc::chip::{ @@ -228,7 +225,7 @@ mod tests { #[test] fn test_running_sum() { struct MyCircuit< - F: FieldExt + PrimeFieldBits, + F: PrimeFieldBits, const WORD_NUM_BITS: usize, const WINDOW_NUM_BITS: usize, const NUM_WINDOWS: usize, @@ -238,7 +235,7 @@ mod tests { } impl< - F: FieldExt + PrimeFieldBits, + F: PrimeFieldBits, const WORD_NUM_BITS: usize, const WINDOW_NUM_BITS: usize, const NUM_WINDOWS: usize, diff --git a/halo2_gadgets/src/utilities/lookup_range_check.rs b/halo2_gadgets/src/utilities/lookup_range_check.rs index f97654c38b..36be7c7745 100644 --- a/halo2_gadgets/src/utilities/lookup_range_check.rs +++ b/halo2_gadgets/src/utilities/lookup_range_check.rs @@ -14,8 +14,8 @@ use super::*; /// The running sum $[z_0, ..., z_W]$. If created in strict mode, $z_W = 0$. #[derive(Debug)] -pub struct RunningSum(Vec>); -impl std::ops::Deref for RunningSum { +pub struct RunningSum(Vec>); +impl std::ops::Deref for RunningSum { type Target = Vec>; fn deref(&self) -> &Vec> { @@ -23,7 +23,7 @@ impl std::ops::Deref for RunningSum { } } -impl RangeConstrained> { +impl RangeConstrained> { /// Witnesses a subset of the bits in `value` and constrains them to be the correct /// number of bits. /// @@ -56,7 +56,7 @@ impl RangeConstrained> { /// Configuration that provides methods for a lookup range check. #[derive(Eq, PartialEq, Debug, Clone, Copy)] -pub struct LookupRangeCheckConfig { +pub struct LookupRangeCheckConfig { q_lookup: Selector, q_running: Selector, q_bitshift: Selector, @@ -65,7 +65,7 @@ pub struct LookupRangeCheckConfig _marker: PhantomData, } -impl LookupRangeCheckConfig { +impl LookupRangeCheckConfig { /// The `running_sum` advice column breaks the field element into `K`-bit /// words. It is used to construct the input expression to the lookup /// argument. @@ -118,7 +118,7 @@ impl LookupRangeCheckConfig // In the short range check, the word is directly witnessed. let short_lookup = { let short_word = z_cur; - let q_short = Expression::Constant(F::one()) - q_running; + let q_short = Expression::Constant(F::ONE) - q_running; q_short * short_word }; @@ -285,7 +285,7 @@ impl LookupRangeCheckConfig if strict { // Constrain the final `z` to be zero. - region.constrain_constant(zs.last().unwrap().cell(), F::zero())?; + region.constrain_constant(zs.last().unwrap().cell(), F::ZERO)?; } Ok(RunningSum(zs)) @@ -395,19 +395,19 @@ mod tests { dev::{FailureLocation, MockProver, VerifyFailure}, plonk::{Circuit, ConstraintSystem, Error}, }; - use halo2curves::{pasta::pallas, FieldExt}; + use halo2curves::pasta::pallas; use std::{convert::TryInto, marker::PhantomData}; #[test] fn lookup_range_check() { #[derive(Clone, Copy)] - struct MyCircuit { + struct MyCircuit { num_words: usize, _marker: PhantomData, } - impl Circuit for MyCircuit { + impl Circuit for MyCircuit { type Config = LookupRangeCheckConfig; type FloorPlanner = SimpleFloorPlanner; @@ -434,11 +434,11 @@ mod tests { // Lookup constraining element to be no longer than num_words * K bits. let elements_and_expected_final_zs = [ - (F::from((1 << (self.num_words * K)) - 1), F::zero(), true), // a word that is within self.num_words * K bits long - (F::from(1 << (self.num_words * K)), F::one(), false), // a word that is just over self.num_words * K bits long + (F::from((1 << (self.num_words * K)) - 1), F::ZERO, true), // a word that is within self.num_words * K bits long + (F::from(1 << (self.num_words * K)), F::ONE, false), // a word that is just over self.num_words * K bits long ]; - fn expected_zs( + fn expected_zs( element: F, num_words: usize, ) -> Vec { @@ -498,12 +498,12 @@ mod tests { #[test] fn short_range_check() { - struct MyCircuit { + struct MyCircuit { element: Value, num_bits: usize, } - impl Circuit for MyCircuit { + impl Circuit for MyCircuit { type Config = LookupRangeCheckConfig; type FloorPlanner = SimpleFloorPlanner; diff --git a/halo2_proofs/Cargo.toml b/halo2_proofs/Cargo.toml index 148088899b..0fcc9bfde9 100644 --- a/halo2_proofs/Cargo.toml +++ b/halo2_proofs/Cargo.toml @@ -46,9 +46,9 @@ harness = false [dependencies] backtrace = { version = "0.3", optional = true } rayon = "1.5.1" -ff = "0.12" -group = "0.12" -halo2curves = { git = 'https://github.com/scroll-tech/halo2curves.git', branch = "0.3.1-derive-serde" } +ff = "0.13" +group = "0.13" +halo2curves = { git = 'https://github.com/privacy-scaling-explorations/halo2curves', tag = "0.3.2" } rand_core = { version = "0.6", default-features = false } tracing = "0.1" blake2b_simd = "1" diff --git a/halo2_proofs/benches/dev_lookup.rs b/halo2_proofs/benches/dev_lookup.rs index bb6cfdadbf..745a36b928 100644 --- a/halo2_proofs/benches/dev_lookup.rs +++ b/halo2_proofs/benches/dev_lookup.rs @@ -1,7 +1,7 @@ #[macro_use] extern crate criterion; -use halo2_proofs::arithmetic::FieldExt; +use ff::{Field, PrimeField}; use halo2_proofs::circuit::{Layouter, SimpleFloorPlanner, Value}; use halo2_proofs::dev::MockProver; use halo2_proofs::plonk::*; @@ -14,7 +14,7 @@ use criterion::{BenchmarkId, Criterion}; fn criterion_benchmark(c: &mut Criterion) { #[derive(Clone, Default)] - struct MyCircuit { + struct MyCircuit { _marker: PhantomData, } @@ -25,7 +25,7 @@ fn criterion_benchmark(c: &mut Criterion) { advice: Column, } - impl Circuit for MyCircuit { + impl Circuit for MyCircuit { type Config = MyConfig; type FloorPlanner = SimpleFloorPlanner; @@ -42,7 +42,7 @@ fn criterion_benchmark(c: &mut Criterion) { meta.lookup("lookup", |meta| { let selector = meta.query_selector(config.selector); - let not_selector = Expression::Constant(F::one()) - selector.clone(); + let not_selector = Expression::Constant(F::ONE) - selector.clone(); let advice = meta.query_advice(config.advice, Rotation::cur()); vec![(selector * advice + not_selector, config.table)] }); diff --git a/halo2_proofs/benches/plonk.rs b/halo2_proofs/benches/plonk.rs index a679961463..cf02cf87e8 100644 --- a/halo2_proofs/benches/plonk.rs +++ b/halo2_proofs/benches/plonk.rs @@ -2,7 +2,6 @@ extern crate criterion; use group::ff::Field; -use halo2_proofs::arithmetic::FieldExt; use halo2_proofs::circuit::{Cell, Layouter, SimpleFloorPlanner, Value}; use halo2_proofs::plonk::*; use halo2_proofs::poly::{commitment::ParamsProver, Rotation}; @@ -43,7 +42,7 @@ fn criterion_benchmark(c: &mut Criterion) { sm: Column, } - trait StandardCs { + trait StandardCs { fn raw_multiply( &self, layouter: &mut impl Layouter, @@ -62,17 +61,17 @@ fn criterion_benchmark(c: &mut Criterion) { } #[derive(Clone)] - struct MyCircuit { + struct MyCircuit { a: Value, k: u32, } - struct StandardPlonk { + struct StandardPlonk { config: PlonkConfig, _marker: PhantomData, } - impl StandardPlonk { + impl StandardPlonk { fn new(config: PlonkConfig) -> Self { StandardPlonk { config, @@ -81,7 +80,7 @@ fn criterion_benchmark(c: &mut Criterion) { } } - impl StandardCs for StandardPlonk { + impl StandardCs for StandardPlonk { fn raw_multiply( &self, layouter: &mut impl Layouter, @@ -116,15 +115,10 @@ fn criterion_benchmark(c: &mut Criterion) { || value.unwrap().map(|v| v.2), )?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::zero()))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::zero()))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::one()))?; - region.assign_fixed( - || "a * b", - self.config.sm, - 0, - || Value::known(FF::one()), - )?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ZERO))?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ZERO))?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::ONE))?; Ok((lhs.cell(), rhs.cell(), out.cell())) }, ) @@ -163,14 +157,14 @@ fn criterion_benchmark(c: &mut Criterion) { || value.unwrap().map(|v| v.2), )?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::one()))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::one()))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::one()))?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; region.assign_fixed( || "a * b", self.config.sm, 0, - || Value::known(FF::zero()), + || Value::known(FF::ZERO), )?; Ok((lhs.cell(), rhs.cell(), out.cell())) }, @@ -186,7 +180,7 @@ fn criterion_benchmark(c: &mut Criterion) { } } - impl Circuit for MyCircuit { + impl Circuit for MyCircuit { type Config = PlonkConfig; type FloorPlanner = SimpleFloorPlanner; diff --git a/halo2_proofs/examples/circuit-layout.rs b/halo2_proofs/examples/circuit-layout.rs index beb99502bd..6a73f51ff8 100644 --- a/halo2_proofs/examples/circuit-layout.rs +++ b/halo2_proofs/examples/circuit-layout.rs @@ -1,6 +1,5 @@ use ff::Field; use halo2_proofs::{ - arithmetic::FieldExt, circuit::{Cell, Layouter, Region, SimpleFloorPlanner, Value}, plonk::{Advice, Assigned, Circuit, Column, ConstraintSystem, Error, Fixed, TableColumn}, poly::Rotation, @@ -28,7 +27,7 @@ struct PlonkConfig { sl: TableColumn, } -trait StandardCs { +trait StandardCs { fn raw_multiply(&self, region: &mut Region, f: F) -> Result<(Cell, Cell, Cell), Error> where F: FnMut() -> Value<(Assigned, Assigned, Assigned)>; @@ -39,17 +38,17 @@ trait StandardCs { fn lookup_table(&self, layouter: &mut impl Layouter, values: &[FF]) -> Result<(), Error>; } -struct MyCircuit { +struct MyCircuit { a: Value, lookup_table: Vec, } -struct StandardPlonk { +struct StandardPlonk { config: PlonkConfig, _marker: PhantomData, } -impl StandardPlonk { +impl StandardPlonk { fn new(config: PlonkConfig) -> Self { StandardPlonk { config, @@ -58,7 +57,7 @@ impl StandardPlonk { } } -impl StandardCs for StandardPlonk { +impl StandardCs for StandardPlonk { fn raw_multiply( &self, region: &mut Region, @@ -94,10 +93,10 @@ impl StandardCs for StandardPlonk { let out = region.assign_advice(|| "out", self.config.c, 0, || value.unwrap().map(|v| v.2))?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::zero()))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::zero()))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::one()))?; - region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::one()))?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ZERO))?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ZERO))?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::ONE))?; Ok((lhs.cell(), rhs.cell(), out.cell())) } fn raw_add(&self, region: &mut Region, mut f: F) -> Result<(Cell, Cell, Cell), Error> @@ -131,10 +130,10 @@ impl StandardCs for StandardPlonk { let out = region.assign_advice(|| "out", self.config.c, 0, || value.unwrap().map(|v| v.2))?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::one()))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::one()))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::one()))?; - region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::zero()))?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::ZERO))?; Ok((lhs.cell(), rhs.cell(), out.cell())) } fn copy(&self, region: &mut Region, left: Cell, right: Cell) -> Result<(), Error> { @@ -159,7 +158,7 @@ impl StandardCs for StandardPlonk { } } -impl Circuit for MyCircuit { +impl Circuit for MyCircuit { type Config = PlonkConfig; type FloorPlanner = SimpleFloorPlanner; diff --git a/halo2_proofs/examples/shuffle.rs b/halo2_proofs/examples/shuffle.rs index 1926074371..08d16b9f27 100644 --- a/halo2_proofs/examples/shuffle.rs +++ b/halo2_proofs/examples/shuffle.rs @@ -1,6 +1,6 @@ -use ff::BatchInvert; +use ff::{BatchInvert, FromUniformBytes}; use halo2_proofs::{ - arithmetic::{CurveAffine, FieldExt}, + arithmetic::{CurveAffine, Field}, circuit::{floor_planner::V1, Layouter, Value}, dev::{metadata, FailureLocation, MockProver, VerifyFailure}, halo2curves::pasta::EqAffine, @@ -21,13 +21,11 @@ use halo2_proofs::{ use rand_core::{OsRng, RngCore}; use std::iter; -fn rand_2d_array( - rng: &mut R, -) -> [[F; H]; W] { +fn rand_2d_array(rng: &mut R) -> [[F; H]; W] { [(); W].map(|_| [(); H].map(|_| F::random(&mut *rng))) } -fn shuffled( +fn shuffled( original: [[F; H]; W], rng: &mut R, ) -> [[F; H]; W] { @@ -56,7 +54,7 @@ struct MyConfig { } impl MyConfig { - fn configure(meta: &mut ConstraintSystem) -> Self { + fn configure(meta: &mut ConstraintSystem) -> Self { let [q_shuffle, q_first, q_last] = [(); 3].map(|_| meta.selector()); // First phase let original = [(); W].map(|_| meta.advice_column_in(FirstPhase)); @@ -68,7 +66,7 @@ impl MyConfig { meta.create_gate("z should start with 1", |meta| { let q_first = meta.query_selector(q_first); let z = meta.query_advice(z, Rotation::cur()); - let one = Expression::Constant(F::one()); + let one = Expression::Constant(F::ONE); vec![q_first * (one - z)] }); @@ -76,7 +74,7 @@ impl MyConfig { meta.create_gate("z should end with 1", |meta| { let q_last = meta.query_selector(q_last); let z = meta.query_advice(z, Rotation::cur()); - let one = Expression::Constant(F::one()); + let one = Expression::Constant(F::ONE); vec![q_last * (one - z)] }); @@ -118,12 +116,12 @@ impl MyConfig { } #[derive(Clone, Default)] -struct MyCircuit { +struct MyCircuit { original: Value<[[F; H]; W]>, shuffled: Value<[[F; H]; W]>, } -impl MyCircuit { +impl MyCircuit { fn rand(rng: &mut R) -> Self { let original = rand_2d_array::(rng); let shuffled = shuffled(original, rng); @@ -135,7 +133,7 @@ impl MyCircuit { } } -impl Circuit for MyCircuit { +impl Circuit for MyCircuit { type Config = MyConfig; type FloorPlanner = V1; @@ -200,9 +198,9 @@ impl Circuit for MyCircuit Circuit for MyCircuit Circuit for MyCircuit>(); #[cfg(feature = "sanity-checks")] - assert_eq!(F::one(), *z.last().unwrap()); + assert_eq!(F::ONE, *z.last().unwrap()); z }, @@ -253,12 +251,12 @@ impl Circuit for MyCircuit( +fn test_mock_prover, const W: usize, const H: usize>( k: u32, circuit: MyCircuit, expected: Result<(), Vec<(metadata::Constraint, FailureLocation)>>, ) { - let prover = MockProver::run::<_>(k, &circuit, vec![]).unwrap(); + let prover = MockProver::run(k, &circuit, vec![]).unwrap(); match (prover.verify(), expected) { (Ok(_), Ok(_)) => {} (Err(err), Err(expected)) => { @@ -284,7 +282,9 @@ fn test_prover( k: u32, circuit: MyCircuit, expected: bool, -) { +) where + C::Scalar: FromUniformBytes<64>, +{ let params = ParamsIPA::::new(k); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); diff --git a/halo2_proofs/examples/simple-example.rs b/halo2_proofs/examples/simple-example.rs index c5e7a9f282..2273ce9759 100644 --- a/halo2_proofs/examples/simple-example.rs +++ b/halo2_proofs/examples/simple-example.rs @@ -1,14 +1,14 @@ use std::marker::PhantomData; use halo2_proofs::{ - arithmetic::FieldExt, + arithmetic::Field, circuit::{AssignedCell, Chip, Layouter, Region, SimpleFloorPlanner, Value}, plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Fixed, Instance, Selector}, poly::Rotation, }; // ANCHOR: instructions -trait NumericInstructions: Chip { +trait NumericInstructions: Chip { /// Variable representing a number. type Num; @@ -39,7 +39,7 @@ trait NumericInstructions: Chip { // ANCHOR: chip /// The chip that will implement our instructions! Chips store their own /// config, as well as type markers if necessary. -struct FieldChip { +struct FieldChip { config: FieldConfig, _marker: PhantomData, } @@ -65,7 +65,7 @@ struct FieldConfig { s_mul: Selector, } -impl FieldChip { +impl FieldChip { fn construct(config: >::Config) -> Self { Self { config, @@ -126,7 +126,7 @@ impl FieldChip { // ANCHOR_END: chip-config // ANCHOR: chip-impl -impl Chip for FieldChip { +impl Chip for FieldChip { type Config = FieldConfig; type Loaded = (); @@ -143,9 +143,9 @@ impl Chip for FieldChip { // ANCHOR: instructions-impl /// A variable representing a number. #[derive(Clone)] -struct Number(AssignedCell); +struct Number(AssignedCell); -impl NumericInstructions for FieldChip { +impl NumericInstructions for FieldChip { type Num = Number; fn load_private( @@ -238,13 +238,13 @@ impl NumericInstructions for FieldChip { /// they won't have any value during key generation. During proving, if any of these /// were `None` we would get an error. #[derive(Default)] -struct MyCircuit { +struct MyCircuit { constant: F, a: Value, b: Value, } -impl Circuit for MyCircuit { +impl Circuit for MyCircuit { // Since we are using a single chip for everything, we can just reuse its config. type Config = FieldConfig; type FloorPlanner = SimpleFloorPlanner; diff --git a/halo2_proofs/examples/two-chip.rs b/halo2_proofs/examples/two-chip.rs index 61d40f93ca..4113d94143 100644 --- a/halo2_proofs/examples/two-chip.rs +++ b/halo2_proofs/examples/two-chip.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; use halo2_proofs::{ - arithmetic::FieldExt, + arithmetic::Field, circuit::{AssignedCell, Chip, Layouter, Region, SimpleFloorPlanner, Value}, plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Instance, Selector}, poly::Rotation, @@ -10,9 +10,9 @@ use halo2_proofs::{ // ANCHOR: field-instructions /// A variable representing a number. #[derive(Clone)] -struct Number(AssignedCell); +struct Number(AssignedCell); -trait FieldInstructions: AddInstructions + MulInstructions { +trait FieldInstructions: AddInstructions + MulInstructions { /// Variable representing a number. type Num; @@ -43,7 +43,7 @@ trait FieldInstructions: AddInstructions + MulInstructions { // ANCHOR_END: field-instructions // ANCHOR: add-instructions -trait AddInstructions: Chip { +trait AddInstructions: Chip { /// Variable representing a number. type Num; @@ -58,7 +58,7 @@ trait AddInstructions: Chip { // ANCHOR_END: add-instructions // ANCHOR: mul-instructions -trait MulInstructions: Chip { +trait MulInstructions: Chip { /// Variable representing a number. type Num; @@ -108,28 +108,28 @@ struct MulConfig { // ANCHOR: field-chip /// The top-level chip that will implement the `FieldInstructions`. -struct FieldChip { +struct FieldChip { config: FieldConfig, _marker: PhantomData, } // ANCHOR_END: field-chip // ANCHOR: add-chip -struct AddChip { +struct AddChip { config: AddConfig, _marker: PhantomData, } // ANCHOR END: add-chip // ANCHOR: mul-chip -struct MulChip { +struct MulChip { config: MulConfig, _marker: PhantomData, } // ANCHOR_END: mul-chip // ANCHOR: add-chip-trait-impl -impl Chip for AddChip { +impl Chip for AddChip { type Config = AddConfig; type Loaded = (); @@ -144,7 +144,7 @@ impl Chip for AddChip { // ANCHOR END: add-chip-trait-impl // ANCHOR: add-chip-impl -impl AddChip { +impl AddChip { fn construct(config: >::Config, _loaded: >::Loaded) -> Self { Self { config, @@ -174,7 +174,7 @@ impl AddChip { // ANCHOR END: add-chip-impl // ANCHOR: add-instructions-impl -impl AddInstructions for FieldChip { +impl AddInstructions for FieldChip { type Num = Number; fn add( &self, @@ -189,7 +189,7 @@ impl AddInstructions for FieldChip { } } -impl AddInstructions for AddChip { +impl AddInstructions for AddChip { type Num = Number; fn add( @@ -231,7 +231,7 @@ impl AddInstructions for AddChip { // ANCHOR END: add-instructions-impl // ANCHOR: mul-chip-trait-impl -impl Chip for MulChip { +impl Chip for MulChip { type Config = MulConfig; type Loaded = (); @@ -246,7 +246,7 @@ impl Chip for MulChip { // ANCHOR END: mul-chip-trait-impl // ANCHOR: mul-chip-impl -impl MulChip { +impl MulChip { fn construct(config: >::Config, _loaded: >::Loaded) -> Self { Self { config, @@ -296,7 +296,7 @@ impl MulChip { // ANCHOR_END: mul-chip-impl // ANCHOR: mul-instructions-impl -impl MulInstructions for FieldChip { +impl MulInstructions for FieldChip { type Num = Number; fn mul( &self, @@ -310,7 +310,7 @@ impl MulInstructions for FieldChip { } } -impl MulInstructions for MulChip { +impl MulInstructions for MulChip { type Num = Number; fn mul( @@ -352,7 +352,7 @@ impl MulInstructions for MulChip { // ANCHOR END: mul-instructions-impl // ANCHOR: field-chip-trait-impl -impl Chip for FieldChip { +impl Chip for FieldChip { type Config = FieldConfig; type Loaded = (); @@ -367,7 +367,7 @@ impl Chip for FieldChip { // ANCHOR_END: field-chip-trait-impl // ANCHOR: field-chip-impl -impl FieldChip { +impl FieldChip { fn construct(config: >::Config, _loaded: >::Loaded) -> Self { Self { config, @@ -396,7 +396,7 @@ impl FieldChip { // ANCHOR_END: field-chip-impl // ANCHOR: field-instructions-impl -impl FieldInstructions for FieldChip { +impl FieldInstructions for FieldChip { type Num = Number; fn load_private( @@ -448,13 +448,13 @@ impl FieldInstructions for FieldChip { /// they won't have any value during key generation. During proving, if any of these /// were `Value::unknown()` we would get an error. #[derive(Default)] -struct MyCircuit { +struct MyCircuit { a: Value, b: Value, c: Value, } -impl Circuit for MyCircuit { +impl Circuit for MyCircuit { // Since we are using a single chip for everything, we can just reuse its config. type Config = FieldConfig; type FloorPlanner = SimpleFloorPlanner; @@ -496,7 +496,6 @@ impl Circuit for MyCircuit { #[allow(clippy::many_single_char_names)] fn main() { - use group::ff::Field; use halo2_proofs::dev::MockProver; use halo2curves::pasta::Fp; use rand_core::OsRng; diff --git a/halo2_proofs/src/arithmetic.rs b/halo2_proofs/src/arithmetic.rs index c06575b549..234ef6db54 100644 --- a/halo2_proofs/src/arithmetic.rs +++ b/halo2_proofs/src/arithmetic.rs @@ -5,10 +5,25 @@ use super::multicore; pub use ff::Field; use group::{ ff::{BatchInvert, PrimeField}, - Curve, Group as _, + Curve, Group, GroupOpsOwned, ScalarMulOwned, }; -pub use halo2curves::{CurveAffine, CurveExt, FieldExt, Group}; +pub use halo2curves::{CurveAffine, CurveExt}; + +/// This represents an element of a group with basic operations that can be +/// performed. This allows an FFT implementation (for example) to operate +/// generically over either a field or elliptic curve group. +pub trait FftGroup: + Copy + Send + Sync + 'static + GroupOpsOwned + ScalarMulOwned +{ +} + +impl FftGroup for T +where + Scalar: Field, + T: Copy + Send + Sync + 'static + GroupOpsOwned + ScalarMulOwned, +{ +} pub const SPARSE_TWIDDLE_DEGREE: u32 = 10; @@ -170,7 +185,7 @@ pub fn best_multiexp(coeffs: &[C::Scalar], bases: &[C]) -> C::Cu /// by $n$. /// /// This will use multithreading if beneficial. -pub fn best_fft(a: &mut [G], omega: G::Scalar, log_n: u32) { +pub fn best_fft>(a: &mut [G], omega: Scalar, log_n: u32) { let threads = multicore::current_num_threads(); let log_split = log2_floor(threads) as usize; let n = a.len() as usize; @@ -193,7 +208,7 @@ fn bitreverse(mut n: usize, l: usize) -> usize { r } -fn serial_fft(a: &mut [G], omega: G::Scalar, log_n: u32) { +fn serial_fft>(a: &mut [G], omega: Scalar, log_n: u32) { let n = a.len() as u32; assert_eq!(n, 1 << log_n); @@ -210,13 +225,13 @@ fn serial_fft(a: &mut [G], omega: G::Scalar, log_n: u32) { let mut k = 0; while k < n { - let mut w = G::Scalar::one(); + let mut w = Scalar::ONE; for j in 0..m { let mut t = a[(k + j + m) as usize]; - t.group_scale(&w); + t *= &w; a[(k + j + m) as usize] = a[(k + j) as usize]; - a[(k + j + m) as usize].group_sub(&t); - a[(k + j) as usize].group_add(&t); + a[(k + j + m) as usize] -= &t; + a[(k + j) as usize] += &t; w *= &w_m; } @@ -227,9 +242,9 @@ fn serial_fft(a: &mut [G], omega: G::Scalar, log_n: u32) { } } -fn serial_split_fft( +fn serial_split_fft>( a: &mut [G], - twiddle_lut: &[G::Scalar], + twiddle_lut: &[Scalar], twiddle_scale: usize, log_n: u32, ) { @@ -248,13 +263,13 @@ fn serial_split_fft( let mut k = 0; while k < n { - let mut w = G::Scalar::one(); + let mut w = G::Scalar::ONE; for j in 0..m { let mut t = a[(k + j + m) as usize]; - t.group_scale(&w); + t *= &w; a[(k + j + m) as usize] = a[(k + j) as usize]; - a[(k + j + m) as usize].group_sub(&t); - a[(k + j) as usize].group_add(&t); + a[(k + j + m) as usize] -= &t; + a[(k + j) as usize] += &t; w *= &w_m; } @@ -265,10 +280,10 @@ fn serial_split_fft( } } -fn split_radix_fft( +fn split_radix_fft>( tmp: &mut [G], a: &[G], - twiddle_lut: &[G::Scalar], + twiddle_lut: &[Scalar], n: usize, sub_fft_offset: usize, log_split: usize, @@ -278,7 +293,7 @@ fn split_radix_fft( // we use out-place bitreverse here, split_m <= num_threads, so the buffer spase is small // and it's is good for data locality - let mut t1 = vec![G::group_zero(); split_m]; + let mut t1 = vec![G::Scalar::ZERO; split_m]; // if unsafe code is allowed, a 10% performance improvement can be achieved // let mut t1: Vec = Vec::with_capacity(split_m as usize); // unsafe{ t1.set_len(split_m as usize); } @@ -295,9 +310,9 @@ fn split_radix_fft( if high_idx > 0 { omega = omega * twiddle_lut[(1 << sparse_degree) + high_idx]; } - let mut w_m = G::Scalar::one(); + let mut w_m = G::Scalar::ONE; for i in 0..split_m { - t1[i].group_scale(&w_m); + t1[i] *= &w_m; tmp[i] = t1[i]; w_m = w_m * omega; } @@ -353,7 +368,7 @@ pub fn generate_twiddle_lookup_table( twiddle_lut } -pub fn parallel_fft(a: &mut [G], omega: G::Scalar, log_n: u32) { +pub fn parallel_fft>(a: &mut [G], omega: Scalar, log_n: u32) { let n = a.len() as usize; assert_eq!(n, 1 << log_n); @@ -363,7 +378,7 @@ pub fn parallel_fft(a: &mut [G], omega: G::Scalar, log_n: u32) { let twiddle_lut = generate_twiddle_lookup_table(omega, log_n, SPARSE_TWIDDLE_DEGREE, true); // split fft - let mut tmp = vec![G::group_zero(); n]; + let mut tmp = vec![G::Scalar::ZERO; n]; // if unsafe code is allowed, a 10% performance improvement can be achieved // let mut tmp: Vec = Vec::with_capacity(n); // unsafe{ tmp.set_len(n); } @@ -449,7 +464,7 @@ pub fn eval_polynomial(poly: &[F], point: F) -> F { fn evaluate(poly: &[F], point: F) -> F { poly.iter() .rev() - .fold(F::zero(), |acc, coeff| acc * point + coeff) + .fold(F::ZERO, |acc, coeff| acc * point + coeff) } let n = poly.len(); let num_threads = multicore::current_num_threads(); @@ -457,7 +472,7 @@ pub fn eval_polynomial(poly: &[F], point: F) -> F { evaluate(poly, point) } else { let chunk_size = (n + num_threads - 1) / num_threads; - let mut parts = vec![F::zero(); num_threads]; + let mut parts = vec![F::ZERO; num_threads]; multicore::scope(|scope| { for (chunk_idx, (out, poly)) in parts.chunks_mut(1).zip(poly.chunks(chunk_size)).enumerate() @@ -468,7 +483,7 @@ pub fn eval_polynomial(poly: &[F], point: F) -> F { }); } }); - parts.iter().fold(F::zero(), |acc, coeff| acc + coeff) + parts.iter().fold(F::ZERO, |acc, coeff| acc + coeff) } } @@ -479,7 +494,7 @@ pub fn compute_inner_product(a: &[F], b: &[F]) -> F { // TODO: parallelize? assert_eq!(a.len(), b.len()); - let mut acc = F::zero(); + let mut acc = F::ZERO; for (a, b) in a.iter().zip(b.iter()) { acc += (*a) * (*b); } @@ -496,9 +511,9 @@ where b = -b; let a = a.into_iter(); - let mut q = vec![F::zero(); a.len() - 1]; + let mut q = vec![F::ZERO; a.len() - 1]; - let mut tmp = F::zero(); + let mut tmp = F::ZERO; for (q, r) in q.iter_mut().rev().zip(a.rev()) { let mut lead_coeff = *r; lead_coeff.sub_assign(&tmp); @@ -546,7 +561,7 @@ fn log2_floor(num: usize) -> u32 { /// Returns coefficients of an n - 1 degree polynomial given a set of n points /// and their evaluations. This function will panic if two values in `points` /// are the same. -pub fn lagrange_interpolate(points: &[F], evals: &[F]) -> Vec { +pub fn lagrange_interpolate(points: &[F], evals: &[F]) -> Vec { assert_eq!(points.len(), evals.len()); if points.len() == 1 { // Constant polynomial @@ -568,11 +583,11 @@ pub fn lagrange_interpolate(points: &[F], evals: &[F]) -> Vec { // Compute (x_j - x_k)^(-1) for each j != i denoms.iter_mut().flat_map(|v| v.iter_mut()).batch_invert(); - let mut final_poly = vec![F::zero(); points.len()]; + let mut final_poly = vec![F::ZERO; points.len()]; for (j, (denoms, eval)) in denoms.into_iter().zip(evals.iter()).enumerate() { let mut tmp: Vec = Vec::with_capacity(points.len()); let mut product = Vec::with_capacity(points.len() - 1); - tmp.push(F::one()); + tmp.push(F::ONE); for (x_k, denom) in points .iter() .enumerate() @@ -580,11 +595,11 @@ pub fn lagrange_interpolate(points: &[F], evals: &[F]) -> Vec { .map(|a| a.1) .zip(denoms.into_iter()) { - product.resize(tmp.len() + 1, F::zero()); + product.resize(tmp.len() + 1, F::ZERO); for ((a, b), product) in tmp .iter() - .chain(std::iter::once(&F::zero())) - .zip(std::iter::once(&F::zero()).chain(tmp.iter())) + .chain(std::iter::once(&F::ZERO)) + .zip(std::iter::once(&F::ZERO).chain(tmp.iter())) .zip(product.iter_mut()) { *product = *a * (-denom * x_k) + *b * denom; @@ -601,9 +616,9 @@ pub fn lagrange_interpolate(points: &[F], evals: &[F]) -> Vec { } } -pub(crate) fn evaluate_vanishing_polynomial(roots: &[F], z: F) -> F { - fn evaluate(roots: &[F], z: F) -> F { - roots.iter().fold(F::one(), |acc, point| (z - point) * acc) +pub(crate) fn evaluate_vanishing_polynomial(roots: &[F], z: F) -> F { + fn evaluate(roots: &[F], z: F) -> F { + roots.iter().fold(F::ONE, |acc, point| (z - point) * acc) } let n = roots.len(); let num_threads = multicore::current_num_threads(); @@ -611,18 +626,18 @@ pub(crate) fn evaluate_vanishing_polynomial(roots: &[F], z: F) -> F evaluate(roots, z) } else { let chunk_size = (n + num_threads - 1) / num_threads; - let mut parts = vec![F::one(); num_threads]; + let mut parts = vec![F::ONE; num_threads]; multicore::scope(|scope| { for (out, roots) in parts.chunks_mut(1).zip(roots.chunks(chunk_size)) { scope.spawn(move |_| out[0] = evaluate(roots, z)); } }); - parts.iter().fold(F::one(), |acc, part| acc * part) + parts.iter().fold(F::ONE, |acc, part| acc * part) } } -pub(crate) fn powers(base: F) -> impl Iterator { - std::iter::successors(Some(F::one()), move |power| Some(base * power)) +pub(crate) fn powers(base: F) -> impl Iterator { + std::iter::successors(Some(F::ONE), move |power| Some(base * power)) } #[cfg(test)] diff --git a/halo2_proofs/src/circuit.rs b/halo2_proofs/src/circuit.rs index 52db772c94..508820f029 100644 --- a/halo2_proofs/src/circuit.rs +++ b/halo2_proofs/src/circuit.rs @@ -4,11 +4,8 @@ use std::{convert::TryInto, fmt, marker::PhantomData}; use ff::Field; -use crate::{ - arithmetic::FieldExt, - plonk::{ - Advice, Any, Assigned, Challenge, Column, Error, Fixed, Instance, Selector, TableColumn, - }, +use crate::plonk::{ + Advice, Any, Assigned, Challenge, Column, Error, Fixed, Instance, Selector, TableColumn, }; mod value; @@ -28,7 +25,7 @@ pub mod layouter; /// The chip also loads any fixed configuration needed at synthesis time /// using its own implementation of `load`, and stores it in [`Chip::Loaded`]. /// This can be accessed via [`Chip::loaded`]. -pub trait Chip: Sized { +pub trait Chip: Sized { /// A type that holds the configuration for this chip, and any other state it may need /// during circuit synthesis, that can be derived during [`Circuit::configure`]. /// diff --git a/halo2_proofs/src/circuit/layouter.rs b/halo2_proofs/src/circuit/layouter.rs index f73d7d7d73..4b9d74b69a 100644 --- a/halo2_proofs/src/circuit/layouter.rs +++ b/halo2_proofs/src/circuit/layouter.rs @@ -14,7 +14,7 @@ use crate::plonk::{Advice, Any, Assigned, Column, Error, Fixed, Instance, Select /// This trait is used for implementing region assignments: /// /// ```ignore -/// impl<'a, F: FieldExt, C: Chip, CS: Assignment + 'a> Layouter for MyLayouter<'a, C, CS> { +/// impl<'a, F: Field, C: Chip, CS: Assignment + 'a> Layouter for MyLayouter<'a, C, CS> { /// fn assign_region( /// &mut self, /// assignment: impl FnOnce(Region<'_, F, C>) -> Result<(), Error>, diff --git a/halo2_proofs/src/dev.rs b/halo2_proofs/src/dev.rs index 28ca17a082..34d7f7b1b3 100644 --- a/halo2_proofs/src/dev.rs +++ b/halo2_proofs/src/dev.rs @@ -9,11 +9,12 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use blake2b_simd::blake2b; +use ff::FromUniformBytes; use ff::{BatchInvert, Field}; +use group::Group; use crate::plonk::permutation::keygen::Assembly; use crate::{ - arithmetic::{FieldExt, Group}, circuit, plonk::{ permutation, @@ -96,8 +97,8 @@ impl Region { } /// The value of a particular cell within the circuit. -#[derive(Clone, Copy, Debug)] -pub enum CellValue { +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum CellValue { /// An unassigned cell. Unassigned, /// A cell that has been assigned a value. @@ -235,16 +236,16 @@ fn batch_invert_cellvalues(cell_values: &mut [Vec /// A value within an expression. #[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)] -enum Value { +enum Value { Real(F), Poison, } -impl From> for Value { +impl From> for Value { fn from(value: CellValue) -> Self { match value { // Cells that haven't been explicitly assigned to, default to zero. - CellValue::Unassigned => Value::Real(F::zero()), + CellValue::Unassigned => Value::Real(F::ZERO), CellValue::Assigned(v) => Value::Real(v), #[cfg(feature = "mock-batch-inv")] CellValue::Rational(n, d) => Value::Real(n * d.invert().unwrap()), @@ -253,7 +254,7 @@ impl From> for Value { } } -impl Neg for Value { +impl Neg for Value { type Output = Self; fn neg(self) -> Self::Output { @@ -264,7 +265,7 @@ impl Neg for Value { } } -impl Add for Value { +impl Add for Value { type Output = Self; fn add(self, rhs: Self) -> Self::Output { @@ -275,7 +276,7 @@ impl Add for Value { } } -impl Mul for Value { +impl Mul for Value { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { @@ -286,14 +287,14 @@ impl Mul for Value { (Value::Real(x), Value::Poison) | (Value::Poison, Value::Real(x)) if x.is_zero_vartime() => { - Value::Real(F::zero()) + Value::Real(F::ZERO) } _ => Value::Poison, } } } -impl Mul for Value { +impl Mul for Value { type Output = Self; fn mul(self, rhs: F) -> Self::Output { @@ -301,7 +302,7 @@ impl Mul for Value { Value::Real(lhs) => Value::Real(lhs * rhs), // If poison is multiplied by zero, then we treat the poison as unconstrained // and we don't propagate it. - Value::Poison if rhs.is_zero_vartime() => Value::Real(F::zero()), + Value::Poison if rhs.is_zero_vartime() => Value::Real(F::ZERO), _ => Value::Poison, } } @@ -319,12 +320,12 @@ impl Mul for Value { /// /// ``` /// use halo2_proofs::{ -/// arithmetic::FieldExt, /// circuit::{Layouter, SimpleFloorPlanner, Value}, /// dev::{FailureLocation, MockProver, VerifyFailure}, /// plonk::{Advice, Any, Circuit, Column, ConstraintSystem, Error, Selector}, /// poly::Rotation, /// }; +/// use ff::PrimeField; /// use halo2curves::pasta::Fp; /// const K: u32 = 5; /// @@ -342,7 +343,7 @@ impl Mul for Value { /// b: Value, /// } /// -/// impl Circuit for MyCircuit { +/// impl Circuit for MyCircuit { /// type Config = MyConfig; /// type FloorPlanner = SimpleFloorPlanner; /// @@ -421,7 +422,7 @@ impl Mul for Value { /// )); /// ``` #[derive(Debug)] -pub struct MockProver<'a, F: Group + Field> { +pub struct MockProver<'a, F: Field> { k: u32, n: u32, cs: ConstraintSystem, @@ -459,13 +460,13 @@ pub struct MockProver<'a, F: Group + Field> { current_phase: sealed::Phase, // crate::plonk::sealed::Phase, } -impl<'a, F: Field + Group> MockProver<'a, F> { +impl<'a, F: Field> MockProver<'a, F> { fn in_phase(&self, phase: P) -> bool { self.current_phase == phase.to_sealed() } } -impl<'a, F: Field + Group> Assignment for MockProver<'a, F> { +impl<'a, F: Field> Assignment for MockProver<'a, F> { fn enter_region(&mut self, name: N) where NR: Into, @@ -913,7 +914,7 @@ impl<'a, F: Field + Group> Assignment for MockProver<'a, F> { } } -impl<'a, F: FieldExt> MockProver<'a, F> { +impl<'a, F: FromUniformBytes<64> + Ord> MockProver<'a, F> { /// Runs a synthetic keygen-and-prove operation on the given circuit, collecting data /// about the constraints and their assignments. pub fn run>( @@ -942,7 +943,7 @@ impl<'a, F: FieldExt> MockProver<'a, F> { return Err(Error::InstanceTooLarge); } - instance.resize(n, F::zero()); + instance.resize(n, F::ZERO); Ok(instance) }) .collect::, _>>()?; @@ -978,7 +979,7 @@ impl<'a, F: FieldExt> MockProver<'a, F> { let mut hash: [u8; 64] = blake2b(b"Halo2-MockProver").as_bytes().try_into().unwrap(); iter::repeat_with(|| { hash = blake2b(&hash).as_bytes().try_into().unwrap(); - F::from_bytes_wide(&hash) + F::from_uniform_bytes(&hash) }) .take(cs.num_challenges) .collect() @@ -1231,7 +1232,7 @@ impl<'a, F: FieldExt> MockProver<'a, F> { &|a, b| a + b, &|a, b| a * b, &|a, scalar| a * scalar, - &Value::Real(F::zero()), + &Value::Real(F::ZERO), ) { Value::Real(x) if x.is_zero_vartime() => None, Value::Real(_) => Some(VerifyFailure::ConstraintNotSatisfied { @@ -1326,7 +1327,7 @@ impl<'a, F: FieldExt> MockProver<'a, F> { &|a, b| a + b, &|a, b| a * b, &|a, scalar| a * scalar, - &Value::Real(F::zero()), + &Value::Real(F::ZERO), ) }; @@ -1617,7 +1618,7 @@ impl<'a, F: FieldExt> MockProver<'a, F> { &|a, b| a + b, &|a, b| a * b, &|a, scalar| a * scalar, - &Value::Real(F::zero()), + &Value::Real(F::ZERO), ) { Value::Real(x) if x.is_zero_vartime() => None, Value::Real(_) => Some(VerifyFailure::ConstraintNotSatisfied { @@ -1705,7 +1706,7 @@ impl<'a, F: FieldExt> MockProver<'a, F> { &|a, b| a + b, &|a, b| a * b, &|a, scalar| a * scalar, - &Value::Real(F::zero()), + &Value::Real(F::ZERO), ) }; diff --git a/halo2_proofs/src/dev/failure.rs b/halo2_proofs/src/dev/failure.rs index 229cb171f4..54b7a473db 100644 --- a/halo2_proofs/src/dev/failure.rs +++ b/halo2_proofs/src/dev/failure.rs @@ -2,7 +2,6 @@ use std::collections::{BTreeMap, HashSet}; use std::fmt::{self, Debug}; use group::ff::Field; -use halo2curves::FieldExt; use super::metadata::{DebugColumn, DebugVirtualCell}; use super::MockProver; @@ -444,7 +443,7 @@ fn render_constraint_not_satisfied( /// | x0 = 0x5 /// | x1 = 1 /// ``` -fn render_lookup( +fn render_lookup( prover: &MockProver, name: &str, lookup_index: usize, @@ -510,7 +509,7 @@ fn render_lookup( ) }); - fn cell_value<'a, F: FieldExt, Q: Into + Copy>( + fn cell_value<'a, F: Field, Q: Into + Copy>( load: impl Fn(Q) -> Value + 'a, ) -> impl Fn(Q) -> BTreeMap + 'a { move |query| { @@ -624,7 +623,7 @@ fn render_lookup( impl VerifyFailure { /// Emits this failure in pretty-printed format to stderr. - pub(super) fn emit(&self, prover: &MockProver) { + pub(super) fn emit(&self, prover: &MockProver) { match self { Self::CellNotAssigned { gate, diff --git a/halo2_proofs/src/dev/util.rs b/halo2_proofs/src/dev/util.rs index 83126e79c7..353f9869f6 100644 --- a/halo2_proofs/src/dev/util.rs +++ b/halo2_proofs/src/dev/util.rs @@ -1,7 +1,5 @@ -use std::collections::BTreeMap; - use group::ff::Field; -use halo2curves::FieldExt; +use std::collections::BTreeMap; use super::{metadata, CellValue, Value}; use crate::{ @@ -59,9 +57,9 @@ impl From for AnyQuery { pub(super) fn format_value(v: F) -> String { if v.is_zero_vartime() { "0".into() - } else if v == F::one() { + } else if v == F::ONE { "1".into() - } else if v == -F::one() { + } else if v == -F::ONE { "-1".into() } else { // Format value as hex. @@ -74,7 +72,7 @@ pub(super) fn format_value(v: F) -> String { } /* -pub(super) fn load<'a, F: FieldExt, T: ColumnType, Q: Into + Copy>( +pub(super) fn load<'a, F: Field, T: ColumnType, Q: Into + Copy>( n: i32, row: i32, queries: &'a [(Column, Rotation)], @@ -101,7 +99,7 @@ pub(super) fn load_slice<'a, F: FieldExt, T: ColumnType, Q: Into + Cop } } -pub(super) fn load_instance<'a, F: FieldExt, T: ColumnType, Q: Into + Copy>( +pub(super) fn load_instance<'a, F: Field, T: ColumnType, Q: Into + Copy>( n: i32, row: i32, queries: &'a [(Column, Rotation)], @@ -114,7 +112,7 @@ pub(super) fn load_instance<'a, F: FieldExt, T: ColumnType, Q: Into + } } -fn cell_value<'a, F: FieldExt, Q: Into + Copy>( +fn cell_value<'a, F: Field, Q: Into + Copy>( virtual_cells: &'a [VirtualCell], load: impl Fn(Q) -> Value + 'a, ) -> impl Fn(Q) -> BTreeMap + 'a { @@ -147,7 +145,7 @@ fn cell_value<'a, F: FieldExt, Q: Into + Copy>( } } -pub(super) fn cell_values<'a, F: FieldExt>( +pub(super) fn cell_values<'a, F: Field>( gate: &Gate, poly: &Expression, load_fixed: impl Fn(FixedQuery) -> Value + 'a, diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index f2e2ce7df8..786ca29a42 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -6,11 +6,10 @@ //! [plonk]: https://eprint.iacr.org/2019/953 use blake2b_simd::Params as Blake2bParams; -use ff::PrimeField; -use group::ff::Field; +use group::ff::{Field, FromUniformBytes, PrimeField}; use halo2curves::pairing::Engine; -use crate::arithmetic::{CurveAffine, FieldExt}; +use crate::arithmetic::CurveAffine; use crate::helpers::{ polynomial_slice_byte_length, read_polynomial_vec, write_polynomial_slice, SerdeCurveAffine, SerdePrimeField, @@ -61,7 +60,7 @@ pub struct VerifyingKey { impl VerifyingKey where - C::Scalar: SerdePrimeField, + C::Scalar: SerdePrimeField + FromUniformBytes<64>, { /// Writes a verifying key to a buffer. /// @@ -151,7 +150,10 @@ where } } -impl VerifyingKey { +impl VerifyingKey +where + C::ScalarExt: FromUniformBytes<64>, +{ fn bytes_length(&self) -> usize { 8 + (self.fixed_commitments.len() * C::default().to_bytes().as_ref().len()) + self.permutation.bytes_length() @@ -182,7 +184,7 @@ impl VerifyingKey { cs, cs_degree, // Temporary, this is not pinned. - transcript_repr: C::Scalar::zero(), + transcript_repr: C::Scalar::ZERO, //selectors, }; @@ -197,7 +199,7 @@ impl VerifyingKey { hasher.update(s.as_bytes()); // Hash in final Blake2bState - vk.transcript_repr = C::Scalar::from_bytes_wide(hasher.finalize().as_array()); + vk.transcript_repr = C::Scalar::from_uniform_bytes(hasher.finalize().as_array()); vk } @@ -267,7 +269,10 @@ pub struct ProvingKey { ev: Evaluator, } -impl ProvingKey { +impl ProvingKey +where + C::Scalar: FromUniformBytes<64>, +{ /// Get the underlying [`VerifyingKey`]. pub fn get_vk(&self) -> &VerifyingKey { &self.vk @@ -288,7 +293,7 @@ impl ProvingKey { impl ProvingKey where - C::Scalar: SerdePrimeField, + C::Scalar: SerdePrimeField + FromUniformBytes<64>, { /// Writes a proving key to a buffer. /// diff --git a/halo2_proofs/src/plonk/assigned.rs b/halo2_proofs/src/plonk/assigned.rs index 7524291e4c..46d527b915 100644 --- a/halo2_proofs/src/plonk/assigned.rs +++ b/halo2_proofs/src/plonk/assigned.rs @@ -280,7 +280,7 @@ impl Assigned { /// Returns the numerator. pub fn numerator(&self) -> F { match self { - Self::Zero => F::zero(), + Self::Zero => F::ZERO, Self::Trivial(x) => *x, Self::Rational(numerator, _) => *numerator, } @@ -341,7 +341,7 @@ impl Assigned { pub fn invert(&self) -> Self { match self { Self::Zero => Self::Zero, - Self::Trivial(x) => Self::Rational(F::one(), *x), + Self::Trivial(x) => Self::Rational(F::ONE, *x), Self::Rational(numerator, denominator) => Self::Rational(*denominator, *numerator), } } @@ -352,13 +352,13 @@ impl Assigned { /// If the denominator is zero, this returns zero. pub fn evaluate(self) -> F { match self { - Self::Zero => F::zero(), + Self::Zero => F::ZERO, Self::Trivial(x) => x, Self::Rational(numerator, denominator) => { - if denominator == F::one() { + if denominator == F::ONE { numerator } else { - numerator * denominator.invert().unwrap_or(F::zero()) + numerator * denominator.invert().unwrap_or(F::ZERO) } } } @@ -451,7 +451,7 @@ mod proptests { }; use group::ff::Field; - use halo2curves::{pasta::Fp, FieldExt}; + use halo2curves::pasta::Fp; use proptest::{collection::vec, prelude::*, sample::select}; use super::Assigned; @@ -477,7 +477,7 @@ mod proptests { } fn inv0(&self) -> Self { - self.invert().unwrap_or(F::zero()) + self.invert().unwrap_or(F::ZERO) } } diff --git a/halo2_proofs/src/plonk/circuit.rs b/halo2_proofs/src/plonk/circuit.rs index f0329fbe85..9b132b4ea0 100644 --- a/halo2_proofs/src/plonk/circuit.rs +++ b/halo2_proofs/src/plonk/circuit.rs @@ -355,11 +355,10 @@ impl TryFrom> for Column { /// row when required: /// ``` /// use halo2_proofs::{ -/// arithmetic::FieldExt, /// circuit::{Chip, Layouter, Value}, /// plonk::{Advice, Column, Error, Selector}, /// }; -/// # use ff::Field; +/// use ff::Field; /// # use halo2_proofs::plonk::Fixed; /// /// struct Config { @@ -368,12 +367,12 @@ impl TryFrom> for Column { /// s: Selector, /// } /// -/// fn circuit_logic>(chip: C, mut layouter: impl Layouter) -> Result<(), Error> { +/// fn circuit_logic>(chip: C, mut layouter: impl Layouter) -> Result<(), Error> { /// let config = chip.config(); /// # let config: Config = todo!(); /// layouter.assign_region(|| "bar", |mut region| { -/// region.assign_advice(|| "a", config.a, 0, || Value::known(F::one()))?; -/// region.assign_advice(|| "a", config.b, 1, || Value::known(F::one()))?; +/// region.assign_advice(|| "a", config.a, 0, || Value::known(F::ONE))?; +/// region.assign_advice(|| "a", config.b, 1, || Value::known(F::ONE))?; /// config.s.enable(&mut region, 1) /// })?; /// Ok(()) diff --git a/halo2_proofs/src/plonk/circuit/compress_selectors.rs b/halo2_proofs/src/plonk/circuit/compress_selectors.rs index 0e8db9ffc8..60898d3950 100644 --- a/halo2_proofs/src/plonk/circuit/compress_selectors.rs +++ b/halo2_proofs/src/plonk/circuit/compress_selectors.rs @@ -81,7 +81,7 @@ where let combination_assignment = selector .activations .iter() - .map(|b| if *b { F::one() } else { F::zero() }) + .map(|b| if *b { F::ONE } else { F::ZERO }) .collect::>(); let combination_index = combination_assignments.len(); combination_assignments.push(combination_assignment); @@ -179,12 +179,12 @@ where } // Now, compute the selector and combination assignments. - let mut combination_assignment = vec![F::zero(); n]; + let mut combination_assignment = vec![F::ZERO; n]; let combination_len = combination.len(); let combination_index = combination_assignments.len(); let query = allocate_fixed_column(); - let mut assigned_root = F::one(); + let mut assigned_root = F::ONE; selector_assignments.extend(combination.into_iter().map(|selector| { // Compute the expression for substitution. This produces an expression of the // form @@ -194,12 +194,12 @@ where // `assigned_root`. In particular, rows set to 0 correspond to all selectors // being disabled. let mut expression = query.clone(); - let mut root = F::one(); + let mut root = F::ONE; for _ in 0..combination_len { if root != assigned_root { expression = expression * (Expression::Constant(root) - query.clone()); } - root += F::one(); + root += F::ONE; } // Update the combination assignment @@ -214,7 +214,7 @@ where } } - assigned_root += F::one(); + assigned_root += F::ONE; SelectorAssignment { selector: selector.selector, diff --git a/halo2_proofs/src/plonk/evaluation.rs b/halo2_proofs/src/plonk/evaluation.rs index c9c9a5cbf1..2f08a43e01 100644 --- a/halo2_proofs/src/plonk/evaluation.rs +++ b/halo2_proofs/src/plonk/evaluation.rs @@ -4,7 +4,7 @@ use crate::plonk::permutation::Argument; use crate::plonk::{lookup, permutation, AdviceQuery, Any, FixedQuery, InstanceQuery, ProvingKey}; use crate::poly::Basis; use crate::{ - arithmetic::{eval_polynomial, parallelize, CurveAffine, FieldExt}, + arithmetic::{eval_polynomial, parallelize, CurveAffine}, poly::{ commitment::Params, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial, ProverQuery, Rotation, @@ -13,7 +13,7 @@ use crate::{ }; use group::prime::PrimeCurve; use group::{ - ff::{BatchInvert, Field}, + ff::{BatchInvert, Field, PrimeField, WithSmallOrderMulGroup}, Curve, }; use std::any::TypeId; @@ -296,7 +296,7 @@ impl Evaluator { let extended_omega = domain.get_extended_omega(); let omega = domain.get_omega(); let isize = size as i32; - let one = C::ScalarExt::one(); + let one = C::ScalarExt::ONE; let p = &pk.vk.cs.permutation; let num_parts = domain.extended_len() >> domain.k(); @@ -527,7 +527,7 @@ impl Evaluator { &gamma, &theta, &y, - &C::ScalarExt::zero(), + &C::ScalarExt::ZERO, idx, rot_scale, isize, @@ -587,8 +587,8 @@ impl Default for GraphEvaluator { Self { // Fixed positions to allow easy access constants: vec![ - C::ScalarExt::zero(), - C::ScalarExt::one(), + C::ScalarExt::ZERO, + C::ScalarExt::ONE, C::ScalarExt::from(2u64), ], rotations: Vec::new(), @@ -736,9 +736,9 @@ impl GraphEvaluator { } } Expression::Scaled(a, f) => { - if *f == C::ScalarExt::zero() { + if *f == C::ScalarExt::ZERO { ValueSource::Constant(0) - } else if *f == C::ScalarExt::one() { + } else if *f == C::ScalarExt::ONE { self.add_expression(a) } else { let cst = self.add_constant(f); @@ -752,7 +752,7 @@ impl GraphEvaluator { /// Creates a new evaluation structure pub fn instance(&self) -> EvaluationData { EvaluationData { - intermediates: vec![C::ScalarExt::zero(); self.num_intermediates], + intermediates: vec![C::ScalarExt::ZERO; self.num_intermediates], rotations: vec![0usize; self.rotations.len()], } } @@ -800,13 +800,13 @@ impl GraphEvaluator { if let Some(calc) = self.calculations.last() { data.intermediates[calc.target] } else { - C::ScalarExt::zero() + C::ScalarExt::ZERO } } } /// Simple evaluation of an expression -pub fn evaluate( +pub fn evaluate( expression: &Expression, size: usize, rot_scale: i32, @@ -815,7 +815,7 @@ pub fn evaluate( instance: &[Polynomial], challenges: &[F], ) -> Vec { - let mut values = vec![F::zero(); size]; + let mut values = vec![F::ZERO; size]; let isize = size as i32; parallelize(&mut values, |values, start| { for (i, value) in values.iter_mut().enumerate() { diff --git a/halo2_proofs/src/plonk/keygen.rs b/halo2_proofs/src/plonk/keygen.rs index 2f461491f6..10a3660d9f 100644 --- a/halo2_proofs/src/plonk/keygen.rs +++ b/halo2_proofs/src/plonk/keygen.rs @@ -3,7 +3,7 @@ use std::ops::Range; use std::sync::Arc; -use ff::Field; +use ff::{Field, FromUniformBytes}; use group::Curve; use super::{ @@ -329,6 +329,7 @@ where C: CurveAffine, P: Params<'params, C>, ConcreteCircuit: Circuit, + C::Scalar: FromUniformBytes<64>, { let (domain, cs, config) = create_domain::(params.k()); @@ -540,23 +541,23 @@ where // Compute l_0(X) // TODO: this can be done more efficiently let mut l0 = vk.domain.empty_lagrange(); - l0[0] = C::Scalar::one(); + l0[0] = C::Scalar::ONE; let l0 = vk.domain.lagrange_to_coeff(l0); // Compute l_blind(X) which evaluates to 1 for each blinding factor row // and 0 otherwise over the domain. let mut l_blind = vk.domain.empty_lagrange(); for evaluation in l_blind[..].iter_mut().rev().take(cs.blinding_factors()) { - *evaluation = C::Scalar::one(); + *evaluation = C::Scalar::ONE; } // Compute l_last(X) which evaluates to 1 on the first inactive row (just // before the blinding factors) and 0 otherwise over the domain let mut l_last = vk.domain.empty_lagrange(); - l_last[params.n() as usize - cs.blinding_factors() - 1] = C::Scalar::one(); + l_last[params.n() as usize - cs.blinding_factors() - 1] = C::Scalar::ONE; // Compute l_active_row(X) - let one = C::Scalar::one(); + let one = C::Scalar::ONE; let mut l_active_row = vk.domain.empty_lagrange(); parallelize(&mut l_active_row, |values, start| { for (i, value) in values.iter_mut().enumerate() { diff --git a/halo2_proofs/src/plonk/lookup/prover.rs b/halo2_proofs/src/plonk/lookup/prover.rs index f5d87d061e..0f0c85d7e3 100644 --- a/halo2_proofs/src/plonk/lookup/prover.rs +++ b/halo2_proofs/src/plonk/lookup/prover.rs @@ -5,7 +5,7 @@ use super::super::{ use super::Argument; use crate::plonk::evaluation::evaluate; use crate::{ - arithmetic::{eval_polynomial, parallelize, CurveAffine, FieldExt}, + arithmetic::{eval_polynomial, parallelize, CurveAffine}, poly::{ commitment::{Blind, Params}, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial, ProverQuery, @@ -13,6 +13,7 @@ use crate::{ }, transcript::{EncodedChallenge, TranscriptWrite}, }; +use ff::WithSmallOrderMulGroup; use group::{ ff::{BatchInvert, Field}, Curve, @@ -51,7 +52,7 @@ pub(in crate::plonk) struct Evaluated { constructed: Committed, } -impl Argument { +impl> Argument { /// Given a Lookup with input expressions [A_0, A_1, ..., A_{m-1}] and table expressions /// [S_0, S_1, ..., S_{m-1}], this method /// - constructs A_compressed = \theta^{m-1} A_0 + theta^{m-2} A_1 + ... + \theta A_{m-2} + A_{m-1} @@ -191,7 +192,7 @@ impl Permuted { // s_j(X) is the jth table expression in this lookup, // s'(X) is the compression of the permuted table expressions, // and i is the ith row of the expression. - let mut lookup_product = vec![C::Scalar::zero(); params.n() as usize]; + let mut lookup_product = vec![C::Scalar::ZERO; params.n() as usize]; // Denominator uses the permuted input expression and permuted table expression parallelize(&mut lookup_product, |lookup_product, start| { for ((lookup_product, permuted_input_value), permuted_table_value) in lookup_product @@ -234,9 +235,9 @@ impl Permuted { // Compute the evaluations of the lookup product polynomial // over our domain, starting with z[0] = 1 - let z = iter::once(C::Scalar::one()) + let z = iter::once(C::Scalar::ONE) .chain(lookup_product) - .scan(C::Scalar::one(), |state, cur| { + .scan(C::Scalar::ONE, |state, cur| { *state *= &cur; Some(*state) }) @@ -257,7 +258,7 @@ impl Permuted { let u = (params.n() as usize) - (blinding_factors + 1); // l_0(X) * (1 - z(X)) = 0 - assert_eq!(z[0], C::Scalar::one()); + assert_eq!(z[0], C::Scalar::ONE); // z(\omega X) (a'(X) + \beta) (s'(X) + \gamma) // - z(X) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma) @@ -284,7 +285,7 @@ impl Permuted { // l_last(X) * (z(X)^2 - z(X)) = 0 // Assertion will fail only when soundness is broken, in which // case this z[u] value will be zero. (bad!) - assert_eq!(z[u], C::Scalar::one()); + assert_eq!(z[u], C::Scalar::ONE); } let product_blind = Blind(C::Scalar::random(rng)); @@ -413,7 +414,7 @@ fn permute_expression_pair<'params, C: CurveAffine, P: Params<'params, C>, R: Rn *acc.entry(*coeff).or_insert(0) += 1; acc }); - let mut permuted_table_coeffs = vec![C::Scalar::zero(); usable_rows]; + let mut permuted_table_coeffs = vec![C::Scalar::ZERO; usable_rows]; let mut repeated_input_rows = permuted_input_expression .iter() diff --git a/halo2_proofs/src/plonk/lookup/verifier.rs b/halo2_proofs/src/plonk/lookup/verifier.rs index add4e592c9..990866b786 100644 --- a/halo2_proofs/src/plonk/lookup/verifier.rs +++ b/halo2_proofs/src/plonk/lookup/verifier.rs @@ -5,7 +5,7 @@ use super::super::{ }; use super::Argument; use crate::{ - arithmetic::{CurveAffine, FieldExt}, + arithmetic::CurveAffine, plonk::{Error, VerifyingKey}, poly::{commitment::MSM, Rotation, VerifierQuery}, transcript::{EncodedChallenge, TranscriptRead}, @@ -34,7 +34,7 @@ pub struct Evaluated { pub permuted_table_eval: C::Scalar, } -impl Argument { +impl Argument { pub fn read_permuted_commitments< C: CurveAffine, E: EncodedChallenge, @@ -104,7 +104,7 @@ impl Evaluated { instance_evals: &[C::Scalar], challenges: &[C::Scalar], ) -> impl Iterator + 'a { - let active_rows = C::Scalar::one() - (l_last + l_blind); + let active_rows = C::Scalar::ONE - (l_last + l_blind); let product_expression = || { // z(\omega X) (a'(X) + \beta) (s'(X) + \gamma) @@ -130,7 +130,7 @@ impl Evaluated { &|a, scalar| a * &scalar, ) }) - .fold(C::Scalar::zero(), |acc, eval| acc * &*theta + &eval) + .fold(C::Scalar::ZERO, |acc, eval| acc * &*theta + &eval) }; let right = self.product_eval * &(compress_expressions(&argument.input_expressions) + &*beta) @@ -142,7 +142,7 @@ impl Evaluated { std::iter::empty() .chain( // l_0(X) * (1 - z'(X)) = 0 - Some(l_0 * &(C::Scalar::one() - &self.product_eval)), + Some(l_0 * &(C::Scalar::ONE - &self.product_eval)), ) .chain( // l_last(X) * (z(X)^2 - z(X)) = 0 diff --git a/halo2_proofs/src/plonk/permutation/keygen.rs b/halo2_proofs/src/plonk/permutation/keygen.rs index cc2dc09bb0..0736de98c5 100644 --- a/halo2_proofs/src/plonk/permutation/keygen.rs +++ b/halo2_proofs/src/plonk/permutation/keygen.rs @@ -1,9 +1,9 @@ -use ff::Field; +use ff::{Field, PrimeField}; use group::Curve; use super::{Argument, ProvingKey, VerifyingKey}; use crate::{ - arithmetic::{parallelize, CurveAffine, FieldExt}, + arithmetic::{parallelize, CurveAffine}, plonk::{Any, Column, Error}, poly::{ commitment::{Blind, CommitmentScheme, Params}, @@ -109,7 +109,7 @@ impl Assembly { p: &Argument, ) -> VerifyingKey { // Compute [omega^0, omega^1, ..., omega^{params.n - 1}] - let mut omega_powers = vec![C::Scalar::zero(); params.n() as usize]; + let mut omega_powers = vec![C::Scalar::ZERO; params.n() as usize]; { let omega = domain.get_omega(); parallelize(&mut omega_powers, |o, start| { @@ -130,7 +130,7 @@ impl Assembly { for v in omega_powers { *v *= &cur; } - cur *= &C::Scalar::DELTA; + cur *= &::DELTA; } }); } @@ -171,7 +171,7 @@ impl Assembly { p: &Argument, ) -> ProvingKey { // Compute [omega^0, omega^1, ..., omega^{params.n - 1}] - let mut omega_powers = vec![C::Scalar::zero(); params.n() as usize]; + let mut omega_powers = vec![C::Scalar::ZERO; params.n() as usize]; { let omega = domain.get_omega(); parallelize(&mut omega_powers, |o, start| { diff --git a/halo2_proofs/src/plonk/permutation/prover.rs b/halo2_proofs/src/plonk/permutation/prover.rs index ad94b02574..0618952f5a 100644 --- a/halo2_proofs/src/plonk/permutation/prover.rs +++ b/halo2_proofs/src/plonk/permutation/prover.rs @@ -1,3 +1,4 @@ +use ff::PrimeField; use group::{ ff::{BatchInvert, Field}, Curve, @@ -8,7 +9,7 @@ use std::iter::{self, ExactSizeIterator}; use super::super::{circuit::Any, ChallengeBeta, ChallengeGamma, ChallengeX}; use super::{Argument, ProvingKey}; use crate::{ - arithmetic::{eval_polynomial, parallelize, CurveAffine, FieldExt}, + arithmetic::{eval_polynomial, parallelize, CurveAffine}, plonk::{self, Error}, poly::{ self, @@ -72,10 +73,10 @@ impl Argument { let blinding_factors = pk.vk.cs.blinding_factors(); // Each column gets its own delta power. - let mut deltaomega = C::Scalar::one(); + let mut deltaomega = C::Scalar::ONE; // Track the "last" value from the previous column set - let mut last_z = C::Scalar::one(); + let mut last_z = C::Scalar::ONE; let mut sets = vec![]; @@ -92,7 +93,7 @@ impl Argument { // where p_j(X) is the jth column in this permutation, // and i is the ith row of the column. - let mut modified_values = vec![C::Scalar::one(); params.n() as usize]; + let mut modified_values = vec![C::Scalar::ONE; params.n() as usize]; // Iterate over each column of the permutation for (&column, permuted_column_values) in columns.iter().zip(permutations.iter()) { @@ -135,7 +136,7 @@ impl Argument { deltaomega *= ω } }); - deltaomega *= &C::Scalar::DELTA; + deltaomega *= &::DELTA; } // The modified_values vector is a vector of products of fractions diff --git a/halo2_proofs/src/plonk/permutation/verifier.rs b/halo2_proofs/src/plonk/permutation/verifier.rs index a33b210e13..ecdef3f59a 100644 --- a/halo2_proofs/src/plonk/permutation/verifier.rs +++ b/halo2_proofs/src/plonk/permutation/verifier.rs @@ -1,10 +1,10 @@ -use ff::Field; +use ff::{Field, PrimeField}; use std::iter; use super::super::{circuit::Any, ChallengeBeta, ChallengeGamma, ChallengeX}; use super::{Argument, VerifyingKey}; use crate::{ - arithmetic::{CurveAffine, FieldExt}, + arithmetic::CurveAffine, plonk::{self, Error}, poly::{commitment::MSM, Rotation, VerifierQuery}, transcript::{EncodedChallenge, TranscriptRead}, @@ -123,9 +123,9 @@ impl Evaluated { // Enforce only for the first set. // l_0(X) * (1 - z_0(X)) = 0 .chain( - self.sets.first().map(|first_set| { - l_0 * &(C::Scalar::one() - &first_set.permutation_product_eval) - }), + self.sets + .first() + .map(|first_set| l_0 * &(C::Scalar::ONE - &first_set.permutation_product_eval)), ) // Enforce only for the last set. // l_last(X) * (z_l(X)^2 - z_l(X)) = 0 @@ -182,7 +182,8 @@ impl Evaluated { let mut right = set.permutation_product_eval; let mut current_delta = (*beta * &*x) - * &(C::Scalar::DELTA.pow_vartime([(chunk_index * chunk_len) as u64])); + * &(::DELTA + .pow_vartime(&[(chunk_index * chunk_len) as u64])); for eval in columns.iter().map(|&column| match column.column_type() { Any::Advice(_) => { advice_evals[vk.cs.get_any_query_index(column, Rotation::cur())] @@ -198,7 +199,7 @@ impl Evaluated { current_delta *= &C::Scalar::DELTA; } - (left - &right) * (C::Scalar::one() - &(l_last + &l_blind)) + (left - &right) * (C::Scalar::ONE - &(l_last + &l_blind)) }), ) } diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index 7c176e576a..0c9edd780d 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -1,4 +1,4 @@ -use ff::Field; +use ff::{Field, FromUniformBytes, PrimeField, WithSmallOrderMulGroup}; use group::Curve; use halo2curves::CurveExt; use rand_core::RngCore; @@ -20,7 +20,7 @@ use super::{ ChallengeY, Error, Expression, ProvingKey, }; use crate::{ - arithmetic::{eval_polynomial, CurveAffine, FieldExt}, + arithmetic::{eval_polynomial, CurveAffine}, circuit::Value, plonk::Assigned, poly::{ @@ -55,7 +55,10 @@ pub fn create_proof< instances: &[&[&[Scheme::Scalar]]], mut rng: R, transcript: &mut T, -) -> Result<(), Error> { +) -> Result<(), Error> +where + Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, +{ for instance in instances.iter() { if instance.len() != pk.vk.cs.num_instance_columns { return Err(Error::InvalidInstances); diff --git a/halo2_proofs/src/plonk/vanishing/prover.rs b/halo2_proofs/src/plonk/vanishing/prover.rs index aa43a07c0f..71d29b180d 100644 --- a/halo2_proofs/src/plonk/vanishing/prover.rs +++ b/halo2_proofs/src/plonk/vanishing/prover.rs @@ -6,7 +6,7 @@ use rand_core::RngCore; use super::Argument; use crate::{ - arithmetic::{eval_polynomial, CurveAffine, FieldExt}, + arithmetic::{eval_polynomial, CurveAffine}, plonk::{ChallengeX, ChallengeY, Error}, poly::{ self, @@ -139,9 +139,7 @@ impl Constructed { .h_blinds .iter() .rev() - .fold(Blind(C::Scalar::zero()), |acc, eval| { - acc * Blind(xn) + *eval - }); + .fold(Blind(C::Scalar::ZERO), |acc, eval| acc * Blind(xn) + *eval); let random_eval = eval_polynomial(&self.committed.random_poly, *x); transcript.write_scalar(random_eval)?; diff --git a/halo2_proofs/src/plonk/vanishing/verifier.rs b/halo2_proofs/src/plonk/vanishing/verifier.rs index 3570dee6c1..0881dfb2c0 100644 --- a/halo2_proofs/src/plonk/vanishing/verifier.rs +++ b/halo2_proofs/src/plonk/vanishing/verifier.rs @@ -94,8 +94,8 @@ impl PartiallyEvaluated { y: ChallengeY, xn: C::Scalar, ) -> Evaluated { - let expected_h_eval = expressions.fold(C::Scalar::zero(), |h_eval, v| h_eval * &*y + &v); - let expected_h_eval = expected_h_eval * ((xn - C::Scalar::one()).invert().unwrap()); + let expected_h_eval = expressions.fold(C::Scalar::ZERO, |h_eval, v| h_eval * &*y + &v); + let expected_h_eval = expected_h_eval * ((xn - C::Scalar::ONE).invert().unwrap()); let h_commitment = self.h_commitments @@ -104,7 +104,7 @@ impl PartiallyEvaluated { .fold(params.empty_msm(), |mut acc, commitment| { acc.scale(xn); let commitment: C::CurveExt = (*commitment).into(); - acc.append_term(C::Scalar::one(), commitment); + acc.append_term(C::Scalar::ONE, commitment); acc }); diff --git a/halo2_proofs/src/plonk/verifier.rs b/halo2_proofs/src/plonk/verifier.rs index e6a2327e7b..f5984d2c79 100644 --- a/halo2_proofs/src/plonk/verifier.rs +++ b/halo2_proofs/src/plonk/verifier.rs @@ -1,4 +1,4 @@ -use ff::Field; +use ff::{Field, FromUniformBytes, WithSmallOrderMulGroup}; use group::Curve; use rand_core::RngCore; use std::iter; @@ -7,7 +7,7 @@ use super::{ vanishing, ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, ChallengeY, Error, VerifyingKey, }; -use crate::arithmetic::{compute_inner_product, CurveAffine, FieldExt}; +use crate::arithmetic::{compute_inner_product, CurveAffine}; use crate::poly::commitment::{CommitmentScheme, Verifier}; use crate::poly::VerificationStrategy; use crate::poly::{ @@ -37,7 +37,10 @@ pub fn verify_proof< strategy: Strategy, instances: &[&[&[Scheme::Scalar]]], transcript: &mut T, -) -> Result { +) -> Result +where + Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, +{ // Check that instances matches the expected number of instance columns for instances in instances.iter() { if instances.len() != vk.cs.num_instance_columns { @@ -56,7 +59,7 @@ pub fn verify_proof< return Err(Error::InstanceTooLarge); } let mut poly = instance.to_vec(); - poly.resize(params.n() as usize, Scheme::Scalar::zero()); + poly.resize(params.n() as usize, Scheme::Scalar::ZERO); let poly = vk.domain.lagrange_from_vec(poly); Ok(params.commit_lagrange(&poly, Blind::default()).to_affine()) @@ -94,7 +97,7 @@ pub fn verify_proof< let (advice_commitments, challenges) = { let mut advice_commitments = vec![vec![Scheme::Curve::default(); vk.cs.num_advice_columns]; num_proofs]; - let mut challenges = vec![Scheme::Scalar::zero(); vk.cs.num_challenges]; + let mut challenges = vec![Scheme::Scalar::ZERO; vk.cs.num_challenges]; for current_phase in vk.cs.phases() { for advice_commitments in advice_commitments.iter_mut() { @@ -253,7 +256,7 @@ pub fn verify_proof< let l_last = l_evals[0]; let l_blind: Scheme::Scalar = l_evals[1..(1 + blinding_factors)] .iter() - .fold(Scheme::Scalar::zero(), |acc, eval| acc + eval); + .fold(Scheme::Scalar::ZERO, |acc, eval| acc + eval); let l_0 = l_evals[1 + blinding_factors]; // Compute the expected value of h(x) diff --git a/halo2_proofs/src/plonk/verifier/batch.rs b/halo2_proofs/src/plonk/verifier/batch.rs index f07ba4141f..04e08be4af 100644 --- a/halo2_proofs/src/plonk/verifier/batch.rs +++ b/halo2_proofs/src/plonk/verifier/batch.rs @@ -1,5 +1,6 @@ use std::{io, marker::PhantomData}; +use ff::FromUniformBytes; use group::ff::Field; use halo2curves::CurveAffine; use rand_core::{OsRng, RngCore}; @@ -67,7 +68,10 @@ pub struct BatchVerifier { items: Vec>, } -impl BatchVerifier { +impl BatchVerifier +where + C::Scalar: FromUniformBytes<64>, +{ /// Constructs a new batch verifier. pub fn new() -> Self { Self { items: vec![] } diff --git a/halo2_proofs/src/poly.rs b/halo2_proofs/src/poly.rs index 84089482aa..42e43b2e29 100644 --- a/halo2_proofs/src/poly.rs +++ b/halo2_proofs/src/poly.rs @@ -9,7 +9,6 @@ use crate::SerdeFormat; use ff::PrimeField; use group::ff::{BatchInvert, Field}; -use halo2curves::FieldExt; use std::fmt::Debug; use std::io; use std::marker::PhantomData; @@ -177,7 +176,7 @@ impl Polynomial { } } -pub(crate) fn batch_invert_assigned( +pub(crate) fn batch_invert_assigned( assigned: Vec, LagrangeCoeff>>, ) -> Vec> { let mut assigned_denominators: Vec<_> = assigned @@ -202,9 +201,7 @@ pub(crate) fn batch_invert_assigned( assigned .iter() .zip(assigned_denominators.into_iter()) - .map(|(poly, inv_denoms)| { - poly.invert(inv_denoms.into_iter().map(|d| d.unwrap_or_else(F::one))) - }) + .map(|(poly, inv_denoms)| poly.invert(inv_denoms.into_iter().map(|d| d.unwrap_or(F::ONE)))) .collect() } @@ -274,13 +271,13 @@ impl Mul for Polynomial { type Output = Polynomial; fn mul(mut self, rhs: F) -> Polynomial { - if rhs == F::zero() { + if rhs == F::ZERO { return Polynomial { - values: vec![F::zero(); self.len()], + values: vec![F::ZERO; self.len()], _marker: PhantomData, }; } - if rhs == F::one() { + if rhs == F::ONE { return self; } diff --git a/halo2_proofs/src/poly/commitment.rs b/halo2_proofs/src/poly/commitment.rs index e82515cfff..3a0b68f62a 100644 --- a/halo2_proofs/src/poly/commitment.rs +++ b/halo2_proofs/src/poly/commitment.rs @@ -6,8 +6,8 @@ use super::{ use crate::poly::Error; use crate::transcript::{EncodedChallenge, TranscriptRead, TranscriptWrite}; use ff::Field; -use group::Curve; -use halo2curves::{CurveAffine, CurveExt, FieldExt}; +use group::{Curve, Group}; +use halo2curves::{CurveAffine, CurveExt}; use rand_core::RngCore; use std::{ fmt::Debug, @@ -18,7 +18,7 @@ use std::{ /// Defines components of a commitment scheme. pub trait CommitmentScheme { /// Application field of this commitment scheme - type Scalar: FieldExt + halo2curves::Group; + type Scalar: Field; /// Elliptic curve used to commit the application and witnesses type Curve: CurveAffine; @@ -192,20 +192,20 @@ pub trait Verifier<'params, Scheme: CommitmentScheme> { #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub struct Blind(pub F); -impl Default for Blind { +impl Default for Blind { fn default() -> Self { - Blind(F::one()) + Blind(F::ONE) } } -impl Blind { +impl Blind { /// Given `rng` creates new blinding scalar pub fn new(rng: &mut R) -> Self { Blind(F::random(rng)) } } -impl Add for Blind { +impl Add for Blind { type Output = Self; fn add(self, rhs: Blind) -> Self { @@ -213,7 +213,7 @@ impl Add for Blind { } } -impl Mul for Blind { +impl Mul for Blind { type Output = Self; fn mul(self, rhs: Blind) -> Self { @@ -221,25 +221,25 @@ impl Mul for Blind { } } -impl AddAssign for Blind { +impl AddAssign for Blind { fn add_assign(&mut self, rhs: Blind) { self.0 += rhs.0; } } -impl MulAssign for Blind { +impl MulAssign for Blind { fn mul_assign(&mut self, rhs: Blind) { self.0 *= rhs.0; } } -impl AddAssign for Blind { +impl AddAssign for Blind { fn add_assign(&mut self, rhs: F) { self.0 += rhs; } } -impl MulAssign for Blind { +impl MulAssign for Blind { fn mul_assign(&mut self, rhs: F) { self.0 *= rhs; } diff --git a/halo2_proofs/src/poly/domain.rs b/halo2_proofs/src/poly/domain.rs index cd1a0cdc9c..e43934a763 100644 --- a/halo2_proofs/src/poly/domain.rs +++ b/halo2_proofs/src/poly/domain.rs @@ -2,13 +2,16 @@ //! domain that is of a suitable size for the application. use crate::{ - arithmetic::{best_fft, parallelize, FieldExt, Group}, + arithmetic::{best_fft, parallelize}, plonk::Assigned, }; use super::{Coeff, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial, Rotation}; - -use group::ff::{BatchInvert, Field, PrimeField}; +use ff::WithSmallOrderMulGroup; +use group::{ + ff::{BatchInvert, Field, PrimeField}, + Group, +}; use std::marker::PhantomData; @@ -16,24 +19,24 @@ use std::marker::PhantomData; /// performing operations on an evaluation domain of size $2^k$ and an extended /// domain of size $2^{k} * j$ with $j \neq 0$. #[derive(Clone, Debug)] -pub struct EvaluationDomain { +pub struct EvaluationDomain { n: u64, k: u32, extended_k: u32, - omega: G::Scalar, - omega_inv: G::Scalar, - extended_omega: G::Scalar, - extended_omega_inv: G::Scalar, - g_coset: G::Scalar, - g_coset_inv: G::Scalar, + omega: F, + omega_inv: F, + extended_omega: F, + extended_omega_inv: F, + g_coset: F, + g_coset_inv: F, quotient_poly_degree: u64, - ifft_divisor: G::Scalar, - extended_ifft_divisor: G::Scalar, - t_evaluations: Vec, - barycentric_weight: G::Scalar, + ifft_divisor: F, + extended_ifft_divisor: F, + t_evaluations: Vec, + barycentric_weight: F, } -impl EvaluationDomain { +impl> EvaluationDomain { /// This constructs a new evaluation domain object based on the provided /// values $j, k$. pub fn new(j: u32, k: u32) -> Self { @@ -51,12 +54,12 @@ impl EvaluationDomain { extended_k += 1; } - let mut extended_omega = G::Scalar::root_of_unity(); + let mut extended_omega = F::ROOT_OF_UNITY; // Get extended_omega, the 2^{extended_k}'th root of unity // The loop computes extended_omega = omega^{2 ^ (S - extended_k)} // Notice that extended_omega ^ {2 ^ extended_k} = omega ^ {2^S} = 1. - for _ in extended_k..G::Scalar::S { + for _ in extended_k..F::S { extended_omega = extended_omega.square(); } let extended_omega = extended_omega; @@ -78,15 +81,15 @@ impl EvaluationDomain { // already. // The coset evaluation domain is: // zeta {1, extended_omega, extended_omega^2, ..., extended_omega^{(2^extended_k) - 1}} - let g_coset = G::Scalar::ZETA; + let g_coset = F::ZETA; let g_coset_inv = g_coset.square(); let mut t_evaluations = Vec::with_capacity(1 << (extended_k - k)); { // Compute the evaluations of t(X) = X^n - 1 in the coset evaluation domain. // We don't have to compute all of them, because it will repeat. - let orig = G::Scalar::ZETA.pow_vartime([n as u64, 0, 0, 0]); - let step = extended_omega.pow_vartime([n as u64, 0, 0, 0]); + let orig = F::ZETA.pow_vartime(&[n as u64, 0, 0, 0]); + let step = extended_omega.pow_vartime(&[n as u64, 0, 0, 0]); let mut cur = orig; loop { t_evaluations.push(cur); @@ -99,19 +102,19 @@ impl EvaluationDomain { // Subtract 1 from each to give us t_evaluations[i] = t(zeta * extended_omega^i) for coeff in &mut t_evaluations { - *coeff -= &G::Scalar::one(); + *coeff -= &F::ONE; } // Invert, because we're dividing by this polynomial. // We invert in a batch, below. } - let mut ifft_divisor = G::Scalar::from(1 << k); // Inversion computed later - let mut extended_ifft_divisor = G::Scalar::from(1 << extended_k); // Inversion computed later + let mut ifft_divisor = F::from(1 << k); // Inversion computed later + let mut extended_ifft_divisor = F::from(1 << extended_k); // Inversion computed later // The barycentric weight of 1 over the evaluation domain // 1 / \prod_{i != 0} (1 - omega^i) - let mut barycentric_weight = G::Scalar::from(n); // Inversion computed later + let mut barycentric_weight = F::from(n); // Inversion computed later // Compute batch inversion t_evaluations @@ -144,7 +147,7 @@ impl EvaluationDomain { /// Obtains a polynomial in Lagrange form when given a vector of Lagrange /// coefficients of size `n`; panics if the provided vector is the wrong /// length. - pub fn lagrange_from_vec(&self, values: Vec) -> Polynomial { + pub fn lagrange_from_vec(&self, values: Vec) -> Polynomial { assert_eq!(values.len(), self.n as usize); Polynomial { @@ -156,7 +159,7 @@ impl EvaluationDomain { /// Obtains a polynomial in coefficient form when given a vector of /// coefficients of size `n`; panics if the provided vector is the wrong /// length. - pub fn coeff_from_vec(&self, values: Vec) -> Polynomial { + pub fn coeff_from_vec(&self, values: Vec) -> Polynomial { assert_eq!(values.len(), self.n as usize); Polynomial { @@ -170,13 +173,13 @@ impl EvaluationDomain { /// provided vector is the wrong length. pub fn extended_from_lagrange_vec( &self, - values: Vec>, - ) -> Polynomial { + values: Vec>, + ) -> Polynomial { assert_eq!(values.len(), (self.extended_len() >> self.k) as usize); assert_eq!(values[0].len(), self.n as usize); // transpose the values in parallel - let mut transposed = vec![vec![G::group_zero(); values.len()]; self.n as usize]; + let mut transposed = vec![vec![F::ZERO; values.len()]; self.n as usize]; values.into_iter().enumerate().for_each(|(i, p)| { parallelize(&mut transposed, |transposed, start| { for (transposed, p) in transposed.iter_mut().zip(p.values[start..].iter()) { @@ -192,35 +195,32 @@ impl EvaluationDomain { } /// Returns an empty (zero) polynomial in the coefficient basis - pub fn empty_coeff(&self) -> Polynomial { + pub fn empty_coeff(&self) -> Polynomial { Polynomial { - values: vec![G::group_zero(); self.n as usize], + values: vec![F::ZERO; self.n as usize], _marker: PhantomData, } } /// Returns an empty (zero) polynomial in the Lagrange coefficient basis - pub fn empty_lagrange(&self) -> Polynomial { + pub fn empty_lagrange(&self) -> Polynomial { Polynomial { - values: vec![G::group_zero(); self.n as usize], + values: vec![F::ZERO; self.n as usize], _marker: PhantomData, } } /// Returns an empty (zero) polynomial in the Lagrange coefficient basis, with /// deferred inversions. - pub(crate) fn empty_lagrange_assigned(&self) -> Polynomial, LagrangeCoeff> - where - G: Field, - { + pub(crate) fn empty_lagrange_assigned(&self) -> Polynomial, LagrangeCoeff> { Polynomial { - values: vec![G::group_zero().into(); self.n as usize], + values: vec![F::ZERO.into(); self.n as usize], _marker: PhantomData, } } /// Returns a constant polynomial in the Lagrange coefficient basis - pub fn constant_lagrange(&self, scalar: G) -> Polynomial { + pub fn constant_lagrange(&self, scalar: F) -> Polynomial { Polynomial { values: vec![scalar; self.n as usize], _marker: PhantomData, @@ -229,16 +229,16 @@ impl EvaluationDomain { /// Returns an empty (zero) polynomial in the extended Lagrange coefficient /// basis - pub fn empty_extended(&self) -> Polynomial { + pub fn empty_extended(&self) -> Polynomial { Polynomial { - values: vec![G::group_zero(); self.extended_len()], + values: vec![F::ZERO; self.extended_len()], _marker: PhantomData, } } /// Returns a constant polynomial in the extended Lagrange coefficient /// basis - pub fn constant_extended(&self, scalar: G) -> Polynomial { + pub fn constant_extended(&self, scalar: F) -> Polynomial { Polynomial { values: vec![scalar; self.extended_len()], _marker: PhantomData, @@ -249,7 +249,7 @@ impl EvaluationDomain { /// /// This function will panic if the provided vector is not the correct /// length. - pub fn lagrange_to_coeff(&self, mut a: Polynomial) -> Polynomial { + pub fn lagrange_to_coeff(&self, mut a: Polynomial) -> Polynomial { assert_eq!(a.values.len(), 1 << self.k); // Perform inverse FFT to obtain the polynomial in coefficient form @@ -265,12 +265,12 @@ impl EvaluationDomain { /// evaluation domain, rotating by `rotation` if desired. pub fn coeff_to_extended( &self, - mut a: Polynomial, - ) -> Polynomial { + mut a: Polynomial, + ) -> Polynomial { assert_eq!(a.values.len(), 1 << self.k); self.distribute_powers_zeta(&mut a.values, true); - a.values.resize(self.extended_len(), G::group_zero()); + a.values.resize(self.extended_len(), F::ZERO); best_fft(&mut a.values, self.extended_omega, self.extended_k); Polynomial { @@ -289,12 +289,12 @@ impl EvaluationDomain { /// `FFT(f(zeta * extended_omega^{m-1} * X), n)` pub fn coeff_to_extended_parts( &self, - a: &Polynomial, - ) -> Vec> { + a: &Polynomial, + ) -> Vec> { assert_eq!(a.values.len(), 1 << self.k); let num_parts = self.extended_len() >> self.k; - let mut extended_omega_factor = G::Scalar::one(); + let mut extended_omega_factor = F::ONE; (0..num_parts) .map(|_| { let part = self.coeff_to_extended_part(a.clone(), extended_omega_factor); @@ -314,11 +314,11 @@ impl EvaluationDomain { /// `FFT(f(zeta * extended_omega^{m-1} * X), n)` pub fn batched_coeff_to_extended_parts( &self, - a: &[Polynomial], - ) -> Vec>> { + a: &[Polynomial], + ) -> Vec>> { assert_eq!(a[0].values.len(), 1 << self.k); - let mut extended_omega_factor = G::Scalar::one(); + let mut extended_omega_factor = F::ONE; let num_parts = self.extended_len() >> self.k; (0..num_parts) .map(|_| { @@ -340,9 +340,9 @@ impl EvaluationDomain { /// where `extended_omega_factor` is `extended_omega^i` with `i` in `[0, m)`. pub fn coeff_to_extended_part( &self, - mut a: Polynomial, - extended_omega_factor: G::Scalar, - ) -> Polynomial { + mut a: Polynomial, + extended_omega_factor: F, + ) -> Polynomial { assert_eq!(a.values.len(), 1 << self.k); self.distribute_powers(&mut a.values, self.g_coset * extended_omega_factor); @@ -357,9 +357,9 @@ impl EvaluationDomain { /// Rotate the extended domain polynomial over the original domain. pub fn rotate_extended( &self, - poly: &Polynomial, + poly: &Polynomial, rotation: Rotation, - ) -> Polynomial { + ) -> Polynomial { let new_rotation = ((1 << (self.extended_k - self.k)) * rotation.0.abs()) as usize; let mut poly = poly.clone(); @@ -379,7 +379,7 @@ impl EvaluationDomain { /// This function will panic if the provided vector is not the correct /// length. // TODO/FIXME: caller should be responsible for truncating - pub fn extended_to_coeff(&self, mut a: Polynomial) -> Vec { + pub fn extended_to_coeff(&self, mut a: Polynomial) -> Vec { assert_eq!(a.values.len(), self.extended_len()); // Inverse FFT @@ -407,15 +407,15 @@ impl EvaluationDomain { /// polynomial of the $2^k$ size domain. pub fn divide_by_vanishing_poly( &self, - mut a: Polynomial, - ) -> Polynomial { + mut a: Polynomial, + ) -> Polynomial { assert_eq!(a.values.len(), self.extended_len()); // Divide to obtain the quotient polynomial in the coset evaluation // domain. parallelize(&mut a.values, |h, mut index| { for h in h { - h.group_scale(&self.t_evaluations[index % self.t_evaluations.len()]); + *h *= &self.t_evaluations[index % self.t_evaluations.len()]; index += 1; } }); @@ -433,7 +433,7 @@ impl EvaluationDomain { /// /// `into_coset` should be set to `true` when moving into the coset, /// and `false` when moving out. This toggles the choice of `zeta`. - fn distribute_powers_zeta(&self, a: &mut [G], into_coset: bool) { + fn distribute_powers_zeta(&self, a: &mut [F], into_coset: bool) { let coset_powers = if into_coset { [self.g_coset, self.g_coset_inv] } else { @@ -444,7 +444,7 @@ impl EvaluationDomain { // Distribute powers to move into/from coset let i = index % (coset_powers.len() + 1); if i != 0 { - a.group_scale(&coset_powers[i - 1]); + *a *= &coset_powers[i - 1]; } index += 1; } @@ -454,22 +454,22 @@ impl EvaluationDomain { /// Given a slice of group elements `[a_0, a_1, a_2, ...]`, this returns /// `[a_0, [c]a_1, [c^2]a_2, [c^3]a_3, [c^4]a_4, ...]`, /// - fn distribute_powers(&self, a: &mut [G], c: G::Scalar) { + fn distribute_powers(&self, a: &mut [F], c: F) { parallelize(a, |a, index| { let mut c_power = c.pow_vartime(&[index as u64, 0, 0, 0]); for a in a { - a.group_scale(&c_power); + a = a * (&c_power); c_power = c_power * c; } }); } - fn ifft(a: &mut [G], omega_inv: G::Scalar, log_n: u32, divisor: G::Scalar) { + fn ifft(a: &mut [F], omega_inv: F, log_n: u32, divisor: F) { best_fft(a, omega_inv, log_n); parallelize(a, |a, _| { for a in a { // Finish iFFT - a.group_scale(&divisor); + *a *= &divisor; } }); } @@ -490,24 +490,24 @@ impl EvaluationDomain { } /// Get $\omega$, the generator of the $2^k$ order multiplicative subgroup. - pub fn get_omega(&self) -> G::Scalar { + pub fn get_omega(&self) -> F { self.omega } /// Get $\omega^{-1}$, the inverse of the generator of the $2^k$ order /// multiplicative subgroup. - pub fn get_omega_inv(&self) -> G::Scalar { + pub fn get_omega_inv(&self) -> F { self.omega_inv } /// Get the generator of the extended domain's multiplicative subgroup. - pub fn get_extended_omega(&self) -> G::Scalar { + pub fn get_extended_omega(&self) -> F { self.extended_omega } /// Multiplies a value by some power of $\omega$, essentially rotating over /// the domain. - pub fn rotate_omega(&self, value: G::Scalar, rotation: Rotation) -> G::Scalar { + pub fn rotate_omega(&self, value: F, rotation: Rotation) -> F { let mut point = value; if rotation.0 >= 0 { point *= &self.get_omega().pow_vartime([rotation.0 as u64]); @@ -548,23 +548,23 @@ impl EvaluationDomain { /// which is the barycentric weight of $\omega^i$. pub fn l_i_range + Clone>( &self, - x: G::Scalar, - xn: G::Scalar, + x: F, + xn: F, rotations: I, - ) -> Vec { + ) -> Vec { let mut results; { let rotations = rotations.clone().into_iter(); results = Vec::with_capacity(rotations.size_hint().1.unwrap_or(0)); for rotation in rotations { let rotation = Rotation(rotation); - let result = x - self.rotate_omega(G::Scalar::one(), rotation); + let result = x - self.rotate_omega(F::ONE, rotation); results.push(result); } results.iter_mut().batch_invert(); } - let common = (xn - G::Scalar::one()) * self.barycentric_weight; + let common = (xn - F::ONE) * self.barycentric_weight; for (rotation, result) in rotations.into_iter().zip(results.iter_mut()) { let rotation = Rotation(rotation); *result = self.rotate_omega(*result * common, rotation); @@ -581,7 +581,7 @@ impl EvaluationDomain { /// Obtain a pinned version of this evaluation domain; a structure with the /// minimal parameters needed to determine the rest of the evaluation /// domain. - pub fn pinned(&self) -> PinnedEvaluationDomain<'_, G> { + pub fn pinned(&self) -> PinnedEvaluationDomain<'_, F> { PinnedEvaluationDomain { k: &self.k, extended_k: &self.extended_k, @@ -593,10 +593,10 @@ impl EvaluationDomain { /// Represents the minimal parameters that determine an `EvaluationDomain`. #[allow(dead_code)] #[derive(Debug)] -pub struct PinnedEvaluationDomain<'a, G: Group> { +pub struct PinnedEvaluationDomain<'a, F: Field> { k: &'a u32, extended_k: &'a u32, - omega: &'a G::Scalar, + omega: &'a F, } #[test] @@ -655,7 +655,7 @@ fn test_l_i() { } for i in 0..8 { let mut l_i = vec![Scalar::zero(); 8]; - l_i[i] = Scalar::one(); + l_i[i] = Scalar::ONE; let l_i = lagrange_interpolate(&points[..], &l_i[..]); l.push(l_i); } diff --git a/halo2_proofs/src/poly/evaluator.rs b/halo2_proofs/src/poly/evaluator.rs index d1ba853c47..5d20221255 100644 --- a/halo2_proofs/src/poly/evaluator.rs +++ b/halo2_proofs/src/poly/evaluator.rs @@ -9,7 +9,7 @@ use std::{ }; use group::ff::Field; -use halo2curves::FieldExt; +use halo2curves::Field; use super::{ Basis, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial, Rotation, @@ -135,7 +135,7 @@ impl Evaluator { ) -> Polynomial where E: Copy + Send + Sync, - F: FieldExt, + F: Field, B: BasisOps, { // Traverse `ast` to collect the used leaves. @@ -192,7 +192,7 @@ impl Evaluator { }) .collect(); - struct AstContext<'a, E, F: FieldExt, B: Basis> { + struct AstContext<'a, E, F: Field, B: Basis> { domain: &'a EvaluationDomain, poly_len: usize, chunk_size: usize, @@ -200,7 +200,7 @@ impl Evaluator { leaves: &'a HashMap, &'a [F]>, } - fn recurse( + fn recurse( ast: &Ast, ctx: &AstContext<'_, E, F, B>, ) -> Vec { @@ -230,7 +230,7 @@ impl Evaluator { lhs } Ast::DistributePowers(terms, base) => terms.iter().fold( - B::constant_term(ctx.poly_len, ctx.chunk_size, ctx.chunk_index, F::zero()), + B::constant_term(ctx.poly_len, ctx.chunk_size, ctx.chunk_index, F::ZERO), |mut acc, term| { let term = recurse(term, ctx); for (acc, term) in acc.iter_mut().zip(term) { @@ -347,7 +347,7 @@ impl From> for Ast { impl Ast { pub(crate) fn one() -> Self { - Self::ConstantTerm(F::one()) + Self::ConstantTerm(F::ONE) } } @@ -355,7 +355,7 @@ impl Neg for Ast { type Output = Ast; fn neg(self) -> Self::Output { - Ast::Scale(Arc::new(self), -F::one()) + Ast::Scale(Arc::new(self), -F::ONE) } } @@ -489,21 +489,21 @@ impl MulAssign for Ast { /// Operations which can be performed over a given basis. pub(crate) trait BasisOps: Basis { - fn empty_poly(domain: &EvaluationDomain) -> Polynomial; - fn constant_term( + fn empty_poly(domain: &EvaluationDomain) -> Polynomial; + fn constant_term( poly_len: usize, chunk_size: usize, chunk_index: usize, scalar: F, ) -> Vec; - fn linear_term( + fn linear_term( domain: &EvaluationDomain, poly_len: usize, chunk_size: usize, chunk_index: usize, scalar: F, ) -> Vec; - fn rotate( + fn rotate( domain: &EvaluationDomain, poly: &Polynomial, rotation: Rotation, @@ -511,31 +511,31 @@ pub(crate) trait BasisOps: Basis { } impl BasisOps for Coeff { - fn empty_poly(domain: &EvaluationDomain) -> Polynomial { + fn empty_poly(domain: &EvaluationDomain) -> Polynomial { domain.empty_coeff() } - fn constant_term( + fn constant_term( poly_len: usize, chunk_size: usize, chunk_index: usize, scalar: F, ) -> Vec { - let mut chunk = vec![F::zero(); cmp::min(chunk_size, poly_len - chunk_size * chunk_index)]; + let mut chunk = vec![F::ZERO; cmp::min(chunk_size, poly_len - chunk_size * chunk_index)]; if chunk_index == 0 { chunk[0] = scalar; } chunk } - fn linear_term( + fn linear_term( _: &EvaluationDomain, poly_len: usize, chunk_size: usize, chunk_index: usize, scalar: F, ) -> Vec { - let mut chunk = vec![F::zero(); cmp::min(chunk_size, poly_len - chunk_size * chunk_index)]; + let mut chunk = vec![F::ZERO; cmp::min(chunk_size, poly_len - chunk_size * chunk_index)]; // If the chunk size is 1 (e.g. if we have a small k and many threads), then the // linear coefficient is the second chunk. Otherwise, the chunk size is greater // than one, and the linear coefficient is the second element of the first chunk. @@ -550,7 +550,7 @@ impl BasisOps for Coeff { chunk } - fn rotate( + fn rotate( _: &EvaluationDomain, _: &Polynomial, _: Rotation, @@ -560,11 +560,11 @@ impl BasisOps for Coeff { } impl BasisOps for LagrangeCoeff { - fn empty_poly(domain: &EvaluationDomain) -> Polynomial { + fn empty_poly(domain: &EvaluationDomain) -> Polynomial { domain.empty_lagrange() } - fn constant_term( + fn constant_term( poly_len: usize, chunk_size: usize, chunk_index: usize, @@ -573,7 +573,7 @@ impl BasisOps for LagrangeCoeff { vec![scalar; cmp::min(chunk_size, poly_len - chunk_size * chunk_index)] } - fn linear_term( + fn linear_term( domain: &EvaluationDomain, poly_len: usize, chunk_size: usize, @@ -592,7 +592,7 @@ impl BasisOps for LagrangeCoeff { .collect() } - fn rotate( + fn rotate( _: &EvaluationDomain, poly: &Polynomial, rotation: Rotation, @@ -602,11 +602,11 @@ impl BasisOps for LagrangeCoeff { } impl BasisOps for ExtendedLagrangeCoeff { - fn empty_poly(domain: &EvaluationDomain) -> Polynomial { + fn empty_poly(domain: &EvaluationDomain) -> Polynomial { domain.empty_extended() } - fn constant_term( + fn constant_term( poly_len: usize, chunk_size: usize, chunk_index: usize, @@ -615,7 +615,7 @@ impl BasisOps for ExtendedLagrangeCoeff { vec![scalar; cmp::min(chunk_size, poly_len - chunk_size * chunk_index)] } - fn linear_term( + fn linear_term( domain: &EvaluationDomain, poly_len: usize, chunk_size: usize, @@ -637,7 +637,7 @@ impl BasisOps for ExtendedLagrangeCoeff { .collect() } - fn rotate( + fn rotate( domain: &EvaluationDomain, poly: &Polynomial, rotation: Rotation, diff --git a/halo2_proofs/src/poly/ipa/commitment.rs b/halo2_proofs/src/poly/ipa/commitment.rs index 9060e8315c..f9b4ad059b 100644 --- a/halo2_proofs/src/poly/ipa/commitment.rs +++ b/halo2_proofs/src/poly/ipa/commitment.rs @@ -4,7 +4,7 @@ //! [halo]: https://eprint.iacr.org/2019/1021 use crate::arithmetic::{ - best_fft, best_multiexp, g_to_lagrange, parallelize, CurveAffine, CurveExt, FieldExt, Group, + best_fft, best_multiexp, g_to_lagrange, parallelize, CurveAffine, CurveExt, }; use crate::helpers::CurveRead; use crate::poly::commitment::{Blind, CommitmentScheme, Params, ParamsProver, ParamsVerifier, MSM}; @@ -12,7 +12,7 @@ use crate::poly::ipa::msm::MSMIPA; use crate::poly::{Coeff, LagrangeCoeff, Polynomial}; use ff::{Field, PrimeField}; -use group::{prime::PrimeCurveAffine, Curve, Group as _}; +use group::{prime::PrimeCurveAffine, Curve, Group}; use std::marker::PhantomData; use std::ops::{Add, AddAssign, Mul, MulAssign}; @@ -234,9 +234,7 @@ impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA { #[cfg(test)] mod test { - use crate::arithmetic::{ - best_fft, best_multiexp, parallelize, CurveAffine, CurveExt, FieldExt, Group, - }; + use crate::arithmetic::{best_fft, best_multiexp, parallelize, CurveAffine, CurveExt}; use crate::helpers::CurveRead; use crate::poly::commitment::ParamsProver; use crate::poly::commitment::{Blind, CommitmentScheme, Params, MSM}; @@ -245,7 +243,7 @@ mod test { use crate::poly::{Coeff, LagrangeCoeff, Polynomial}; use ff::{Field, PrimeField}; - use group::{prime::PrimeCurveAffine, Curve, Group as _}; + use group::{prime::PrimeCurveAffine, Curve, Group}; use std::marker::PhantomData; use std::ops::{Add, AddAssign, Mul, MulAssign}; @@ -309,7 +307,7 @@ mod test { use rand_core::OsRng; use super::super::commitment::{Blind, Params}; - use crate::arithmetic::{eval_polynomial, FieldExt}; + use crate::arithmetic::eval_polynomial; use crate::halo2curves::pasta::{EpAffine, Fq}; use crate::poly::EvaluationDomain; use crate::transcript::{ @@ -363,7 +361,7 @@ mod test { assert_eq!(v, v_prime); let mut commitment_msm = MSMIPA::new(¶ms); - commitment_msm.append_term(Field::one(), p.into()); + commitment_msm.append_term(Fq::one(), p.into()); let guard = verify_proof(¶ms, commitment_msm, &mut transcript, *x, v).unwrap(); let ch_verifier = transcript.squeeze_challenge(); diff --git a/halo2_proofs/src/poly/ipa/commitment/prover.rs b/halo2_proofs/src/poly/ipa/commitment/prover.rs index 3b22b31b36..d176987c96 100644 --- a/halo2_proofs/src/poly/ipa/commitment/prover.rs +++ b/halo2_proofs/src/poly/ipa/commitment/prover.rs @@ -3,7 +3,7 @@ use rand_core::RngCore; use super::{Params, ParamsIPA}; use crate::arithmetic::{ - best_multiexp, compute_inner_product, eval_polynomial, parallelize, CurveAffine, FieldExt, + best_multiexp, compute_inner_product, eval_polynomial, parallelize, CurveAffine, }; use crate::poly::commitment::ParamsProver; @@ -87,7 +87,7 @@ pub fn create_proof< // `p_prime` and `b` is the evaluation of the polynomial at `x_3`. let mut b = Vec::with_capacity(1 << params.k); { - let mut cur = C::Scalar::one(); + let mut cur = C::Scalar::ONE; for _ in 0..(1 << params.k) { b.push(cur); cur *= &x_3; diff --git a/halo2_proofs/src/poly/ipa/commitment/verifier.rs b/halo2_proofs/src/poly/ipa/commitment/verifier.rs index b3b30e0b4b..0b60842899 100644 --- a/halo2_proofs/src/poly/ipa/commitment/verifier.rs +++ b/halo2_proofs/src/poly/ipa/commitment/verifier.rs @@ -96,10 +96,10 @@ pub fn verify_proof<'params, C: CurveAffine, E: EncodedChallenge, T: Transcri /// Computes $\prod\limits_{i=0}^{k-1} (1 + u_{k - 1 - i} x^{2^i})$. fn compute_b(x: F, u: &[F]) -> F { - let mut tmp = F::one(); + let mut tmp = F::ONE; let mut cur = x; for u_j in u.iter().rev() { - tmp *= F::one() + &(*u_j * &cur); + tmp *= F::ONE + &(*u_j * &cur); cur *= cur; } tmp diff --git a/halo2_proofs/src/poly/ipa/msm.rs b/halo2_proofs/src/poly/ipa/msm.rs index 63f994b46e..3316e25337 100644 --- a/halo2_proofs/src/poly/ipa/msm.rs +++ b/halo2_proofs/src/poly/ipa/msm.rs @@ -191,7 +191,7 @@ impl<'a, C: CurveAffine> MSMIPA<'a, C> { if let Some(g_scalars) = self.g_scalars.as_mut() { g_scalars[0] += &constant; } else { - let mut g_scalars = vec![C::Scalar::zero(); self.params.n as usize]; + let mut g_scalars = vec![C::Scalar::ZERO; self.params.n as usize]; g_scalars[0] += &constant; self.g_scalars = Some(g_scalars); } diff --git a/halo2_proofs/src/poly/ipa/multiopen.rs b/halo2_proofs/src/poly/ipa/multiopen.rs index b724139a8f..fd6aa78544 100644 --- a/halo2_proofs/src/poly/ipa/multiopen.rs +++ b/halo2_proofs/src/poly/ipa/multiopen.rs @@ -3,14 +3,10 @@ //! //! [halo]: https://eprint.iacr.org/2019/1021 -use std::collections::{BTreeMap, BTreeSet}; - use super::*; -use crate::{ - arithmetic::{CurveAffine, FieldExt}, - poly::query::Query, - transcript::ChallengeScalar, -}; +use crate::{arithmetic::CurveAffine, poly::query::Query, transcript::ChallengeScalar}; +use ff::Field; +use std::collections::{BTreeMap, BTreeSet}; mod prover; mod verifier; @@ -63,7 +59,7 @@ type IntermediateSets = ( Vec>, ); -fn construct_intermediate_sets>(queries: I) -> IntermediateSets +fn construct_intermediate_sets>(queries: I) -> IntermediateSets where I: IntoIterator + Clone, { diff --git a/halo2_proofs/src/poly/ipa/multiopen/prover.rs b/halo2_proofs/src/poly/ipa/multiopen/prover.rs index bba038c93a..6d65e7ae64 100644 --- a/halo2_proofs/src/poly/ipa/multiopen/prover.rs +++ b/halo2_proofs/src/poly/ipa/multiopen/prover.rs @@ -1,7 +1,7 @@ use super::{ construct_intermediate_sets, ChallengeX1, ChallengeX2, ChallengeX3, ChallengeX4, Query, }; -use crate::arithmetic::{eval_polynomial, kate_division, CurveAffine, FieldExt}; +use crate::arithmetic::{eval_polynomial, kate_division, CurveAffine}; use crate::poly::commitment::ParamsProver; use crate::poly::commitment::{Blind, Params, Prover}; use crate::poly::ipa::commitment::{self, IPACommitmentScheme, ParamsIPA}; @@ -47,7 +47,7 @@ impl<'params, C: CurveAffine> Prover<'params, IPACommitmentScheme> for Prover // Collapse openings at same point sets together into single openings using // x_1 challenge. let mut q_polys: Vec>> = vec![None; point_sets.len()]; - let mut q_blinds = vec![Blind(C::Scalar::zero()); point_sets.len()]; + let mut q_blinds = vec![Blind(C::Scalar::ZERO); point_sets.len()]; { let mut accumulate = |set_idx: usize, @@ -80,7 +80,7 @@ impl<'params, C: CurveAffine> Prover<'params, IPACommitmentScheme> for Prover .fold(poly.clone().unwrap().values, |poly, point| { kate_division(&poly, *point) }); - poly.resize(self.params.n as usize, C::Scalar::zero()); + poly.resize(self.params.n as usize, C::Scalar::ZERO); let poly = Polynomial { values: poly, _marker: PhantomData, diff --git a/halo2_proofs/src/poly/ipa/multiopen/verifier.rs b/halo2_proofs/src/poly/ipa/multiopen/verifier.rs index ff4c7626f6..391f89e15b 100644 --- a/halo2_proofs/src/poly/ipa/multiopen/verifier.rs +++ b/halo2_proofs/src/poly/ipa/multiopen/verifier.rs @@ -8,7 +8,7 @@ use rand_core::RngCore; use super::{ construct_intermediate_sets, ChallengeX1, ChallengeX2, ChallengeX3, ChallengeX4, Query, }; -use crate::arithmetic::{eval_polynomial, lagrange_interpolate, CurveAffine, FieldExt}; +use crate::arithmetic::{eval_polynomial, lagrange_interpolate, CurveAffine}; use crate::poly::commitment::{Params, Verifier, MSM}; use crate::poly::ipa::commitment::{IPACommitmentScheme, ParamsIPA, ParamsVerifierIPA}; use crate::poly::ipa::msm::MSMIPA; @@ -63,7 +63,7 @@ impl<'params, C: CurveAffine> Verifier<'params, IPACommitmentScheme> // while the inner vec corresponds to the points in a particular set. let mut q_eval_sets = Vec::with_capacity(point_sets.len()); for point_set in point_sets.iter() { - q_eval_sets.push(vec![C::Scalar::zero(); point_set.len()]); + q_eval_sets.push(vec![C::Scalar::ZERO; point_set.len()]); } { let mut accumulate = |set_idx: usize, @@ -72,7 +72,7 @@ impl<'params, C: CurveAffine> Verifier<'params, IPACommitmentScheme> q_commitments[set_idx].scale(*x_1); match new_commitment { CommitmentReference::Commitment(c) => { - q_commitments[set_idx].append_term(C::Scalar::one(), (*c).into()); + q_commitments[set_idx].append_term(C::Scalar::ONE, (*c).into()); } CommitmentReference::MSM(msm) => { q_commitments[set_idx].add_msm(msm); @@ -116,7 +116,7 @@ impl<'params, C: CurveAffine> Verifier<'params, IPACommitmentScheme> .zip(q_eval_sets.iter()) .zip(u.iter()) .fold( - C::Scalar::zero(), + C::Scalar::ZERO, |msm_eval, ((points, evals), proof_eval)| { let r_poly = lagrange_interpolate(points, evals); let r_eval = eval_polynomial(&r_poly, *x_3); @@ -132,7 +132,7 @@ impl<'params, C: CurveAffine> Verifier<'params, IPACommitmentScheme> let x_4: ChallengeX4<_> = transcript.squeeze_challenge_scalar(); // Compute the final commitment that has to be opened - msm.append_term(C::Scalar::one(), q_prime_commitment.into()); + msm.append_term(C::Scalar::ONE, q_prime_commitment.into()); let (msm, v) = q_commitments.into_iter().zip(u.iter()).fold( (msm, msm_eval), |(mut msm, msm_eval), (q_commitment, q_eval)| { diff --git a/halo2_proofs/src/poly/ipa/strategy.rs b/halo2_proofs/src/poly/ipa/strategy.rs index 6f3b4b7228..c8d385f90c 100644 --- a/halo2_proofs/src/poly/ipa/strategy.rs +++ b/halo2_proofs/src/poly/ipa/strategy.rs @@ -70,7 +70,7 @@ impl<'params, C: CurveAffine> GuardIPA<'params, C> { /// Computes G = ⟨s, params.g⟩ pub fn compute_g(&self) -> C { - let s = compute_s(&self.u, C::Scalar::one()); + let s = compute_s(&self.u, C::Scalar::ONE); best_multiexp(&s, &self.msm.params.g).to_affine() } @@ -160,7 +160,7 @@ impl<'params, C: CurveAffine> /// Computes the coefficients of $g(X) = \prod\limits_{i=0}^{k-1} (1 + u_{k - 1 - i} X^{2^i})$. fn compute_s(u: &[F], init: F) -> Vec { assert!(!u.is_empty()); - let mut v = vec![F::zero(); 1 << u.len()]; + let mut v = vec![F::ZERO; 1 << u.len()]; v[0] = init; for (len, u_j) in u.iter().rev().enumerate().map(|(i, u_j)| (1 << i, u_j)) { diff --git a/halo2_proofs/src/poly/kzg/commitment.rs b/halo2_proofs/src/poly/kzg/commitment.rs index 08665667b3..f9fc508c6a 100644 --- a/halo2_proofs/src/poly/kzg/commitment.rs +++ b/halo2_proofs/src/poly/kzg/commitment.rs @@ -1,5 +1,5 @@ use crate::arithmetic::{ - best_fft, best_multiexp, g_to_lagrange, parallelize, CurveAffine, CurveExt, FieldExt, Group, + best_fft, best_multiexp, g_to_lagrange, parallelize, CurveAffine, CurveExt, }; use crate::helpers::SerdeCurveAffine; use crate::poly::commitment::{Blind, CommitmentScheme, Params, ParamsProver, ParamsVerifier, MSM}; @@ -7,7 +7,7 @@ use crate::poly::{Coeff, LagrangeCoeff, Polynomial}; use crate::SerdeFormat; use ff::{Field, PrimeField}; -use group::{prime::PrimeCurveAffine, Curve, Group as _}; +use group::{prime::PrimeCurveAffine, Curve, Group}; use halo2curves::pairing::Engine; use rand_core::{OsRng, RngCore}; use std::fmt::Debug; @@ -37,6 +37,7 @@ pub struct KZGCommitmentScheme { impl CommitmentScheme for KZGCommitmentScheme where + E::Scalar: PrimeField, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { @@ -55,7 +56,10 @@ where } } -impl ParamsKZG { +impl ParamsKZG +where + E::Scalar: PrimeField, +{ /// Initializes parameters for the curve, draws toxic secret from given rng. /// MUST NOT be used in production. pub fn setup(k: u32, rng: R) -> Self { @@ -80,7 +84,7 @@ impl ParamsKZG { // Calculate g = [G1, [s] G1, [s^2] G1, ..., [s^(n-1)] G1] in parallel. let g1 = E::G1Affine::generator(); - let mut g_projective = vec![E::G1::group_zero(); n as usize]; + let mut g_projective = vec![E::G1::identity(); n as usize]; parallelize(&mut g_projective, |g, start| { let mut current_g: E::G1 = g1.into(); current_g *= s.pow_vartime([start as u64]); @@ -98,14 +102,14 @@ impl ParamsKZG { g }; - let mut g_lagrange_projective = vec![E::G1::group_zero(); n as usize]; + let mut g_lagrange_projective = vec![E::G1::identity(); n as usize]; let mut root = E::Scalar::ROOT_OF_UNITY_INV.invert().unwrap(); for _ in k..E::Scalar::S { root = root.square(); } let n_inv = Option::::from(E::Scalar::from(n).invert()) .expect("inversion should be ok for n = 1< = ParamsKZG; impl<'params, E: Engine + Debug> Params<'params, E::G1Affine> for ParamsKZG where + E::Scalar: PrimeField, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { @@ -316,6 +321,7 @@ where impl<'params, E: Engine + Debug> ParamsVerifier<'params, E::G1Affine> for ParamsKZG where + E::Scalar: PrimeField, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { @@ -323,6 +329,7 @@ where impl<'params, E: Engine + Debug> ParamsProver<'params, E::G1Affine> for ParamsKZG where + E::Scalar: PrimeField, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { @@ -352,9 +359,7 @@ where #[cfg(test)] mod test { - use crate::arithmetic::{ - best_fft, best_multiexp, parallelize, CurveAffine, CurveExt, FieldExt, Group, - }; + use crate::arithmetic::{best_fft, best_multiexp, parallelize, CurveAffine, CurveExt}; use crate::poly::commitment::ParamsProver; use crate::poly::commitment::{Blind, CommitmentScheme, Params, MSM}; use crate::poly::kzg::commitment::{ParamsKZG, ParamsVerifierKZG}; @@ -363,7 +368,7 @@ mod test { use crate::poly::{Coeff, LagrangeCoeff, Polynomial}; use ff::{Field, PrimeField}; - use group::{prime::PrimeCurveAffine, Curve, Group as _}; + use group::{prime::PrimeCurveAffine, Curve, Group}; use halo2curves::bn256::G1Affine; use std::marker::PhantomData; use std::ops::{Add, AddAssign, Mul, MulAssign}; @@ -403,7 +408,7 @@ mod test { use rand_core::OsRng; use super::super::commitment::{Blind, Params}; - use crate::arithmetic::{eval_polynomial, FieldExt}; + use crate::arithmetic::eval_polynomial; use crate::halo2curves::bn256::{Bn256, Fr}; use crate::poly::EvaluationDomain; diff --git a/halo2_proofs/src/poly/kzg/msm.rs b/halo2_proofs/src/poly/kzg/msm.rs index 6cc90a5103..abd8309f56 100644 --- a/halo2_proofs/src/poly/kzg/msm.rs +++ b/halo2_proofs/src/poly/kzg/msm.rs @@ -27,7 +27,7 @@ impl MSMKZG { /// Prepares all scalars in the MSM to linear combination pub fn combine_with_base(&mut self, base: E::Scalar) { use ff::Field; - let mut acc = E::Scalar::one(); + let mut acc = E::Scalar::ONE; if !self.scalars.is_empty() { for scalar in self.scalars.iter_mut().rev() { *scalar *= &acc; diff --git a/halo2_proofs/src/poly/kzg/multiopen/gwc.rs b/halo2_proofs/src/poly/kzg/multiopen/gwc.rs index 4869238ae7..8e7d742fc0 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/gwc.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/gwc.rs @@ -5,7 +5,7 @@ pub use prover::ProverGWC; pub use verifier::VerifierGWC; use crate::{ - arithmetic::{eval_polynomial, CurveAffine, FieldExt}, + arithmetic::{eval_polynomial, CurveAffine}, poly::{ commitment::{Params, ParamsVerifier}, query::Query, @@ -13,7 +13,7 @@ use crate::{ }, transcript::ChallengeScalar, }; - +use ff::Field; use std::{ collections::{BTreeMap, BTreeSet}, marker::PhantomData, @@ -27,13 +27,13 @@ type ChallengeU = ChallengeScalar; struct V {} type ChallengeV = ChallengeScalar; -struct CommitmentData> { +struct CommitmentData> { queries: Vec, point: F, _marker: PhantomData, } -fn construct_intermediate_sets>(queries: I) -> Vec> +fn construct_intermediate_sets>(queries: I) -> Vec> where I: IntoIterator + Clone, { diff --git a/halo2_proofs/src/poly/kzg/multiopen/gwc/prover.rs b/halo2_proofs/src/poly/kzg/multiopen/gwc/prover.rs index ee8a549a00..d5d977fb2d 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/gwc/prover.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/gwc/prover.rs @@ -1,5 +1,5 @@ use super::{construct_intermediate_sets, ChallengeV, Query}; -use crate::arithmetic::{eval_polynomial, kate_division, powers, CurveAffine, FieldExt}; +use crate::arithmetic::{eval_polynomial, kate_division, powers, CurveAffine}; use crate::helpers::SerdeCurveAffine; use crate::poly::commitment::ParamsProver; use crate::poly::commitment::Prover; @@ -12,7 +12,7 @@ use crate::poly::{ }; use crate::transcript::{EncodedChallenge, TranscriptWrite}; -use ff::Field; +use ff::{Field, PrimeField}; use group::Curve; use halo2curves::pairing::Engine; use rand_core::RngCore; @@ -29,6 +29,7 @@ pub struct ProverGWC<'params, E: Engine> { /// Create a multi-opening proof impl<'params, E: Engine + Debug> Prover<'params, KZGCommitmentScheme> for ProverGWC<'params, E> where + E::Scalar: PrimeField, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { diff --git a/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs index 22fa139480..1d0c9468b4 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs @@ -3,7 +3,7 @@ use std::io::Read; use std::marker::PhantomData; use super::{construct_intermediate_sets, ChallengeU, ChallengeV}; -use crate::arithmetic::{eval_polynomial, lagrange_interpolate, powers, CurveAffine, FieldExt}; +use crate::arithmetic::{eval_polynomial, lagrange_interpolate, powers, CurveAffine}; use crate::helpers::SerdeCurveAffine; use crate::poly::commitment::Verifier; use crate::poly::commitment::MSM; @@ -19,7 +19,7 @@ use crate::poly::{ }; use crate::transcript::{EncodedChallenge, TranscriptRead}; -use ff::Field; +use ff::{Field, PrimeField}; use group::Group; use halo2curves::pairing::{Engine, MillerLoopResult, MultiMillerLoop}; use rand_core::OsRng; @@ -33,6 +33,7 @@ pub struct VerifierGWC<'params, E: Engine> { impl<'params, E> Verifier<'params, KZGCommitmentScheme> for VerifierGWC<'params, E> where E: MultiMillerLoop + Debug, + E::Scalar: PrimeField, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { @@ -70,7 +71,7 @@ where let u: ChallengeU<_> = transcript.squeeze_challenge_scalar(); let mut commitment_multi = MSMKZG::::new(); - let mut eval_multi = E::Scalar::zero(); + let mut eval_multi = E::Scalar::ZERO; let mut witness = MSMKZG::::new(); let mut witness_with_aux = MSMKZG::::new(); diff --git a/halo2_proofs/src/poly/kzg/multiopen/shplonk.rs b/halo2_proofs/src/poly/kzg/multiopen/shplonk.rs index 0b1a2492b1..d14132fb43 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/shplonk.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/shplonk.rs @@ -1,20 +1,20 @@ mod prover; mod verifier; -pub use prover::ProverSHPLONK; -pub use verifier::VerifierSHPLONK; - use crate::{ - arithmetic::{eval_polynomial, lagrange_interpolate, CurveAffine, FieldExt}, + arithmetic::{eval_polynomial, lagrange_interpolate, CurveAffine}, poly::{query::Query, Coeff, Polynomial}, transcript::ChallengeScalar, }; +use ff::Field; +pub use prover::ProverSHPLONK; use rayon::prelude::*; use std::{ collections::{btree_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet}, marker::PhantomData, sync::Arc, }; +pub use verifier::VerifierSHPLONK; #[derive(Clone, Copy, Debug)] struct U {} @@ -29,9 +29,9 @@ struct Y {} type ChallengeY = ChallengeScalar; #[derive(Debug, Clone, PartialEq)] -struct Commitment((T, Vec)); +struct Commitment((T, Vec)); -impl Commitment { +impl Commitment { fn get(&self) -> T { self.0 .0.clone() } @@ -42,18 +42,18 @@ impl Commitment { } #[derive(Debug, Clone, PartialEq)] -struct RotationSet { +struct RotationSet { commitments: Vec>, points: Vec, } #[derive(Debug, PartialEq)] -struct IntermediateSets> { +struct IntermediateSets> { rotation_sets: Vec>, super_point_set: BTreeSet, } -fn construct_intermediate_sets>( +fn construct_intermediate_sets>( queries: I, ) -> IntermediateSets where @@ -157,8 +157,8 @@ mod proptests { use super::{construct_intermediate_sets, Commitment, IntermediateSets}; use crate::poly::Rotation; - use halo2curves::{pasta::Fp, FieldExt}; - + use ff::{Field, FromUniformBytes}; + use halo2curves::pasta::Fp; use std::collections::BTreeMap; use std::convert::TryFrom; @@ -190,7 +190,7 @@ mod proptests { fn arb_point()( bytes in vec(any::(), 64) ) -> Fp { - Fp::from_bytes_wide(&<[u8; 64]>::try_from(bytes).unwrap()) + Fp::from_uniform_bytes(&<[u8; 64]>::try_from(bytes).unwrap()) } } diff --git a/halo2_proofs/src/poly/kzg/multiopen/shplonk/prover.rs b/halo2_proofs/src/poly/kzg/multiopen/shplonk/prover.rs index 3206364b8f..bb50eafe58 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/shplonk/prover.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/shplonk/prover.rs @@ -3,7 +3,7 @@ use super::{ }; use crate::arithmetic::{ eval_polynomial, evaluate_vanishing_polynomial, kate_division, lagrange_interpolate, - parallelize, powers, CurveAffine, FieldExt, + parallelize, powers, CurveAffine, }; use crate::helpers::SerdeCurveAffine; use crate::poly::commitment::{Blind, ParamsProver, Prover}; @@ -13,7 +13,7 @@ use crate::poly::Rotation; use crate::poly::{commitment::Params, Coeff, Polynomial}; use crate::transcript::{EncodedChallenge, TranscriptWrite}; -use ff::Field; +use ff::{Field, PrimeField}; use group::Curve; use halo2curves::pairing::Engine; use rand_core::RngCore; @@ -23,7 +23,7 @@ use std::io::{self, Write}; use std::marker::PhantomData; use std::ops::MulAssign; -fn div_by_vanishing(poly: Polynomial, roots: &[F]) -> Vec { +fn div_by_vanishing(poly: Polynomial, roots: &[F]) -> Vec { let poly = roots .iter() .fold(poly.values, |poly, point| kate_division(&poly, *point)); @@ -105,6 +105,7 @@ impl<'a, E: Engine> ProverSHPLONK<'a, E> { impl<'params, E: Engine + Debug> Prover<'params, KZGCommitmentScheme> for ProverSHPLONK<'params, E> where + E::Scalar: Ord + PrimeField, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { @@ -162,7 +163,7 @@ where // Q_i(X) = N_i(X) / Z_i(X) where // Z_i(X) = (x - r_i_0) * (x - r_i_1) * ... let mut poly = div_by_vanishing(n_x, points); - poly.resize(self.params.n as usize, E::Scalar::zero()); + poly.resize(self.params.n as usize, E::Scalar::ZERO); Polynomial { values: poly, @@ -261,7 +262,7 @@ where #[cfg(debug_assertions)] { let must_be_zero = eval_polynomial(&l_x.values[..], *u); - assert_eq!(must_be_zero, E::Scalar::zero()); + assert_eq!(must_be_zero, E::Scalar::ZERO); } let mut h_x = div_by_vanishing(l_x, &[*u]); diff --git a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs index 11ffa880ef..d1d1660e9c 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs @@ -5,7 +5,6 @@ use super::ChallengeY; use super::{construct_intermediate_sets, ChallengeU, ChallengeV}; use crate::arithmetic::{ eval_polynomial, evaluate_vanishing_polynomial, lagrange_interpolate, powers, CurveAffine, - FieldExt, }; use crate::helpers::SerdeCurveAffine; use crate::poly::commitment::Verifier; @@ -22,7 +21,7 @@ use crate::poly::{ Error, }; use crate::transcript::{EncodedChallenge, TranscriptRead}; -use ff::Field; +use ff::{Field, PrimeField}; use group::Group; use halo2curves::pairing::{Engine, MillerLoopResult, MultiMillerLoop}; use rand_core::OsRng; @@ -37,6 +36,7 @@ pub struct VerifierSHPLONK<'params, E: Engine> { impl<'params, E> Verifier<'params, KZGCommitmentScheme> for VerifierSHPLONK<'params, E> where E: MultiMillerLoop + Debug, + E::Scalar: PrimeField + Ord, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { @@ -77,8 +77,8 @@ where let u: ChallengeU<_> = transcript.squeeze_challenge_scalar(); let h2 = transcript.read_point().map_err(|_| Error::SamplingError)?; - let (mut z_0_diff_inverse, mut z_0) = (E::Scalar::zero(), E::Scalar::zero()); - let (mut outer_msm, mut r_outer_acc) = (PreMSM::::new(), E::Scalar::zero()); + let (mut z_0_diff_inverse, mut z_0) = (E::Scalar::ZERO, E::Scalar::ZERO); + let (mut outer_msm, mut r_outer_acc) = (PreMSM::::new(), E::Scalar::ZERO); for (i, (rotation_set, power_of_v)) in rotation_sets.iter().zip(powers(*v)).enumerate() { let diffs: Vec = super_point_set .iter() @@ -91,7 +91,7 @@ where if i == 0 { z_0 = evaluate_vanishing_polynomial(&rotation_set.points[..], *u); z_0_diff_inverse = z_diff_i.invert().unwrap(); - z_diff_i = E::Scalar::one(); + z_diff_i = E::Scalar::ONE; } else { z_diff_i.mul_assign(z_0_diff_inverse); } @@ -137,9 +137,7 @@ where outer_msm.append_term(-z_0, h1.into()); outer_msm.append_term(*u, h2.into()); - msm_accumulator - .left - .append_term(E::Scalar::one(), h2.into()); + msm_accumulator.left.append_term(E::Scalar::ONE, h2.into()); msm_accumulator.right.add_msm(&outer_msm); diff --git a/halo2_proofs/src/poly/kzg/strategy.rs b/halo2_proofs/src/poly/kzg/strategy.rs index ca4b4fb18a..15cdba2069 100644 --- a/halo2_proofs/src/poly/kzg/strategy.rs +++ b/halo2_proofs/src/poly/kzg/strategy.rs @@ -15,7 +15,7 @@ use crate::{ }, transcript::{EncodedChallenge, TranscriptRead}, }; -use ff::Field; +use ff::{Field, PrimeField}; use group::Group; use halo2curves::{ pairing::{Engine, MillerLoopResult, MultiMillerLoop}, @@ -32,6 +32,7 @@ pub struct GuardKZG<'params, E: MultiMillerLoop + Debug> { /// Define accumulator type as `DualMSM` impl<'params, E> Guard> for GuardKZG<'params, E> where + E::Scalar: PrimeField, E: MultiMillerLoop + Debug, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, @@ -92,6 +93,7 @@ impl< >, > VerificationStrategy<'params, KZGCommitmentScheme, V> for AccumulatorStrategy<'params, E> where + E::Scalar: PrimeField, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { @@ -130,6 +132,7 @@ impl< >, > VerificationStrategy<'params, KZGCommitmentScheme, V> for SingleStrategy<'params, E> where + E::Scalar: PrimeField, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { diff --git a/halo2_proofs/src/poly/multiopen_test.rs b/halo2_proofs/src/poly/multiopen_test.rs index 8dd563b15a..d57243f712 100644 --- a/halo2_proofs/src/poly/multiopen_test.rs +++ b/halo2_proofs/src/poly/multiopen_test.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod test { - use crate::arithmetic::{eval_polynomial, FieldExt}; + use crate::arithmetic::eval_polynomial; use crate::plonk::Error; use crate::poly::commitment::ParamsProver; use crate::poly::commitment::{Blind, ParamsVerifier, MSM}; @@ -17,7 +17,7 @@ mod test { Keccak256Write, TranscriptRead, TranscriptReadBuffer, TranscriptWrite, TranscriptWriterBuffer, }; - use ff::Field; + use ff::{Field, PrimeField, WithSmallOrderMulGroup}; use group::{Curve, Group}; use halo2curves::CurveAffine; use rand_core::{OsRng, RngCore}; @@ -233,28 +233,25 @@ mod test { T: TranscriptWriterBuffer, Scheme::Curve, E>, >( params: &'params Scheme::ParamsProver, - ) -> Vec { + ) -> Vec + where + Scheme::Scalar: WithSmallOrderMulGroup<3>, + { let domain = EvaluationDomain::new(1, params.k()); let mut ax = domain.empty_coeff(); for (i, a) in ax.iter_mut().enumerate() { - *a = <::Curve as CurveAffine>::ScalarExt::from( - 10 + i as u64, - ); + *a = <::Scalar>::from(10 + i as u64); } let mut bx = domain.empty_coeff(); for (i, a) in bx.iter_mut().enumerate() { - *a = <::Curve as CurveAffine>::ScalarExt::from( - 100 + i as u64, - ); + *a = <::Scalar>::from(100 + i as u64); } let mut cx = domain.empty_coeff(); for (i, a) in cx.iter_mut().enumerate() { - *a = <::Curve as CurveAffine>::ScalarExt::from( - 100 + i as u64, - ); + *a = <::Scalar>::from(100 + i as u64); } let mut transcript = T::init(vec![]); diff --git a/halo2_proofs/src/transcript.rs b/halo2_proofs/src/transcript.rs index 8907f9779d..166b0e6f90 100644 --- a/halo2_proofs/src/transcript.rs +++ b/halo2_proofs/src/transcript.rs @@ -2,11 +2,11 @@ //! transcripts. use blake2b_simd::{Params as Blake2bParams, State as Blake2bState}; -use group::ff::PrimeField; +use group::ff::{FromUniformBytes, PrimeField}; use sha3::{Digest, Keccak256}; use std::convert::TryInto; -use halo2curves::{Coordinates, CurveAffine, FieldExt}; +use halo2curves::{Coordinates, CurveAffine}; use std::io::{self, Read, Write}; use std::marker::PhantomData; @@ -119,6 +119,8 @@ pub struct Keccak256Read> { impl TranscriptReadBuffer> for Blake2bRead> +where + C::Scalar: FromUniformBytes<64>, { /// Initialize a transcript given an input buffer. fn init(reader: R) -> Self { @@ -135,6 +137,8 @@ impl TranscriptReadBuffer> impl TranscriptReadBuffer> for Keccak256Read> +where + C::Scalar: FromUniformBytes<64>, { /// Initialize a transcript given an input buffer. fn init(reader: R) -> Self { @@ -150,6 +154,8 @@ impl TranscriptReadBuffer> impl TranscriptRead> for Blake2bRead> +where + C::Scalar: FromUniformBytes<64>, { fn read_point(&mut self) -> io::Result { let mut compressed = C::Repr::default(); @@ -179,6 +185,8 @@ impl TranscriptRead> impl TranscriptRead> for Keccak256Read> +where + C::Scalar: FromUniformBytes<64>, { fn read_point(&mut self) -> io::Result { let mut compressed = C::Repr::default(); @@ -206,8 +214,9 @@ impl TranscriptRead> } } -impl Transcript> - for Blake2bRead> +impl Transcript> for Blake2bRead> +where + C::Scalar: FromUniformBytes<64>, { fn squeeze_challenge(&mut self) -> Challenge255 { self.state.update(&[BLAKE2B_PREFIX_CHALLENGE]); @@ -240,6 +249,8 @@ impl Transcript> impl Transcript> for Keccak256Read> +where + C::Scalar: FromUniformBytes<64>, { fn squeeze_challenge(&mut self) -> Challenge255 { self.state.update(&[KECCAK256_PREFIX_CHALLENGE]); @@ -298,6 +309,8 @@ pub struct Keccak256Write> { impl TranscriptWriterBuffer> for Blake2bWrite> +where + C::Scalar: FromUniformBytes<64>, { /// Initialize a transcript given an output buffer. fn init(writer: W) -> Self { @@ -319,6 +332,8 @@ impl TranscriptWriterBuffer> impl TranscriptWriterBuffer> for Keccak256Write> +where + C::Scalar: FromUniformBytes<64>, { /// Initialize a transcript given an output buffer. fn init(writer: W) -> Self { @@ -340,6 +355,8 @@ impl TranscriptWriterBuffer> impl TranscriptWrite> for Blake2bWrite> +where + C::Scalar: FromUniformBytes<64>, { fn write_point(&mut self, point: C) -> io::Result<()> { self.common_point(point)?; @@ -355,6 +372,8 @@ impl TranscriptWrite> impl TranscriptWrite> for Keccak256Write> +where + C::Scalar: FromUniformBytes<64>, { fn write_point(&mut self, point: C) -> io::Result<()> { self.common_point(point)?; @@ -370,6 +389,8 @@ impl TranscriptWrite> impl Transcript> for Blake2bWrite> +where + C::Scalar: FromUniformBytes<64>, { fn squeeze_challenge(&mut self) -> Challenge255 { self.state.update(&[BLAKE2B_PREFIX_CHALLENGE]); @@ -402,6 +423,8 @@ impl Transcript> impl Transcript> for Keccak256Write> +where + C::Scalar: FromUniformBytes<64>, { fn squeeze_challenge(&mut self) -> Challenge255 { self.state.update(&[KECCAK256_PREFIX_CHALLENGE]); @@ -496,12 +519,15 @@ impl std::ops::Deref for Challenge255 { } } -impl EncodedChallenge for Challenge255 { +impl EncodedChallenge for Challenge255 +where + C::Scalar: FromUniformBytes<64>, +{ type Input = [u8; 64]; fn new(challenge_input: &[u8; 64]) -> Self { Challenge255( - C::Scalar::from_bytes_wide(challenge_input) + C::Scalar::from_uniform_bytes(challenge_input) .to_repr() .as_ref() .try_into() diff --git a/halo2_proofs/tests/plonk_api.rs b/halo2_proofs/tests/plonk_api.rs index edfdfac3b2..6c69a472ab 100644 --- a/halo2_proofs/tests/plonk_api.rs +++ b/halo2_proofs/tests/plonk_api.rs @@ -2,7 +2,8 @@ #![allow(clippy::op_ref)] // use assert_matches::assert_matches; -use halo2_proofs::arithmetic::{Field, FieldExt}; +use ff::{FromUniformBytes, WithSmallOrderMulGroup}; +use halo2_proofs::arithmetic::Field; use halo2_proofs::circuit::{Cell, Layouter, Region, SimpleFloorPlanner, Value}; use halo2_proofs::dev::MockProver; use halo2_proofs::plonk::{ @@ -46,7 +47,7 @@ fn plonk_api() { } #[allow(clippy::type_complexity)] - trait StandardCs { + trait StandardCs { fn raw_multiply( &self, layouter: &mut impl Layouter, @@ -73,17 +74,17 @@ fn plonk_api() { } #[derive(Clone)] - struct MyCircuit { + struct MyCircuit { a: Value, lookup_table: Vec, } - struct StandardPlonk { + struct StandardPlonk { config: PlonkConfig, _marker: PhantomData, } - impl StandardPlonk { + impl StandardPlonk { fn new(config: PlonkConfig) -> Self { StandardPlonk { config, @@ -92,7 +93,7 @@ fn plonk_api() { } } - impl StandardCs for StandardPlonk { + impl StandardCs for StandardPlonk { fn raw_multiply( &self, layouter: &mut impl Layouter, @@ -139,15 +140,10 @@ fn plonk_api() { || value.unwrap().map(|v| v.2), )?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::zero()))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::zero()))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::one()))?; - region.assign_fixed( - || "a * b", - self.config.sm, - 0, - || Value::known(FF::one()), - )?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ZERO))?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ZERO))?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::ONE))?; Ok((lhs.cell(), rhs.cell(), out.cell())) }, ) @@ -198,14 +194,14 @@ fn plonk_api() { || value.unwrap().map(|v| v.2), )?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::one()))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::one()))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::one()))?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; region.assign_fixed( || "a * b", self.config.sm, 0, - || Value::known(FF::zero()), + || Value::known(FF::ZERO), )?; Ok((lhs.cell(), rhs.cell(), out.cell())) }, @@ -237,7 +233,7 @@ fn plonk_api() { || "public", self.config.sp, 0, - || Value::known(FF::one()), + || Value::known(FF::ONE), )?; Ok(value.cell()) @@ -267,7 +263,7 @@ fn plonk_api() { } } - impl Circuit for MyCircuit { + impl Circuit for MyCircuit { type Config = PlonkConfig; type FloorPlanner = SimpleFloorPlanner; @@ -376,7 +372,7 @@ fn plonk_api() { let cs = StandardPlonk::new(config); let mut is_first_pass_vec = vec![true; 8]; - let _ = cs.public_input(&mut layouter, || Value::known(F::one() + F::one()))?; + let _ = cs.public_input(&mut layouter, || Value::known(F::ONE + F::ONE))?; let a: Value> = self.a.into(); let parallel_regions_time = Instant::now(); @@ -470,14 +466,9 @@ fn plonk_api() { ($scheme:ident) => {{ let a = <$scheme as CommitmentScheme>::Scalar::from(2834758237) * <$scheme as CommitmentScheme>::Scalar::ZETA; - let instance = <$scheme as CommitmentScheme>::Scalar::one() - + <$scheme as CommitmentScheme>::Scalar::one(); - let lookup_table = vec![ - instance, - a, - a, - <$scheme as CommitmentScheme>::Scalar::zero(), - ]; + let instance = <$scheme as CommitmentScheme>::Scalar::ONE + + <$scheme as CommitmentScheme>::Scalar::ONE; + let lookup_table = vec![instance, a, a, <$scheme as CommitmentScheme>::Scalar::ZERO]; (a, instance, lookup_table) }}; } @@ -514,9 +505,10 @@ fn plonk_api() { } */ - fn keygen( - params: &Scheme::ParamsProver, - ) -> ProvingKey { + fn keygen(params: &Scheme::ParamsProver) -> ProvingKey + where + Scheme::Scalar: FromUniformBytes<64> + WithSmallOrderMulGroup<3>, + { let (_, _, lookup_table) = common!(Scheme); let empty_circuit: MyCircuit = MyCircuit { a: Value::unknown(), @@ -544,7 +536,10 @@ fn plonk_api() { rng: R, params: &'params Scheme::ParamsProver, pk: &ProvingKey, - ) -> Vec { + ) -> Vec + where + Scheme::Scalar: Ord + WithSmallOrderMulGroup<3> + FromUniformBytes<64>, + { let (a, instance, lookup_table) = common!(Scheme); let circuit: MyCircuit = MyCircuit { @@ -579,7 +574,9 @@ fn plonk_api() { params_verifier: &'params Scheme::ParamsVerifier, vk: &VerifyingKey, proof: &'a [u8], - ) { + ) where + Scheme::Scalar: Ord + WithSmallOrderMulGroup<3> + FromUniformBytes<64>, + { let (_, instance, _) = common!(Scheme); let pubinputs = vec![instance];