mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 23:03:08 +00:00
Refactor GMiMC code (#224)
* Refactor GMiMC code Adds a sub-trait of `Field` called `GMiMCInterface`, which is similar to `PoseidonInterface`. This lets us have different fields with different GMiMC constants in a type-safe way. * Remove `Interface` * Const generic for width
This commit is contained in:
parent
a2eaaceb34
commit
3bc34c59d8
@ -4,8 +4,7 @@ use std::time::Instant;
|
||||
|
||||
use plonky2::field::crandall_field::CrandallField;
|
||||
use plonky2::field::field_types::Field;
|
||||
use plonky2::hash::gmimc::gmimc_permute_array;
|
||||
use plonky2::hash::hashing::{GMIMC_CONSTANTS, GMIMC_ROUNDS};
|
||||
use plonky2::hash::gmimc::GMiMC;
|
||||
|
||||
type F = CrandallField;
|
||||
|
||||
@ -26,7 +25,7 @@ fn main() {
|
||||
let hashes_per_thread = HASHES_PER_POLY * PROVER_POLYS / THREADS;
|
||||
let start = Instant::now();
|
||||
for _ in 0..hashes_per_thread {
|
||||
x = gmimc_permute_array::<_, W, GMIMC_ROUNDS>(x, GMIMC_CONSTANTS);
|
||||
x = F::gmimc_permute(x);
|
||||
}
|
||||
let duration = start.elapsed();
|
||||
println!("took {:?}", duration);
|
||||
|
||||
@ -2,14 +2,16 @@ use std::time::Instant;
|
||||
|
||||
use plonky2::field::crandall_field::CrandallField as F;
|
||||
use plonky2::field::field_types::Field;
|
||||
use plonky2::hash::gmimc::gmimc_permute_array;
|
||||
use plonky2::hash::hashing::{GMIMC_CONSTANTS, GMIMC_ROUNDS};
|
||||
use plonky2::hash::poseidon::PoseidonInterface;
|
||||
use plonky2::hash::gmimc::GMiMC;
|
||||
use plonky2::hash::poseidon::Poseidon;
|
||||
use plonky2::hash::rescue::rescue;
|
||||
|
||||
#[inline]
|
||||
fn gmimc_hash<const W: usize>(x: [F; W]) -> [F; W] {
|
||||
gmimc_permute_array::<_, W, GMIMC_ROUNDS>(x, GMIMC_CONSTANTS)
|
||||
fn gmimc_hash<const W: usize>(x: [F; W]) -> [F; W]
|
||||
where
|
||||
F: GMiMC<W>,
|
||||
{
|
||||
F::gmimc_permute(x)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -70,7 +72,7 @@ fn bench_hash<const W: usize>(name: &str, hash: fn([F; W]) -> [F; W], gmimc_tm:
|
||||
fn main() {
|
||||
println!(" -- Width 8 (time μs, slowdown wrt GMiMC)--");
|
||||
let mut tm: f64 = 0.0;
|
||||
bench_hash("GMiMC", gmimc_hash::<8>, &mut tm);
|
||||
// bench_hash("GMiMC", gmimc_hash::<8>, &mut tm); // Not implemented yet.
|
||||
bench_hash("Poseidon", poseidon8_hash, &mut tm);
|
||||
bench_hash("Poseidon naive", poseidon8_naive_hash, &mut tm);
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ use env_logger::Env;
|
||||
use log::info;
|
||||
use plonky2::field::crandall_field::CrandallField;
|
||||
use plonky2::field::extension_field::Extendable;
|
||||
use plonky2::field::field_types::PrimeField;
|
||||
use plonky2::field::field_types::RichField;
|
||||
use plonky2::fri::FriConfig;
|
||||
use plonky2::iop::witness::PartialWitness;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -19,7 +19,7 @@ fn main() -> Result<()> {
|
||||
bench_prove::<CrandallField, 4>()
|
||||
}
|
||||
|
||||
fn bench_prove<F: PrimeField + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
fn bench_prove<F: RichField + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
let config = CircuitConfig {
|
||||
num_wires: 126,
|
||||
num_routed_wires: 33,
|
||||
|
||||
@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::field::extension_field::quadratic::QuadraticCrandallField;
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::field::extension_field::{Extendable, Frobenius};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, PrimeField, RichField};
|
||||
|
||||
/// EPSILON = 9 * 2**28 - 1
|
||||
const EPSILON: u64 = 2415919103;
|
||||
@ -458,7 +458,9 @@ impl Extendable<4> for CrandallField {
|
||||
type Extension = QuarticCrandallField;
|
||||
}
|
||||
|
||||
/// Faster addition for when we know that lhs.0 + rhs.0 < 2^64 + Self::ORDER. If this is the case,
|
||||
impl RichField for CrandallField {}
|
||||
|
||||
/// Faster addition for when we know that lhs.0 + rhs.0 < 2^64 + FIELD_ORDER. If this is the case,
|
||||
/// then the .to_canonical_u64() that addition usually performs is unnecessary. Omitting it saves
|
||||
/// three instructions.
|
||||
/// This function is marked unsafe because it may yield incorrect result if the condition is not
|
||||
|
||||
@ -3,7 +3,7 @@ use std::ops::Range;
|
||||
|
||||
use crate::field::extension_field::algebra::ExtensionAlgebra;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension, OEF};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
@ -16,14 +16,14 @@ impl<const D: usize> ExtensionTarget<D> {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn frobenius<F: PrimeField + Extendable<D>>(
|
||||
pub fn frobenius<F: RichField + Extendable<D>>(
|
||||
&self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> Self {
|
||||
self.repeated_frobenius(1, builder)
|
||||
}
|
||||
|
||||
pub fn repeated_frobenius<F: PrimeField + Extendable<D>>(
|
||||
pub fn repeated_frobenius<F: RichField + Extendable<D>>(
|
||||
&self,
|
||||
count: usize,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
@ -74,7 +74,7 @@ impl<const D: usize> ExtensionAlgebraTarget<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn constant_extension(&mut self, c: F::Extension) -> ExtensionTarget<D> {
|
||||
let c_parts = c.to_basefield_array();
|
||||
let mut parts = [self.zero(); D];
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use crate::field::field_types::PrimeField;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! test_field_arithmetic {
|
||||
($field:ty) => {
|
||||
|
||||
@ -11,8 +11,12 @@ use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::field::extension_field::Frobenius;
|
||||
use crate::hash::gmimc::GMiMC;
|
||||
use crate::util::bits_u64;
|
||||
|
||||
/// A prime order field with the features we need to use it as a base field in our argument system.
|
||||
pub trait RichField: PrimeField + GMiMC<12> {}
|
||||
|
||||
/// A finite field.
|
||||
pub trait Field:
|
||||
'static
|
||||
@ -309,6 +313,10 @@ pub trait Field:
|
||||
Self::rand_from_rng(&mut rand::thread_rng())
|
||||
}
|
||||
|
||||
fn rand_arr<const N: usize>() -> [Self; N] {
|
||||
Self::rand_vec(N).try_into().unwrap()
|
||||
}
|
||||
|
||||
fn rand_vec(n: usize) -> Vec<Self> {
|
||||
(0..n).map(|_| Self::rand()).collect()
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use rayon::prelude::*;
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::fft::DEFAULT_STRATEGY;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::fri::proof::FriProof;
|
||||
use crate::fri::prover::fri_proof;
|
||||
use crate::hash::merkle_tree::MerkleTree;
|
||||
@ -20,7 +20,7 @@ use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place, transp
|
||||
pub const SALT_SIZE: usize = 2;
|
||||
|
||||
/// Represents a batch FRI based commitment to a list of polynomials.
|
||||
pub struct PolynomialBatchCommitment<F: PrimeField> {
|
||||
pub struct PolynomialBatchCommitment<F: RichField> {
|
||||
pub polynomials: Vec<PolynomialCoeffs<F>>,
|
||||
pub merkle_tree: MerkleTree<F>,
|
||||
pub degree_log: usize,
|
||||
@ -28,7 +28,7 @@ pub struct PolynomialBatchCommitment<F: PrimeField> {
|
||||
pub blinding: bool,
|
||||
}
|
||||
|
||||
impl<F: PrimeField> PolynomialBatchCommitment<F> {
|
||||
impl<F: RichField> PolynomialBatchCommitment<F> {
|
||||
/// Creates a list polynomial commitment for the polynomials interpolating the values in `values`.
|
||||
pub(crate) fn from_values(
|
||||
values: Vec<PolynomialValues<F>>,
|
||||
@ -125,7 +125,7 @@ impl<F: PrimeField> PolynomialBatchCommitment<F> {
|
||||
timing: &mut TimingTree,
|
||||
) -> (FriProof<F, D>, OpeningSet<F, D>)
|
||||
where
|
||||
F: PrimeField + Extendable<D>,
|
||||
F: RichField + Extendable<D>,
|
||||
{
|
||||
let config = &common_data.config;
|
||||
assert!(D > 1, "Not implemented for D=1.");
|
||||
@ -280,7 +280,7 @@ mod tests {
|
||||
point
|
||||
}
|
||||
|
||||
fn check_batch_polynomial_commitment<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn check_batch_polynomial_commitment<F: RichField + Extendable<D>, const D: usize>(
|
||||
) -> Result<()> {
|
||||
let ks = [10, 2, 10, 8];
|
||||
let degree_bits = 11;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use rayon::prelude::*;
|
||||
|
||||
use crate::field::extension_field::{flatten, unflatten, Extendable};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::fri::proof::{FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep};
|
||||
use crate::fri::FriConfig;
|
||||
use crate::hash::hash_types::HashOut;
|
||||
@ -16,7 +16,7 @@ use crate::util::reverse_index_bits_in_place;
|
||||
use crate::util::timing::TimingTree;
|
||||
|
||||
/// Builds a FRI proof.
|
||||
pub fn fri_proof<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub fn fri_proof<F: RichField + Extendable<D>, const D: usize>(
|
||||
initial_merkle_trees: &[&MerkleTree<F>],
|
||||
// Coefficients of the polynomial on which the LDT is performed. Only the first `1/rate` coefficients are non-zero.
|
||||
lde_polynomial_coeffs: PolynomialCoeffs<F::Extension>,
|
||||
@ -66,7 +66,7 @@ pub fn fri_proof<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
}
|
||||
}
|
||||
|
||||
fn fri_committed_trees<F: Field + Extendable<D>, const D: usize>(
|
||||
fn fri_committed_trees<F: RichField + Extendable<D>, const D: usize>(
|
||||
mut coeffs: PolynomialCoeffs<F::Extension>,
|
||||
mut values: PolynomialValues<F::Extension>,
|
||||
challenger: &mut Challenger<F>,
|
||||
@ -110,7 +110,7 @@ fn fri_committed_trees<F: Field + Extendable<D>, const D: usize>(
|
||||
(trees, coeffs)
|
||||
}
|
||||
|
||||
fn fri_proof_of_work<F: PrimeField>(current_hash: HashOut<F>, config: &FriConfig) -> F {
|
||||
fn fri_proof_of_work<F: RichField>(current_hash: HashOut<F>, config: &FriConfig) -> F {
|
||||
(0..=F::NEG_ONE.to_canonical_u64())
|
||||
.into_par_iter()
|
||||
.find_any(|&i| {
|
||||
@ -131,7 +131,7 @@ fn fri_proof_of_work<F: PrimeField>(current_hash: HashOut<F>, config: &FriConfig
|
||||
.expect("Proof of work failed. This is highly unlikely!")
|
||||
}
|
||||
|
||||
fn fri_prover_query_rounds<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn fri_prover_query_rounds<F: RichField + Extendable<D>, const D: usize>(
|
||||
initial_merkle_trees: &[&MerkleTree<F>],
|
||||
trees: &[MerkleTree<F>],
|
||||
challenger: &mut Challenger<F>,
|
||||
@ -143,7 +143,7 @@ fn fri_prover_query_rounds<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn fri_prover_query_round<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn fri_prover_query_round<F: RichField + Extendable<D>, const D: usize>(
|
||||
initial_merkle_trees: &[&MerkleTree<F>],
|
||||
trees: &[MerkleTree<F>],
|
||||
challenger: &mut Challenger<F>,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::field::extension_field::target::{flatten_target, ExtensionTarget};
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::fri::proof::{FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget};
|
||||
use crate::fri::FriConfig;
|
||||
use crate::hash::hash_types::MerkleCapTarget;
|
||||
@ -14,7 +14,7 @@ use crate::util::reducing::ReducingFactorTarget;
|
||||
use crate::util::{log2_strict, reverse_index_bits_in_place};
|
||||
use crate::with_context;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Computes P'(x^arity) from {P(x*g^i)}_(i=0..arity), where g is a `arity`-th root of unity
|
||||
/// and P' is the FRI reduced polynomial.
|
||||
fn compute_evaluation(
|
||||
@ -394,7 +394,7 @@ struct PrecomputedReducedEvalsTarget<const D: usize> {
|
||||
}
|
||||
|
||||
impl<const D: usize> PrecomputedReducedEvalsTarget<D> {
|
||||
fn from_os_and_alpha<F: PrimeField + Extendable<D>>(
|
||||
fn from_os_and_alpha<F: RichField + Extendable<D>>(
|
||||
os: &OpeningSetTarget<D>,
|
||||
alpha: ExtensionTarget<D>,
|
||||
degree_log: usize,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use anyhow::{ensure, Result};
|
||||
|
||||
use crate::field::extension_field::{flatten, Extendable, FieldExtension};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::field::interpolation::{barycentric_weights, interpolate, interpolate2};
|
||||
use crate::fri::proof::{FriInitialTreeProof, FriProof, FriQueryRound};
|
||||
use crate::fri::FriConfig;
|
||||
@ -44,7 +44,7 @@ fn compute_evaluation<F: Field + Extendable<D>, const D: usize>(
|
||||
interpolate(&points, beta, &barycentric_weights)
|
||||
}
|
||||
|
||||
fn fri_verify_proof_of_work<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn fri_verify_proof_of_work<F: RichField + Extendable<D>, const D: usize>(
|
||||
proof: &FriProof<F, D>,
|
||||
challenger: &mut Challenger<F>,
|
||||
config: &FriConfig,
|
||||
@ -68,7 +68,7 @@ fn fri_verify_proof_of_work<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn verify_fri_proof<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub fn verify_fri_proof<F: RichField + Extendable<D>, const D: usize>(
|
||||
// Openings of the PLONK polynomials.
|
||||
os: &OpeningSet<F, D>,
|
||||
// Point at which the PLONK polynomials are opened.
|
||||
@ -136,7 +136,7 @@ pub fn verify_fri_proof<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fri_verify_initial_proof<F: Field>(
|
||||
fn fri_verify_initial_proof<F: RichField>(
|
||||
x_index: usize,
|
||||
proof: &FriInitialTreeProof<F>,
|
||||
initial_merkle_caps: &[MerkleCap<F>],
|
||||
@ -179,7 +179,7 @@ impl<F: Extendable<D>, const D: usize> PrecomputedReducedEvals<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fri_combine_initial<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn fri_combine_initial<F: RichField + Extendable<D>, const D: usize>(
|
||||
proof: &FriInitialTreeProof<F>,
|
||||
alpha: F::Extension,
|
||||
zeta: F::Extension,
|
||||
@ -244,7 +244,7 @@ fn fri_combine_initial<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
sum
|
||||
}
|
||||
|
||||
fn fri_verifier_query_round<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn fri_verifier_query_round<F: RichField + Extendable<D>, const D: usize>(
|
||||
zeta: F::Extension,
|
||||
alpha: F::Extension,
|
||||
precomputed_reduced_evals: PrecomputedReducedEvals<F, D>,
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use std::borrow::Borrow;
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::exponentiation::ExponentiationGate;
|
||||
use crate::iop::target::{BoolTarget, Target};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Computes `-x`.
|
||||
pub fn neg(&mut self, x: Target) -> Target {
|
||||
let neg_one = self.neg_one();
|
||||
|
||||
@ -3,7 +3,7 @@ use std::convert::TryInto;
|
||||
use crate::field::extension_field::target::{ExtensionAlgebraTarget, ExtensionTarget};
|
||||
use crate::field::extension_field::FieldExtension;
|
||||
use crate::field::extension_field::{Extendable, OEF};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::arithmetic::{ArithmeticExtensionGate, NUM_ARITHMETIC_OPS};
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -11,7 +11,7 @@ use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::util::bits_u64;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Finds the last available arithmetic gate with the given constants or add one if there aren't any.
|
||||
/// Returns `(g,i)` such that there is an arithmetic gate with the given constants at index
|
||||
/// `g` and the gate's `i`-th operation is available.
|
||||
@ -440,7 +440,7 @@ struct QuotientGeneratorExtension<const D: usize> {
|
||||
quotient: ExtensionTarget<D>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for QuotientGeneratorExtension<D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
@ -465,7 +465,7 @@ pub struct PowersTarget<const D: usize> {
|
||||
}
|
||||
|
||||
impl<const D: usize> PowersTarget<D> {
|
||||
pub fn next<F: PrimeField + Extendable<D>>(
|
||||
pub fn next<F: RichField + Extendable<D>>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D> {
|
||||
@ -474,7 +474,7 @@ impl<const D: usize> PowersTarget<D> {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn repeated_frobenius<F: PrimeField + Extendable<D>>(
|
||||
pub fn repeated_frobenius<F: RichField + Extendable<D>>(
|
||||
self,
|
||||
k: usize,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
@ -487,7 +487,7 @@ impl<const D: usize> PowersTarget<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn powers(&mut self, base: ExtensionTarget<D>) -> PowersTarget<D> {
|
||||
PowersTarget {
|
||||
base,
|
||||
|
||||
@ -1,22 +1,25 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::gmimc::GMiMCGate;
|
||||
use crate::hash::hashing::GMIMC_ROUNDS;
|
||||
use crate::hash::gmimc::GMiMC;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
// TODO: Move to be next to native `permute`?
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn permute(&mut self, inputs: [Target; 12]) -> [Target; 12] {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn permute<const W: usize>(&mut self, inputs: [Target; W]) -> [Target; W]
|
||||
where
|
||||
F: GMiMC<W>,
|
||||
{
|
||||
let zero = self.zero();
|
||||
let gate_type = GMiMCGate::<F, D, GMIMC_ROUNDS>::new_automatic_constants();
|
||||
let gate_type = GMiMCGate::<F, D, W>::new();
|
||||
let gate = self.add_gate(gate_type, vec![]);
|
||||
|
||||
// We don't want to swap any inputs, so set that wire to 0.
|
||||
let swap_wire = GMiMCGate::<F, D, GMIMC_ROUNDS>::WIRE_SWAP;
|
||||
let swap_wire = GMiMCGate::<F, D, W>::WIRE_SWAP;
|
||||
let swap_wire = Target::Wire(Wire {
|
||||
gate,
|
||||
input: swap_wire,
|
||||
@ -24,8 +27,8 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
self.connect(zero, swap_wire);
|
||||
|
||||
// Route input wires.
|
||||
for i in 0..12 {
|
||||
let in_wire = GMiMCGate::<F, D, GMIMC_ROUNDS>::wire_input(i);
|
||||
for i in 0..W {
|
||||
let in_wire = GMiMCGate::<F, D, W>::wire_input(i);
|
||||
let in_wire = Target::Wire(Wire {
|
||||
gate,
|
||||
input: in_wire,
|
||||
@ -34,11 +37,11 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
|
||||
// Collect output wires.
|
||||
(0..12)
|
||||
(0..W)
|
||||
.map(|i| {
|
||||
Target::Wire(Wire {
|
||||
gate,
|
||||
input: GMiMCGate::<F, D, GMIMC_ROUNDS>::wire_output(i),
|
||||
input: GMiMCGate::<F, D, W>::wire_output(i),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::insertion::InsertionGate;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Inserts a `Target` in a vector at a non-deterministic index.
|
||||
/// Note: `index` is not range-checked.
|
||||
pub fn insert(
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::interpolation::InterpolationGate;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Interpolate a list of point/evaluation pairs at a given point.
|
||||
/// Returns the evaluation of the interpolated polynomial at `evaluation_point`.
|
||||
pub fn interpolate(
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::field::{
|
||||
extension_field::Extendable,
|
||||
field_types::{Field, PrimeField},
|
||||
};
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::field::{extension_field::Extendable, field_types::Field};
|
||||
use crate::gates::switch::SwitchGate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -12,7 +10,7 @@ use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::util::bimap::bimap_from_lists;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Assert that two lists of expressions evaluate to permutations of one another.
|
||||
pub fn assert_permutation(&mut self, a: Vec<Vec<Target>>, b: Vec<Vec<Target>>) {
|
||||
assert_eq!(
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::field::extension_field::target::{ExtensionAlgebraTarget, ExtensionTarget};
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::util::reducing::ReducingFactorTarget;
|
||||
@ -12,7 +12,7 @@ impl<const D: usize> PolynomialCoeffsExtTarget<D> {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn eval_scalar<F: PrimeField + Extendable<D>>(
|
||||
pub fn eval_scalar<F: RichField + Extendable<D>>(
|
||||
&self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
point: Target,
|
||||
@ -22,7 +22,7 @@ impl<const D: usize> PolynomialCoeffsExtTarget<D> {
|
||||
point.reduce(&self.0, builder)
|
||||
}
|
||||
|
||||
pub fn eval<F: PrimeField + Extendable<D>>(
|
||||
pub fn eval<F: RichField + Extendable<D>>(
|
||||
&self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
point: ExtensionTarget<D>,
|
||||
@ -41,7 +41,7 @@ impl<const D: usize> PolynomialCoeffsExtAlgebraTarget<D> {
|
||||
point: ExtensionTarget<D>,
|
||||
) -> ExtensionAlgebraTarget<D>
|
||||
where
|
||||
F: PrimeField + Extendable<D>,
|
||||
F: RichField + Extendable<D>,
|
||||
{
|
||||
let mut acc = builder.zero_ext_algebra();
|
||||
for &c in self.0.iter().rev() {
|
||||
@ -56,7 +56,7 @@ impl<const D: usize> PolynomialCoeffsExtAlgebraTarget<D> {
|
||||
point: ExtensionAlgebraTarget<D>,
|
||||
) -> ExtensionAlgebraTarget<D>
|
||||
where
|
||||
F: PrimeField + Extendable<D>,
|
||||
F: RichField + Extendable<D>,
|
||||
{
|
||||
let mut acc = builder.zero_ext_algebra();
|
||||
for &c in self.0.iter().rev() {
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::random_access::RandomAccessGate;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Checks that a `Target` matches a vector at a non-deterministic index.
|
||||
/// Note: `index` is not range-checked.
|
||||
pub fn random_access(
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::base_sum::BaseSumGate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
||||
use crate::iop::target::{BoolTarget, Target};
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Checks that `x < 2^n_log` using a `BaseSumGate`.
|
||||
pub fn range_check(&mut self, x: Target, n_log: usize) {
|
||||
let gate = self.add_gate(BaseSumGate::<2>::new(n_log), vec![]);
|
||||
@ -51,7 +51,7 @@ struct LowHighGenerator {
|
||||
high: Target,
|
||||
}
|
||||
|
||||
impl<F: PrimeField> SimpleGenerator<F> for LowHighGenerator {
|
||||
impl<F: RichField> SimpleGenerator<F> for LowHighGenerator {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![self.integer]
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::iop::target::{BoolTarget, Target};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Selects `x` or `y` based on `b`, i.e., this returns `if b { x } else { y }`.
|
||||
pub fn select_ext(
|
||||
&mut self,
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
use std::borrow::Borrow;
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::base_sum::BaseSumGate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
||||
use crate::iop::target::{BoolTarget, Target};
|
||||
use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Split the given element into a list of targets, where each one represents a
|
||||
/// base-B limb of the element, with little-endian ordering.
|
||||
pub fn split_le_base<const B: usize>(&mut self, x: Target, num_limbs: usize) -> Vec<Target> {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::base_sum::BaseSumGate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
||||
use crate::iop::target::{BoolTarget, Target};
|
||||
@ -7,7 +7,7 @@ use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::util::ceil_div_usize;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Split the given integer into a list of wires, where each one represents a
|
||||
/// bit of the integer, with little-endian ordering.
|
||||
/// Verifies that the decomposition is correct by using `k` `BaseSum<2>` gates
|
||||
@ -63,7 +63,7 @@ struct SplitGenerator {
|
||||
bits: Vec<Target>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField> SimpleGenerator<F> for SplitGenerator {
|
||||
impl<F: RichField> SimpleGenerator<F> for SplitGenerator {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![self.integer]
|
||||
}
|
||||
@ -91,7 +91,7 @@ struct WireSplitGenerator {
|
||||
num_limbs: usize,
|
||||
}
|
||||
|
||||
impl<F: PrimeField> SimpleGenerator<F> for WireSplitGenerator {
|
||||
impl<F: RichField> SimpleGenerator<F> for WireSplitGenerator {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![self.integer]
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use std::ops::Range;
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::extension_field::FieldExtension;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -33,7 +33,7 @@ impl<const D: usize> ArithmeticExtensionGate<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExtensionGate<D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExtensionGate<D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}", self)
|
||||
}
|
||||
@ -143,14 +143,14 @@ impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for ArithmeticExt
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct ArithmeticExtensionGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
struct ArithmeticExtensionGenerator<F: RichField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
const_0: F,
|
||||
const_1: F,
|
||||
i: usize,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for ArithmeticExtensionGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
|
||||
@ -2,7 +2,7 @@ use std::ops::Range;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -31,7 +31,7 @@ impl<const B: usize> BaseSumGate<B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGate<B> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGate<B> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?} + Base: {}", self, B)
|
||||
}
|
||||
@ -134,7 +134,7 @@ pub struct BaseSplitGenerator<const B: usize> {
|
||||
num_limbs: usize,
|
||||
}
|
||||
|
||||
impl<F: PrimeField, const B: usize> SimpleGenerator<F> for BaseSplitGenerator<B> {
|
||||
impl<F: RichField, const B: usize> SimpleGenerator<F> for BaseSplitGenerator<B> {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![Target::wire(self.gate_index, BaseSumGate::<B>::WIRE_SUM)]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -18,7 +18,7 @@ impl ConstantGate {
|
||||
pub const WIRE_OUTPUT: usize = 0;
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
|
||||
fn id(&self) -> String {
|
||||
"ConstantGate".into()
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use std::marker::PhantomData;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -14,12 +14,12 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
/// A gate for raising a value to a power.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct ExponentiationGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) struct ExponentiationGate<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub num_power_bits: usize,
|
||||
pub _phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> ExponentiationGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> ExponentiationGate<F, D> {
|
||||
pub fn new(num_power_bits: usize) -> Self {
|
||||
Self {
|
||||
num_power_bits,
|
||||
@ -59,7 +59,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> ExponentiationGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for ExponentiationGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ExponentiationGate<F, D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}<D={}>", self, D)
|
||||
}
|
||||
@ -205,12 +205,12 @@ impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for Exponentiatio
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ExponentiationGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
struct ExponentiationGenerator<F: RichField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: ExponentiationGate<F, D>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for ExponentiationGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
|
||||
@ -4,14 +4,14 @@ use std::sync::Arc;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate_tree::Tree;
|
||||
use crate::iop::generator::WitnessGenerator;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
/// A custom gate.
|
||||
pub trait Gate<F: PrimeField + Extendable<D>, const D: usize>: 'static + Send + Sync {
|
||||
pub trait Gate<F: RichField + Extendable<D>, const D: usize>: 'static + Send + Sync {
|
||||
fn id(&self) -> String;
|
||||
|
||||
fn eval_unfiltered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension>;
|
||||
@ -108,48 +108,48 @@ pub trait Gate<F: PrimeField + Extendable<D>, const D: usize>: 'static + Send +
|
||||
|
||||
/// A wrapper around an `Rc<Gate>` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs.
|
||||
#[derive(Clone)]
|
||||
pub struct GateRef<F: PrimeField + Extendable<D>, const D: usize>(pub(crate) Arc<dyn Gate<F, D>>);
|
||||
pub struct GateRef<F: RichField + Extendable<D>, const D: usize>(pub(crate) Arc<dyn Gate<F, D>>);
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> GateRef<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> GateRef<F, D> {
|
||||
pub fn new<G: Gate<F, D>>(gate: G) -> GateRef<F, D> {
|
||||
GateRef(Arc::new(gate))
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> PartialEq for GateRef<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> PartialEq for GateRef<F, D> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.id() == other.0.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Hash for GateRef<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Hash for GateRef<F, D> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.0.id().hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Eq for GateRef<F, D> {}
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Eq for GateRef<F, D> {}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Debug for GateRef<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Debug for GateRef<F, D> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
|
||||
write!(f, "{}", self.0.id())
|
||||
}
|
||||
}
|
||||
|
||||
/// A gate along with any constants used to configure it.
|
||||
pub struct GateInstance<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub struct GateInstance<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub gate_ref: GateRef<F, D>,
|
||||
pub constants: Vec<F>,
|
||||
}
|
||||
|
||||
/// Map each gate to a boolean prefix used to construct the gate's selector polynomial.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PrefixedGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub struct PrefixedGate<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub gate: GateRef<F, D>,
|
||||
pub prefix: Vec<bool>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> PrefixedGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> PrefixedGate<F, D> {
|
||||
pub fn from_tree(tree: Tree<GateRef<F, D>>) -> Vec<Self> {
|
||||
tree.traversal()
|
||||
.into_iter()
|
||||
@ -174,7 +174,7 @@ fn compute_filter<K: Field>(prefix: &[bool], constants: &[K]) -> K {
|
||||
.product()
|
||||
}
|
||||
|
||||
fn compute_filter_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn compute_filter_recursively<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
prefix: &[bool],
|
||||
constants: &[ExtensionTarget<D>],
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use anyhow::{ensure, Result};
|
||||
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::hash::hash_types::HashOut;
|
||||
use crate::iop::witness::{PartialWitness, Witness};
|
||||
@ -17,7 +17,7 @@ const WITNESS_DEGREE: usize = WITNESS_SIZE - 1;
|
||||
|
||||
/// Tests that the constraints imposed by the given gate are low-degree by applying them to random
|
||||
/// low-degree witness polynomials.
|
||||
pub(crate) fn test_low_degree<F: PrimeField + Extendable<D>, G: Gate<F, D>, const D: usize>(
|
||||
pub(crate) fn test_low_degree<F: RichField + Extendable<D>, G: Gate<F, D>, const D: usize>(
|
||||
gate: G,
|
||||
) {
|
||||
let rate_bits = log2_ceil(gate.degree() + 1);
|
||||
@ -84,7 +84,7 @@ fn random_low_degree_values<F: Field>(rate_bits: usize) -> Vec<F> {
|
||||
.values
|
||||
}
|
||||
|
||||
pub(crate) fn test_eval_fns<F: PrimeField + Extendable<D>, G: Gate<F, D>, const D: usize>(
|
||||
pub(crate) fn test_eval_fns<F: RichField + Extendable<D>, G: Gate<F, D>, const D: usize>(
|
||||
gate: G,
|
||||
) -> Result<()> {
|
||||
// Test that `eval_unfiltered` and `eval_unfiltered_base` are coherent.
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use log::info;
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::gate::GateRef;
|
||||
|
||||
/// A binary tree where leaves hold some type `T` and other nodes are empty.
|
||||
@ -51,7 +51,7 @@ impl<T: Clone> Tree<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Tree<GateRef<F, D>> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Tree<GateRef<F, D>> {
|
||||
/// The binary gate tree influences the degree `D` of the constraint polynomial and the number `C`
|
||||
/// of constant wires in the circuit. We want to construct a tree minimizing both values. To do so
|
||||
/// we iterate over possible values of `(D, C)` and try to construct a tree with these values.
|
||||
@ -229,7 +229,6 @@ mod tests {
|
||||
use crate::gates::gmimc::GMiMCGate;
|
||||
use crate::gates::interpolation::InterpolationGate;
|
||||
use crate::gates::noop::NoopGate;
|
||||
use crate::hash::hashing::GMIMC_ROUNDS;
|
||||
|
||||
#[test]
|
||||
fn test_prefix_generation() {
|
||||
@ -242,7 +241,7 @@ mod tests {
|
||||
GateRef::new(ConstantGate),
|
||||
GateRef::new(ArithmeticExtensionGate),
|
||||
GateRef::new(BaseSumGate::<4>::new(4)),
|
||||
GateRef::new(GMiMCGate::<F, D, GMIMC_ROUNDS>::new_automatic_constants()),
|
||||
GateRef::new(GMiMCGate::<F, D, 12>::new()),
|
||||
GateRef::new(InterpolationGate::new(4)),
|
||||
];
|
||||
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
use std::sync::Arc;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::hash::gmimc::gmimc_automatic_constants;
|
||||
use crate::hash::gmimc;
|
||||
use crate::hash::gmimc::GMiMC;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
@ -12,9 +13,6 @@ use crate::iop::witness::{PartitionWitness, Witness};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
/// The width of the permutation, in field elements.
|
||||
const W: usize = 12;
|
||||
|
||||
/// Evaluates a full GMiMC permutation with 12 state elements, and writes the output to the next
|
||||
/// gate's first `width` wires (which could be the input of another `GMiMCGate`).
|
||||
///
|
||||
@ -23,18 +21,21 @@ const W: usize = 12;
|
||||
/// sibling digests. It also has an accumulator that computes the weighted sum of these flags, for
|
||||
/// computing the index of the leaf based on these swap bits.
|
||||
#[derive(Debug)]
|
||||
pub struct GMiMCGate<F: PrimeField + Extendable<D>, const D: usize, const R: usize> {
|
||||
constants: Arc<[F; R]>,
|
||||
pub struct GMiMCGate<
|
||||
F: RichField + Extendable<D> + GMiMC<WIDTH>,
|
||||
const D: usize,
|
||||
const WIDTH: usize,
|
||||
> {
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> GMiMCGate<F, D, R> {
|
||||
pub fn new(constants: Arc<[F; R]>) -> Self {
|
||||
Self { constants }
|
||||
}
|
||||
|
||||
pub fn new_automatic_constants() -> Self {
|
||||
let constants = Arc::new(gmimc_automatic_constants::<F, R>());
|
||||
Self::new(constants)
|
||||
impl<F: RichField + Extendable<D> + GMiMC<WIDTH>, const D: usize, const WIDTH: usize>
|
||||
GMiMCGate<F, D, WIDTH>
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
GMiMCGate {
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// The wire index for the `i`th input to the permutation.
|
||||
@ -44,29 +45,29 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> GMiMCGate<F,
|
||||
|
||||
/// The wire index for the `i`th output to the permutation.
|
||||
pub fn wire_output(i: usize) -> usize {
|
||||
W + i
|
||||
WIDTH + i
|
||||
}
|
||||
|
||||
/// If this is set to 1, the first four inputs will be swapped with the next four inputs. This
|
||||
/// is useful for ordering hashes in Merkle proofs. Otherwise, this should be set to 0.
|
||||
pub const WIRE_SWAP: usize = 2 * W;
|
||||
pub const WIRE_SWAP: usize = 2 * WIDTH;
|
||||
|
||||
/// A wire which stores the input to the `i`th cubing.
|
||||
fn wire_cubing_input(i: usize) -> usize {
|
||||
2 * W + 1 + i
|
||||
2 * WIDTH + 1 + i
|
||||
}
|
||||
|
||||
/// End of wire indices, exclusive.
|
||||
fn end() -> usize {
|
||||
2 * W + 1 + R
|
||||
2 * WIDTH + 1 + gmimc::NUM_ROUNDS
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
for GMiMCGate<F, D, R>
|
||||
impl<F: RichField + Extendable<D> + GMiMC<WIDTH>, const D: usize, const WIDTH: usize> Gate<F, D>
|
||||
for GMiMCGate<F, D, WIDTH>
|
||||
{
|
||||
fn id(&self) -> String {
|
||||
format!("<R={}> {:?}", R, self)
|
||||
format!("<WIDTH={}> {:?}", WIDTH, self)
|
||||
}
|
||||
|
||||
fn eval_unfiltered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension> {
|
||||
@ -95,9 +96,10 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
// See https://affine.group/2020/02/starkware-challenge
|
||||
let mut addition_buffer = F::Extension::ZERO;
|
||||
|
||||
for r in 0..R {
|
||||
let active = r % W;
|
||||
let cubing_input = state[active] + addition_buffer + self.constants[r].into();
|
||||
for r in 0..gmimc::NUM_ROUNDS {
|
||||
let active = r % WIDTH;
|
||||
let constant = F::from_canonical_u64(<F as GMiMC<WIDTH>>::ROUND_CONSTANTS[r]);
|
||||
let cubing_input = state[active] + addition_buffer + constant.into();
|
||||
let cubing_input_wire = vars.local_wires[Self::wire_cubing_input(r)];
|
||||
constraints.push(cubing_input - cubing_input_wire);
|
||||
let f = cubing_input_wire.cube();
|
||||
@ -105,7 +107,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
state[active] -= f;
|
||||
}
|
||||
|
||||
for i in 0..W {
|
||||
for i in 0..WIDTH {
|
||||
state[i] += addition_buffer;
|
||||
constraints.push(state[i] - vars.local_wires[Self::wire_output(i)]);
|
||||
}
|
||||
@ -139,9 +141,10 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
// See https://affine.group/2020/02/starkware-challenge
|
||||
let mut addition_buffer = F::ZERO;
|
||||
|
||||
for r in 0..R {
|
||||
let active = r % W;
|
||||
let cubing_input = state[active] + addition_buffer + self.constants[r];
|
||||
for r in 0..gmimc::NUM_ROUNDS {
|
||||
let active = r % WIDTH;
|
||||
let constant = F::from_canonical_u64(<F as GMiMC<WIDTH>>::ROUND_CONSTANTS[r]);
|
||||
let cubing_input = state[active] + addition_buffer + constant;
|
||||
let cubing_input_wire = vars.local_wires[Self::wire_cubing_input(r)];
|
||||
constraints.push(cubing_input - cubing_input_wire);
|
||||
let f = cubing_input_wire.cube();
|
||||
@ -149,7 +152,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
state[active] -= f;
|
||||
}
|
||||
|
||||
for i in 0..W {
|
||||
for i in 0..WIDTH {
|
||||
state[i] += addition_buffer;
|
||||
constraints.push(state[i] - vars.local_wires[Self::wire_output(i)]);
|
||||
}
|
||||
@ -188,10 +191,11 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
// See https://affine.group/2020/02/starkware-challenge
|
||||
let mut addition_buffer = builder.zero_extension();
|
||||
|
||||
for r in 0..R {
|
||||
let active = r % W;
|
||||
for r in 0..gmimc::NUM_ROUNDS {
|
||||
let active = r % WIDTH;
|
||||
|
||||
let constant = builder.constant_extension(self.constants[r].into());
|
||||
let constant = F::from_canonical_u64(<F as GMiMC<WIDTH>>::ROUND_CONSTANTS[r]);
|
||||
let constant = builder.constant_extension(constant.into());
|
||||
let cubing_input =
|
||||
builder.add_many_extension(&[state[active], addition_buffer, constant]);
|
||||
let cubing_input_wire = vars.local_wires[Self::wire_cubing_input(r)];
|
||||
@ -201,7 +205,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
state[active] = builder.sub_extension(state[active], f);
|
||||
}
|
||||
|
||||
for i in 0..W {
|
||||
for i in 0..WIDTH {
|
||||
state[i] = builder.add_extension(state[i], addition_buffer);
|
||||
constraints
|
||||
.push(builder.sub_extension(state[i], vars.local_wires[Self::wire_output(i)]));
|
||||
@ -215,9 +219,9 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
gate_index: usize,
|
||||
_local_constants: &[F],
|
||||
) -> Vec<Box<dyn WitnessGenerator<F>>> {
|
||||
let gen = GMiMCGenerator {
|
||||
let gen = GMiMCGenerator::<F, D, WIDTH> {
|
||||
gate_index,
|
||||
constants: self.constants.clone(),
|
||||
_phantom: PhantomData,
|
||||
};
|
||||
vec![Box::new(gen.adapter())]
|
||||
}
|
||||
@ -235,25 +239,29 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> Gate<F, D>
|
||||
}
|
||||
|
||||
fn num_constraints(&self) -> usize {
|
||||
R + W + 1
|
||||
gmimc::NUM_ROUNDS + WIDTH + 1
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct GMiMCGenerator<F: PrimeField + Extendable<D>, const D: usize, const R: usize> {
|
||||
struct GMiMCGenerator<
|
||||
F: RichField + Extendable<D> + GMiMC<WIDTH>,
|
||||
const D: usize,
|
||||
const WIDTH: usize,
|
||||
> {
|
||||
gate_index: usize,
|
||||
constants: Arc<[F; R]>,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> SimpleGenerator<F>
|
||||
for GMiMCGenerator<F, D, R>
|
||||
impl<F: RichField + Extendable<D> + GMiMC<WIDTH>, const D: usize, const WIDTH: usize>
|
||||
SimpleGenerator<F> for GMiMCGenerator<F, D, WIDTH>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
let mut dep_input_indices = Vec::with_capacity(W + 1);
|
||||
for i in 0..W {
|
||||
dep_input_indices.push(GMiMCGate::<F, D, R>::wire_input(i));
|
||||
let mut dep_input_indices = Vec::with_capacity(WIDTH + 1);
|
||||
for i in 0..WIDTH {
|
||||
dep_input_indices.push(GMiMCGate::<F, D, WIDTH>::wire_input(i));
|
||||
}
|
||||
dep_input_indices.push(GMiMCGate::<F, D, R>::WIRE_SWAP);
|
||||
dep_input_indices.push(GMiMCGate::<F, D, WIDTH>::WIRE_SWAP);
|
||||
|
||||
dep_input_indices
|
||||
.into_iter()
|
||||
@ -267,18 +275,18 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> SimpleGenera
|
||||
}
|
||||
|
||||
fn run_once(&self, witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) {
|
||||
let mut state = (0..W)
|
||||
let mut state = (0..WIDTH)
|
||||
.map(|i| {
|
||||
witness.get_wire(Wire {
|
||||
gate: self.gate_index,
|
||||
input: GMiMCGate::<F, D, R>::wire_input(i),
|
||||
input: GMiMCGate::<F, D, WIDTH>::wire_input(i),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let swap_value = witness.get_wire(Wire {
|
||||
gate: self.gate_index,
|
||||
input: GMiMCGate::<F, D, R>::WIRE_SWAP,
|
||||
input: GMiMCGate::<F, D, WIDTH>::WIRE_SWAP,
|
||||
});
|
||||
debug_assert!(swap_value == F::ZERO || swap_value == F::ONE);
|
||||
if swap_value == F::ONE {
|
||||
@ -291,13 +299,14 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> SimpleGenera
|
||||
// See https://affine.group/2020/02/starkware-challenge
|
||||
let mut addition_buffer = F::ZERO;
|
||||
|
||||
for r in 0..R {
|
||||
let active = r % W;
|
||||
let cubing_input = state[active] + addition_buffer + self.constants[r];
|
||||
for r in 0..gmimc::NUM_ROUNDS {
|
||||
let active = r % WIDTH;
|
||||
let constant = F::from_canonical_u64(<F as GMiMC<WIDTH>>::ROUND_CONSTANTS[r]);
|
||||
let cubing_input = state[active] + addition_buffer + constant;
|
||||
out_buffer.set_wire(
|
||||
Wire {
|
||||
gate: self.gate_index,
|
||||
input: GMiMCGate::<F, D, R>::wire_cubing_input(r),
|
||||
input: GMiMCGate::<F, D, WIDTH>::wire_cubing_input(r),
|
||||
},
|
||||
cubing_input,
|
||||
);
|
||||
@ -306,12 +315,12 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> SimpleGenera
|
||||
state[active] -= f;
|
||||
}
|
||||
|
||||
for i in 0..W {
|
||||
for i in 0..WIDTH {
|
||||
state[i] += addition_buffer;
|
||||
out_buffer.set_wire(
|
||||
Wire {
|
||||
gate: self.gate_index,
|
||||
input: GMiMCGate::<F, D, R>::wire_output(i),
|
||||
input: GMiMCGate::<F, D, WIDTH>::wire_output(i),
|
||||
},
|
||||
state[i],
|
||||
);
|
||||
@ -322,7 +331,6 @@ impl<F: PrimeField + Extendable<D>, const D: usize, const R: usize> SimpleGenera
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::convert::TryInto;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
@ -330,8 +338,8 @@ mod tests {
|
||||
use crate::field::field_types::Field;
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
|
||||
use crate::gates::gmimc::{GMiMCGate, W};
|
||||
use crate::hash::gmimc::gmimc_permute_naive;
|
||||
use crate::gates::gmimc::GMiMCGate;
|
||||
use crate::hash::gmimc::GMiMC;
|
||||
use crate::iop::generator::generate_partial_witness;
|
||||
use crate::iop::target::Target;
|
||||
use crate::iop::wire::Wire;
|
||||
@ -341,12 +349,11 @@ mod tests {
|
||||
#[test]
|
||||
fn generated_output() {
|
||||
type F = CrandallField;
|
||||
const R: usize = 101;
|
||||
let constants = Arc::new([F::TWO; R]);
|
||||
type Gate = GMiMCGate<F, 4, R>;
|
||||
let gate = Gate::new(constants.clone());
|
||||
const WIDTH: usize = 12;
|
||||
type Gate = GMiMCGate<F, 4, WIDTH>;
|
||||
let gate = Gate::new();
|
||||
|
||||
let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::<Vec<_>>();
|
||||
let permutation_inputs = (0..WIDTH).map(F::from_canonical_usize).collect::<Vec<_>>();
|
||||
|
||||
let mut witness = PartialWitness::new();
|
||||
witness.set_wire(
|
||||
@ -356,7 +363,7 @@ mod tests {
|
||||
},
|
||||
F::ZERO,
|
||||
);
|
||||
for i in 0..W {
|
||||
for i in 0..WIDTH {
|
||||
witness.set_wire(
|
||||
Wire {
|
||||
gate: 0,
|
||||
@ -380,10 +387,10 @@ mod tests {
|
||||
&mut TimingTree::default(),
|
||||
);
|
||||
|
||||
let expected_outputs: [F; W] =
|
||||
gmimc_permute_naive(permutation_inputs.try_into().unwrap(), constants);
|
||||
let expected_outputs: [F; WIDTH] =
|
||||
F::gmimc_permute_naive(permutation_inputs.try_into().unwrap());
|
||||
|
||||
for i in 0..W {
|
||||
for i in 0..WIDTH {
|
||||
let out = partition_witness.get_wire(Wire {
|
||||
gate: 0,
|
||||
input: Gate::wire_output(i),
|
||||
@ -395,18 +402,16 @@ mod tests {
|
||||
#[test]
|
||||
fn low_degree() {
|
||||
type F = CrandallField;
|
||||
const R: usize = 101;
|
||||
let constants = Arc::new([F::TWO; R]);
|
||||
let gate = GMiMCGate::<F, 4, R>::new(constants);
|
||||
const WIDTH: usize = 12;
|
||||
let gate = GMiMCGate::<F, 4, WIDTH>::new();
|
||||
test_low_degree(gate)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_fns() -> Result<()> {
|
||||
type F = CrandallField;
|
||||
const R: usize = 101;
|
||||
let constants = Arc::new([F::TWO; R]);
|
||||
let gate = GMiMCGate::<F, 4, R>::new(constants);
|
||||
const WIDTH: usize = 12;
|
||||
let gate = GMiMCGate::<F, 4, WIDTH>::new();
|
||||
test_eval_fns(gate)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ use std::ops::Range;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -15,12 +15,12 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
/// A gate for inserting a value into a list at a non-deterministic location.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct InsertionGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) struct InsertionGate<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub vec_size: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> InsertionGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> InsertionGate<F, D> {
|
||||
pub fn new(vec_size: usize) -> Self {
|
||||
Self {
|
||||
vec_size,
|
||||
@ -70,7 +70,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> InsertionGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for InsertionGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for InsertionGate<F, D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}<D={}>", self, D)
|
||||
}
|
||||
@ -241,14 +241,12 @@ impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for InsertionGate
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InsertionGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
struct InsertionGenerator<F: RichField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: InsertionGate<F, D>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for InsertionGenerator<F, D>
|
||||
{
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F> for InsertionGenerator<F, D> {
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
let local_target = |input| Target::wire(self.gate_index, input);
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use std::ops::Range;
|
||||
use crate::field::extension_field::algebra::PolynomialCoeffsAlgebra;
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::field::interpolation::interpolant;
|
||||
use crate::gadgets::polynomial::PolynomialCoeffsExtAlgebraTarget;
|
||||
use crate::gates::gate::Gate;
|
||||
@ -23,12 +23,12 @@ use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||
/// to evaluate the interpolant at. It computes the interpolant and outputs its evaluation at the
|
||||
/// given point.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct InterpolationGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) struct InterpolationGate<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub num_points: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> InterpolationGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> InterpolationGate<F, D> {
|
||||
pub fn new(num_points: usize) -> Self {
|
||||
Self {
|
||||
num_points,
|
||||
@ -94,7 +94,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> InterpolationGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for InterpolationGate<F, D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}<D={}>", self, D)
|
||||
}
|
||||
@ -215,13 +215,13 @@ impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for Interpolation
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InterpolationGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
struct InterpolationGenerator<F: RichField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: InterpolationGate<F, D>,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for InterpolationGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::WitnessGenerator;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -9,7 +9,7 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
/// A gate which does nothing.
|
||||
pub struct NoopGate;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for NoopGate {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for NoopGate {
|
||||
fn id(&self) -> String {
|
||||
"NoopGate".into()
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use std::ops::Range;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::WitnessGenerator;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -17,7 +17,7 @@ impl PublicInputGate {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for PublicInputGate {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for PublicInputGate {
|
||||
fn id(&self) -> String {
|
||||
"PublicInputGate".into()
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use std::ops::Range;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -14,12 +14,12 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
/// A gate for checking that a particular element of a list matches a given value.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct RandomAccessGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) struct RandomAccessGate<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub vec_size: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
pub fn new(vec_size: usize) -> Self {
|
||||
Self {
|
||||
vec_size,
|
||||
@ -61,7 +61,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGate<F, D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}<D={}>", self, D)
|
||||
}
|
||||
@ -188,12 +188,12 @@ impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessG
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct RandomAccessGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
struct RandomAccessGenerator<F: RichField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: RandomAccessGate<F, D>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for RandomAccessGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
|
||||
@ -3,7 +3,7 @@ use std::ops::Range;
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::extension_field::FieldExtension;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -51,7 +51,7 @@ impl<const D: usize> ReducingGate<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}", self)
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ use array_tool::vec::Union;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate::Gate;
|
||||
use crate::iop::generator::{GeneratedValues, WitnessGenerator};
|
||||
use crate::iop::target::Target;
|
||||
@ -16,13 +16,13 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
/// A gate for conditionally swapping input values based on a boolean.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct SwitchGate<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) struct SwitchGate<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub(crate) chunk_size: usize,
|
||||
pub(crate) num_copies: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SwitchGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SwitchGate<F, D> {
|
||||
pub fn new(num_copies: usize, chunk_size: usize) -> Self {
|
||||
Self {
|
||||
chunk_size,
|
||||
@ -66,7 +66,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> SwitchGate<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for SwitchGate<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for SwitchGate<F, D> {
|
||||
fn id(&self) -> String {
|
||||
format!("{:?}<D={}>", self, D)
|
||||
}
|
||||
@ -194,13 +194,13 @@ impl<F: PrimeField + Extendable<D>, const D: usize> Gate<F, D> for SwitchGate<F,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SwitchGenerator<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
struct SwitchGenerator<F: RichField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: SwitchGate<F, D>,
|
||||
copy: usize,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> SwitchGenerator<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SwitchGenerator<F, D> {
|
||||
fn in_out_dependencies(&self) -> Vec<Target> {
|
||||
let local_target = |input| Target::wire(self.gate_index, input);
|
||||
|
||||
@ -282,7 +282,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> SwitchGenerator<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> WitnessGenerator<F> for SwitchGenerator<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> WitnessGenerator<F> for SwitchGenerator<F, D> {
|
||||
fn watch_list(&self) -> Vec<Target> {
|
||||
self.in_out_dependencies()
|
||||
.union(self.in_switch_dependencies())
|
||||
|
||||
@ -1,136 +1,99 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use rand::SeedableRng;
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
use unroll::unroll_for_loops;
|
||||
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::field_types::Field;
|
||||
|
||||
pub(crate) fn gmimc_automatic_constants<F: Field, const R: usize>() -> [F; R] {
|
||||
let mut rng = ChaCha8Rng::seed_from_u64(0);
|
||||
let mut constants = [F::ZERO; R];
|
||||
for i in 0..R {
|
||||
constants[i] = F::rand_from_rng(&mut rng);
|
||||
}
|
||||
constants
|
||||
}
|
||||
pub(crate) const NUM_ROUNDS: usize = 101;
|
||||
|
||||
pub fn gmimc_compress<F: Field, const R: usize>(
|
||||
a: [F; 4],
|
||||
b: [F; 4],
|
||||
constants: Arc<[F; R]>,
|
||||
) -> [F; 4] {
|
||||
// Sponge with r=8, c=4.
|
||||
let state_0 = [
|
||||
a[0],
|
||||
a[1],
|
||||
a[2],
|
||||
a[3],
|
||||
b[0],
|
||||
b[1],
|
||||
b[2],
|
||||
b[3],
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
F::ZERO,
|
||||
];
|
||||
let state_1 = gmimc_permute::<F, 12, R>(state_0, constants);
|
||||
[state_1[0], state_1[1], state_1[2], state_1[3]]
|
||||
}
|
||||
pub trait GMiMC<const WIDTH: usize>: Field
|
||||
where
|
||||
[u64; NUM_ROUNDS]: Sized,
|
||||
{
|
||||
const ROUND_CONSTANTS: [u64; NUM_ROUNDS];
|
||||
|
||||
/// Like `gmimc_permute`, but takes constants as an owned array. May be faster.
|
||||
#[unroll_for_loops]
|
||||
pub fn gmimc_permute_array<F: Field, const W: usize, const R: usize>(
|
||||
mut xs: [F; W],
|
||||
constants: [u64; R],
|
||||
) -> [F; W] {
|
||||
// Value that is implicitly added to each element.
|
||||
// See https://affine.group/2020/02/starkware-challenge
|
||||
let mut addition_buffer = F::ZERO;
|
||||
#[unroll_for_loops]
|
||||
fn gmimc_permute(mut xs: [Self; WIDTH]) -> [Self; WIDTH] {
|
||||
// Value that is implicitly added to each element.
|
||||
// See https://affine.group/2020/02/starkware-challenge
|
||||
let mut addition_buffer = Self::ZERO;
|
||||
|
||||
for r in 0..R {
|
||||
let active = r % W;
|
||||
let f = (xs[active] + addition_buffer + F::from_canonical_u64(constants[r])).cube();
|
||||
addition_buffer += f;
|
||||
xs[active] -= f;
|
||||
for (r, &constant) in Self::ROUND_CONSTANTS.iter().enumerate() {
|
||||
let active = r % WIDTH;
|
||||
let f = (xs[active] + addition_buffer + Self::from_canonical_u64(constant)).cube();
|
||||
addition_buffer += f;
|
||||
xs[active] -= f;
|
||||
}
|
||||
|
||||
for i in 0..WIDTH {
|
||||
xs[i] += addition_buffer;
|
||||
}
|
||||
|
||||
xs
|
||||
}
|
||||
|
||||
for x_i in xs.iter_mut() {
|
||||
*x_i += addition_buffer;
|
||||
}
|
||||
|
||||
xs
|
||||
}
|
||||
|
||||
#[unroll_for_loops]
|
||||
pub fn gmimc_permute<F: Field, const W: usize, const R: usize>(
|
||||
mut xs: [F; W],
|
||||
constants: Arc<[F; R]>,
|
||||
) -> [F; W] {
|
||||
// Value that is implicitly added to each element.
|
||||
// See https://affine.group/2020/02/starkware-challenge
|
||||
let mut addition_buffer = F::ZERO;
|
||||
|
||||
for r in 0..R {
|
||||
let active = r % W;
|
||||
let f = (xs[active] + addition_buffer + constants[r]).cube();
|
||||
addition_buffer += f;
|
||||
xs[active] -= f;
|
||||
}
|
||||
|
||||
for i in 0..W {
|
||||
xs[i] += addition_buffer;
|
||||
}
|
||||
|
||||
xs
|
||||
}
|
||||
|
||||
#[unroll_for_loops]
|
||||
pub fn gmimc_permute_naive<F: Field, const W: usize, const R: usize>(
|
||||
mut xs: [F; W],
|
||||
constants: Arc<[F; R]>,
|
||||
) -> [F; W] {
|
||||
for r in 0..R {
|
||||
let active = r % W;
|
||||
let f = (xs[active] + constants[r]).cube();
|
||||
for i in 0..W {
|
||||
if i != active {
|
||||
xs[i] += f;
|
||||
#[unroll_for_loops]
|
||||
fn gmimc_permute_naive(mut xs: [Self; WIDTH]) -> [Self; WIDTH] {
|
||||
for (r, &constant) in Self::ROUND_CONSTANTS.iter().enumerate() {
|
||||
let active = r % WIDTH;
|
||||
let f = (xs[active] + Self::from_canonical_u64(constant)).cube();
|
||||
for i in 0..WIDTH {
|
||||
if i != active {
|
||||
xs[i] += f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xs
|
||||
xs
|
||||
}
|
||||
}
|
||||
|
||||
impl GMiMC<12> for CrandallField {
|
||||
/// This is the result of `gmimc_automatic_constants`; i.e. it's from ChaCha20 seeded with 0.
|
||||
#[rustfmt::skip]
|
||||
const ROUND_CONSTANTS: [u64; NUM_ROUNDS] = [
|
||||
0xb585f767417ee042, 0x7746a55f77c10331, 0xb2fb0d321d356f7a, 0x0f6760a486f1621f,
|
||||
0xe10d6666b36abcdf, 0x8cae14cb455cc50b, 0xd438539cf2cee334, 0xef781c7d4c1fd8b4,
|
||||
0xcdc4a23a0aca4b1f, 0x277fa208d07b52e3, 0xe17653a300493d38, 0xc54302f27c287dc1,
|
||||
0x8628782231d47d10, 0x59cd1a8a690b49f2, 0xc3b919ad9efec0b0, 0xa484c4c637641d97,
|
||||
0x308bbd23f191398b, 0x6e4a40c1bf713cf1, 0x9a2eedb7510414fb, 0xe360c6e111c2c63b,
|
||||
0xd5c771901d4d89aa, 0xc35eae076e7d6b2f, 0x849c2656d0a09cad, 0xc0572c8c5cf1df2b,
|
||||
0xe9fa634a883b8bf3, 0xf56f6d4900fb1fdd, 0xf7d713e872a72a1b, 0x8297132b6ba47612,
|
||||
0xad6805e12ee8af1c, 0xac51d9f6485c22b9, 0x502ad7dc3bd56bf8, 0x57a1550c3761c577,
|
||||
0x66bbd30e99d311da, 0x0da2abef5e948f87, 0xf0612750443f8e94, 0x28b8ec3afb937d8c,
|
||||
0x92a756e6be54ca18, 0x70e741ec304e925d, 0x019d5ee2b037c59f, 0x6f6f2ed7a30707d1,
|
||||
0x7cf416d01e8c169c, 0x61df517bb17617df, 0x85dc499b4c67dbaa, 0x4b959b48dad27b23,
|
||||
0xe8be3e5e0dd779a0, 0xf5c0bc1e525ed8e6, 0x40b12cbf263cf853, 0xa637093f13e2ea3c,
|
||||
0x3cc3f89232e3b0c8, 0x2e479dc16bfe86c0, 0x6f49de07d6d39469, 0x213ce7beecc232de,
|
||||
0x5b043134851fc00a, 0xa2de45784a861506, 0x7103aaf97bed8dd5, 0x5326fc0dbb88a147,
|
||||
0xa9ceb750364cb77a, 0x27f8ec88cc9e991f, 0xfceb4fda8c93fb83, 0xfac6ff13b45b260e,
|
||||
0x7131aa455813380b, 0x93510360d5d68119, 0xad535b24fb96e3db, 0x4627f5c6b7efc045,
|
||||
0x645cf794e4da78a9, 0x241c70ed1ac2877f, 0xacb8e076b009e825, 0x3737e9db6477bd9d,
|
||||
0xe7ea5e344cd688ed, 0x90dee4a009214640, 0xd1b1edf7c77e74af, 0x0b65481bab42158e,
|
||||
0x99ad1aab4b4fe3e7, 0x438a7c91f1a360cd, 0xb60de3bd159088bf, 0xc99cab6b47a3e3bb,
|
||||
0x69a5ed92d5677cef, 0x5e7b329c482a9396, 0x5fc0ac0829f893c9, 0x32db82924fb757ea,
|
||||
0x0ade699c5cf24145, 0x7cc5583b46d7b5bb, 0x85df9ed31bf8abcb, 0x6604df501ad4de64,
|
||||
0xeb84f60941611aec, 0xda60883523989bd4, 0x8f97fe40bf3470bf, 0xa93f485ce0ff2b32,
|
||||
0x6704e8eebc2afb4b, 0xcee3e9ac788ad755, 0x510d0e66062a270d, 0xf6323f48d74634a0,
|
||||
0x0b508cdf04990c90, 0xf241708a4ef7ddf9, 0x60e75c28bb368f82, 0xa6217d8c3f0f9989,
|
||||
0x7159cd30f5435b53, 0x839b4e8fe97ec79f, 0x0d3f3e5e885db625, 0x8f7d83be1daea54b,
|
||||
0x780f22441e8dbc04,
|
||||
];
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::field_types::Field;
|
||||
use crate::hash::gmimc::{gmimc_permute, gmimc_permute_naive};
|
||||
use crate::hash::gmimc::GMiMC;
|
||||
|
||||
fn check_consistency<F: GMiMC<WIDTH>, const WIDTH: usize>() {
|
||||
let xs = F::rand_arr::<WIDTH>();
|
||||
let out = F::gmimc_permute(xs);
|
||||
let out_naive = F::gmimc_permute_naive(xs);
|
||||
assert_eq!(out, out_naive);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn consistency() {
|
||||
type F = CrandallField;
|
||||
const W: usize = 12;
|
||||
const R: usize = 101;
|
||||
|
||||
let mut constants = [F::ZERO; R];
|
||||
for i in 0..R {
|
||||
constants[i] = F::from_canonical_usize(i);
|
||||
}
|
||||
let constants = Arc::new(constants);
|
||||
|
||||
let mut xs = [F::ZERO; W];
|
||||
for i in 0..W {
|
||||
xs[i] = F::from_canonical_usize(i);
|
||||
}
|
||||
|
||||
let out = gmimc_permute::<F, W, R>(xs, constants.clone());
|
||||
let out_naive = gmimc_permute_naive::<F, W, R>(xs, constants);
|
||||
assert_eq!(out, out_naive);
|
||||
check_consistency::<CrandallField, 12>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
//! Concrete instantiation of a hash function.
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::hash::gmimc::gmimc_permute_array;
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::hash::gmimc::GMiMC;
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget};
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -11,115 +11,42 @@ pub(crate) const SPONGE_RATE: usize = 8;
|
||||
pub(crate) const SPONGE_CAPACITY: usize = 4;
|
||||
pub(crate) const SPONGE_WIDTH: usize = SPONGE_RATE + SPONGE_CAPACITY;
|
||||
|
||||
pub const GMIMC_ROUNDS: usize = 101;
|
||||
pub const NUM_ROUNDS: usize = 101;
|
||||
|
||||
/// This is the result of `gmimc_automatic_constants`; i.e. it's from ChaCha20 seeded with 0.
|
||||
pub const GMIMC_CONSTANTS: [u64; GMIMC_ROUNDS] = [
|
||||
13080132715619999810,
|
||||
8594738768332784433,
|
||||
12896916466795114362,
|
||||
1109962092924985887,
|
||||
16216730424513838303,
|
||||
10137062674532189451,
|
||||
15292064468290167604,
|
||||
17255573296743700660,
|
||||
14827154243383347999,
|
||||
2846171648262623971,
|
||||
16246264665335217464,
|
||||
14214208089399786945,
|
||||
9667108688411000080,
|
||||
6470857421371427314,
|
||||
14103331941574951088,
|
||||
11854816474757864855,
|
||||
3498097497657653643,
|
||||
7947235693333396721,
|
||||
11110078702363612411,
|
||||
16384314114341783099,
|
||||
15404405914224921002,
|
||||
14077880832148466479,
|
||||
9555554663682579629,
|
||||
13859595359622389547,
|
||||
16859897326779206643,
|
||||
17685474422023725021,
|
||||
17858764736437889563,
|
||||
9410011023624402450,
|
||||
12495243630852222748,
|
||||
12416945299436348089,
|
||||
5776666812952701944,
|
||||
6314421663507268983,
|
||||
7402742472177291738,
|
||||
982536713292517255,
|
||||
17321168867539521172,
|
||||
2934354895304883596,
|
||||
10567510599683852824,
|
||||
8135543734546633309,
|
||||
116353493093565855,
|
||||
8029688164312877009,
|
||||
9003846638141970076,
|
||||
7052445133185619935,
|
||||
9645665433271393194,
|
||||
5446430061585660707,
|
||||
16770910636054378912,
|
||||
17708360573237778662,
|
||||
4661556288797079635,
|
||||
11977051900536351292,
|
||||
4378616569536950472,
|
||||
3334807503157233344,
|
||||
8019184736760206441,
|
||||
2395043909056213726,
|
||||
6558421058999795722,
|
||||
11735894061922784518,
|
||||
8143540539718733269,
|
||||
5991753490174091591,
|
||||
12235918792748480378,
|
||||
2880312033996085535,
|
||||
18224748117164817283,
|
||||
18070411014966027790,
|
||||
8156487614951798795,
|
||||
10615269511128318233,
|
||||
12489426406026437595,
|
||||
5055279340584943685,
|
||||
7231927320516917417,
|
||||
2602078848371820415,
|
||||
12445944370602567717,
|
||||
3978905924297801117,
|
||||
16711272946032085229,
|
||||
10439032362290464320,
|
||||
15110119873264383151,
|
||||
821141790739535246,
|
||||
11073536381779174375,
|
||||
4866839313593360589,
|
||||
13118391690850240703,
|
||||
14527674975242150843,
|
||||
7612751960041028847,
|
||||
6808090908507673494,
|
||||
6899703780195472329,
|
||||
3664666286710282218,
|
||||
783179505504239941,
|
||||
8990689242729919931,
|
||||
9646603556395461579,
|
||||
7351246026916028004,
|
||||
16970959815450893036,
|
||||
15735726859844361172,
|
||||
10347018222946250943,
|
||||
12195545879691602738,
|
||||
7423314197870213963,
|
||||
14908016118492485461,
|
||||
5840340123122280205,
|
||||
17740311464247702688,
|
||||
815306422036794512,
|
||||
17456357369997417977,
|
||||
6982651077270605698,
|
||||
11970987325834369417,
|
||||
8167785009370061651,
|
||||
9483259820363401119,
|
||||
954550221761525285,
|
||||
10339565172077536587,
|
||||
8651171085167737860,
|
||||
#[rustfmt::skip]
|
||||
pub const ROUND_CONSTANTS: [u64; NUM_ROUNDS] = [
|
||||
0xb585f767417ee042, 0x7746a55f77c10331, 0xb2fb0d321d356f7a, 0x0f6760a486f1621f,
|
||||
0xe10d6666b36abcdf, 0x8cae14cb455cc50b, 0xd438539cf2cee334, 0xef781c7d4c1fd8b4,
|
||||
0xcdc4a23a0aca4b1f, 0x277fa208d07b52e3, 0xe17653a300493d38, 0xc54302f27c287dc1,
|
||||
0x8628782231d47d10, 0x59cd1a8a690b49f2, 0xc3b919ad9efec0b0, 0xa484c4c637641d97,
|
||||
0x308bbd23f191398b, 0x6e4a40c1bf713cf1, 0x9a2eedb7510414fb, 0xe360c6e111c2c63b,
|
||||
0xd5c771901d4d89aa, 0xc35eae076e7d6b2f, 0x849c2656d0a09cad, 0xc0572c8c5cf1df2b,
|
||||
0xe9fa634a883b8bf3, 0xf56f6d4900fb1fdd, 0xf7d713e872a72a1b, 0x8297132b6ba47612,
|
||||
0xad6805e12ee8af1c, 0xac51d9f6485c22b9, 0x502ad7dc3bd56bf8, 0x57a1550c3761c577,
|
||||
0x66bbd30e99d311da, 0x0da2abef5e948f87, 0xf0612750443f8e94, 0x28b8ec3afb937d8c,
|
||||
0x92a756e6be54ca18, 0x70e741ec304e925d, 0x019d5ee2b037c59f, 0x6f6f2ed7a30707d1,
|
||||
0x7cf416d01e8c169c, 0x61df517bb17617df, 0x85dc499b4c67dbaa, 0x4b959b48dad27b23,
|
||||
0xe8be3e5e0dd779a0, 0xf5c0bc1e525ed8e6, 0x40b12cbf263cf853, 0xa637093f13e2ea3c,
|
||||
0x3cc3f89232e3b0c8, 0x2e479dc16bfe86c0, 0x6f49de07d6d39469, 0x213ce7beecc232de,
|
||||
0x5b043134851fc00a, 0xa2de45784a861506, 0x7103aaf97bed8dd5, 0x5326fc0dbb88a147,
|
||||
0xa9ceb750364cb77a, 0x27f8ec88cc9e991f, 0xfceb4fda8c93fb83, 0xfac6ff13b45b260e,
|
||||
0x7131aa455813380b, 0x93510360d5d68119, 0xad535b24fb96e3db, 0x4627f5c6b7efc045,
|
||||
0x645cf794e4da78a9, 0x241c70ed1ac2877f, 0xacb8e076b009e825, 0x3737e9db6477bd9d,
|
||||
0xe7ea5e344cd688ed, 0x90dee4a009214640, 0xd1b1edf7c77e74af, 0x0b65481bab42158e,
|
||||
0x99ad1aab4b4fe3e7, 0x438a7c91f1a360cd, 0xb60de3bd159088bf, 0xc99cab6b47a3e3bb,
|
||||
0x69a5ed92d5677cef, 0x5e7b329c482a9396, 0x5fc0ac0829f893c9, 0x32db82924fb757ea,
|
||||
0x0ade699c5cf24145, 0x7cc5583b46d7b5bb, 0x85df9ed31bf8abcb, 0x6604df501ad4de64,
|
||||
0xeb84f60941611aec, 0xda60883523989bd4, 0x8f97fe40bf3470bf, 0xa93f485ce0ff2b32,
|
||||
0x6704e8eebc2afb4b, 0xcee3e9ac788ad755, 0x510d0e66062a270d, 0xf6323f48d74634a0,
|
||||
0x0b508cdf04990c90, 0xf241708a4ef7ddf9, 0x60e75c28bb368f82, 0xa6217d8c3f0f9989,
|
||||
0x7159cd30f5435b53, 0x839b4e8fe97ec79f, 0x0d3f3e5e885db625, 0x8f7d83be1daea54b,
|
||||
0x780f22441e8dbc04,
|
||||
];
|
||||
|
||||
/// Hash the vector if necessary to reduce its length to ~256 bits. If it already fits, this is a
|
||||
/// no-op.
|
||||
pub fn hash_or_noop<F: Field>(inputs: Vec<F>) -> HashOut<F> {
|
||||
pub fn hash_or_noop<F: RichField>(inputs: Vec<F>) -> HashOut<F> {
|
||||
if inputs.len() <= 4 {
|
||||
HashOut::from_partial(inputs)
|
||||
} else {
|
||||
@ -127,7 +54,7 @@ pub fn hash_or_noop<F: Field>(inputs: Vec<F>) -> HashOut<F> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn hash_or_noop(&mut self, inputs: Vec<Target>) -> HashOutTarget {
|
||||
let zero = self.zero();
|
||||
if inputs.len() <= 4 {
|
||||
@ -184,21 +111,21 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
|
||||
/// A one-way compression function which takes two ~256 bit inputs and returns a ~256 bit output.
|
||||
pub fn compress<F: Field>(x: HashOut<F>, y: HashOut<F>) -> HashOut<F> {
|
||||
pub fn compress<F: RichField>(x: HashOut<F>, y: HashOut<F>) -> HashOut<F> {
|
||||
let mut inputs = Vec::with_capacity(8);
|
||||
inputs.extend(&x.elements);
|
||||
inputs.extend(&y.elements);
|
||||
hash_n_to_hash(inputs, false)
|
||||
}
|
||||
|
||||
pub fn permute<F: Field>(xs: [F; SPONGE_WIDTH]) -> [F; SPONGE_WIDTH] {
|
||||
gmimc_permute_array(xs, GMIMC_CONSTANTS)
|
||||
}
|
||||
|
||||
/// If `pad` is enabled, the message is padded using the pad10*1 rule. In general this is required
|
||||
/// for the hash to be secure, but it can safely be disabled in certain cases, like if the input
|
||||
/// length is fixed.
|
||||
pub fn hash_n_to_m<F: Field>(mut inputs: Vec<F>, num_outputs: usize, pad: bool) -> Vec<F> {
|
||||
pub fn hash_n_to_m<F: Field + GMiMC<12>>(
|
||||
mut inputs: Vec<F>,
|
||||
num_outputs: usize,
|
||||
pad: bool,
|
||||
) -> Vec<F> {
|
||||
if pad {
|
||||
inputs.push(F::ZERO);
|
||||
while (inputs.len() + 1) % SPONGE_WIDTH != 0 {
|
||||
@ -214,7 +141,7 @@ pub fn hash_n_to_m<F: Field>(mut inputs: Vec<F>, num_outputs: usize, pad: bool)
|
||||
for i in 0..input_chunk.len() {
|
||||
state[i] = input_chunk[i];
|
||||
}
|
||||
state = permute(state);
|
||||
state = F::gmimc_permute(state);
|
||||
}
|
||||
|
||||
// Squeeze until we have the desired number of outputs.
|
||||
@ -226,14 +153,14 @@ pub fn hash_n_to_m<F: Field>(mut inputs: Vec<F>, num_outputs: usize, pad: bool)
|
||||
return outputs;
|
||||
}
|
||||
}
|
||||
state = permute(state);
|
||||
state = F::gmimc_permute(state);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash_n_to_hash<F: Field>(inputs: Vec<F>, pad: bool) -> HashOut<F> {
|
||||
pub fn hash_n_to_hash<F: RichField>(inputs: Vec<F>, pad: bool) -> HashOut<F> {
|
||||
HashOut::from_vec(hash_n_to_m(inputs, 4, pad))
|
||||
}
|
||||
|
||||
pub fn hash_n_to_1<F: Field>(inputs: Vec<F>, pad: bool) -> F {
|
||||
pub fn hash_n_to_1<F: RichField>(inputs: Vec<F>, pad: bool) -> F {
|
||||
hash_n_to_m(inputs, 1, pad)[0]
|
||||
}
|
||||
|
||||
@ -5,10 +5,10 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gmimc::GMiMCGate;
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget};
|
||||
use crate::hash::hashing::{compress, hash_or_noop, GMIMC_ROUNDS};
|
||||
use crate::hash::hashing::{compress, hash_or_noop};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::target::{BoolTarget, Target};
|
||||
use crate::iop::wire::Wire;
|
||||
@ -29,7 +29,7 @@ pub struct MerkleProofTarget {
|
||||
|
||||
/// Verifies that the given leaf data is present at the given index in the Merkle tree with the
|
||||
/// given cap.
|
||||
pub(crate) fn verify_merkle_proof<F: Field>(
|
||||
pub(crate) fn verify_merkle_proof<F: RichField>(
|
||||
leaf_data: Vec<F>,
|
||||
leaf_index: usize,
|
||||
merkle_cap: &MerkleCap<F>,
|
||||
@ -54,7 +54,7 @@ pub(crate) fn verify_merkle_proof<F: Field>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Verifies that the given leaf data is present at the given index in the Merkle tree with the
|
||||
/// given cap. The index is given by it's little-endian bits.
|
||||
/// Note: Works only for D=4.
|
||||
@ -70,10 +70,10 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
let mut state: HashOutTarget = self.hash_or_noop(leaf_data);
|
||||
|
||||
for (&bit, &sibling) in leaf_index_bits.iter().zip(&proof.siblings) {
|
||||
let gate_type = GMiMCGate::<F, D, GMIMC_ROUNDS>::new_automatic_constants();
|
||||
let gate_type = GMiMCGate::<F, D, 12>::new();
|
||||
let gate = self.add_gate(gate_type, vec![]);
|
||||
|
||||
let swap_wire = GMiMCGate::<F, D, GMIMC_ROUNDS>::WIRE_SWAP;
|
||||
let swap_wire = GMiMCGate::<F, D, 12>::WIRE_SWAP;
|
||||
let swap_wire = Target::Wire(Wire {
|
||||
gate,
|
||||
input: swap_wire,
|
||||
@ -84,7 +84,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.map(|i| {
|
||||
Target::Wire(Wire {
|
||||
gate,
|
||||
input: GMiMCGate::<F, D, GMIMC_ROUNDS>::wire_input(i),
|
||||
input: GMiMCGate::<F, D, 12>::wire_input(i),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@ -100,7 +100,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.map(|i| {
|
||||
Target::Wire(Wire {
|
||||
gate,
|
||||
input: GMiMCGate::<F, D, GMIMC_ROUNDS>::wire_output(i),
|
||||
input: GMiMCGate::<F, D, 12>::wire_output(i),
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
@ -136,10 +136,10 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
let mut state: HashOutTarget = self.hash_or_noop(leaf_data);
|
||||
|
||||
for (&bit, &sibling) in leaf_index_bits.iter().zip(&proof.siblings) {
|
||||
let gate_type = GMiMCGate::<F, D, GMIMC_ROUNDS>::new_automatic_constants();
|
||||
let gate_type = GMiMCGate::<F, D, 12>::new();
|
||||
let gate = self.add_gate(gate_type, vec![]);
|
||||
|
||||
let swap_wire = GMiMCGate::<F, D, GMIMC_ROUNDS>::WIRE_SWAP;
|
||||
let swap_wire = GMiMCGate::<F, D, 12>::WIRE_SWAP;
|
||||
let swap_wire = Target::Wire(Wire {
|
||||
gate,
|
||||
input: swap_wire,
|
||||
@ -150,7 +150,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.map(|i| {
|
||||
Target::Wire(Wire {
|
||||
gate,
|
||||
input: GMiMCGate::<F, D, GMIMC_ROUNDS>::wire_input(i),
|
||||
input: GMiMCGate::<F, D, 12>::wire_input(i),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@ -166,7 +166,7 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.map(|i| {
|
||||
Target::Wire(Wire {
|
||||
gate,
|
||||
input: GMiMCGate::<F, D, GMIMC_ROUNDS>::wire_output(i),
|
||||
input: GMiMCGate::<F, D, 12>::wire_output(i),
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::field::field_types::Field;
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::hash::hash_types::HashOut;
|
||||
use crate::hash::hashing::{compress, hash_or_noop};
|
||||
use crate::hash::merkle_proofs::MerkleProof;
|
||||
@ -30,7 +30,7 @@ pub struct MerkleTree<F: Field> {
|
||||
pub cap: MerkleCap<F>,
|
||||
}
|
||||
|
||||
impl<F: Field> MerkleTree<F> {
|
||||
impl<F: RichField> MerkleTree<F> {
|
||||
pub fn new(leaves: Vec<Vec<F>>, cap_height: usize) -> Self {
|
||||
let mut layers = vec![leaves
|
||||
.par_iter()
|
||||
@ -82,11 +82,11 @@ mod tests {
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::hash::merkle_proofs::verify_merkle_proof;
|
||||
|
||||
fn random_data<F: Field>(n: usize, k: usize) -> Vec<Vec<F>> {
|
||||
fn random_data<F: RichField>(n: usize, k: usize) -> Vec<Vec<F>> {
|
||||
(0..n).map(|_| F::rand_vec(k)).collect()
|
||||
}
|
||||
|
||||
fn verify_all_leaves<F: Field>(leaves: Vec<Vec<F>>, n: usize) -> Result<()> {
|
||||
fn verify_all_leaves<F: RichField>(leaves: Vec<Vec<F>>, n: usize) -> Result<()> {
|
||||
let tree = MerkleTree::new(leaves.clone(), 1);
|
||||
for i in 0..n {
|
||||
let proof = tree.prove(i);
|
||||
|
||||
@ -22,6 +22,8 @@ const MAX_WIDTH: usize = 12; // we only have width 8 and 12, and 12 is bigger. :
|
||||
// generated from ChaCha8 with a seed of 0. In this case we need
|
||||
// to generate more though. We include enough for a WIDTH of 12;
|
||||
// smaller widths just use a subset.
|
||||
// TODO: These are specific to CrandallField; for other fields they wouldn't represent uniformly
|
||||
// random numbers.
|
||||
#[rustfmt::skip]
|
||||
const ALL_ROUND_CONSTANTS: [u64; MAX_WIDTH * N_ROUNDS] = [
|
||||
0xb585f767417ee042, 0x7746a55f77c10331, 0xb2fb0d321d356f7a, 0x0f6760a486f1621f,
|
||||
@ -116,7 +118,7 @@ const ALL_ROUND_CONSTANTS: [u64; MAX_WIDTH * N_ROUNDS] = [
|
||||
0x4543d9df72c4831d, 0xf172d73e69f20739, 0xdfd1c4ff1eb3d868, 0xbc8dfb62d26376f7,
|
||||
];
|
||||
|
||||
pub trait PoseidonInterface<const WIDTH: usize>: PrimeField
|
||||
pub trait Poseidon<const WIDTH: usize>: PrimeField
|
||||
where
|
||||
// magic to get const generic expressions to work
|
||||
[(); WIDTH - 1]: ,
|
||||
@ -335,7 +337,7 @@ where
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl PoseidonInterface<8> for CrandallField {
|
||||
impl Poseidon<8> for CrandallField {
|
||||
// The MDS matrix we use is the circulant matrix with first row given by the vector
|
||||
// [ 2^x for x in MDS_MATRIX_EXPS] = [4, 1, 2, 256, 16, 8, 1, 1]
|
||||
//
|
||||
@ -475,7 +477,7 @@ impl PoseidonInterface<8> for CrandallField {
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl PoseidonInterface<12> for CrandallField {
|
||||
impl Poseidon<12> for CrandallField {
|
||||
// The MDS matrix we use is the circulant matrix with first row given by the vector
|
||||
// [ 2^x for x in MDS_MATRIX_EXPS] = [1024, 8192, 4, 1, 16, 2, 256, 128, 32768, 32, 1, 1]
|
||||
//
|
||||
@ -683,11 +685,11 @@ impl PoseidonInterface<12> for CrandallField {
|
||||
mod tests {
|
||||
use crate::field::crandall_field::CrandallField as F;
|
||||
use crate::field::field_types::Field;
|
||||
use crate::hash::poseidon::PoseidonInterface;
|
||||
use crate::hash::poseidon::Poseidon;
|
||||
|
||||
fn check_test_vectors<const WIDTH: usize>(test_vectors: Vec<([u64; WIDTH], [u64; WIDTH])>)
|
||||
where
|
||||
F: PoseidonInterface<WIDTH>,
|
||||
F: Poseidon<WIDTH>,
|
||||
[(); WIDTH - 1]: ,
|
||||
{
|
||||
for (input_, expected_output_) in test_vectors.into_iter() {
|
||||
@ -750,7 +752,7 @@ mod tests {
|
||||
|
||||
fn check_consistency<const WIDTH: usize>()
|
||||
where
|
||||
F: PoseidonInterface<WIDTH>,
|
||||
F: Poseidon<WIDTH>,
|
||||
[(); WIDTH - 1]: ,
|
||||
{
|
||||
let mut input = [F::ZERO; WIDTH];
|
||||
|
||||
@ -2,9 +2,9 @@ use std::convert::TryInto;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget};
|
||||
use crate::hash::hashing::{permute, SPONGE_RATE, SPONGE_WIDTH};
|
||||
use crate::hash::hashing::{SPONGE_RATE, SPONGE_WIDTH};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -12,7 +12,7 @@ use crate::plonk::proof::{OpeningSet, OpeningSetTarget};
|
||||
|
||||
/// Observes prover messages, and generates challenges by hashing the transcript, a la Fiat-Shamir.
|
||||
#[derive(Clone)]
|
||||
pub struct Challenger<F: Field> {
|
||||
pub struct Challenger<F: RichField> {
|
||||
sponge_state: [F; SPONGE_WIDTH],
|
||||
input_buffer: Vec<F>,
|
||||
output_buffer: Vec<F>,
|
||||
@ -26,7 +26,7 @@ pub struct Challenger<F: Field> {
|
||||
/// design, but it can be viewed as a duplex sponge whose inputs are sometimes zero (when we perform
|
||||
/// multiple squeezes) and whose outputs are sometimes ignored (when we perform multiple
|
||||
/// absorptions). Thus the security properties of a duplex sponge still apply to our design.
|
||||
impl<F: Field> Challenger<F> {
|
||||
impl<F: RichField> Challenger<F> {
|
||||
pub fn new() -> Challenger<F> {
|
||||
Challenger {
|
||||
sponge_state: [F::ZERO; SPONGE_WIDTH],
|
||||
@ -105,7 +105,7 @@ impl<F: Field> Challenger<F> {
|
||||
|
||||
if self.output_buffer.is_empty() {
|
||||
// Evaluate the permutation to produce `r` new outputs.
|
||||
self.sponge_state = permute(self.sponge_state);
|
||||
self.sponge_state = F::gmimc_permute(self.sponge_state);
|
||||
self.output_buffer = self.sponge_state[0..SPONGE_RATE].to_vec();
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ impl<F: Field> Challenger<F> {
|
||||
}
|
||||
|
||||
// Apply the permutation.
|
||||
self.sponge_state = permute(self.sponge_state);
|
||||
self.sponge_state = F::gmimc_permute(self.sponge_state);
|
||||
}
|
||||
|
||||
self.output_buffer = self.sponge_state[0..SPONGE_RATE].to_vec();
|
||||
@ -169,7 +169,7 @@ impl<F: Field> Challenger<F> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Default for Challenger<F> {
|
||||
impl<F: RichField> Default for Challenger<F> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
@ -183,7 +183,7 @@ pub struct RecursiveChallenger {
|
||||
}
|
||||
|
||||
impl RecursiveChallenger {
|
||||
pub(crate) fn new<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn new<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> Self {
|
||||
let zero = builder.zero();
|
||||
@ -250,7 +250,7 @@ impl RecursiveChallenger {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_challenge<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn get_challenge<F: RichField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> Target {
|
||||
@ -267,7 +267,7 @@ impl RecursiveChallenger {
|
||||
.expect("Output buffer should be non-empty")
|
||||
}
|
||||
|
||||
pub(crate) fn get_n_challenges<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn get_n_challenges<F: RichField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
n: usize,
|
||||
@ -275,7 +275,7 @@ impl RecursiveChallenger {
|
||||
(0..n).map(|_| self.get_challenge(builder)).collect()
|
||||
}
|
||||
|
||||
pub fn get_hash<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub fn get_hash<F: RichField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> HashOutTarget {
|
||||
@ -289,7 +289,7 @@ impl RecursiveChallenger {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_extension_challenge<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub fn get_extension_challenge<F: RichField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D> {
|
||||
@ -297,7 +297,7 @@ impl RecursiveChallenger {
|
||||
}
|
||||
|
||||
/// Absorb any buffered inputs. After calling this, the input buffer will be empty.
|
||||
fn absorb_buffered_inputs<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn absorb_buffered_inputs<F: RichField + Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) {
|
||||
|
||||
@ -7,7 +7,7 @@ use log::{info, Level};
|
||||
use crate::field::cosets::get_unique_coset_shifts;
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::fri::commitment::PolynomialBatchCommitment;
|
||||
use crate::gates::arithmetic::{ArithmeticExtensionGate, NUM_ARITHMETIC_OPS};
|
||||
use crate::gates::constant::ConstantGate;
|
||||
@ -37,7 +37,7 @@ use crate::util::partial_products::num_partial_products;
|
||||
use crate::util::timing::TimingTree;
|
||||
use crate::util::{log2_ceil, log2_strict, transpose, transpose_poly_values};
|
||||
|
||||
pub struct CircuitBuilder<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub struct CircuitBuilder<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub(crate) config: CircuitConfig,
|
||||
|
||||
/// The types of gates used in this circuit.
|
||||
@ -76,7 +76,7 @@ pub struct CircuitBuilder<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) current_switch_gates: Vec<Option<(SwitchGate<F, D>, usize, usize)>>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn new(config: CircuitConfig) -> Self {
|
||||
CircuitBuilder {
|
||||
config,
|
||||
|
||||
@ -3,10 +3,10 @@ use std::ops::{Range, RangeFrom};
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::fri::commitment::PolynomialBatchCommitment;
|
||||
use crate::fri::FriConfig;
|
||||
use crate::gates::gate::{GateInstance, PrefixedGate};
|
||||
use crate::gates::gate::PrefixedGate;
|
||||
use crate::hash::hash_types::{HashOut, MerkleCapTarget};
|
||||
use crate::hash::merkle_tree::MerkleCap;
|
||||
use crate::iop::generator::WitnessGenerator;
|
||||
@ -91,13 +91,13 @@ impl CircuitConfig {
|
||||
}
|
||||
|
||||
/// Circuit data required by the prover or the verifier.
|
||||
pub struct CircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub struct CircuitData<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
|
||||
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
|
||||
pub(crate) common: CommonCircuitData<F, D>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitData<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitData<F, D> {
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
|
||||
prove(&self.prover_only, &self.common, inputs)
|
||||
}
|
||||
@ -114,12 +114,12 @@ impl<F: PrimeField + Extendable<D>, const D: usize> CircuitData<F, D> {
|
||||
/// structure as succinct as we can. Thus we include various precomputed data which isn't strictly
|
||||
/// required, like LDEs of preprocessed polynomials. If more succinctness was desired, we could
|
||||
/// construct a more minimal prover structure and convert back and forth.
|
||||
pub struct ProverCircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub struct ProverCircuitData<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
|
||||
pub(crate) common: CommonCircuitData<F, D>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> ProverCircuitData<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> ProverCircuitData<F, D> {
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Result<ProofWithPublicInputs<F, D>> {
|
||||
prove(&self.prover_only, &self.common, inputs)
|
||||
}
|
||||
@ -127,19 +127,19 @@ impl<F: PrimeField + Extendable<D>, const D: usize> ProverCircuitData<F, D> {
|
||||
|
||||
/// Circuit data required by the prover.
|
||||
#[derive(Debug)]
|
||||
pub struct VerifierCircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub struct VerifierCircuitData<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
|
||||
pub(crate) common: CommonCircuitData<F, D>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> VerifierCircuitData<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> VerifierCircuitData<F, D> {
|
||||
pub fn verify(&self, proof_with_pis: ProofWithPublicInputs<F, D>) -> Result<()> {
|
||||
verify(proof_with_pis, &self.verifier_only, &self.common)
|
||||
}
|
||||
}
|
||||
|
||||
/// Circuit data required by the prover, but not the verifier.
|
||||
pub(crate) struct ProverOnlyCircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) struct ProverOnlyCircuitData<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub generators: Vec<Box<dyn WitnessGenerator<F>>>,
|
||||
/// Commitments to the constants polynomials and sigma polynomials.
|
||||
pub constants_sigmas_commitment: PolynomialBatchCommitment<F>,
|
||||
@ -164,7 +164,7 @@ pub(crate) struct VerifierOnlyCircuitData<F: Field> {
|
||||
|
||||
/// Circuit data required by both the prover and the verifier.
|
||||
#[derive(Debug)]
|
||||
pub struct CommonCircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub struct CommonCircuitData<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub(crate) config: CircuitConfig,
|
||||
|
||||
pub(crate) degree_bits: usize,
|
||||
@ -193,7 +193,7 @@ pub struct CommonCircuitData<F: PrimeField + Extendable<D>, const D: usize> {
|
||||
pub(crate) circuit_digest: HashOut<F>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CommonCircuitData<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CommonCircuitData<F, D> {
|
||||
pub fn degree(&self) -> usize {
|
||||
1 << self.degree_bits
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::fri::commitment::SALT_SIZE;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -125,7 +125,7 @@ pub(crate) fn eval_l_1<F: Field>(n: usize, x: F) -> F {
|
||||
/// the order-`n` subgroup.
|
||||
///
|
||||
/// Assumes `x != 1`; if `x` could be 1 then this is unsound.
|
||||
pub(crate) fn eval_l_1_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn eval_l_1_recursively<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
n: usize,
|
||||
x: ExtensionTarget<D>,
|
||||
@ -163,7 +163,7 @@ pub(crate) fn reduce_with_powers<F: Field>(terms: &[F], alpha: F) -> F {
|
||||
sum
|
||||
}
|
||||
|
||||
pub(crate) fn reduce_with_powers_ext_recursive<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn reduce_with_powers_ext_recursive<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
terms: &[ExtensionTarget<D>],
|
||||
alpha: Target,
|
||||
|
||||
@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::fri::commitment::PolynomialBatchCommitment;
|
||||
use crate::fri::proof::{FriProof, FriProofTarget};
|
||||
use crate::hash::hash_types::MerkleCapTarget;
|
||||
@ -58,7 +58,7 @@ pub struct OpeningSet<F: Extendable<D>, const D: usize> {
|
||||
pub quotient_polys: Vec<F::Extension>,
|
||||
}
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> OpeningSet<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> OpeningSet<F, D> {
|
||||
pub fn new(
|
||||
z: F::Extension,
|
||||
g: F::Extension,
|
||||
|
||||
@ -3,7 +3,7 @@ use log::Level;
|
||||
use rayon::prelude::*;
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::fri::commitment::PolynomialBatchCommitment;
|
||||
use crate::hash::hash_types::HashOut;
|
||||
use crate::hash::hashing::hash_n_to_hash;
|
||||
@ -22,7 +22,7 @@ use crate::util::partial_products::partial_products;
|
||||
use crate::util::timing::TimingTree;
|
||||
use crate::util::{log2_ceil, transpose};
|
||||
|
||||
pub(crate) fn prove<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn prove<F: RichField + Extendable<D>, const D: usize>(
|
||||
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
inputs: PartialWitness<F>,
|
||||
@ -217,7 +217,7 @@ pub(crate) fn prove<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
}
|
||||
|
||||
/// Compute the partial products used in the `Z` polynomials.
|
||||
fn all_wires_permutation_partial_products<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn all_wires_permutation_partial_products<F: RichField + Extendable<D>, const D: usize>(
|
||||
witness: &MatrixWitness<F>,
|
||||
betas: &[F],
|
||||
gammas: &[F],
|
||||
@ -240,7 +240,7 @@ fn all_wires_permutation_partial_products<F: PrimeField + Extendable<D>, const D
|
||||
/// Compute the partial products used in the `Z` polynomial.
|
||||
/// Returns the polynomials interpolating `partial_products(f / g)`
|
||||
/// where `f, g` are the products in the definition of `Z`: `Z(g^i) = f / g`.
|
||||
fn wires_permutation_partial_products<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn wires_permutation_partial_products<F: RichField + Extendable<D>, const D: usize>(
|
||||
witness: &MatrixWitness<F>,
|
||||
beta: F,
|
||||
gamma: F,
|
||||
@ -294,7 +294,7 @@ fn wires_permutation_partial_products<F: PrimeField + Extendable<D>, const D: us
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn compute_zs<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn compute_zs<F: RichField + Extendable<D>, const D: usize>(
|
||||
partial_products: &[Vec<PolynomialValues<F>>],
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> Vec<PolynomialValues<F>> {
|
||||
@ -304,7 +304,7 @@ fn compute_zs<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
}
|
||||
|
||||
/// Compute the `Z` polynomial by reusing the computations done in `wires_permutation_partial_products`.
|
||||
fn compute_z<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn compute_z<F: RichField + Extendable<D>, const D: usize>(
|
||||
partial_products: &[PolynomialValues<F>],
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> PolynomialValues<F> {
|
||||
@ -317,7 +317,7 @@ fn compute_z<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
plonk_z_points.into()
|
||||
}
|
||||
|
||||
fn compute_quotient_polys<'a, F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn compute_quotient_polys<'a, F: RichField + Extendable<D>, const D: usize>(
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
prover_data: &'a ProverOnlyCircuitData<F, D>,
|
||||
public_inputs_hash: &HashOut<F>,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::hash::hash_types::HashOutTarget;
|
||||
use crate::iop::challenger::RecursiveChallenger;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -10,7 +10,7 @@ use crate::plonk::vars::EvaluationTargets;
|
||||
use crate::util::reducing::ReducingFactorTarget;
|
||||
use crate::with_context;
|
||||
|
||||
impl<F: PrimeField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Recursively verifies an inner proof.
|
||||
pub fn add_recursive_verifier(
|
||||
&mut self,
|
||||
@ -140,7 +140,7 @@ mod tests {
|
||||
use crate::util::log2_strict;
|
||||
|
||||
// Construct a `FriQueryRoundTarget` with the same dimensions as the ones in `proof`.
|
||||
fn get_fri_query_round<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn get_fri_query_round<F: RichField + Extendable<D>, const D: usize>(
|
||||
proof: &Proof<F, D>,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> FriQueryRoundTarget<D> {
|
||||
@ -173,7 +173,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// Construct a `ProofTarget` with the same dimensions as `proof`.
|
||||
fn proof_to_proof_target<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
fn proof_to_proof_target<F: RichField + Extendable<D>, const D: usize>(
|
||||
proof_with_pis: &ProofWithPublicInputs<F, D>,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ProofWithPublicInputsTarget<D> {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::gate::PrefixedGate;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -15,7 +15,7 @@ use crate::with_context;
|
||||
/// Evaluate the vanishing polynomial at `x`. In this context, the vanishing polynomial is a random
|
||||
/// linear combination of gate constraints, plus some other terms relating to the permutation
|
||||
/// argument. All such terms should vanish on `H`.
|
||||
pub(crate) fn eval_vanishing_poly<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn eval_vanishing_poly<F: RichField + Extendable<D>, const D: usize>(
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
x: F::Extension,
|
||||
vars: EvaluationVars<F, D>,
|
||||
@ -102,7 +102,7 @@ pub(crate) fn eval_vanishing_poly<F: PrimeField + Extendable<D>, const D: usize>
|
||||
}
|
||||
|
||||
/// Like `eval_vanishing_poly`, but specialized for base field points.
|
||||
pub(crate) fn eval_vanishing_poly_base<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn eval_vanishing_poly_base<F: RichField + Extendable<D>, const D: usize>(
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
index: usize,
|
||||
x: F,
|
||||
@ -200,7 +200,7 @@ pub(crate) fn eval_vanishing_poly_base<F: PrimeField + Extendable<D>, const D: u
|
||||
/// `num_gate_constraints` is the largest number of constraints imposed by any gate. It is not
|
||||
/// strictly necessary, but it helps performance by ensuring that we allocate a vector with exactly
|
||||
/// the capacity that we need.
|
||||
pub fn evaluate_gate_constraints<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub fn evaluate_gate_constraints<F: RichField + Extendable<D>, const D: usize>(
|
||||
gates: &[PrefixedGate<F, D>],
|
||||
num_gate_constraints: usize,
|
||||
vars: EvaluationVars<F, D>,
|
||||
@ -219,7 +219,7 @@ pub fn evaluate_gate_constraints<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
constraints
|
||||
}
|
||||
|
||||
pub fn evaluate_gate_constraints_base<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub fn evaluate_gate_constraints_base<F: RichField + Extendable<D>, const D: usize>(
|
||||
gates: &[PrefixedGate<F, D>],
|
||||
num_gate_constraints: usize,
|
||||
vars: EvaluationVarsBase<F>,
|
||||
@ -238,7 +238,7 @@ pub fn evaluate_gate_constraints_base<F: PrimeField + Extendable<D>, const D: us
|
||||
constraints
|
||||
}
|
||||
|
||||
pub fn evaluate_gate_constraints_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub fn evaluate_gate_constraints_recursively<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
gates: &[PrefixedGate<F, D>],
|
||||
num_gate_constraints: usize,
|
||||
@ -270,7 +270,7 @@ pub fn evaluate_gate_constraints_recursively<F: PrimeField + Extendable<D>, cons
|
||||
///
|
||||
/// Assumes `x != 1`; if `x` could be 1 then this is unsound. This is fine if `x` is a random
|
||||
/// variable drawn from a sufficiently large domain.
|
||||
pub(crate) fn eval_vanishing_poly_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn eval_vanishing_poly_recursively<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
x: ExtensionTarget<D>,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use anyhow::{ensure, Result};
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::fri::verifier::verify_fri_proof;
|
||||
use crate::hash::hashing::hash_n_to_hash;
|
||||
use crate::iop::challenger::Challenger;
|
||||
@ -11,7 +11,7 @@ use crate::plonk::proof::ProofWithPublicInputs;
|
||||
use crate::plonk::vanishing_poly::eval_vanishing_poly;
|
||||
use crate::plonk::vars::EvaluationVars;
|
||||
|
||||
pub(crate) fn verify<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn verify<F: RichField + Extendable<D>, const D: usize>(
|
||||
proof_with_pis: ProofWithPublicInputs<F, D>,
|
||||
verifier_data: &VerifierOnlyCircuitData<F>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
|
||||
@ -3,7 +3,7 @@ use std::ops::Sub;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::PrimeField;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::util::ceil_div_usize;
|
||||
|
||||
@ -61,7 +61,7 @@ pub fn check_partial_products<T: Product + Copy + Sub<Output = T>>(
|
||||
res
|
||||
}
|
||||
|
||||
pub fn check_partial_products_recursively<F: PrimeField + Extendable<D>, const D: usize>(
|
||||
pub fn check_partial_products_recursively<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
v: &[ExtensionTarget<D>],
|
||||
partials: &[ExtensionTarget<D>],
|
||||
|
||||
@ -2,7 +2,7 @@ use std::borrow::Borrow;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::gates::reducing::ReducingGate;
|
||||
use crate::iop::target::Target;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
@ -100,7 +100,7 @@ impl<const D: usize> ReducingFactorTarget<D> {
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D>
|
||||
where
|
||||
F: PrimeField + Extendable<D>,
|
||||
F: RichField + Extendable<D>,
|
||||
{
|
||||
let max_coeffs_len = ReducingGate::<D>::max_coeffs_len(
|
||||
builder.config.num_wires,
|
||||
@ -149,7 +149,7 @@ impl<const D: usize> ReducingFactorTarget<D> {
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D>
|
||||
where
|
||||
F: PrimeField + Extendable<D>,
|
||||
F: RichField + Extendable<D>,
|
||||
{
|
||||
let l = terms.len();
|
||||
self.count += l as u64;
|
||||
@ -170,7 +170,7 @@ impl<const D: usize> ReducingFactorTarget<D> {
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D>
|
||||
where
|
||||
F: PrimeField + Extendable<D>,
|
||||
F: RichField + Extendable<D>,
|
||||
{
|
||||
let exp = builder.exp_u64_extension(self.base, self.count);
|
||||
self.count = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user