change: Migrate workspace to pasta_curves-0.5 (#157)

* change: Migrate workspace to pasta_curves-0.5

This ports the majority of the workspace to the `pasta_curves-0.5.0`
leaving some tricky edge-cases that we need to handle carefully.

Resolves: #132

* fix: Complete latest trait bounds to compile halo2proofs

* change: Migrate examples & benches to pasta 0.5

* change: Migrate halo2_gadgets to pasta-0.5

* change: Update gadgets outdated code with latest upstream

* fix: Sha3 gadget circuit

* fix: doc tests

* chore: Update merged main

* fix: Apply review suggestions
This commit is contained in:
Carlos Pérez 2023-03-07 17:29:37 +01:00 committed by GitHub
parent 4d93d01ca2
commit fcdd5b910d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
84 changed files with 844 additions and 783 deletions

View File

@ -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', branch = "main" }
proptest = { version = "1.0.0", optional = true }
rand = "0.8"
subtle = "2.3"

View File

@ -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<const WIDTH: usize, const RATE: usize> Spec<Fp, WIDTH, RATE> for MySpec<WID
fn secure_mds() -> usize {
0
}
fn constants() -> (Vec<[Fp; WIDTH]>, Mds<Fp, WIDTH>, Mds<Fp, WIDTH>) {
generate_constants::<_, Self, WIDTH, RATE>()
}
}
const K: u32 = 7;

View File

@ -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)]

View File

