Merge branch 'main' into more_recursive_verifier

# Conflicts:
#	src/polynomial/commitment.rs
#	src/proof.rs
This commit is contained in:
wborgeaud 2021-07-19 07:08:06 +02:00
commit 461f24a57e
22 changed files with 91 additions and 64 deletions

View File

@ -18,9 +18,11 @@ itertools = "0.10.0"
num = "0.3" num = "0.3"
rand = "0.7.3" rand = "0.7.3"
rand_chacha = "0.2.2" rand_chacha = "0.2.2"
rayon = "1.5.0" rayon = "1.5.1"
unroll = "0.1.5" unroll = "0.1.5"
anyhow = "1.0.40" anyhow = "1.0.40"
serde = { version = "1.0", features = ["derive"] }
serde_cbor = "0.11.1"
[profile.release] [profile.release]
opt-level = 3 opt-level = 3

View File

@ -1,3 +1,4 @@
use std::convert::TryInto;
use std::thread; use std::thread;
use std::time::Instant; use std::time::Instant;
@ -15,15 +16,12 @@ fn main() {
const THREADS: usize = 12; const THREADS: usize = 12;
const LDE_BITS: i32 = 3; const LDE_BITS: i32 = 3;
const W: usize = 12; const W: usize = 12;
const HASHES_PER_POLY: usize = 1 << (13 + LDE_BITS) / 6; const HASHES_PER_POLY: usize = 1 << ((13 + LDE_BITS) / 6);
let threads = (0..THREADS) let threads = (0..THREADS)
.map(|_i| { .map(|_i| {
thread::spawn(move || { thread::spawn(move || {
let mut x = [F::ZERO; W]; let mut x: [F; W] = F::rand_vec(W).try_into().unwrap();
for i in 0..W {
x[i] = F::from_canonical_u64((i as u64) * 123456 + 789);
}
let hashes_per_thread = HASHES_PER_POLY * PROVER_POLYS / THREADS; let hashes_per_thread = HASHES_PER_POLY * PROVER_POLYS / THREADS;
let start = Instant::now(); let start = Instant::now();

View File

@ -1,4 +1,5 @@
use env_logger::Env; use env_logger::Env;
use log::info;
use plonky2::circuit_builder::CircuitBuilder; use plonky2::circuit_builder::CircuitBuilder;
use plonky2::circuit_data::CircuitConfig; use plonky2::circuit_data::CircuitConfig;
use plonky2::field::crandall_field::CrandallField; use plonky2::field::crandall_field::CrandallField;
@ -25,10 +26,10 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() {
rate_bits: 3, rate_bits: 3,
num_challenges: 3, num_challenges: 3,
fri_config: FriConfig { fri_config: FriConfig {
proof_of_work_bits: 1, proof_of_work_bits: 20,
rate_bits: 3, rate_bits: 3,
reduction_arity_bits: vec![2, 2, 2, 2, 2], reduction_arity_bits: vec![2, 2, 2, 2, 2, 2],
num_query_rounds: 1, num_query_rounds: 35,
}, },
}; };
@ -46,7 +47,10 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() {
builder.add(zero, zero); builder.add(zero, zero);
builder.add_extension(zero_ext, zero_ext); builder.add_extension(zero_ext, zero_ext);
let prover = builder.build_prover(); let circuit = builder.build();
let inputs = PartialWitness::new(); let inputs = PartialWitness::new();
prover.prove(inputs); let proof = circuit.prove(inputs);
let proof_bytes = serde_cbor::to_vec(&proof).unwrap();
info!("Proof length: {} bytes", proof_bytes.len());
circuit.verify(proof).unwrap();
} }

View File

@ -1,3 +1,4 @@
use std::convert::TryInto;
use std::thread; use std::thread;
use std::time::Instant; use std::time::Instant;
@ -19,10 +20,7 @@ fn main() {
let threads = (0..THREADS) let threads = (0..THREADS)
.map(|_i| { .map(|_i| {
thread::spawn(move || { thread::spawn(move || {
let mut x = [F::ZERO; W]; let mut x: [F; W] = F::rand_vec(W).try_into().unwrap();
for i in 0..W {
x[i] = F::from_canonical_u64((i as u64) * 123456 + 789);
}
let hashes_per_thread = HASHES_PER_POLY * PROVER_POLYS / THREADS; let hashes_per_thread = HASHES_PER_POLY * PROVER_POLYS / THREADS;
let start = Instant::now(); let start = Instant::now();

View File

@ -39,7 +39,7 @@ impl Default for CircuitConfig {
num_challenges: 3, num_challenges: 3,
fri_config: FriConfig { fri_config: FriConfig {
proof_of_work_bits: 1, proof_of_work_bits: 1,
rate_bits: 1, rate_bits: 3,
reduction_arity_bits: vec![1, 1, 1, 1], reduction_arity_bits: vec![1, 1, 1, 1],
num_query_rounds: 1, num_query_rounds: 1,
}, },

View File

@ -5,6 +5,7 @@ use std::iter::{Product, Sum};
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use num::Integer; use num::Integer;
use serde::{Deserialize, Serialize};
use crate::field::extension_field::quadratic::QuadraticCrandallField; use crate::field::extension_field::quadratic::QuadraticCrandallField;
use crate::field::extension_field::quartic::QuarticCrandallField; use crate::field::extension_field::quartic::QuarticCrandallField;
@ -106,7 +107,7 @@ const CAUCHY_MDS_8: [[CrandallField; 8]; 8] = [
/// = 2**64 - 9 * 2**28 + 1 /// = 2**64 - 9 * 2**28 + 1
/// = 2**28 * (2**36 - 9) + 1 /// = 2**28 * (2**36 - 9) + 1
/// ``` /// ```
#[derive(Copy, Clone)] #[derive(Copy, Clone, Serialize, Deserialize)]
pub struct CrandallField(pub u64); pub struct CrandallField(pub u64);
impl PartialEq for CrandallField { impl PartialEq for CrandallField {

View File

@ -4,12 +4,13 @@ use std::iter::{Product, Sum};
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use rand::Rng; use rand::Rng;
use serde::{Deserialize, Serialize};
use crate::field::crandall_field::CrandallField; use crate::field::crandall_field::CrandallField;
use crate::field::extension_field::{FieldExtension, Frobenius, OEF}; use crate::field::extension_field::{FieldExtension, Frobenius, OEF};
use crate::field::field::Field; use crate::field::field::Field;
#[derive(Copy, Clone, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct QuadraticCrandallField([CrandallField; 2]); pub struct QuadraticCrandallField([CrandallField; 2]);
impl OEF<2> for QuadraticCrandallField { impl OEF<2> for QuadraticCrandallField {

View File

@ -4,13 +4,14 @@ use std::iter::{Product, Sum};
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use rand::Rng; use rand::Rng;
use serde::{Deserialize, Serialize};
use crate::field::crandall_field::CrandallField; use crate::field::crandall_field::CrandallField;
use crate::field::extension_field::{FieldExtension, Frobenius, OEF}; use crate::field::extension_field::{FieldExtension, Frobenius, OEF};
use crate::field::field::Field; use crate::field::field::Field;
/// A quartic extension of `CrandallField`. /// A quartic extension of `CrandallField`.
#[derive(Copy, Clone, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct QuarticCrandallField(pub(crate) [CrandallField; 4]); pub struct QuarticCrandallField(pub(crate) [CrandallField; 4]);
impl OEF<4> for QuarticCrandallField { impl OEF<4> for QuarticCrandallField {

View File

@ -250,9 +250,9 @@ fn fft_unrolled<F: Field>(input: Vec<F>, r_orig: usize, root_table: FftRootTable
// NB: Grouping statements as is done in the main loop below // NB: Grouping statements as is done in the main loop below
// does not seem to help here (worse by a few millis). // does not seem to help here (worse by a few millis).
let omega_0 = root_table[0][0]; let omega_0 = root_table[0][0];
let tmp_0 = omega_0 * values[k + 2 + 0]; let tmp_0 = omega_0 * values[k + 2];
values[k + 2 + 0] = values[k + 0] - tmp_0; values[k + 2] = values[k] - tmp_0;
values[k + 0] += tmp_0; values[k] += tmp_0;
let omega_1 = root_table[0][1]; let omega_1 = root_table[0][1];
let tmp_1 = omega_1 * values[k + 2 + 1]; let tmp_1 = omega_1 * values[k + 2 + 1];
@ -281,21 +281,21 @@ fn fft_unrolled<F: Field>(input: Vec<F>, r_orig: usize, root_table: FftRootTable
let off1 = k + j; let off1 = k + j;
let off2 = k + m + j; let off2 = k + m + j;
let omega_0 = root_table[lg_m - 1][j + 0]; let omega_0 = root_table[lg_m - 1][j];
let omega_1 = root_table[lg_m - 1][j + 1]; let omega_1 = root_table[lg_m - 1][j + 1];
let omega_2 = root_table[lg_m - 1][j + 2]; let omega_2 = root_table[lg_m - 1][j + 2];
let omega_3 = root_table[lg_m - 1][j + 3]; let omega_3 = root_table[lg_m - 1][j + 3];
let tmp_0 = omega_0 * values[off2 + 0]; let tmp_0 = omega_0 * values[off2];
let tmp_1 = omega_1 * values[off2 + 1]; let tmp_1 = omega_1 * values[off2 + 1];
let tmp_2 = omega_2 * values[off2 + 2]; let tmp_2 = omega_2 * values[off2 + 2];
let tmp_3 = omega_3 * values[off2 + 3]; let tmp_3 = omega_3 * values[off2 + 3];
values[off2 + 0] = values[off1 + 0] - tmp_0; values[off2] = values[off1] - tmp_0;
values[off2 + 1] = values[off1 + 1] - tmp_1; values[off2 + 1] = values[off1 + 1] - tmp_1;
values[off2 + 2] = values[off1 + 2] - tmp_2; values[off2 + 2] = values[off1 + 2] - tmp_2;
values[off2 + 3] = values[off1 + 3] - tmp_3; values[off2 + 3] = values[off1 + 3] - tmp_3;
values[off1 + 0] += tmp_0; values[off1] += tmp_0;
values[off1 + 1] += tmp_1; values[off1 + 1] += tmp_1;
values[off1 + 2] += tmp_2; values[off1 + 2] += tmp_2;
values[off1 + 3] += tmp_3; values[off1 + 3] += tmp_3;

View File

@ -6,6 +6,8 @@ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssi
use num::Integer; use num::Integer;
use rand::Rng; use rand::Rng;
use serde::de::DeserializeOwned;
use serde::Serialize;
use crate::field::extension_field::Frobenius; use crate::field::extension_field::Frobenius;
use crate::util::bits_u64; use crate::util::bits_u64;
@ -31,6 +33,8 @@ pub trait Field:
+ Display + Display
+ Send + Send
+ Sync + Sync
+ Serialize
+ DeserializeOwned
{ {
type PrimeField: Field; type PrimeField: Field;
@ -131,7 +135,7 @@ pub trait Field:
fn primitive_root_of_unity(n_log: usize) -> Self { fn primitive_root_of_unity(n_log: usize) -> Self {
assert!(n_log <= Self::TWO_ADICITY); assert!(n_log <= Self::TWO_ADICITY);
let mut base = Self::POWER_OF_TWO_GENERATOR; let base = Self::POWER_OF_TWO_GENERATOR;
base.exp_power_of_2(Self::TWO_ADICITY - n_log) base.exp_power_of_2(Self::TWO_ADICITY - n_log)
} }

View File

@ -1,3 +1,5 @@
use rayon::prelude::*;
use crate::field::extension_field::{flatten, unflatten, Extendable}; use crate::field::extension_field::{flatten, unflatten, Extendable};
use crate::field::field::Field; use crate::field::field::Field;
use crate::fri::FriConfig; use crate::fri::FriConfig;
@ -7,6 +9,7 @@ use crate::plonk_challenger::Challenger;
use crate::plonk_common::reduce_with_powers; use crate::plonk_common::reduce_with_powers;
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues}; use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
use crate::proof::{FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep, Hash}; use crate::proof::{FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep, Hash};
use crate::timed;
use crate::util::reverse_index_bits_in_place; use crate::util::reverse_index_bits_in_place;
/// Builds a FRI proof. /// Builds a FRI proof.
@ -32,7 +35,10 @@ pub fn fri_proof<F: Field + Extendable<D>, const D: usize>(
// PoW phase // PoW phase
let current_hash = challenger.get_hash(); let current_hash = challenger.get_hash();
let pow_witness = fri_proof_of_work(current_hash, config); let pow_witness = timed!(
fri_proof_of_work(current_hash, config),
"to find for proof-of-work witness"
);
// Query phase // Query phase
let query_round_proofs = let query_round_proofs =
@ -94,8 +100,9 @@ fn fri_committed_trees<F: Field + Extendable<D>, const D: usize>(
} }
fn fri_proof_of_work<F: Field>(current_hash: Hash<F>, config: &FriConfig) -> F { fn fri_proof_of_work<F: Field>(current_hash: Hash<F>, config: &FriConfig) -> F {
(0u64..) (0..u64::MAX)
.find(|&i| { .into_par_iter()
.find_any(|&i| {
hash_n_to_1( hash_n_to_1(
current_hash current_hash
.elements .elements
@ -110,7 +117,7 @@ fn fri_proof_of_work<F: Field>(current_hash: Hash<F>, config: &FriConfig) -> F {
>= config.proof_of_work_bits + F::ORDER.leading_zeros() >= config.proof_of_work_bits + F::ORDER.leading_zeros()
}) })
.map(F::from_canonical_u64) .map(F::from_canonical_u64)
.expect("Proof of work failed.") .expect("Proof of work failed. This is highly unlikely!")
} }
fn fri_prover_query_rounds<F: Field + Extendable<D>, const D: usize>( fn fri_prover_query_rounds<F: Field + Extendable<D>, const D: usize>(

View File

@ -1,3 +1,6 @@
// Gates have `new` methods that return `GateRef`s.
#![allow(clippy::new_ret_no_self)]
pub mod arithmetic; pub mod arithmetic;
pub mod base_sum; pub mod base_sum;
pub mod constant; pub mod constant;

View File

@ -56,8 +56,8 @@ pub fn gmimc_permute_array<F: Field, const W: usize, const R: usize>(
xs[active] -= f; xs[active] -= f;
} }
for i in 0..W { for x_i in xs.iter_mut() {
xs[i] += addition_buffer; *x_i += addition_buffer;
} }
xs xs

View File

@ -117,12 +117,6 @@ pub const GMIMC_CONSTANTS: [u64; GMIMC_ROUNDS] = [
8651171085167737860, 8651171085167737860,
]; ];
/// Controls the granularity of parallelization when building Merkle trees. I.e., we will try to
/// split up the task into units of work, such that each unit involves hashing roughly this many
/// elements. If this is too small, there may be too much synchronization overhead; if it's too
/// large, some threads may spend significant time idle.
const ELEMS_PER_CHUNK: usize = 1 << 8;
/// Hash the vector if necessary to reduce its length to ~256 bits. If it already fits, this is a /// Hash the vector if necessary to reduce its length to ~256 bits. If it already fits, this is a
/// no-op. /// no-op.
pub fn hash_or_noop<F: Field>(inputs: Vec<F>) -> Hash<F> { pub fn hash_or_noop<F: Field>(inputs: Vec<F>) -> Hash<F> {
@ -226,8 +220,8 @@ pub fn hash_n_to_m<F: Field>(mut inputs: Vec<F>, num_outputs: usize, pad: bool)
// Squeeze until we have the desired number of outputs. // Squeeze until we have the desired number of outputs.
let mut outputs = Vec::new(); let mut outputs = Vec::new();
loop { loop {
for i in 0..SPONGE_RATE { for &item in state.iter().take(SPONGE_RATE) {
outputs.push(state[i]); outputs.push(item);
if outputs.len() == num_outputs { if outputs.len() == num_outputs {
return outputs; return outputs;
} }

View File

@ -1,4 +1,5 @@
use anyhow::{ensure, Result}; use anyhow::{ensure, Result};
use serde::{Deserialize, Serialize};
use crate::circuit_builder::CircuitBuilder; use crate::circuit_builder::CircuitBuilder;
use crate::field::extension_field::Extendable; use crate::field::extension_field::Extendable;
@ -10,7 +11,8 @@ use crate::proof::{Hash, HashTarget};
use crate::target::Target; use crate::target::Target;
use crate::wire::Wire; use crate::wire::Wire;
#[derive(Clone, Debug)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(bound = "")]
pub struct MerkleProof<F: Field> { pub struct MerkleProof<F: Field> {
/// The Merkle digest of each sibling subtree, staying from the bottommost layer. /// The Merkle digest of each sibling subtree, staying from the bottommost layer.
pub siblings: Vec<Hash<F>>, pub siblings: Vec<Hash<F>>,

View File

@ -46,7 +46,7 @@ impl<T: Debug + Copy + Eq + PartialEq + Hash, F: Fn(T) -> usize> TargetPartition
} }
/// Path compression method, see https://en.wikipedia.org/wiki/Disjoint-set_data_structure#Finding_set_representatives. /// Path compression method, see https://en.wikipedia.org/wiki/Disjoint-set_data_structure#Finding_set_representatives.
pub fn find(&mut self, mut x: ForestNode<T>) -> ForestNode<T> { pub fn find(&mut self, x: ForestNode<T>) -> ForestNode<T> {
if x.parent != x.index { if x.parent != x.index {
let root = self.find(self.forest[x.parent]); let root = self.find(self.forest[x.parent]);
self.forest[x.index].parent = root.index; self.forest[x.index].parent = root.index;

View File

@ -1,5 +1,6 @@
use anyhow::Result; use anyhow::Result;
use rayon::prelude::*; use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use crate::circuit_builder::CircuitBuilder; use crate::circuit_builder::CircuitBuilder;
use crate::circuit_data::CommonCircuitData; use crate::circuit_data::CommonCircuitData;
@ -247,9 +248,10 @@ impl<F: Field> ListPolynomialCommitment<F> {
} }
} }
#[derive(Clone)] #[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "")]
pub struct OpeningProof<F: Extendable<D>, const D: usize> { pub struct OpeningProof<F: Extendable<D>, const D: usize> {
pub fri_proof: FriProof<F, D>, fri_proof: FriProof<F, D>,
// TODO: Get the degree from `CommonCircuitData` instead. // TODO: Get the degree from `CommonCircuitData` instead.
quotient_degree: usize, quotient_degree: usize,
} }
@ -281,7 +283,7 @@ impl<F: Extendable<D>, const D: usize> OpeningProof<F, D> {
} }
pub struct OpeningProofTarget<const D: usize> { pub struct OpeningProofTarget<const D: usize> {
pub fri_proof: FriProofTarget<D>, fri_proof: FriProofTarget<D>,
} }
impl<const D: usize> OpeningProofTarget<D> { impl<const D: usize> OpeningProofTarget<D> {

View File

@ -3,6 +3,7 @@ use std::iter::Sum;
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
use anyhow::{ensure, Result}; use anyhow::{ensure, Result};
use serde::{Deserialize, Serialize};
use crate::field::extension_field::Extendable; use crate::field::extension_field::Extendable;
use crate::field::fft::{fft, fft_with_options, ifft}; use crate::field::fft::{fft, fft_with_options, ifft};
@ -76,7 +77,8 @@ impl<F: Field> From<Vec<F>> for PolynomialValues<F> {
} }
/// A polynomial in coefficient form. /// A polynomial in coefficient form.
#[derive(Clone, Debug)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(bound = "")]
pub struct PolynomialCoeffs<F: Field> { pub struct PolynomialCoeffs<F: Field> {
pub(crate) coeffs: Vec<F>, pub(crate) coeffs: Vec<F>,
} }

View File

@ -1,5 +1,7 @@
use std::convert::TryInto; use std::convert::TryInto;
use serde::{Deserialize, Serialize};
use crate::circuit_data::CommonCircuitData; use crate::circuit_data::CommonCircuitData;
use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable; use crate::field::extension_field::Extendable;
@ -12,7 +14,8 @@ use crate::polynomial::polynomial::PolynomialCoeffs;
use crate::target::Target; use crate::target::Target;
/// Represents a ~256 bit hash output. /// Represents a ~256 bit hash output.
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(bound = "")]
pub struct Hash<F: Field> { pub struct Hash<F: Field> {
pub(crate) elements: [F; 4], pub(crate) elements: [F; 4],
} }
@ -61,7 +64,8 @@ impl HashTarget {
} }
} }
#[derive(Clone)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "")]
pub struct Proof<F: Extendable<D>, const D: usize> { pub struct Proof<F: Extendable<D>, const D: usize> {
/// Merkle root of LDEs of wire values. /// Merkle root of LDEs of wire values.
pub wires_root: Hash<F>, pub wires_root: Hash<F>,
@ -84,8 +88,9 @@ pub struct ProofTarget<const D: usize> {
} }
/// Evaluations and Merkle proof produced by the prover in a FRI query step. /// Evaluations and Merkle proof produced by the prover in a FRI query step.
#[derive(Clone)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct FriQueryStep<F: Field + Extendable<D>, const D: usize> { #[serde(bound = "")]
pub struct FriQueryStep<F: Extendable<D>, const D: usize> {
pub evals: Vec<F::Extension>, pub evals: Vec<F::Extension>,
pub merkle_proof: MerkleProof<F>, pub merkle_proof: MerkleProof<F>,
} }
@ -98,7 +103,8 @@ pub struct FriQueryStepTarget<const D: usize> {
/// Evaluations and Merkle proofs of the original set of polynomials, /// Evaluations and Merkle proofs of the original set of polynomials,
/// before they are combined into a composition polynomial. /// before they are combined into a composition polynomial.
#[derive(Clone)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "")]
pub struct FriInitialTreeProof<F: Field> { pub struct FriInitialTreeProof<F: Field> {
pub evals_proofs: Vec<(Vec<F>, MerkleProof<F>)>, pub evals_proofs: Vec<(Vec<F>, MerkleProof<F>)>,
} }
@ -123,8 +129,9 @@ impl FriInitialTreeProofTarget {
} }
/// Proof for a FRI query round. /// Proof for a FRI query round.
#[derive(Clone)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct FriQueryRound<F: Field + Extendable<D>, const D: usize> { #[serde(bound = "")]
pub struct FriQueryRound<F: Extendable<D>, const D: usize> {
pub initial_trees_proof: FriInitialTreeProof<F>, pub initial_trees_proof: FriInitialTreeProof<F>,
pub steps: Vec<FriQueryStep<F, D>>, pub steps: Vec<FriQueryStep<F, D>>,
} }
@ -135,8 +142,9 @@ pub struct FriQueryRoundTarget<const D: usize> {
pub steps: Vec<FriQueryStepTarget<D>>, pub steps: Vec<FriQueryStepTarget<D>>,
} }
#[derive(Clone)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct FriProof<F: Field + Extendable<D>, const D: usize> { #[serde(bound = "")]
pub struct FriProof<F: Extendable<D>, const D: usize> {
/// A Merkle root for each reduced polynomial in the commit phase. /// A Merkle root for each reduced polynomial in the commit phase.
pub commit_phase_merkle_roots: Vec<Hash<F>>, pub commit_phase_merkle_roots: Vec<Hash<F>>,
/// Query rounds proofs /// Query rounds proofs
@ -154,9 +162,9 @@ pub struct FriProofTarget<const D: usize> {
pub pow_witness: Target, pub pow_witness: Target,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, Serialize, Deserialize)]
/// The purported values of each polynomial at a single point. /// The purported values of each polynomial at a single point.
pub struct OpeningSet<F: Field + Extendable<D>, const D: usize> { pub struct OpeningSet<F: Extendable<D>, const D: usize> {
pub constants: Vec<F::Extension>, pub constants: Vec<F::Extension>,
pub plonk_sigmas: Vec<F::Extension>, pub plonk_sigmas: Vec<F::Extension>,
pub wires: Vec<F::Extension>, pub wires: Vec<F::Extension>,
@ -166,7 +174,7 @@ pub struct OpeningSet<F: Field + Extendable<D>, const D: usize> {
pub quotient_polys: Vec<F::Extension>, pub quotient_polys: Vec<F::Extension>,
} }
impl<F: Field + Extendable<D>, const D: usize> OpeningSet<F, D> { impl<F: Extendable<D>, const D: usize> OpeningSet<F, D> {
pub fn new( pub fn new(
z: F::Extension, z: F::Extension,
g: F::Extension, g: F::Extension,

View File

@ -86,7 +86,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
let gammas = challenger.get_n_challenges(num_challenges); let gammas = challenger.get_n_challenges(num_challenges);
assert!( assert!(
common_data.quotient_degree_factor + 1 <=common_data.config.num_routed_wires, common_data.quotient_degree_factor < common_data.config.num_routed_wires,
"When the number of routed wires is smaller that the degree, we should change the logic to avoid computing partial products." "When the number of routed wires is smaller that the degree, we should change the logic to avoid computing partial products."
); );
let mut partial_products = timed!( let mut partial_products = timed!(

View File

@ -179,7 +179,7 @@ const MDS: [[u64; W]; W] = [
], ],
]; ];
const RESCUE_CONSTANTS: [[u64; W]; 16] = [ const RESCUE_CONSTANTS: [[u64; W]; ROUNDS * 2] = [
[ [
12050887499329086906, 12050887499329086906,
1748247961703512657, 1748247961703512657,
@ -442,7 +442,7 @@ fn mds_layer<F: Field>(x: [F; W]) -> [F; W] {
let mut result = [F::ZERO; W]; let mut result = [F::ZERO; W];
for r in 0..W { for r in 0..W {
for c in 0..W { for c in 0..W {
result[r] = result[r] + F::from_canonical_u64(MDS[r][c]) * x[c]; result[r] += F::from_canonical_u64(MDS[r][c]) * x[c];
} }
} }
result result

View File

@ -43,8 +43,8 @@ pub(crate) fn transpose<T: Clone>(matrix: &[Vec<T>]) -> Vec<Vec<T>> {
let old_cols = matrix[0].len(); let old_cols = matrix[0].len();
let mut transposed = vec![Vec::with_capacity(old_rows); old_cols]; let mut transposed = vec![Vec::with_capacity(old_rows); old_cols];
for new_r in 0..old_cols { for new_r in 0..old_cols {
for new_c in 0..old_rows { for old_row in matrix.iter() {
transposed[new_r].push(matrix[new_c][new_r].clone()); transposed[new_r].push(old_row[new_r].clone());
} }
} }
transposed transposed