@ -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<C: CurveAffine>(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<C: CurveAffine>(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<C: CurveAffine>(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<C: CurveAffine>(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
}
}

View File

@ -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<F: FieldExt>(AssignedCell<Assigned<F>, F>);
impl<F: FieldExt> Deref for X<F> {
struct X<F: Field>(AssignedCell<Assigned<F>, F>);
impl<F: Field> Deref for X<F> {
type Target = AssignedCell<Assigned<F>, F>;
fn deref(&self) -> &Self::Target {
@ -400,8 +399,8 @@ impl<F: FieldExt> Deref for X<F> {
#[derive(Clone, Debug)]
// `y`-coordinate of the accumulator.
struct Y<F: FieldExt>(AssignedCell<Assigned<F>, F>);
impl<F: FieldExt> Deref for Y<F> {
struct Y<F: Field>(AssignedCell<Assigned<F>, F>);
impl<F: Field> Deref for Y<F> {
type Target = AssignedCell<Assigned<F>, F>;
fn deref(&self) -> &Self::Target {
@ -411,8 +410,8 @@ impl<F: FieldExt> Deref for Y<F> {
#[derive(Clone, Debug)]
// Cumulative sum `z` used to decompose the scalar.
struct Z<F: FieldExt>(AssignedCell<F, F>);
impl<F: FieldExt> Deref for Z<F> {
struct Z<F: Field>(AssignedCell<F, F>);
impl<F: Field> Deref for Z<F> {
type Target = AssignedCell<F, F>;
fn deref(&self) -> &Self::Target {

View File

@ -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)]

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"),

View File

@ -209,6 +209,7 @@ impl<Fixed: FixedPoints<pallas::Affine>> Config<Fixed> {
// tested at the circuit-level.
{
use super::super::FixedPoint;
use ff::Field;
use group::{ff::PrimeField, Curve};
scalar
@ -228,9 +229,9 @@ impl<Fixed: FixedPoints<pallas::Affine>> Config<Fixed> {
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<Fixed: FixedPoints<pallas::Affine>> Config<Fixed> {
#[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
};

View File

@ -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<F: Field> {
}
/// The set of circuit instructions required to use the Poseidon permutation.
pub trait PoseidonInstructions<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>:
pub trait PoseidonInstructions<F: Field, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>:
Chip<F>
{
/// Variable representing the word over which the Poseidon permutation operates.
@ -45,7 +45,7 @@ pub trait PoseidonInstructions<F: FieldExt, S: Spec<F, T, RATE>, const T: usize,
///
/// [`Hash`]: self::Hash
pub trait PoseidonSpongeInstructions<
F: FieldExt,
F: Field,
S: Spec<F, T, RATE>,
D: Domain<F, RATE>,
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<F, S, T, RATE>,
S: Spec<F, T, RATE>,
const T: usize,
@ -81,7 +81,7 @@ pub struct Word<
}
impl<
F: FieldExt,
F: Field,
PoseidonChip: PoseidonInstructions<F, S, T, RATE>,
S: Spec<F, T, RATE>,
const T: usize,
@ -100,7 +100,7 @@ impl<
}
fn poseidon_sponge<
F: FieldExt,
F: Field,
PoseidonChip: PoseidonSpongeInstructions<F, S, D, T, RATE>,
S: Spec<F, T, RATE>,
D: Domain<F, RATE>,
@ -122,7 +122,7 @@ fn poseidon_sponge<
/// A Poseidon sponge.
#[derive(Debug)]
pub struct Sponge<
F: FieldExt,
F: Field,
PoseidonChip: PoseidonSpongeInstructions<F, S, D, T, RATE>,
S: Spec<F, T, RATE>,
M: SpongeMode,
@ -137,7 +137,7 @@ pub struct Sponge<
}
impl<
F: FieldExt,
F: Field,
PoseidonChip: PoseidonSpongeInstructions<F, S, D, T, RATE>,
S: Spec<F, T, RATE>,
D: Domain<F, RATE>,
@ -210,7 +210,7 @@ impl<
}
impl<
F: FieldExt,
F: Field,
PoseidonChip: PoseidonSpongeInstructions<F, S, D, T, RATE>,
S: Spec<F, T, RATE>,
D: Domain<F, RATE>,
@ -241,7 +241,7 @@ impl<
/// A Poseidon hash function, built around a sponge.
#[derive(Debug)]
pub struct Hash<
F: FieldExt,
F: Field,
PoseidonChip: PoseidonSpongeInstructions<F, S, D, T, RATE>,
S: Spec<F, T, RATE>,
D: Domain<F, RATE>,
@ -252,7 +252,7 @@ pub struct Hash<
}
impl<
F: FieldExt,
F: Field,
PoseidonChip: PoseidonSpongeInstructions<F, S, D, T, RATE>,
S: Spec<F, T, RATE>,
D: Domain<F, RATE>,
@ -267,7 +267,7 @@ impl<
}
impl<
F: FieldExt,
F: PrimeField,
PoseidonChip: PoseidonSpongeInstructions<F, S, ConstantLength<L>, T, RATE>,
S: Spec<F, T, RATE>,
const T: usize,

View File

@ -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<F: FieldExt, const WIDTH: usize, const RATE: usize> {
pub struct Pow5Config<F: Field, const WIDTH: usize, const RATE: usize> {
pub(crate) state: [Column<Advice>; WIDTH],
partial_sbox: Column<Advice>,
rc_a: [Column<Fixed>; WIDTH],
@ -40,11 +40,11 @@ pub struct Pow5Config<F: FieldExt, const WIDTH: usize, const RATE: usize> {
/// 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<F: FieldExt, const WIDTH: usize, const RATE: usize> {
pub struct Pow5Chip<F: Field, const WIDTH: usize, const RATE: usize> {
config: Pow5Config<F, WIDTH, RATE>,
}
impl<F: FieldExt, const WIDTH: usize, const RATE: usize> Pow5Chip<F, WIDTH, RATE> {
impl<F: Field, const WIDTH: usize, const RATE: usize> Pow5Chip<F, WIDTH, RATE> {
/// Configures this chip for use in a circuit.
///
/// # Side-effects
@ -209,7 +209,7 @@ impl<F: FieldExt, const WIDTH: usize, const RATE: usize> Pow5Chip<F, WIDTH, RATE
}
}
impl<F: FieldExt, const WIDTH: usize, const RATE: usize> Chip<F> for Pow5Chip<F, WIDTH, RATE> {
impl<F: Field, const WIDTH: usize, const RATE: usize> Chip<F> for Pow5Chip<F, WIDTH, RATE> {
type Config = Pow5Config<F, WIDTH, RATE>;
type Loaded = ();
@ -222,7 +222,7 @@ impl<F: FieldExt, const WIDTH: usize, const RATE: usize> Chip<F> for Pow5Chip<F,
}
}
impl<F: FieldExt, S: Spec<F, WIDTH, RATE>, const WIDTH: usize, const RATE: usize>
impl<F: Field, S: Spec<F, WIDTH, RATE>, const WIDTH: usize, const RATE: usize>
PoseidonInstructions<F, S, WIDTH, RATE> for Pow5Chip<F, WIDTH, RATE>
{
type Word = StateWord<F>;
@ -273,7 +273,7 @@ impl<F: FieldExt, S: Spec<F, WIDTH, RATE>, const WIDTH: usize, const RATE: usize
}
impl<
F: FieldExt,
F: Field,
S: Spec<F, WIDTH, RATE>,
D: Domain<F, RATE>,
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<F: FieldExt>(AssignedCell<F, F>);
pub struct StateWord<F: Field>(AssignedCell<F, F>);
impl<F: FieldExt> From<StateWord<F>> for AssignedCell<F, F> {
impl<F: Field> From<StateWord<F>> for AssignedCell<F, F> {
fn from(state_word: StateWord<F>) -> AssignedCell<F, F> {
state_word.0
}
}
impl<F: FieldExt> From<AssignedCell<F, F>> for StateWord<F> {
impl<F: Field> From<AssignedCell<F, F>> for StateWord<F> {
fn from(cell_value: AssignedCell<F, F>) -> StateWord<F> {
StateWord(cell_value)
}
}
impl<F: FieldExt> Var<F> for StateWord<F> {
impl<F: Field> Var<F> for StateWord<F> {
fn cell(&self) -> Cell {
self.0.cell()
}
@ -428,9 +428,9 @@ impl<F: FieldExt> Var<F> for StateWord<F> {
}
#[derive(Debug)]
struct Pow5State<F: FieldExt, const WIDTH: usize>([StateWord<F>; WIDTH]);
struct Pow5State<F: Field, const WIDTH: usize>([StateWord<F>; WIDTH]);
impl<F: FieldExt, const WIDTH: usize> Pow5State<F, WIDTH> {
impl<F: Field, const WIDTH: usize> Pow5State<F, WIDTH> {
fn full_round<const RATE: usize>(
self,
region: &mut Region<F>,
@ -450,7 +450,7 @@ impl<F: FieldExt, const WIDTH: usize> Pow5State<F, WIDTH> {
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<F: FieldExt, const WIDTH: usize> Pow5State<F, WIDTH> {
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<F: FieldExt, const WIDTH: usize> Pow5State<F, WIDTH> {
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();

View File

@ -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, const T: usize> = [F; T];
pub(crate) type SpongeRate<F, const RATE: usize> = [Option<F>; RATE];
/// The type used to hold the MDS matrix and its inverse.
pub(crate) type Mds<F, const T: usize> = [[F; T]; T];
pub type Mds<F, const T: usize> = [[F; T]; T];
/// A specification for a Poseidon permutation.
pub trait Spec<F: FieldExt, const T: usize, const RATE: usize>: fmt::Debug {
pub trait Spec<F: Field, const T: usize, const RATE: usize>: fmt::Debug {
/// The number of full rounds for this specification.
///
/// This must be an even number.
@ -50,33 +52,41 @@ pub trait Spec<F: FieldExt, const T: usize, const RATE: usize>: fmt::Debug {
fn secure_mds() -> usize;
/// Generates `(round_constants, mds, mds^-1)` corresponding to this specification.
fn constants() -> (Vec<[F; T]>, Mds<F, T>, Mds<F, T>) {
let r_f = Self::full_rounds();
let r_p = Self::partial_rounds();
fn constants() -> (Vec<[F; T]>, Mds<F, T>, Mds<F, T>);
}
let mut grain = grain::Grain::new(SboxType::Pow, T as u16, r_f as u16, r_p as u16);
/// Generates `(round_constants, mds, mds^-1)` corresponding to this specification.
pub fn generate_constants<
F: FromUniformBytes<64> + Ord,
S: Spec<F, T, RATE>,
const T: usize,
const RATE: usize,
>() -> (Vec<[F; T]>, Mds<F, T>, Mds<F, T>) {
let r_f = S::full_rounds();
let r_p = S::partial_rounds();
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 mut grain = grain::Grain::new(SboxType::Pow, T as u16, r_f as u16, r_p as u16);
let (mds, mds_inv) = mds::generate_mds::<F, T>(&mut grain, Self::secure_mds());
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();
(round_constants, mds, mds_inv)
}
let (mds, mds_inv) = mds::generate_mds::<F, T>(&mut grain, S::secure_mds());
(round_constants, mds, mds_inv)
}
/// Runs the Poseidon permutation on the given state.
pub(crate) fn permute<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>(
pub(crate) fn permute<F: Field, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>(
state: &mut State<F, T>,
mds: &Mds<F, T>,
round_constants: &[[F; T]],
@ -85,7 +95,7 @@ pub(crate) fn permute<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RA
let r_p = S::partial_rounds();
let apply_mds = |state: &mut State<F, T>| {
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<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RA
});
}
fn poseidon_sponge<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>(
fn poseidon_sponge<F: Field, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>(
state: &mut State<F, T>,
input: Option<&Absorbing<F, RATE>>,
mds_matrix: &Mds<F, T>,
@ -180,7 +190,7 @@ impl<F: fmt::Debug, const RATE: usize> Absorbing<F, RATE> {
/// A Poseidon sponge.
pub(crate) struct Sponge<
F: FieldExt,
F: Field,
S: Spec<F, T, RATE>,
M: SpongeMode,
const T: usize,
@ -193,7 +203,7 @@ pub(crate) struct Sponge<
_marker: PhantomData<S>,
}
impl<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>
impl<F: Field, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>
Sponge<F, S, Absorbing<F, RATE>, T, RATE>
{
/// Constructs a new sponge for the given Poseidon specification.
@ -201,7 +211,7 @@ impl<F: FieldExt, S: Spec<F, T, RATE>, 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<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>
}
}
impl<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>
impl<F: Field, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>
Sponge<F, S, Squeezing<F, RATE>, T, RATE>
{
/// Squeezes an element from the sponge.
@ -275,7 +285,7 @@ impl<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>
}
/// A domain in which a Poseidon hash function is being used.
pub trait Domain<F: FieldExt, const RATE: usize> {
pub trait Domain<F: Field, const RATE: usize> {
/// Iterator that outputs padding field elements.
type Padding: IntoIterator<Item = F>;
@ -295,7 +305,7 @@ pub trait Domain<F: FieldExt, const RATE: usize> {
#[derive(Clone, Copy, Debug)]
pub struct ConstantLength<const L: usize>;
impl<F: FieldExt, const RATE: usize, const L: usize> Domain<F, RATE> for ConstantLength<L> {
impl<F: PrimeField, const RATE: usize, const L: usize> Domain<F, RATE> for ConstantLength<L> {
type Padding = iter::Take<iter::Repeat<F>>;
fn name() -> String {
@ -315,13 +325,13 @@ impl<F: FieldExt, const RATE: usize, const L: usize> Domain<F, RATE> 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<F, T, RATE>,
D: Domain<F, RATE>,
const T: usize,
@ -331,7 +341,7 @@ pub struct Hash<
_domain: PhantomData<D>,
}
impl<F: FieldExt, S: Spec<F, T, RATE>, D: Domain<F, RATE>, const T: usize, const RATE: usize>
impl<F: Field, S: Spec<F, T, RATE>, D: Domain<F, RATE>, const T: usize, const RATE: usize>
fmt::Debug for Hash<F, S, D, T, RATE>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -345,7 +355,7 @@ impl<F: FieldExt, S: Spec<F, T, RATE>, D: Domain<F, RATE>, const T: usize, const
}
}
impl<F: FieldExt, S: Spec<F, T, RATE>, D: Domain<F, RATE>, const T: usize, const RATE: usize>
impl<F: Field, S: Spec<F, T, RATE>, D: Domain<F, RATE>, const T: usize, const RATE: usize>
Hash<F, S, D, T, RATE>
{
/// Initializes a new hasher.
@ -357,7 +367,7 @@ impl<F: FieldExt, S: Spec<F, T, RATE>, D: Domain<F, RATE>, const T: usize, const
}
}
impl<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize, const L: usize>
impl<F: PrimeField, S: Spec<F, T, RATE>, const T: usize, const RATE: usize, const L: usize>
Hash<F, S, ConstantLength<L>, T, RATE>
{
/// Hashes the given input.
@ -374,9 +384,9 @@ impl<F: FieldExt, S: Spec<F, T, RATE>, 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() {

View File

@ -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<F: FieldExt> {
pub(super) struct Grain<F: Field> {
state: BitArr!(for 80, in u8, Msb0),
next_bit: usize,
_field: PhantomData<F>,
}
impl<F: FieldExt> Grain<F> {
impl<F: PrimeField> Grain<F> {
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<F: FieldExt> Grain<F> {
}
}
}
}
impl<F: FromUniformBytes<64>> Grain<F> {
/// 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<F: FieldExt> Grain<F> {
view[i / 8] |= if bit { 1 << (i % 8) } else { 0 };
}
F::from_bytes_wide(&bytes)
F::from_uniform_bytes(&bytes)
}
}
impl<F: FieldExt> Iterator for Grain<F> {
impl<F: PrimeField> Iterator for Grain<F> {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {

View File

@ -1,8 +1,8 @@
use halo2_proofs::arithmetic::FieldExt;
use ff::FromUniformBytes;
use super::{grain::Grain, Mds};
pub(super) fn generate_mds<F: FieldExt, const T: usize>(
pub(super) fn generate_mds<F: FromUniformBytes<64> + Ord, const T: usize>(
grain: &mut Grain<F>,
mut select: usize,
) -> (Mds<F, T>, Mds<F, T>) {
@ -48,7 +48,7 @@ pub(super) fn generate_mds<F: FieldExt, const T: usize>(
// 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<F: FieldExt, const T: usize>(
// 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 {

View File

@ -66,29 +66,31 @@ impl Spec<Fq, 3, 2> 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<F: FieldExt, const SECURE_MDS: usize>(PhantomData<F>);
pub struct P128Pow5T3Gen<F: Field, const SECURE_MDS: usize>(PhantomData<F>);
impl<F: FieldExt, const SECURE_MDS: usize> P128Pow5T3Gen<F, SECURE_MDS> {
impl<F: Field, const SECURE_MDS: usize> P128Pow5T3Gen<F, SECURE_MDS> {
pub fn new() -> Self {
P128Pow5T3Gen(PhantomData::default())
}
}
impl<F: FieldExt, const SECURE_MDS: usize> Spec<F, 3, 2> for P128Pow5T3Gen<F, SECURE_MDS> {
impl<F: FromUniformBytes<64> + Ord, const SECURE_MDS: usize> Spec<F, 3, 2>
for P128Pow5T3Gen<F, SECURE_MDS>
{
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<F, 3>, Mds<F, 3>) {
generate_constants::<_, Self, 3, 2>()
}
}
#[test]
fn verify_constants() {
fn verify_constants_helper<F: FieldExt>(
fn verify_constants_helper<F: FromUniformBytes<64> + Ord>(
expected_round_constants: [[F; 3]; 64],
expected_mds: [[F; 3]; 3],
expected_mds_inv: [[F; 3]; 3],

View File

@ -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<F: FieldExt>: Chip<F> {
pub trait Sha256Instructions<F: Field>: Chip<F> {
/// 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>([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<F: FieldExt, CS: Sha256Instructions<F>> {
pub struct Sha256<F: Field, CS: Sha256Instructions<F>> {
chip: CS,
state: CS::State,
cur_block: Vec<CS::BlockWord>,
length: usize,
}
impl<F: FieldExt, Sha256Chip: Sha256Instructions<F>> Sha256<F, Sha256Chip> {
impl<F: Field, Sha256Chip: Sha256Instructions<F>> Sha256<F, Sha256Chip> {
/// Create a new hasher instance.
pub fn new(chip: Sha256Chip, mut layouter: impl Layouter<F>) -> Result<Self, Error> {
let state = chip.initialization_vector(&mut layouter)?;

View File

@ -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<F: FieldExt>(PhantomData<F>);
pub struct CompressionGate<F: PrimeField>(PhantomData<F>);
impl<F: FieldExt> CompressionGate<F> {
impl<F: PrimeField> CompressionGate<F> {
fn ones() -> Expression<F> {
Expression::Constant(F::one())
Expression::Constant(F::ONE)
}
// Decompose `A,B,C,D` words
@ -59,16 +57,16 @@ impl<F: FieldExt> CompressionGate<F> {
+ 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<F: FieldExt> CompressionGate<F> {
+ 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<F: FieldExt> CompressionGate<F> {
+ 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<F: FieldExt> CompressionGate<F> {
+ 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<F: FieldExt> CompressionGate<F> {
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<F: FieldExt> CompressionGate<F> {
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)))

View File

@ -1,10 +1,11 @@
use halo2_proofs::{arithmetic::FieldExt, plonk::Expression};
use ff::PrimeField;
use halo2_proofs::{arithmetic::Field, plonk::Expression};
pub struct Gate<F: FieldExt>(pub Expression<F>);
pub struct Gate<F: Field>(pub Expression<F>);
impl<F: FieldExt> Gate<F> {
impl<F: PrimeField> Gate<F> {
fn ones() -> Expression<F> {
Expression::Constant(F::one())
Expression::Constant(F::ONE)
}
// Helper gates
@ -32,7 +33,7 @@ impl<F: FieldExt> Gate<F> {
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<F: FieldExt> Gate<F> {
}
}
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<F: FieldExt> Gate<F> {
pub fn range_check(value: Expression<F>, lower_range: u64, upper_range: u64) -> Expression<F> {
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
}

View File

@ -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<F: FieldExt>(PhantomData<F>);
pub struct ScheduleGate<F: PrimeField>(PhantomData<F>);
impl<F: FieldExt> ScheduleGate<F> {
impl<F: PrimeField> ScheduleGate<F> {
/// s_word for W_16 to W_63
#[allow(clippy::too_many_arguments)]
pub fn s_word(
@ -25,8 +26,8 @@ impl<F: FieldExt> ScheduleGate<F> {
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<F: FieldExt> ScheduleGate<F> {
tag_d: Expression<F>,
word: Expression<F>,
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
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<F: FieldExt> ScheduleGate<F> {
+ 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<F: FieldExt> ScheduleGate<F> {
+ 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);

View File

@ -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<F: FieldExt> {
pub(super) struct SpreadTableChip<F: Field> {
config: SpreadTableConfig,
_marker: PhantomData<F>,
}
impl<F: FieldExt> Chip<F> for SpreadTableChip<F> {
impl<F: Field> Chip<F> for SpreadTableChip<F> {
type Config = SpreadTableConfig;
type Loaded = ();
@ -171,7 +172,7 @@ impl<F: FieldExt> Chip<F> for SpreadTableChip<F> {
}
}
impl<F: FieldExt> SpreadTableChip<F> {
impl<F: PrimeField> SpreadTableChip<F> {
pub fn configure(
meta: &mut ConstraintSystem<F>,
input_tag: Column<Advice>,
@ -250,45 +251,42 @@ impl<F: FieldExt> SpreadTableChip<F> {
}
impl SpreadTableConfig {
fn generate<F: FieldExt>() -> impl Iterator<Item = (F, F, F)> {
(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);
fn generate<F: PrimeField>() -> impl Iterator<Item = (F, F, F)> {
(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));
}
// 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<F: FieldExt> Circuit<F> for MyCircuit {
impl<F: PrimeField> Circuit<F> 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),
)?;

View File

@ -203,9 +203,9 @@ where
let to_base_field = |bits: &[Value<bool>]| -> Value<C::Base> {
let bits: Value<Vec<bool>> = 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<Item = RangeConstrained<C::Base, Value<C::Base>>>,
) -> Result<Self, Error> {
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

View File

@ -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)]

View File

@ -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<F: FieldExt>(AssignedCell<Assigned<F>, F>);
struct X<F: Field>(AssignedCell<Assigned<F>, F>);
impl<F: FieldExt> From<AssignedCell<Assigned<F>, F>> for X<F> {
impl<F: Field> From<AssignedCell<Assigned<F>, F>> for X<F> {
fn from(cell_value: AssignedCell<Assigned<F>, F>) -> Self {
X(cell_value)
}
}
impl<F: FieldExt> Deref for X<F> {
impl<F: Field> Deref for X<F> {
type Target = AssignedCell<Assigned<F>, F>;
fn deref(&self) -> &AssignedCell<Assigned<F>, F> {
@ -397,15 +397,15 @@ impl<F: FieldExt> Deref for X<F> {
/// 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<F: FieldExt>(Value<Assigned<F>>);
struct Y<F: Field>(Value<Assigned<F>>);
impl<F: FieldExt> From<Value<Assigned<F>>> for Y<F> {
impl<F: Field> From<Value<Assigned<F>>> for Y<F> {
fn from(value: Value<Assigned<F>>) -> Self {
Y(value)
}
}
impl<F: FieldExt> Deref for Y<F> {
impl<F: Field> Deref for Y<F> {
type Target = Value<Assigned<F>>;
fn deref(&self) -> &Value<Assigned<F>> {

View File

@ -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;

View File

@ -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<F: FieldExt, const K: usize, const MAX_WORDS: usize>(Vec<MessagePiece<F, K>>);
pub struct Message<F: Field, const K: usize, const MAX_WORDS: usize>(Vec<MessagePiece<F, K>>);
impl<F: FieldExt + PrimeFieldBits, const K: usize, const MAX_WORDS: usize>
From<Vec<MessagePiece<F, K>>> for Message<F, K, MAX_WORDS>
impl<F: PrimeFieldBits, const K: usize, const MAX_WORDS: usize> From<Vec<MessagePiece<F, K>>>
for Message<F, K, MAX_WORDS>
{
fn from(pieces: Vec<MessagePiece<F, K>>) -> Self {
// A message cannot contain more than `MAX_WORDS` words.
@ -20,7 +20,7 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize, const MAX_WORDS: usize>
}
}
impl<F: FieldExt + PrimeFieldBits, const K: usize, const MAX_WORDS: usize> std::ops::Deref
impl<F: PrimeFieldBits, const K: usize, const MAX_WORDS: usize> std::ops::Deref
for Message<F, K, MAX_WORDS>
{
type Target = [MessagePiece<F, K>];
@ -35,13 +35,13 @@ impl<F: FieldExt + PrimeFieldBits, const K: usize, const MAX_WORDS: usize> 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<F: FieldExt, const K: usize> {
pub struct MessagePiece<F: Field, const K: usize> {
cell_value: AssignedCell<F, F>,
/// The number of K-bit words in this message piece.
num_words: usize,
}
impl<F: FieldExt + PrimeFieldBits, const K: usize> MessagePiece<F, K> {
impl<F: PrimeFieldBits, const K: usize> MessagePiece<F, K> {
pub fn new(cell_value: AssignedCell<F, F>, num_words: usize) -> Self {
assert!(num_words * K < F::NUM_BITS as usize);
Self {

View File

@ -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<F: Field> FieldValue<F> for AssignedCell<F, F> {
}
/// Trait for a variable in the circuit.
pub trait Var<F: FieldExt>: Clone + std::fmt::Debug + From<AssignedCell<F, F>> {
pub trait Var<F: Field>: Clone + std::fmt::Debug + From<AssignedCell<F, F>> {
/// The cell at which this variable was allocated.
fn cell(&self) -> Cell;
@ -40,7 +39,7 @@ pub trait Var<F: FieldExt>: Clone + std::fmt::Debug + From<AssignedCell<F, F>> {
fn value(&self) -> Value<F>;
}
impl<F: FieldExt> Var<F> for AssignedCell<F, F> {
impl<F: Field> Var<F> for AssignedCell<F, F> {
fn cell(&self) -> Cell {
self.cell()
}
@ -51,7 +50,7 @@ impl<F: FieldExt> Var<F> for AssignedCell<F, F> {
}
/// Trait for utilities used across circuits.
pub trait UtilitiesInstructions<F: FieldExt> {
pub trait UtilitiesInstructions<F: Field> {
/// Variable in the circuit.
type Var: Var<F>;
@ -130,15 +129,15 @@ impl<F: Field> RangeConstrained<F, AssignedCell<F, F>> {
}
/// Checks that an expression is either 1 or 0.
pub fn bool_check<F: FieldExt>(value: Expression<F>) -> Expression<F> {
pub fn bool_check<F: PrimeField>(value: Expression<F>) -> Expression<F> {
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<F: FieldExt>(a: Expression<F>, b: Expression<F>, c: Expression<F>) -> Expression<F> {
let one_minus_a = Expression::Constant(F::one()) - a.clone();
pub fn ternary<F: Field>(a: Expression<F>, b: Expression<F>, c: Expression<F>) -> Expression<F> {
let one_minus_a = Expression::Constant(F::ONE) - a.clone();
a * b + one_minus_a * c
}
@ -156,9 +155,9 @@ pub fn bitrange_subset<F: PrimeFieldBits>(field_elem: &F, bitrange: Range<usize>
.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<F: PrimeFieldBits>(field_elem: &F, bitrange: Range<usize>
/// Check that an expression is in the small range [0..range),
/// i.e. 0 ≤ word < range.
pub fn range_check<F: FieldExt>(word: Expression<F>, range: usize) -> Expression<F> {
pub fn range_check<F: PrimeField>(word: Expression<F>, range: usize) -> Expression<F> {
(1..range).fold(word.clone(), |acc, i| {
acc * (Expression::Constant(F::from(i as u64)) - word.clone())
})
@ -240,6 +239,7 @@ pub fn i2lebsp<const NUM_BITS: usize>(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)
}
}

View File

@ -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<F: FieldExt>: UtilitiesInstructions<F> {
pub trait CondSwapInstructions<F: Field>: UtilitiesInstructions<F> {
#[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<F> {
_marker: PhantomData<F>,
}
impl<F: FieldExt> Chip<F> for CondSwapChip<F> {
impl<F: Field> Chip<F> for CondSwapChip<F> {
type Config = CondSwapConfig;
type Loaded = ();
@ -63,11 +63,11 @@ impl CondSwapConfig {
}
}
impl<F: FieldExt> UtilitiesInstructions<F> for CondSwapChip<F> {
impl<F: Field> UtilitiesInstructions<F> for CondSwapChip<F> {
type Var = AssignedCell<F, F>;
}
impl<F: FieldExt> CondSwapInstructions<F> for CondSwapChip<F> {
impl<F: PrimeField> CondSwapInstructions<F> for CondSwapChip<F> {
#[allow(clippy::type_complexity)]
fn swap(
&self,
@ -122,7 +122,7 @@ impl<F: FieldExt> CondSwapInstructions<F> for CondSwapChip<F> {
}
}
impl<F: FieldExt> CondSwapChip<F> {
impl<F: PrimeField> CondSwapChip<F> {
/// Configures this chip for use in a circuit.
///
/// # Side-effects
@ -195,25 +195,26 @@ impl<F: FieldExt> CondSwapChip<F> {
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<F: FieldExt> {
struct MyCircuit<F: Field> {
a: Value<F>,
b: Value<F>,
swap: Value<bool>,
}
impl<F: FieldExt> Circuit<F> for MyCircuit<F> {
impl<F: PrimeField> Circuit<F> for MyCircuit<F> {
type Config = CondSwapConfig;
type FloorPlanner = SimpleFloorPlanner;

View File

@ -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<F: FieldExt + PrimeFieldBits>(Vec<AssignedCell<F, F>>);
impl<F: FieldExt + PrimeFieldBits> std::ops::Deref for RunningSum<F> {
pub struct RunningSum<F: PrimeFieldBits>(Vec<AssignedCell<F, F>>);
impl<F: PrimeFieldBits> std::ops::Deref for RunningSum<F> {
type Target = Vec<AssignedCell<F, F>>;
fn deref(&self) -> &Vec<AssignedCell<F, F>> {
@ -46,15 +45,13 @@ impl<F: FieldExt + PrimeFieldBits> std::ops::Deref for RunningSum<F> {
/// Configuration that provides methods for running sum decomposition.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct RunningSumConfig<F: FieldExt + PrimeFieldBits, const WINDOW_NUM_BITS: usize> {
pub struct RunningSumConfig<F: PrimeFieldBits, const WINDOW_NUM_BITS: usize> {
q_range_check: Selector,
z: Column<Advice>,
_marker: PhantomData<F>,
}
impl<F: FieldExt + PrimeFieldBits, const WINDOW_NUM_BITS: usize>
RunningSumConfig<F, WINDOW_NUM_BITS>
{
impl<F: PrimeFieldBits, const WINDOW_NUM_BITS: usize> RunningSumConfig<F, WINDOW_NUM_BITS> {
/// 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<F: FieldExt + PrimeFieldBits, const WINDOW_NUM_BITS: usize>
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,

View File

@ -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<F: FieldExt + PrimeFieldBits>(Vec<AssignedCell<F, F>>);
impl<F: FieldExt + PrimeFieldBits> std::ops::Deref for RunningSum<F> {
pub struct RunningSum<F: PrimeFieldBits>(Vec<AssignedCell<F, F>>);
impl<F: PrimeFieldBits> std::ops::Deref for RunningSum<F> {
type Target = Vec<AssignedCell<F, F>>;
fn deref(&self) -> &Vec<AssignedCell<F, F>> {
@ -23,7 +23,7 @@ impl<F: FieldExt + PrimeFieldBits> std::ops::Deref for RunningSum<F> {
}
}
impl<F: FieldExt + PrimeFieldBits> RangeConstrained<F, AssignedCell<F, F>> {
impl<F: PrimeFieldBits> RangeConstrained<F, AssignedCell<F, F>> {
/// Witnesses a subset of the bits in `value` and constrains them to be the correct
/// number of bits.
///
@ -56,7 +56,7 @@ impl<F: FieldExt + PrimeFieldBits> RangeConstrained<F, AssignedCell<F, F>> {
/// Configuration that provides methods for a lookup range check.
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
pub struct LookupRangeCheckConfig<F: FieldExt + PrimeFieldBits, const K: usize> {
pub struct LookupRangeCheckConfig<F: PrimeFieldBits, const K: usize> {
q_lookup: Selector,
q_running: Selector,
q_bitshift: Selector,
@ -65,7 +65,7 @@ pub struct LookupRangeCheckConfig<F: FieldExt + PrimeFieldBits, const K: usize>
_marker: PhantomData<F>,
}
impl<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K> {
impl<F: PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K> {
/// 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<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K>
// 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<F: FieldExt + PrimeFieldBits, const K: usize> LookupRangeCheckConfig<F, K>
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<F: FieldExt + PrimeFieldBits> {
struct MyCircuit<F: PrimeFieldBits> {
num_words: usize,
_marker: PhantomData<F>,
}
impl<F: FieldExt + PrimeFieldBits> Circuit<F> for MyCircuit<F> {
impl<F: PrimeFieldBits> Circuit<F> for MyCircuit<F> {
type Config = LookupRangeCheckConfig<F, K>;
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<F: FieldExt + PrimeFieldBits, const K: usize>(
fn expected_zs<F: PrimeFieldBits, const K: usize>(
element: F,
num_words: usize,
) -> Vec<F> {
@ -498,12 +498,12 @@ mod tests {
#[test]
fn short_range_check() {
struct MyCircuit<F: FieldExt + PrimeFieldBits> {
struct MyCircuit<F: PrimeFieldBits> {
element: Value<F>,
num_bits: usize,
}
impl<F: FieldExt + PrimeFieldBits> Circuit<F> for MyCircuit<F> {
impl<F: PrimeFieldBits> Circuit<F> for MyCircuit<F> {
type Config = LookupRangeCheckConfig<F, K>;
type FloorPlanner = SimpleFloorPlanner;

View File

@ -50,9 +50,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/privacy-scaling-explorations/halo2curves.git', tag = "0.3.1" }
ff = "0.13"
group = "0.13"
halo2curves = { git = 'https://github.com/privacy-scaling-explorations/halo2curves.git', branch = "main" }
rand_core = { version = "0.6", default-features = false }
tracing = "0.1"
blake2b_simd = "1"

View File

@ -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<F: FieldExt> {
struct MyCircuit<F: Field> {
_marker: PhantomData<F>,
}
@ -25,7 +25,7 @@ fn criterion_benchmark(c: &mut Criterion) {
advice: Column<Advice>,
}
impl<F: FieldExt> Circuit<F> for MyCircuit<F> {
impl<F: PrimeField> Circuit<F> for MyCircuit<F> {
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)]
});

View File

@ -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<Fixed>,
}
trait StandardCs<FF: FieldExt> {
trait StandardCs<FF: Field> {
fn raw_multiply<F>(
&self,
layouter: &mut impl Layouter<FF>,
@ -62,17 +61,17 @@ fn criterion_benchmark(c: &mut Criterion) {
}
#[derive(Clone)]
struct MyCircuit<F: FieldExt> {
struct MyCircuit<F: Field> {
a: Value<F>,
k: u32,
}
struct StandardPlonk<F: FieldExt> {
struct StandardPlonk<F: Field> {
config: PlonkConfig,
_marker: PhantomData<F>,
}
impl<FF: FieldExt> StandardPlonk<FF> {
impl<FF: Field> StandardPlonk<FF> {
fn new(config: PlonkConfig) -> Self {
StandardPlonk {
config,
@ -81,7 +80,7 @@ fn criterion_benchmark(c: &mut Criterion) {
}
}
impl<FF: FieldExt> StandardCs<FF> for StandardPlonk<FF> {
impl<FF: Field> StandardCs<FF> for StandardPlonk<FF> {
fn raw_multiply<F>(
&self,
layouter: &mut impl Layouter<FF>,
@ -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<F: FieldExt> Circuit<F> for MyCircuit<F> {
impl<F: Field> Circuit<F> for MyCircuit<F> {
type Config = PlonkConfig;
type FloorPlanner = SimpleFloorPlanner;

View File

@ -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<FF: FieldExt> {
trait StandardCs<FF: Field> {
fn raw_multiply<F>(&self, region: &mut Region<FF>, f: F) -> Result<(Cell, Cell, Cell), Error>
where
F: FnMut() -> Value<(Assigned<FF>, Assigned<FF>, Assigned<FF>)>;
@ -39,17 +38,17 @@ trait StandardCs<FF: FieldExt> {
fn lookup_table(&self, layouter: &mut impl Layouter<FF>, values: &[FF]) -> Result<(), Error>;
}
struct MyCircuit<F: FieldExt> {
struct MyCircuit<F: Field> {
a: Value<F>,
lookup_table: Vec<F>,
}
struct StandardPlonk<F: FieldExt> {
struct StandardPlonk<F: Field> {
config: PlonkConfig,
_marker: PhantomData<F>,
}
impl<FF: FieldExt> StandardPlonk<FF> {
impl<FF: Field> StandardPlonk<FF> {
fn new(config: PlonkConfig) -> Self {
StandardPlonk {
config,
@ -58,7 +57,7 @@ impl<FF: FieldExt> StandardPlonk<FF> {
}
}
impl<FF: FieldExt> StandardCs<FF> for StandardPlonk<FF> {
impl<FF: Field> StandardCs<FF> for StandardPlonk<FF> {
fn raw_multiply<F>(
&self,
region: &mut Region<FF>,
@ -94,10 +93,10 @@ impl<FF: FieldExt> StandardCs<FF> for StandardPlonk<FF> {
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<F>(&self, region: &mut Region<FF>, mut f: F) -> Result<(Cell, Cell, Cell), Error>
@ -131,10 +130,10 @@ impl<FF: FieldExt> StandardCs<FF> for StandardPlonk<FF> {
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<FF>, left: Cell, right: Cell) -> Result<(), Error> {
@ -159,7 +158,7 @@ impl<FF: FieldExt> StandardCs<FF> for StandardPlonk<FF> {
}
}
impl<F: FieldExt> Circuit<F> for MyCircuit<F> {
impl<F: Field> Circuit<F> for MyCircuit<F> {
type Config = PlonkConfig;
type FloorPlanner = SimpleFloorPlanner;

View File

@ -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<F: FieldExt, R: RngCore, const W: usize, const H: usize>(
rng: &mut R,
) -> [[F; H]; W] {
fn rand_2d_array<F: Field, R: RngCore, const W: usize, const H: usize>(rng: &mut R) -> [[F; H]; W] {
[(); W].map(|_| [(); H].map(|_| F::random(&mut *rng)))
}
fn shuffled<F: FieldExt, R: RngCore, const W: usize, const H: usize>(
fn shuffled<F: Field, R: RngCore, const W: usize, const H: usize>(
original: [[F; H]; W],
rng: &mut R,
) -> [[F; H]; W] {
@ -56,7 +54,7 @@ struct MyConfig<const W: usize> {
}
impl<const W: usize> MyConfig<W> {
fn configure<F: FieldExt>(meta: &mut ConstraintSystem<F>) -> Self {
fn configure<F: Field>(meta: &mut ConstraintSystem<F>) -> 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<const W: usize> MyConfig<W> {
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<const W: usize> MyConfig<W> {
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<const W: usize> MyConfig<W> {
}
#[derive(Clone, Default)]
struct MyCircuit<F: FieldExt, const W: usize, const H: usize> {
struct MyCircuit<F: Field, const W: usize, const H: usize> {
original: Value<[[F; H]; W]>,
shuffled: Value<[[F; H]; W]>,
}
impl<F: FieldExt, const W: usize, const H: usize> MyCircuit<F, W, H> {
impl<F: Field, const W: usize, const H: usize> MyCircuit<F, W, H> {
fn rand<R: RngCore>(rng: &mut R) -> Self {
let original = rand_2d_array::<F, _, W, H>(rng);
let shuffled = shuffled(original, rng);
@ -135,7 +133,7 @@ impl<F: FieldExt, const W: usize, const H: usize> MyCircuit<F, W, H> {
}
}
impl<F: FieldExt, const W: usize, const H: usize> Circuit<F> for MyCircuit<F, W, H> {
impl<F: Field, const W: usize, const H: usize> Circuit<F> for MyCircuit<F, W, H> {
type Config = MyConfig<W>;
type FloorPlanner = V1;
@ -200,9 +198,9 @@ impl<F: FieldExt, const W: usize, const H: usize> Circuit<F> for MyCircuit<F, W,
// Second phase
let z = self.original.zip(self.shuffled).zip(theta).zip(gamma).map(
|(((original, shuffled), theta), gamma)| {
let mut product = vec![F::zero(); H];
let mut product = vec![F::ZERO; H];
for (idx, product) in product.iter_mut().enumerate() {
let mut compressed = F::zero();
let mut compressed = F::ZERO;
for value in shuffled.iter() {
compressed *= theta;
compressed += value[idx];
@ -214,7 +212,7 @@ impl<F: FieldExt, const W: usize, const H: usize> Circuit<F> for MyCircuit<F, W,
product.iter_mut().batch_invert();
for (idx, product) in product.iter_mut().enumerate() {
let mut compressed = F::zero();
let mut compressed = F::ZERO;
for value in original.iter() {
compressed *= theta;
compressed += value[idx];
@ -224,16 +222,16 @@ impl<F: FieldExt, const W: usize, const H: usize> Circuit<F> for MyCircuit<F, W,
}
#[allow(clippy::let_and_return)]
let z = iter::once(F::one())
let z = iter::once(F::ONE)
.chain(product)
.scan(F::one(), |state, cur| {
.scan(F::ONE, |state, cur| {
*state *= &cur;
Some(*state)
})
.collect::<Vec<_>>();
#[cfg(feature = "sanity-checks")]
assert_eq!(F::one(), *z.last().unwrap());
assert_eq!(F::ONE, *z.last().unwrap());
z
},
@ -253,12 +251,12 @@ impl<F: FieldExt, const W: usize, const H: usize> Circuit<F> for MyCircuit<F, W,
}
}
fn test_mock_prover<F: FieldExt, const W: usize, const H: usize>(
fn test_mock_prover<F: Ord + FromUniformBytes<64>, const W: usize, const H: usize>(
k: u32,
circuit: MyCircuit<F, W, H>,
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<C: CurveAffine, const W: usize, const H: usize>(
k: u32,
circuit: MyCircuit<C::Scalar, W, H>,
expected: bool,
) {
) where
C::Scalar: FromUniformBytes<64>,
{
let params = ParamsIPA::<C>::new(k);
let vk = keygen_vk(&params, &circuit).unwrap();
let pk = keygen_pk(&params, vk, &circuit).unwrap();

View File

@ -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<F: FieldExt>: Chip<F> {
trait NumericInstructions<F: Field>: Chip<F> {
/// Variable representing a number.
type Num;
@ -39,7 +39,7 @@ trait NumericInstructions<F: FieldExt>: Chip<F> {
// ANCHOR: chip
/// The chip that will implement our instructions! Chips store their own
/// config, as well as type markers if necessary.
struct FieldChip<F: FieldExt> {
struct FieldChip<F: Field> {
config: FieldConfig,
_marker: PhantomData<F>,
}
@ -65,7 +65,7 @@ struct FieldConfig {
s_mul: Selector,
}
impl<F: FieldExt> FieldChip<F> {
impl<F: Field> FieldChip<F> {
fn construct(config: <Self as Chip<F>>::Config) -> Self {
Self {
config,
@ -126,7 +126,7 @@ impl<F: FieldExt> FieldChip<F> {
// ANCHOR_END: chip-config
// ANCHOR: chip-impl
impl<F: FieldExt> Chip<F> for FieldChip<F> {
impl<F: Field> Chip<F> for FieldChip<F> {
type Config = FieldConfig;
type Loaded = ();
@ -143,9 +143,9 @@ impl<F: FieldExt> Chip<F> for FieldChip<F> {
// ANCHOR: instructions-impl
/// A variable representing a number.
#[derive(Clone)]
struct Number<F: FieldExt>(AssignedCell<F, F>);
struct Number<F: Field>(AssignedCell<F, F>);
impl<F: FieldExt> NumericInstructions<F> for FieldChip<F> {
impl<F: Field> NumericInstructions<F> for FieldChip<F> {
type Num = Number<F>;
fn load_private(
@ -238,13 +238,13 @@ impl<F: FieldExt> NumericInstructions<F> for FieldChip<F> {
/// 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<F: FieldExt> {
struct MyCircuit<F: Field> {
constant: F,
a: Value<F>,
b: Value<F>,
}
impl<F: FieldExt> Circuit<F> for MyCircuit<F> {
impl<F: Field> Circuit<F> for MyCircuit<F> {
// Since we are using a single chip for everything, we can just reuse its config.
type Config = FieldConfig;
type FloorPlanner = SimpleFloorPlanner;

View File

@ -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<F: FieldExt>(AssignedCell<F, F>);
struct Number<F: Field>(AssignedCell<F, F>);
trait FieldInstructions<F: FieldExt>: AddInstructions<F> + MulInstructions<F> {
trait FieldInstructions<F: Field>: AddInstructions<F> + MulInstructions<F> {
/// Variable representing a number.
type Num;
@ -43,7 +43,7 @@ trait FieldInstructions<F: FieldExt>: AddInstructions<F> + MulInstructions<F> {
// ANCHOR_END: field-instructions
// ANCHOR: add-instructions
trait AddInstructions<F: FieldExt>: Chip<F> {
trait AddInstructions<F: Field>: Chip<F> {
/// Variable representing a number.
type Num;
@ -58,7 +58,7 @@ trait AddInstructions<F: FieldExt>: Chip<F> {
// ANCHOR_END: add-instructions
// ANCHOR: mul-instructions
trait MulInstructions<F: FieldExt>: Chip<F> {
trait MulInstructions<F: Field>: Chip<F> {
/// 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<F: FieldExt> {
struct FieldChip<F: Field> {
config: FieldConfig,
_marker: PhantomData<F>,
}
// ANCHOR_END: field-chip
// ANCHOR: add-chip
struct AddChip<F: FieldExt> {
struct AddChip<F: Field> {
config: AddConfig,
_marker: PhantomData<F>,
}
// ANCHOR END: add-chip
// ANCHOR: mul-chip
struct MulChip<F: FieldExt> {
struct MulChip<F: Field> {
config: MulConfig,
_marker: PhantomData<F>,
}
// ANCHOR_END: mul-chip
// ANCHOR: add-chip-trait-impl
impl<F: FieldExt> Chip<F> for AddChip<F> {
impl<F: Field> Chip<F> for AddChip<F> {
type Config = AddConfig;
type Loaded = ();
@ -144,7 +144,7 @@ impl<F: FieldExt> Chip<F> for AddChip<F> {
// ANCHOR END: add-chip-trait-impl
// ANCHOR: add-chip-impl
impl<F: FieldExt> AddChip<F> {
impl<F: Field> AddChip<F> {
fn construct(config: <Self as Chip<F>>::Config, _loaded: <Self as Chip<F>>::Loaded) -> Self {
Self {
config,
@ -174,7 +174,7 @@ impl<F: FieldExt> AddChip<F> {
// ANCHOR END: add-chip-impl
// ANCHOR: add-instructions-impl
impl<F: FieldExt> AddInstructions<F> for FieldChip<F> {
impl<F: Field> AddInstructions<F> for FieldChip<F> {
type Num = Number<F>;
fn add(
&self,
@ -189,7 +189,7 @@ impl<F: FieldExt> AddInstructions<F> for FieldChip<F> {
}
}
impl<F: FieldExt> AddInstructions<F> for AddChip<F> {
impl<F: Field> AddInstructions<F> for AddChip<F> {
type Num = Number<F>;
fn add(
@ -231,7 +231,7 @@ impl<F: FieldExt> AddInstructions<F> for AddChip<F> {
// ANCHOR END: add-instructions-impl
// ANCHOR: mul-chip-trait-impl
impl<F: FieldExt> Chip<F> for MulChip<F> {
impl<F: Field> Chip<F> for MulChip<F> {
type Config = MulConfig;
type Loaded = ();
@ -246,7 +246,7 @@ impl<F: FieldExt> Chip<F> for MulChip<F> {
// ANCHOR END: mul-chip-trait-impl
// ANCHOR: mul-chip-impl
impl<F: FieldExt> MulChip<F> {
impl<F: Field> MulChip<F> {
fn construct(config: <Self as Chip<F>>::Config, _loaded: <Self as Chip<F>>::Loaded) -> Self {
Self {
config,
@ -296,7 +296,7 @@ impl<F: FieldExt> MulChip<F> {
// ANCHOR_END: mul-chip-impl
// ANCHOR: mul-instructions-impl
impl<F: FieldExt> MulInstructions<F> for FieldChip<F> {
impl<F: Field> MulInstructions<F> for FieldChip<F> {
type Num = Number<F>;
fn mul(
&self,
@ -310,7 +310,7 @@ impl<F: FieldExt> MulInstructions<F> for FieldChip<F> {
}
}
impl<F: FieldExt> MulInstructions<F> for MulChip<F> {
impl<F: Field> MulInstructions<F> for MulChip<F> {
type Num = Number<F>;
fn mul(
@ -352,7 +352,7 @@ impl<F: FieldExt> MulInstructions<F> for MulChip<F> {
// ANCHOR END: mul-instructions-impl
// ANCHOR: field-chip-trait-impl
impl<F: FieldExt> Chip<F> for FieldChip<F> {
impl<F: Field> Chip<F> for FieldChip<F> {
type Config = FieldConfig;
type Loaded = ();
@ -367,7 +367,7 @@ impl<F: FieldExt> Chip<F> for FieldChip<F> {
// ANCHOR_END: field-chip-trait-impl
// ANCHOR: field-chip-impl
impl<F: FieldExt> FieldChip<F> {
impl<F: Field> FieldChip<F> {
fn construct(config: <Self as Chip<F>>::Config, _loaded: <Self as Chip<F>>::Loaded) -> Self {
Self {
config,
@ -396,7 +396,7 @@ impl<F: FieldExt> FieldChip<F> {
// ANCHOR_END: field-chip-impl
// ANCHOR: field-instructions-impl
impl<F: FieldExt> FieldInstructions<F> for FieldChip<F> {
impl<F: Field> FieldInstructions<F> for FieldChip<F> {
type Num = Number<F>;
fn load_private(
@ -448,13 +448,13 @@ impl<F: FieldExt> FieldInstructions<F> for FieldChip<F> {
/// 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<F: FieldExt> {
struct MyCircuit<F: Field> {
a: Value<F>,
b: Value<F>,
c: Value<F>,
}
impl<F: FieldExt> Circuit<F> for MyCircuit<F> {
impl<F: Field> Circuit<F> for MyCircuit<F> {
// 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<F: FieldExt> Circuit<F> for MyCircuit<F> {
#[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;

View File

@ -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<Scalar: Field>:
Copy + Send + Sync + 'static + GroupOpsOwned + ScalarMulOwned<Scalar>
{
}
impl<T, Scalar> FftGroup<Scalar> for T
where
Scalar: Field,
T: Copy + Send + Sync + 'static + GroupOpsOwned + ScalarMulOwned<Scalar>,
{
}
fn multiexp_serial<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C], acc: &mut C::Curve) {
let coeffs: Vec<_> = coeffs.iter().map(|a| a.to_repr()).collect();
@ -168,7 +183,7 @@ pub fn best_multiexp<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C]) -> C::Cu
/// by $n$.
///
/// This will use multithreading if beneficial.
pub fn best_fft<G: Group>(a: &mut [G], omega: G::Scalar, log_n: u32) {
pub fn best_fft<Scalar: Field, G: FftGroup<Scalar>>(a: &mut [G], omega: Scalar, log_n: u32) {
fn bitreverse(mut n: usize, l: usize) -> usize {
let mut r = 0;
for _ in 0..l {
@ -192,9 +207,9 @@ pub fn best_fft<G: Group>(a: &mut [G], omega: G::Scalar, log_n: u32) {
// precompute twiddle factors
let twiddles: Vec<_> = (0..(n / 2) as usize)
.scan(G::Scalar::one(), |w, _| {
.scan(Scalar::ONE, |w, _| {
let tw = *w;
w.group_scale(&omega);
*w *= &omega;
Some(tw)
})
.collect();
@ -211,18 +226,18 @@ pub fn best_fft<G: Group>(a: &mut [G], omega: G::Scalar, log_n: u32) {
let (b, right) = right.split_at_mut(1);
let t = b[0];
b[0] = a[0];
a[0].group_add(&t);
b[0].group_sub(&t);
a[0] += &t;
b[0] -= &t;
left.iter_mut()
.zip(right.iter_mut())
.enumerate()
.for_each(|(i, (a, b))| {
let mut t = *b;
t.group_scale(&twiddles[(i + 1) * twiddle_chunk]);
t *= &twiddles[(i + 1) * twiddle_chunk];
*b = *a;
a.group_add(&t);
b.group_sub(&t);
*a += &t;
*b -= &t;
});
});
chunk *= 2;
@ -234,17 +249,17 @@ pub fn best_fft<G: Group>(a: &mut [G], omega: G::Scalar, log_n: u32) {
}
/// This perform recursive butterfly arithmetic
pub fn recursive_butterfly_arithmetic<G: Group>(
pub fn recursive_butterfly_arithmetic<Scalar: Field, G: FftGroup<Scalar>>(
a: &mut [G],
n: usize,
twiddle_chunk: usize,
twiddles: &[G::Scalar],
twiddles: &[Scalar],
) {
if n == 2 {
let t = a[1];
a[1] = a[0];
a[0].group_add(&t);
a[1].group_sub(&t);
a[0] += &t;
a[1] -= &t;
} else {
let (left, right) = a.split_at_mut(n / 2);
rayon::join(
@ -257,18 +272,18 @@ pub fn recursive_butterfly_arithmetic<G: Group>(
let (b, right) = right.split_at_mut(1);
let t = b[0];
b[0] = a[0];
a[0].group_add(&t);
b[0].group_sub(&t);
a[0] += &t;
b[0] -= &t;
left.iter_mut()
.zip(right.iter_mut())
.enumerate()
.for_each(|(i, (a, b))| {
let mut t = *b;
t.group_scale(&twiddles[(i + 1) * twiddle_chunk]);
t *= &twiddles[(i + 1) * twiddle_chunk];
*b = *a;
a.group_add(&t);
b.group_sub(&t);
*a += &t;
*b -= &t;
});
}
}
@ -305,7 +320,7 @@ pub fn eval_polynomial<F: Field>(poly: &[F], point: F) -> F {
fn evaluate<F: Field>(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();
@ -313,7 +328,7 @@ pub fn eval_polynomial<F: Field>(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()
@ -324,7 +339,7 @@ pub fn eval_polynomial<F: Field>(poly: &[F], point: F) -> F {
});
}
});
parts.iter().fold(F::zero(), |acc, coeff| acc + coeff)
parts.iter().fold(F::ZERO, |acc, coeff| acc + coeff)
}
}
@ -335,7 +350,7 @@ pub fn compute_inner_product<F: Field>(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);
}
@ -352,9 +367,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);
@ -402,7 +417,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<F: FieldExt>(points: &[F], evals: &[F]) -> Vec<F> {
pub fn lagrange_interpolate<F: Field>(points: &[F], evals: &[F]) -> Vec<F> {
assert_eq!(points.len(), evals.len());
if points.len() == 1 {
// Constant polynomial
@ -424,11 +439,11 @@ pub fn lagrange_interpolate<F: FieldExt>(points: &[F], evals: &[F]) -> Vec<F> {
// 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<F> = 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()
@ -436,11 +451,11 @@ pub fn lagrange_interpolate<F: FieldExt>(points: &[F], evals: &[F]) -> Vec<F> {
.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;
@ -457,9 +472,9 @@ pub fn lagrange_interpolate<F: FieldExt>(points: &[F], evals: &[F]) -> Vec<F> {
}
}
pub(crate) fn evaluate_vanishing_polynomial<F: FieldExt>(roots: &[F], z: F) -> F {
fn evaluate<F: FieldExt>(roots: &[F], z: F) -> F {
roots.iter().fold(F::one(), |acc, point| (z - point) * acc)
pub(crate) fn evaluate_vanishing_polynomial<F: Field>(roots: &[F], z: F) -> F {
fn evaluate<F: Field>(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();
@ -467,18 +482,18 @@ pub(crate) fn evaluate_vanishing_polynomial<F: FieldExt>(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<F: FieldExt>(base: F) -> impl Iterator<Item = F> {
std::iter::successors(Some(F::one()), move |power| Some(base * power))
pub(crate) fn powers<F: Field>(base: F) -> impl Iterator<Item = F> {
std::iter::successors(Some(F::ONE), move |power| Some(base * power))
}
#[cfg(test)]

View File

@ -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;
@ -27,7 +24,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<F: FieldExt>: Sized {
pub trait Chip<F: Field>: 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`].
///

View File

@ -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<F>, CS: Assignment<F> + 'a> Layouter<C> for MyLayouter<'a, C, CS> {
/// impl<'a, F: Field, C: Chip<F>, CS: Assignment<F> + 'a> Layouter<C> for MyLayouter<'a, C, CS> {
/// fn assign_region(
/// &mut self,
/// assignment: impl FnOnce(Region<'_, F, C>) -> Result<(), Error>,

View File

@ -9,10 +9,11 @@ use std::time::{Duration, Instant};
use blake2b_simd::blake2b;
use ff::Field;
use ff::FromUniformBytes;
use group::Group;
use crate::plonk::permutation::keygen::Assembly;
use crate::{
arithmetic::{FieldExt, Group},
circuit,
plonk::{
permutation,
@ -88,7 +89,7 @@ impl Region {
/// The value of a particular cell within the circuit.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CellValue<F: Group + Field> {
pub enum CellValue<F: Field> {
/// An unassigned cell.
Unassigned,
/// A cell that has been assigned a value.
@ -99,23 +100,23 @@ pub enum CellValue<F: Group + Field> {
/// A value within an expression.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)]
enum Value<F: Group + Field> {
enum Value<F: Field> {
Real(F),
Poison,
}
impl<F: Group + Field> From<CellValue<F>> for Value<F> {
impl<F: Field> From<CellValue<F>> for Value<F> {
fn from(value: CellValue<F>) -> 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),
CellValue::Poison(_) => Value::Poison,
}
}
}
impl<F: Group + Field> Neg for Value<F> {
impl<F: Field> Neg for Value<F> {
type Output = Self;
fn neg(self) -> Self::Output {
@ -126,7 +127,7 @@ impl<F: Group + Field> Neg for Value<F> {
}
}
impl<F: Group + Field> Add for Value<F> {
impl<F: Field> Add for Value<F> {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
@ -137,7 +138,7 @@ impl<F: Group + Field> Add for Value<F> {
}
}
impl<F: Group + Field> Mul for Value<F> {
impl<F: Field> Mul for Value<F> {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
@ -148,14 +149,14 @@ impl<F: Group + Field> Mul for Value<F> {
(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<F: Group + Field> Mul<F> for Value<F> {
impl<F: Field> Mul<F> for Value<F> {
type Output = Self;
fn mul(self, rhs: F) -> Self::Output {
@ -163,7 +164,7 @@ impl<F: Group + Field> Mul<F> for Value<F> {
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,
}
}
@ -181,12 +182,12 @@ impl<F: Group + Field> Mul<F> for Value<F> {
///
/// ```
/// 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;
///
@ -204,7 +205,7 @@ impl<F: Group + Field> Mul<F> for Value<F> {
/// b: Value<u64>,
/// }
///
/// impl<F: FieldExt> Circuit<F> for MyCircuit {
/// impl<F: PrimeField> Circuit<F> for MyCircuit {
/// type Config = MyConfig;
/// type FloorPlanner = SimpleFloorPlanner;
///
@ -285,7 +286,7 @@ impl<F: Group + Field> Mul<F> for Value<F> {
/// );
/// ```
#[derive(Debug)]
pub struct MockProver<F: Group + Field> {
pub struct MockProver<F: Field> {
k: u32,
n: u32,
cs: ConstraintSystem<F>,
@ -315,13 +316,13 @@ pub struct MockProver<F: Group + Field> {
current_phase: sealed::Phase,
}
impl<F: Field + Group> MockProver<F> {
impl<F: Field> MockProver<F> {
fn in_phase<P: Phase>(&self, phase: P) -> bool {
self.current_phase == phase.to_sealed()
}
}
impl<F: Field + Group> Assignment<F> for MockProver<F> {
impl<F: Field> Assignment<F> for MockProver<F> {
fn enter_region<NR, N>(&mut self, name: N)
where
NR: Into<String>,
@ -589,7 +590,7 @@ impl<F: Field + Group> Assignment<F> for MockProver<F> {
}
}
impl<F: FieldExt> MockProver<F> {
impl<F: FromUniformBytes<64> + Ord> MockProver<F> {
/// Runs a synthetic keygen-and-prove operation on the given circuit, collecting data
/// about the constraints and their assignments.
pub fn run<ConcreteCircuit: Circuit<F>>(
@ -624,7 +625,7 @@ impl<F: FieldExt> MockProver<F> {
cs.blinding_factors()
);
instance.resize(n, F::zero());
instance.resize(n, F::ZERO);
instance
})
.collect::<Vec<_>>();
@ -654,7 +655,7 @@ impl<F: FieldExt> MockProver<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()
@ -814,7 +815,7 @@ impl<F: FieldExt> MockProver<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 {
@ -899,7 +900,7 @@ impl<F: FieldExt> MockProver<F> {
&|a, b| a + b,
&|a, b| a * b,
&|a, scalar| a * scalar,
&Value::Real(F::zero()),
&Value::Real(F::ZERO),
)
};
@ -1187,7 +1188,7 @@ impl<F: FieldExt> MockProver<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 {
@ -1265,7 +1266,7 @@ impl<F: FieldExt> MockProver<F> {
&|a, b| a + b,
&|a, b| a * b,
&|a, scalar| a * scalar,
&Value::Real(F::zero()),
&Value::Real(F::ZERO),
)
};

View File

@ -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<F: Field>(
/// | x0 = 0x5
/// | x1 = 1
/// ```
fn render_lookup<F: FieldExt>(
fn render_lookup<F: Field>(
prover: &MockProver<F>,
name: &str,
lookup_index: usize,
@ -510,7 +509,7 @@ fn render_lookup<F: FieldExt>(
)
});
fn cell_value<'a, F: FieldExt, Q: Into<AnyQuery> + Copy>(
fn cell_value<'a, F: Field, Q: Into<AnyQuery> + Copy>(
load: impl Fn(Q) -> Value<F> + 'a,
) -> impl Fn(Q) -> BTreeMap<metadata::VirtualCell, String> + 'a {
move |query| {
@ -614,7 +613,7 @@ fn render_lookup<F: FieldExt>(
impl VerifyFailure {
/// Emits this failure in pretty-printed format to stderr.
pub(super) fn emit<F: FieldExt>(&self, prover: &MockProver<F>) {
pub(super) fn emit<F: Field>(&self, prover: &MockProver<F>) {
match self {
Self::CellNotAssigned {
gate,

View File

@ -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<InstanceQuery> for AnyQuery {
pub(super) fn format_value<F: Field>(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.
@ -73,7 +71,7 @@ pub(super) fn format_value<F: Field>(v: F) -> String {
}
}
pub(super) fn load<'a, F: FieldExt, T: ColumnType, Q: Into<AnyQuery> + Copy>(
pub(super) fn load<'a, F: Field, T: ColumnType, Q: Into<AnyQuery> + Copy>(
n: i32,
row: i32,
queries: &'a [(Column<T>, Rotation)],
@ -86,7 +84,7 @@ pub(super) fn load<'a, F: FieldExt, T: ColumnType, Q: Into<AnyQuery> + Copy>(
}
}
pub(super) fn load_instance<'a, F: FieldExt, T: ColumnType, Q: Into<AnyQuery> + Copy>(
pub(super) fn load_instance<'a, F: Field, T: ColumnType, Q: Into<AnyQuery> + Copy>(
n: i32,
row: i32,
queries: &'a [(Column<T>, Rotation)],
@ -99,7 +97,7 @@ pub(super) fn load_instance<'a, F: FieldExt, T: ColumnType, Q: Into<AnyQuery> +
}
}
fn cell_value<'a, F: FieldExt, Q: Into<AnyQuery> + Copy>(
fn cell_value<'a, F: Field, Q: Into<AnyQuery> + Copy>(
virtual_cells: &'a [VirtualCell],
load: impl Fn(Q) -> Value<F> + 'a,
) -> impl Fn(Q) -> BTreeMap<metadata::VirtualCell, String> + 'a {
@ -132,7 +130,7 @@ fn cell_value<'a, F: FieldExt, Q: Into<AnyQuery> + Copy>(
}
}
pub(super) fn cell_values<'a, F: FieldExt>(
pub(super) fn cell_values<'a, F: Field>(
gate: &Gate<F>,
poly: &Expression<F>,
load_fixed: impl Fn(FixedQuery) -> Value<F> + 'a,

View File

@ -6,10 +6,9 @@
//! [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 crate::arithmetic::{CurveAffine, FieldExt};
use crate::arithmetic::CurveAffine;
use crate::helpers::{
polynomial_slice_byte_length, read_polynomial_vec, write_polynomial_slice, SerdeCurveAffine,
SerdePrimeField,
@ -60,7 +59,7 @@ pub struct VerifyingKey<C: CurveAffine> {
impl<C: SerdeCurveAffine> VerifyingKey<C>
where
C::Scalar: SerdePrimeField,
C::Scalar: SerdePrimeField + FromUniformBytes<64>,
{
/// Writes a verifying key to a buffer.
///
@ -156,7 +155,10 @@ where
}
}
impl<C: CurveAffine> VerifyingKey<C> {
impl<C: CurveAffine> VerifyingKey<C>
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()
@ -185,7 +187,7 @@ impl<C: CurveAffine> VerifyingKey<C> {
cs,
cs_degree,
// Temporary, this is not pinned.
transcript_repr: C::Scalar::zero(),
transcript_repr: C::Scalar::ZERO,
selectors,
};
@ -200,7 +202,7 @@ impl<C: CurveAffine> VerifyingKey<C> {
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
}
@ -271,7 +273,10 @@ pub struct ProvingKey<C: CurveAffine> {
ev: Evaluator<C>,
}
impl<C: CurveAffine> ProvingKey<C> {
impl<C: CurveAffine> ProvingKey<C>
where
C::Scalar: FromUniformBytes<64>,
{
/// Get the underlying [`VerifyingKey`].
pub fn get_vk(&self) -> &VerifyingKey<C> {
&self.vk
@ -292,7 +297,7 @@ impl<C: CurveAffine> ProvingKey<C> {
impl<C: SerdeCurveAffine> ProvingKey<C>
where
C::Scalar: SerdePrimeField,
C::Scalar: SerdePrimeField + FromUniformBytes<64>,
{
/// Writes a proving key to a buffer.
///

View File

@ -280,7 +280,7 @@ impl<F: Field> Assigned<F> {
/// 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<F: Field> Assigned<F> {
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<F: Field> Assigned<F> {
/// 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)
}
}

View File

@ -354,11 +354,10 @@ impl TryFrom<Column<Any>> for Column<Instance> {
/// 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 {
@ -367,12 +366,12 @@ impl TryFrom<Column<Any>> for Column<Instance> {
/// s: Selector,
/// }
///
/// fn circuit_logic<F: FieldExt, C: Chip<F>>(chip: C, mut layouter: impl Layouter<F>) -> Result<(), Error> {
/// fn circuit_logic<F: Field, C: Chip<F>>(chip: C, mut layouter: impl Layouter<F>) -> 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(())

View File

@ -79,7 +79,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::<Vec<_>>();
let combination_index = combination_assignments.len();
combination_assignments.push(combination_assignment);
@ -177,12 +177,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
@ -192,12 +192,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
@ -212,7 +212,7 @@ where
}
}
assigned_root += F::one();
assigned_root += F::ONE;
SelectorAssignment {
selector: selector.selector,

View File

@ -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<C: CurveAffine> Evaluator<C> {
let fixed = &pk.fixed_cosets[..];
let extended_omega = domain.get_extended_omega();
let isize = size as i32;
let one = C::ScalarExt::one();
let one = C::ScalarExt::ONE;
let l0 = &pk.l0;
let l_last = &pk.l_last;
let l_active_row = &pk.l_active_row;
@ -475,7 +475,7 @@ impl<C: CurveAffine> Evaluator<C> {
&gamma,
&theta,
&y,
&C::ScalarExt::zero(),
&C::ScalarExt::ZERO,
idx,
rot_scale,
isize,
@ -527,8 +527,8 @@ impl<C: CurveAffine> Default for GraphEvaluator<C> {
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(),
@ -676,9 +676,9 @@ impl<C: CurveAffine> GraphEvaluator<C> {
}
}
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);
@ -692,7 +692,7 @@ impl<C: CurveAffine> GraphEvaluator<C> {
/// Creates a new evaluation structure
pub fn instance(&self) -> EvaluationData<C> {
EvaluationData {
intermediates: vec![C::ScalarExt::zero(); self.num_intermediates],
intermediates: vec![C::ScalarExt::ZERO; self.num_intermediates],
rotations: vec![0usize; self.rotations.len()],
}
}
@ -740,13 +740,13 @@ impl<C: CurveAffine> GraphEvaluator<C> {
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<F: FieldExt, B: Basis>(
pub fn evaluate<F: Field, B: Basis>(
expression: &Expression<F>,
size: usize,
rot_scale: i32,
@ -755,7 +755,7 @@ pub fn evaluate<F: FieldExt, B: Basis>(
instance: &[Polynomial<F, B>],
challenges: &[F],
) -> Vec<F> {
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() {

View File

@ -2,7 +2,7 @@
use std::ops::Range;
use ff::Field;
use ff::{Field, FromUniformBytes};
use group::Curve;
use super::{
@ -208,6 +208,7 @@ where
C: CurveAffine,
P: Params<'params, C>,
ConcreteCircuit: Circuit<C::Scalar>,
C::Scalar: FromUniformBytes<64>,
{
let (domain, cs, config) = create_domain::<C, ConcreteCircuit>(params.k());
@ -320,7 +321,7 @@ 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);
let l0 = vk.domain.coeff_to_extended(l0);
@ -328,7 +329,7 @@ where
// 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;
}
let l_blind = vk.domain.lagrange_to_coeff(l_blind);
let l_blind = vk.domain.coeff_to_extended(l_blind);
@ -336,12 +337,12 @@ where
// 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;
let l_last = vk.domain.lagrange_to_coeff(l_last);
let l_last = vk.domain.coeff_to_extended(l_last);
// Compute l_active_row(X)
let one = C::Scalar::one();
let one = C::Scalar::ONE;
let mut l_active_row = vk.domain.empty_extended();
parallelize(&mut l_active_row, |values, start| {
for (i, value) in values.iter_mut().enumerate() {

View File

@ -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<C: CurveAffine> {
constructed: Committed<C>,
}
impl<F: FieldExt> Argument<F> {
impl<F: WithSmallOrderMulGroup<3>> Argument<F> {
/// 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<C: CurveAffine> Permuted<C> {
// 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<C: CurveAffine> Permuted<C> {
// 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<C: CurveAffine> Permuted<C> {
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<C: CurveAffine> Permuted<C> {
// 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()

View File

@ -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},
@ -31,7 +31,7 @@ pub struct Evaluated<C: CurveAffine> {
permuted_table_eval: C::Scalar,
}
impl<F: FieldExt> Argument<F> {
impl<F: Field> Argument<F> {
pub(in crate::plonk) fn read_permuted_commitments<
C: CurveAffine,
E: EncodedChallenge<C>,
@ -104,7 +104,7 @@ impl<C: CurveAffine> Evaluated<C> {
instance_evals: &[C::Scalar],
challenges: &[C::Scalar],
) -> impl Iterator<Item = C::Scalar> + '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<C: CurveAffine> Evaluated<C> {
&|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<C: CurveAffine> Evaluated<C> {
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

View File

@ -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<C> {
// 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 *= &<C::Scalar as PrimeField>::DELTA;
}
});
}
@ -171,7 +171,7 @@ impl Assembly {
p: &Argument,
) -> ProvingKey<C> {
// 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| {

View File

@ -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,
@ -73,10 +74,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![];
@ -93,7 +94,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()) {
@ -136,7 +137,7 @@ impl Argument {
deltaomega *= &omega;
}
});
deltaomega *= &C::Scalar::DELTA;
deltaomega *= &<C::Scalar as PrimeField>::DELTA;
}
// The modified_values vector is a vector of products of fractions

View File

@ -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},
@ -119,9 +119,9 @@ impl<C: CurveAffine> Evaluated<C> {
// 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
@ -178,7 +178,8 @@ impl<C: CurveAffine> Evaluated<C> {
let mut right = set.permutation_product_eval;
let mut current_delta = (*beta * &*x)
* &(C::Scalar::DELTA.pow_vartime(&[(chunk_index * chunk_len) as u64]));
* &(<C::Scalar as PrimeField>::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())]
@ -194,7 +195,7 @@ impl<C: CurveAffine> Evaluated<C> {
current_delta *= &C::Scalar::DELTA;
}
(left - &right) * (C::Scalar::one() - &(l_last + &l_blind))
(left - &right) * (C::Scalar::ONE - &(l_last + &l_blind))
}),
)
}

View File

@ -1,4 +1,4 @@
use ff::Field;
use ff::{Field, FromUniformBytes, PrimeField, WithSmallOrderMulGroup};
use group::Curve;
use halo2curves::CurveExt;
use rand_core::RngCore;
@ -19,7 +19,7 @@ use super::{
ChallengeY, Error, Expression, ProvingKey,
};
use crate::{
arithmetic::{eval_polynomial, CurveAffine, FieldExt},
arithmetic::{eval_polynomial, CurveAffine},
circuit::Value,
plonk::Assigned,
poly::{
@ -53,7 +53,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);

View File

@ -8,7 +8,7 @@ use rayon::{current_num_threads, prelude::*};
use super::Argument;
use crate::{
arithmetic::{eval_polynomial, CurveAffine, FieldExt},
arithmetic::{eval_polynomial, CurveAffine},
plonk::{ChallengeX, ChallengeY, Error},
poly::{
self,
@ -52,7 +52,7 @@ impl<C: CurveAffine> Argument<C> {
let n_threads = current_num_threads();
let n = 1usize << domain.k() as usize;
let n_chunks = n_threads + if n % n_threads != 0 { 1 } else { 0 };
let mut rand_vec = vec![C::Scalar::zero(); n];
let mut rand_vec = vec![C::Scalar::ZERO; n];
let mut thread_seeds: Vec<ChaCha20Rng> = (0..n_chunks)
.into_iter()
@ -161,9 +161,7 @@ impl<C: CurveAffine> Constructed<C> {
.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)?;

View File

@ -94,8 +94,8 @@ impl<C: CurveAffine> PartiallyEvaluated<C> {
y: ChallengeY<C>,
xn: C::Scalar,
) -> Evaluated<C, P::MSM> {
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<C: CurveAffine> PartiallyEvaluated<C> {
.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
});

View File

@ -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<Strategy::Output, Error> {
) -> Result<Strategy::Output, Error>
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)

View File

@ -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<C: CurveAffine> {
items: Vec<BatchItem<C>>,
}
impl<C: CurveAffine> BatchVerifier<C> {
impl<C: CurveAffine> BatchVerifier<C>
where
C::Scalar: FromUniformBytes<64>,
{
/// Constructs a new batch verifier.
pub fn new() -> Self {
Self { items: vec![] }

View File

@ -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<F: SerdePrimeField, B> Polynomial<F, B> {
}
}
pub(crate) fn batch_invert_assigned<F: FieldExt>(
pub(crate) fn batch_invert_assigned<F: Field>(
assigned: Vec<Polynomial<Assigned<F>, LagrangeCoeff>>,
) -> Vec<Polynomial<F, LagrangeCoeff>> {
let mut assigned_denominators: Vec<_> = assigned
@ -202,9 +201,7 @@ pub(crate) fn batch_invert_assigned<F: FieldExt>(
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<F: Field, B: Basis> Mul<F> for Polynomial<F, B> {
type Output = Polynomial<F, B>;
fn mul(mut self, rhs: F) -> Polynomial<F, B> {
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;
}

View File

@ -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<ScalarExt = Self::Scalar>;
@ -192,20 +192,20 @@ pub trait Verifier<'params, Scheme: CommitmentScheme> {
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct Blind<F>(pub F);
impl<F: FieldExt> Default for Blind<F> {
impl<F: Field> Default for Blind<F> {
fn default() -> Self {
Blind(F::one())
Blind(F::ONE)
}
}
impl<F: FieldExt> Blind<F> {
impl<F: Field> Blind<F> {
/// Given `rng` creates new blinding scalar
pub fn new<R: RngCore>(rng: &mut R) -> Self {
Blind(F::random(rng))
}
}
impl<F: FieldExt> Add for Blind<F> {
impl<F: Field> Add for Blind<F> {
type Output = Self;
fn add(self, rhs: Blind<F>) -> Self {
@ -213,7 +213,7 @@ impl<F: FieldExt> Add for Blind<F> {
}
}
impl<F: FieldExt> Mul for Blind<F> {
impl<F: Field> Mul for Blind<F> {
type Output = Self;
fn mul(self, rhs: Blind<F>) -> Self {
@ -221,25 +221,25 @@ impl<F: FieldExt> Mul for Blind<F> {
}
}
impl<F: FieldExt> AddAssign for Blind<F> {
impl<F: Field> AddAssign for Blind<F> {
fn add_assign(&mut self, rhs: Blind<F>) {
self.0 += rhs.0;
}
}
impl<F: FieldExt> MulAssign for Blind<F> {
impl<F: Field> MulAssign for Blind<F> {
fn mul_assign(&mut self, rhs: Blind<F>) {
self.0 *= rhs.0;
}
}
impl<F: FieldExt> AddAssign<F> for Blind<F> {
impl<F: Field> AddAssign<F> for Blind<F> {
fn add_assign(&mut self, rhs: F) {
self.0 += rhs;
}
}
impl<F: FieldExt> MulAssign<F> for Blind<F> {
impl<F: Field> MulAssign<F> for Blind<F> {
fn mul_assign(&mut self, rhs: F) {
self.0 *= rhs;
}

View File

@ -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<G: Group> {
pub struct EvaluationDomain<F: Field> {
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<G::Scalar>,
barycentric_weight: G::Scalar,
ifft_divisor: F,
extended_ifft_divisor: F,
t_evaluations: Vec<F>,
barycentric_weight: F,
}
impl<G: Group> EvaluationDomain<G> {
impl<F: WithSmallOrderMulGroup<3>> EvaluationDomain<F> {
/// 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<G: Group> EvaluationDomain<G> {
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,14 +81,14 @@ impl<G: Group> EvaluationDomain<G> {
// 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 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 {
@ -99,19 +102,19 @@ impl<G: Group> EvaluationDomain<G> {
// 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<G: Group> EvaluationDomain<G> {
/// 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<G>) -> Polynomial<G, LagrangeCoeff> {
pub fn lagrange_from_vec(&self, values: Vec<F>) -> Polynomial<F, LagrangeCoeff> {
assert_eq!(values.len(), self.n as usize);
Polynomial {
@ -156,7 +159,7 @@ impl<G: Group> EvaluationDomain<G> {
/// 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<G>) -> Polynomial<G, Coeff> {
pub fn coeff_from_vec(&self, values: Vec<F>) -> Polynomial<F, Coeff> {
assert_eq!(values.len(), self.n as usize);
Polynomial {
@ -166,35 +169,32 @@ impl<G: Group> EvaluationDomain<G> {
}
/// Returns an empty (zero) polynomial in the coefficient basis
pub fn empty_coeff(&self) -> Polynomial<G, Coeff> {
pub fn empty_coeff(&self) -> Polynomial<F, Coeff> {
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<G, LagrangeCoeff> {
pub fn empty_lagrange(&self) -> Polynomial<F, LagrangeCoeff> {
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<Assigned<G>, LagrangeCoeff>
where
G: Field,
{
pub(crate) fn empty_lagrange_assigned(&self) -> Polynomial<Assigned<F>, 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<G, LagrangeCoeff> {
pub fn constant_lagrange(&self, scalar: F) -> Polynomial<F, LagrangeCoeff> {
Polynomial {
values: vec![scalar; self.n as usize],
_marker: PhantomData,
@ -203,16 +203,16 @@ impl<G: Group> EvaluationDomain<G> {
/// Returns an empty (zero) polynomial in the extended Lagrange coefficient
/// basis
pub fn empty_extended(&self) -> Polynomial<G, ExtendedLagrangeCoeff> {
pub fn empty_extended(&self) -> Polynomial<F, ExtendedLagrangeCoeff> {
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<G, ExtendedLagrangeCoeff> {
pub fn constant_extended(&self, scalar: F) -> Polynomial<F, ExtendedLagrangeCoeff> {
Polynomial {
values: vec![scalar; self.extended_len()],
_marker: PhantomData,
@ -223,7 +223,7 @@ impl<G: Group> EvaluationDomain<G> {
///
/// This function will panic if the provided vector is not the correct
/// length.
pub fn lagrange_to_coeff(&self, mut a: Polynomial<G, LagrangeCoeff>) -> Polynomial<G, Coeff> {
pub fn lagrange_to_coeff(&self, mut a: Polynomial<F, LagrangeCoeff>) -> Polynomial<F, Coeff> {
assert_eq!(a.values.len(), 1 << self.k);
// Perform inverse FFT to obtain the polynomial in coefficient form
@ -239,12 +239,12 @@ impl<G: Group> EvaluationDomain<G> {
/// evaluation domain, rotating by `rotation` if desired.
pub fn coeff_to_extended(
&self,
mut a: Polynomial<G, Coeff>,
) -> Polynomial<G, ExtendedLagrangeCoeff> {
mut a: Polynomial<F, Coeff>,
) -> Polynomial<F, ExtendedLagrangeCoeff> {
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 {
@ -256,9 +256,9 @@ impl<G: Group> EvaluationDomain<G> {
/// Rotate the extended domain polynomial over the original domain.
pub fn rotate_extended(
&self,
poly: &Polynomial<G, ExtendedLagrangeCoeff>,
poly: &Polynomial<F, ExtendedLagrangeCoeff>,
rotation: Rotation,
) -> Polynomial<G, ExtendedLagrangeCoeff> {
) -> Polynomial<F, ExtendedLagrangeCoeff> {
let new_rotation = ((1 << (self.extended_k - self.k)) * rotation.0.abs()) as usize;
let mut poly = poly.clone();
@ -278,7 +278,7 @@ impl<G: Group> EvaluationDomain<G> {
/// 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<G, ExtendedLagrangeCoeff>) -> Vec<G> {
pub fn extended_to_coeff(&self, mut a: Polynomial<F, ExtendedLagrangeCoeff>) -> Vec<F> {
assert_eq!(a.values.len(), self.extended_len());
// Inverse FFT
@ -306,15 +306,15 @@ impl<G: Group> EvaluationDomain<G> {
/// polynomial of the $2^k$ size domain.
pub fn divide_by_vanishing_poly(
&self,
mut a: Polynomial<G, ExtendedLagrangeCoeff>,
) -> Polynomial<G, ExtendedLagrangeCoeff> {
mut a: Polynomial<F, ExtendedLagrangeCoeff>,
) -> Polynomial<F, ExtendedLagrangeCoeff> {
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;
}
});
@ -332,7 +332,7 @@ impl<G: Group> EvaluationDomain<G> {
///
/// `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 {
@ -343,19 +343,19 @@ impl<G: Group> EvaluationDomain<G> {
// 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;
}
});
}
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;
}
});
}
@ -376,24 +376,24 @@ impl<G: Group> EvaluationDomain<G> {
}
/// 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]);
@ -434,23 +434,23 @@ impl<G: Group> EvaluationDomain<G> {
/// which is the barycentric weight of $\omega^i$.
pub fn l_i_range<I: IntoIterator<Item = i32> + Clone>(
&self,
x: G::Scalar,
xn: G::Scalar,
x: F,
xn: F,
rotations: I,
) -> Vec<G::Scalar> {
) -> Vec<F> {
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);
@ -467,7 +467,7 @@ impl<G: Group> EvaluationDomain<G> {
/// 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,
@ -479,10 +479,10 @@ impl<G: Group> EvaluationDomain<G> {
/// 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]
@ -541,7 +541,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);
}

View File

@ -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<E, F: Field, B: Basis> Evaluator<E, F, B> {
) -> Polynomial<F, B>
where
E: Copy + Send + Sync,
F: FieldExt,
F: Field,
B: BasisOps,
{
// Traverse `ast` to collect the used leaves.
@ -192,7 +192,7 @@ impl<E, F: Field, B: Basis> Evaluator<E, F, B> {
})
.collect();
struct AstContext<'a, E, F: FieldExt, B: Basis> {
struct AstContext<'a, E, F: Field, B: Basis> {
domain: &'a EvaluationDomain<F>,
poly_len: usize,
chunk_size: usize,
@ -200,7 +200,7 @@ impl<E, F: Field, B: Basis> Evaluator<E, F, B> {
leaves: &'a HashMap<AstLeaf<E, B>, &'a [F]>,
}
fn recurse<E, F: FieldExt, B: BasisOps>(
fn recurse<E, F: Field, B: BasisOps>(
ast: &Ast<E, F, B>,
ctx: &AstContext<'_, E, F, B>,
) -> Vec<F> {
@ -230,7 +230,7 @@ impl<E, F: Field, B: Basis> Evaluator<E, F, B> {
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<E, F: Field, B: Basis> From<AstLeaf<E, B>> for Ast<E, F, B> {
impl<E, F: Field, B: Basis> Ast<E, F, B> {
pub(crate) fn one() -> Self {
Self::ConstantTerm(F::one())
Self::ConstantTerm(F::ONE)
}
}
@ -355,7 +355,7 @@ impl<E, F: Field, B: Basis> Neg for Ast<E, F, B> {
type Output = Ast<E, F, B>;
fn neg(self) -> Self::Output {
Ast::Scale(Arc::new(self), -F::one())
Ast::Scale(Arc::new(self), -F::ONE)
}
}
@ -489,21 +489,21 @@ impl<E: Clone, F: Field> MulAssign for Ast<E, F, ExtendedLagrangeCoeff> {
/// Operations which can be performed over a given basis.
pub(crate) trait BasisOps: Basis {
fn empty_poly<F: FieldExt>(domain: &EvaluationDomain<F>) -> Polynomial<F, Self>;
fn constant_term<F: FieldExt>(
fn empty_poly<F: Field>(domain: &EvaluationDomain<F>) -> Polynomial<F, Self>;
fn constant_term<F: Field>(
poly_len: usize,
chunk_size: usize,
chunk_index: usize,
scalar: F,
) -> Vec<F>;
fn linear_term<F: FieldExt>(
fn linear_term<F: Field>(
domain: &EvaluationDomain<F>,
poly_len: usize,
chunk_size: usize,
chunk_index: usize,
scalar: F,
) -> Vec<F>;
fn rotate<F: FieldExt>(
fn rotate<F: Field>(
domain: &EvaluationDomain<F>,
poly: &Polynomial<F, Self>,
rotation: Rotation,
@ -511,31 +511,31 @@ pub(crate) trait BasisOps: Basis {
}
impl BasisOps for Coeff {
fn empty_poly<F: FieldExt>(domain: &EvaluationDomain<F>) -> Polynomial<F, Self> {
fn empty_poly<F: Field>(domain: &EvaluationDomain<F>) -> Polynomial<F, Self> {
domain.empty_coeff()
}
fn constant_term<F: FieldExt>(
fn constant_term<F: Field>(
poly_len: usize,
chunk_size: usize,
chunk_index: usize,
scalar: F,
) -> Vec<F> {
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<F: FieldExt>(
fn linear_term<F: Field>(
_: &EvaluationDomain<F>,
poly_len: usize,
chunk_size: usize,
chunk_index: usize,
scalar: F,
) -> Vec<F> {
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<F: FieldExt>(
fn rotate<F: Field>(
_: &EvaluationDomain<F>,
_: &Polynomial<F, Self>,
_: Rotation,
@ -560,11 +560,11 @@ impl BasisOps for Coeff {
}
impl BasisOps for LagrangeCoeff {
fn empty_poly<F: FieldExt>(domain: &EvaluationDomain<F>) -> Polynomial<F, Self> {
fn empty_poly<F: Field>(domain: &EvaluationDomain<F>) -> Polynomial<F, Self> {
domain.empty_lagrange()
}
fn constant_term<F: FieldExt>(
fn constant_term<F: Field>(
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<F: FieldExt>(
fn linear_term<F: Field>(
domain: &EvaluationDomain<F>,
poly_len: usize,
chunk_size: usize,
@ -592,7 +592,7 @@ impl BasisOps for LagrangeCoeff {
.collect()
}
fn rotate<F: FieldExt>(
fn rotate<F: Field>(
_: &EvaluationDomain<F>,
poly: &Polynomial<F, Self>,
rotation: Rotation,
@ -602,11 +602,11 @@ impl BasisOps for LagrangeCoeff {
}
impl BasisOps for ExtendedLagrangeCoeff {
fn empty_poly<F: FieldExt>(domain: &EvaluationDomain<F>) -> Polynomial<F, Self> {
fn empty_poly<F: Field>(domain: &EvaluationDomain<F>) -> Polynomial<F, Self> {
domain.empty_extended()
}
fn constant_term<F: FieldExt>(
fn constant_term<F: Field>(
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<F: FieldExt>(
fn linear_term<F: Field>(
domain: &EvaluationDomain<F>,
poly_len: usize,
chunk_size: usize,
@ -637,7 +637,7 @@ impl BasisOps for ExtendedLagrangeCoeff {
.collect()
}
fn rotate<F: FieldExt>(
fn rotate<F: Field>(
domain: &EvaluationDomain<F>,
poly: &Polynomial<F, Self>,
rotation: Rotation,

View File

@ -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<C> {
#[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(&params);
commitment_msm.append_term(Field::one(), p.into());
commitment_msm.append_term(Fq::one(), p.into());
let guard = verify_proof(&params, commitment_msm, &mut transcript, *x, v).unwrap();
let ch_verifier = transcript.squeeze_challenge();

View File

@ -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;

View File

@ -96,10 +96,10 @@ pub fn verify_proof<'params, C: CurveAffine, E: EncodedChallenge<C>, T: Transcri
/// Computes $\prod\limits_{i=0}^{k-1} (1 + u_{k - 1 - i} x^{2^i})$.
fn compute_b<F: Field>(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

View File

@ -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);
}

View File

@ -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<F, Q> = (
Vec<Vec<F>>,
);
fn construct_intermediate_sets<F: FieldExt, I, Q: Query<F>>(queries: I) -> IntermediateSets<F, Q>
fn construct_intermediate_sets<F: Field + Ord, I, Q: Query<F>>(queries: I) -> IntermediateSets<F, Q>
where
I: IntoIterator<Item = Q> + Clone,
{

View File

@ -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<C>> for Prover
// Collapse openings at same point sets together into single openings using
// x_1 challenge.
let mut q_polys: Vec<Option<Polynomial<C::Scalar, Coeff>>> = 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<C>> 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,

View File

@ -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<C>>
// 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<C>>
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<C>>
.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<C>>
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)| {

View File

@ -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<F: Field>(u: &[F], init: F) -> Vec<F> {
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)) {

View File

@ -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<E: Engine> {
impl<E: Engine + Debug> CommitmentScheme for KZGCommitmentScheme<E>
where
E::Scalar: PrimeField,
E::G1Affine: SerdeCurveAffine,
E::G2Affine: SerdeCurveAffine,
{
@ -55,7 +56,10 @@ where
}
}
impl<E: Engine + Debug> ParamsKZG<E> {
impl<E: Engine + Debug> ParamsKZG<E>
where
E::Scalar: PrimeField,
{
/// Initializes parameters for the curve, draws toxic secret from given rng.
/// MUST NOT be used in production.
pub fn setup<R: RngCore>(k: u32, rng: R) -> Self {
@ -68,7 +72,7 @@ impl<E: Engine + Debug> ParamsKZG<E> {
let g1 = E::G1Affine::generator();
let s = <E::Scalar>::random(rng);
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]);
@ -86,14 +90,14 @@ impl<E: Engine + Debug> ParamsKZG<E> {
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::<E::Scalar>::from(E::Scalar::from(n).invert())
.expect("inversion should be ok for n = 1<<k");
let multiplier = (s.pow_vartime(&[n as u64]) - E::Scalar::one()) * n_inv;
let multiplier = (s.pow_vartime(&[n as u64]) - E::Scalar::ONE) * n_inv;
parallelize(&mut g_lagrange_projective, |g, start| {
for (idx, g) in g.iter_mut().enumerate() {
let offset = start + idx;
@ -251,6 +255,7 @@ pub type ParamsVerifierKZG<C> = ParamsKZG<C>;
impl<'params, E: Engine + Debug> Params<'params, E::G1Affine> for ParamsKZG<E>
where
E::Scalar: PrimeField,
E::G1Affine: SerdeCurveAffine,
E::G2Affine: SerdeCurveAffine,
{
@ -304,6 +309,7 @@ where
impl<'params, E: Engine + Debug> ParamsVerifier<'params, E::G1Affine> for ParamsKZG<E>
where
E::Scalar: PrimeField,
E::G1Affine: SerdeCurveAffine,
E::G2Affine: SerdeCurveAffine,
{
@ -311,6 +317,7 @@ where
impl<'params, E: Engine + Debug> ParamsProver<'params, E::G1Affine> for ParamsKZG<E>
where
E::Scalar: PrimeField,
E::G1Affine: SerdeCurveAffine,
E::G2Affine: SerdeCurveAffine,
{
@ -340,9 +347,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};
@ -351,7 +356,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};
@ -391,7 +396,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;

View File

@ -27,7 +27,7 @@ impl<E: Engine> MSMKZG<E> {
/// 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;

View File

@ -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<F> = ChallengeScalar<F, U>;
struct V {}
type ChallengeV<F> = ChallengeScalar<F, V>;
struct CommitmentData<F: FieldExt, Q: Query<F>> {
struct CommitmentData<F: Field, Q: Query<F>> {
queries: Vec<Q>,
point: F,
_marker: PhantomData<F>,
}
fn construct_intermediate_sets<F: FieldExt, I, Q: Query<F>>(queries: I) -> Vec<CommitmentData<F, Q>>
fn construct_intermediate_sets<F: Field, I, Q: Query<F>>(queries: I) -> Vec<CommitmentData<F, Q>>
where
I: IntoIterator<Item = Q> + Clone,
{

View File

@ -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<E>> for ProverGWC<'params, E>
where
E::Scalar: PrimeField,
E::G1Affine: SerdeCurveAffine,
E::G2Affine: SerdeCurveAffine,
{

View File

@ -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<E>> 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::<E>::new();
let mut eval_multi = E::Scalar::zero();
let mut eval_multi = E::Scalar::ZERO;
let mut witness = MSMKZG::<E>::new();
let mut witness_with_aux = MSMKZG::<E>::new();

View File

@ -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<F> = ChallengeScalar<F, Y>;
#[derive(Debug, Clone, PartialEq)]
struct Commitment<F: FieldExt, T: PartialEq + Clone>((T, Vec<F>));
struct Commitment<F: Field, T: PartialEq + Clone>((T, Vec<F>));
impl<F: FieldExt, T: PartialEq + Clone> Commitment<F, T> {
impl<F: Field, T: PartialEq + Clone> Commitment<F, T> {
fn get(&self) -> T {
self.0 .0.clone()
}
@ -42,18 +42,18 @@ impl<F: FieldExt, T: PartialEq + Clone> Commitment<F, T> {
}
#[derive(Debug, Clone, PartialEq)]
struct RotationSet<F: FieldExt, T: PartialEq + Clone> {
struct RotationSet<F: Field, T: PartialEq + Clone> {
commitments: Vec<Commitment<F, T>>,
points: Vec<F>,
}
#[derive(Debug, PartialEq)]
struct IntermediateSets<F: FieldExt, Q: Query<F>> {
struct IntermediateSets<F: Field, Q: Query<F>> {
rotation_sets: Vec<RotationSet<F, Q::Commitment>>,
super_point_set: BTreeSet<F>,
}
fn construct_intermediate_sets<F: FieldExt, I, Q: Query<F, Eval = F>>(
fn construct_intermediate_sets<F: Field + Ord, I, Q: Query<F, Eval = F>>(
queries: I,
) -> IntermediateSets<F, Q>
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::<u8>(), 64)
) -> Fp {
Fp::from_bytes_wide(&<[u8; 64]>::try_from(bytes).unwrap())
Fp::from_uniform_bytes(&<[u8; 64]>::try_from(bytes).unwrap())
}
}

View File

@ -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<F: FieldExt>(poly: Polynomial<F, Coeff>, roots: &[F]) -> Vec<F> {
fn div_by_vanishing<F: Field>(poly: Polynomial<F, Coeff>, roots: &[F]) -> Vec<F> {
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<E>>
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]);

View File

@ -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<E>> 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::<E>::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::<E>::new(), E::Scalar::ZERO);
for (i, (rotation_set, power_of_v)) in rotation_sets.iter().zip(powers(*v)).enumerate() {
let diffs: Vec<E::Scalar> = 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);

View File

@ -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<KZGCommitmentScheme<E>> 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<E>, V> for AccumulatorStrategy<'params, E>
where
E::Scalar: PrimeField,
E::G1Affine: SerdeCurveAffine,
E::G2Affine: SerdeCurveAffine,
{
@ -130,6 +132,7 @@ impl<
>,
> VerificationStrategy<'params, KZGCommitmentScheme<E>, V> for SingleStrategy<'params, E>
where
E::Scalar: PrimeField,
E::G1Affine: SerdeCurveAffine,
E::G2Affine: SerdeCurveAffine,
{

View File

@ -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<Vec<u8>, Scheme::Curve, E>,
>(
params: &'params Scheme::ParamsProver,
) -> Vec<u8> {
) -> Vec<u8>
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 = <<Scheme as CommitmentScheme>::Curve as CurveAffine>::ScalarExt::from(
10 + i as u64,
);
*a = <<Scheme as CommitmentScheme>::Scalar>::from(10 + i as u64);
}
let mut bx = domain.empty_coeff();
for (i, a) in bx.iter_mut().enumerate() {
*a = <<Scheme as CommitmentScheme>::Curve as CurveAffine>::ScalarExt::from(
100 + i as u64,
);
*a = <<Scheme as CommitmentScheme>::Scalar>::from(100 + i as u64);
}
let mut cx = domain.empty_coeff();
for (i, a) in cx.iter_mut().enumerate() {
*a = <<Scheme as CommitmentScheme>::Curve as CurveAffine>::ScalarExt::from(
100 + i as u64,
);
*a = <<Scheme as CommitmentScheme>::Scalar>::from(100 + i as u64);
}
let mut transcript = T::init(vec![]);

View File

@ -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;
@ -116,6 +116,8 @@ pub struct Keccak256Read<R: Read, C: CurveAffine, E: EncodedChallenge<C>> {
impl<R: Read, C: CurveAffine> TranscriptReadBuffer<R, C, Challenge255<C>>
for Blake2bRead<R, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
/// Initialize a transcript given an input buffer.
fn init(reader: R) -> Self {
@ -132,6 +134,8 @@ impl<R: Read, C: CurveAffine> TranscriptReadBuffer<R, C, Challenge255<C>>
impl<R: Read, C: CurveAffine> TranscriptReadBuffer<R, C, Challenge255<C>>
for Keccak256Read<R, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
/// Initialize a transcript given an input buffer.
fn init(reader: R) -> Self {
@ -147,6 +151,8 @@ impl<R: Read, C: CurveAffine> TranscriptReadBuffer<R, C, Challenge255<C>>
impl<R: Read, C: CurveAffine> TranscriptRead<C, Challenge255<C>>
for Blake2bRead<R, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn read_point(&mut self) -> io::Result<C> {
let mut compressed = C::Repr::default();
@ -176,6 +182,8 @@ impl<R: Read, C: CurveAffine> TranscriptRead<C, Challenge255<C>>
impl<R: Read, C: CurveAffine> TranscriptRead<C, Challenge255<C>>
for Keccak256Read<R, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn read_point(&mut self) -> io::Result<C> {
let mut compressed = C::Repr::default();
@ -203,8 +211,9 @@ impl<R: Read, C: CurveAffine> TranscriptRead<C, Challenge255<C>>
}
}
impl<R: Read, C: CurveAffine> Transcript<C, Challenge255<C>>
for Blake2bRead<R, C, Challenge255<C>>
impl<R: Read, C: CurveAffine> Transcript<C, Challenge255<C>> for Blake2bRead<R, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn squeeze_challenge(&mut self) -> Challenge255<C> {
self.state.update(&[BLAKE2B_PREFIX_CHALLENGE]);
@ -237,6 +246,8 @@ impl<R: Read, C: CurveAffine> Transcript<C, Challenge255<C>>
impl<R: Read, C: CurveAffine> Transcript<C, Challenge255<C>>
for Keccak256Read<R, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn squeeze_challenge(&mut self) -> Challenge255<C> {
self.state.update(&[KECCAK256_PREFIX_CHALLENGE]);
@ -295,6 +306,8 @@ pub struct Keccak256Write<W: Write, C: CurveAffine, E: EncodedChallenge<C>> {
impl<W: Write, C: CurveAffine> TranscriptWriterBuffer<W, C, Challenge255<C>>
for Blake2bWrite<W, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
/// Initialize a transcript given an output buffer.
fn init(writer: W) -> Self {
@ -316,6 +329,8 @@ impl<W: Write, C: CurveAffine> TranscriptWriterBuffer<W, C, Challenge255<C>>
impl<W: Write, C: CurveAffine> TranscriptWriterBuffer<W, C, Challenge255<C>>
for Keccak256Write<W, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
/// Initialize a transcript given an output buffer.
fn init(writer: W) -> Self {
@ -337,6 +352,8 @@ impl<W: Write, C: CurveAffine> TranscriptWriterBuffer<W, C, Challenge255<C>>
impl<W: Write, C: CurveAffine> TranscriptWrite<C, Challenge255<C>>
for Blake2bWrite<W, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn write_point(&mut self, point: C) -> io::Result<()> {
self.common_point(point)?;
@ -352,6 +369,8 @@ impl<W: Write, C: CurveAffine> TranscriptWrite<C, Challenge255<C>>
impl<W: Write, C: CurveAffine> TranscriptWrite<C, Challenge255<C>>
for Keccak256Write<W, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn write_point(&mut self, point: C) -> io::Result<()> {
self.common_point(point)?;
@ -367,6 +386,8 @@ impl<W: Write, C: CurveAffine> TranscriptWrite<C, Challenge255<C>>
impl<W: Write, C: CurveAffine> Transcript<C, Challenge255<C>>
for Blake2bWrite<W, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn squeeze_challenge(&mut self) -> Challenge255<C> {
self.state.update(&[BLAKE2B_PREFIX_CHALLENGE]);
@ -399,6 +420,8 @@ impl<W: Write, C: CurveAffine> Transcript<C, Challenge255<C>>
impl<W: Write, C: CurveAffine> Transcript<C, Challenge255<C>>
for Keccak256Write<W, C, Challenge255<C>>
where
C::Scalar: FromUniformBytes<64>,
{
fn squeeze_challenge(&mut self) -> Challenge255<C> {
self.state.update(&[KECCAK256_PREFIX_CHALLENGE]);
@ -493,12 +516,15 @@ impl<C: CurveAffine> std::ops::Deref for Challenge255<C> {
}
}
impl<C: CurveAffine> EncodedChallenge<C> for Challenge255<C> {
impl<C: CurveAffine> EncodedChallenge<C> for Challenge255<C>
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()

View File

@ -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, SimpleFloorPlanner, Value};
use halo2_proofs::dev::MockProver;
use halo2_proofs::plonk::{
@ -45,7 +46,7 @@ fn plonk_api() {
}
#[allow(clippy::type_complexity)]
trait StandardCs<FF: FieldExt> {
trait StandardCs<FF: Field> {
fn raw_multiply<F>(
&self,
layouter: &mut impl Layouter<FF>,
@ -72,17 +73,17 @@ fn plonk_api() {
}
#[derive(Clone)]
struct MyCircuit<F: FieldExt> {
struct MyCircuit<F: Field> {
a: Value<F>,
lookup_table: Vec<F>,
}
struct StandardPlonk<F: FieldExt> {
struct StandardPlonk<F: Field> {
config: PlonkConfig,
_marker: PhantomData<F>,
}
impl<FF: FieldExt> StandardPlonk<FF> {
impl<FF: Field> StandardPlonk<FF> {
fn new(config: PlonkConfig) -> Self {
StandardPlonk {
config,
@ -91,7 +92,7 @@ fn plonk_api() {
}
}
impl<FF: FieldExt> StandardCs<FF> for StandardPlonk<FF> {
impl<FF: Field> StandardCs<FF> for StandardPlonk<FF> {
fn raw_multiply<F>(
&self,
layouter: &mut impl Layouter<FF>,
@ -138,15 +139,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()))
},
)
@ -197,14 +193,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()))
},
@ -236,7 +232,7 @@ fn plonk_api() {
|| "public",
self.config.sp,
0,
|| Value::known(FF::one()),
|| Value::known(FF::ONE),
)?;
Ok(value.cell())
@ -266,7 +262,7 @@ fn plonk_api() {
}
}
impl<F: FieldExt> Circuit<F> for MyCircuit<F> {
impl<F: Field> Circuit<F> for MyCircuit<F> {
type Config = PlonkConfig;
type FloorPlanner = SimpleFloorPlanner;
@ -374,7 +370,7 @@ fn plonk_api() {
) -> Result<(), Error> {
let cs = StandardPlonk::new(config);
let _ = cs.public_input(&mut layouter, || Value::known(F::one() + F::one()))?;
let _ = cs.public_input(&mut layouter, || Value::known(F::ONE + F::ONE))?;
for _ in 0..10 {
let a: Value<Assigned<_>> = self.a.into();
@ -403,14 +399,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)
}};
}
@ -445,9 +436,10 @@ fn plonk_api() {
}};
}
fn keygen<Scheme: CommitmentScheme>(
params: &Scheme::ParamsProver,
) -> ProvingKey<Scheme::Curve> {
fn keygen<Scheme: CommitmentScheme>(params: &Scheme::ParamsProver) -> ProvingKey<Scheme::Curve>
where
Scheme::Scalar: FromUniformBytes<64> + WithSmallOrderMulGroup<3>,
{
let (_, _, lookup_table) = common!(Scheme);
let empty_circuit: MyCircuit<Scheme::Scalar> = MyCircuit {
a: Value::unknown(),
@ -471,7 +463,10 @@ fn plonk_api() {
rng: R,
params: &'params Scheme::ParamsProver,
pk: &ProvingKey<Scheme::Curve>,
) -> Vec<u8> {
) -> Vec<u8>
where
Scheme::Scalar: Ord + WithSmallOrderMulGroup<3> + FromUniformBytes<64>,
{
let (a, instance, lookup_table) = common!(Scheme);
let circuit: MyCircuit<Scheme::Scalar> = MyCircuit {
@ -513,7 +508,9 @@ fn plonk_api() {
params_verifier: &'params Scheme::ParamsVerifier,
vk: &VerifyingKey<Scheme::Curve>,
proof: &'a [u8],
) {
) where
Scheme::Scalar: Ord + WithSmallOrderMulGroup<3> + FromUniformBytes<64>,
{
let (_, instance, _) = common!(Scheme);
let pubinputs = vec![instance];