Const generics everywhere

This commit is contained in:
wborgeaud 2021-05-18 15:44:50 +02:00
parent 37f6ee53cc
commit adf5c2d4ec
8 changed files with 72 additions and 88 deletions

View File

@ -20,7 +20,7 @@ fn main() {
// change this to info or warn later.
env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init();
bench_prove::<CrandallField>();
bench_prove::<CrandallField, 2>();
// bench_field_mul::<CrandallField>();
@ -29,7 +29,7 @@ fn main() {
// bench_gmimc::<CrandallField>();
}
fn bench_prove<F: Field + Extendable<EXTENSION_DEGREE>>() {
fn bench_prove<F: Field + Extendable<D>, const D: usize>() {
let gmimc_gate = GMiMCGate::<F, GMIMC_ROUNDS>::with_automatic_constants();
let config = CircuitConfig {

View File

@ -56,8 +56,11 @@ pub struct CircuitData<F: Field> {
pub(crate) common: CommonCircuitData<F>,
}
impl<F: Field + Extendable<EXTENSION_DEGREE>> CircuitData<F> {
pub fn prove(&self, inputs: PartialWitness<F>) -> Proof<F> {
impl<F: Field> CircuitData<F> {
pub fn prove<const D: usize>(&self, inputs: PartialWitness<F>) -> Proof<F, D>
where
F: Extendable<D>,
{
prove(&self.prover_only, &self.common, inputs)
}
@ -78,8 +81,11 @@ pub struct ProverCircuitData<F: Field> {
pub(crate) common: CommonCircuitData<F>,
}
impl<F: Field + Extendable<EXTENSION_DEGREE>> ProverCircuitData<F> {
pub fn prove(&self, inputs: PartialWitness<F>) -> Proof<F> {
impl<F: Field> ProverCircuitData<F> {
pub fn prove<const D: usize>(&self, inputs: PartialWitness<F>) -> Proof<F, D>
where
F: Extendable<D>,
{
prove(&self.prover_only, &self.common, inputs)
}
}

View File

@ -100,9 +100,9 @@ mod tests {
PolynomialValues::new(coset_lde.values.into_iter().map(|x| F2::from(x)).collect());
let root = tree.root;
let mut challenger = Challenger::new();
let proof = fri_proof(
let proof = fri_proof::<F, 2>(
&[&tree],
&coeffs.to_extension::<EXTENSION_DEGREE>(),
&coeffs.to_extension::<2>(),
&coset_lde,
&mut challenger,
&config,

View File

@ -11,7 +11,7 @@ use crate::proof::{FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep, H
use crate::util::reverse_index_bits_in_place;
/// Builds a FRI proof.
pub fn fri_proof<F: Field>(
pub fn fri_proof<F: Field + 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>,
@ -19,10 +19,7 @@ pub fn fri_proof<F: Field>(
lde_polynomial_values: &PolynomialValues<F::Extension>,
challenger: &mut Challenger<F>,
config: &FriConfig,
) -> FriProof<F>
where
F: Extendable<EXTENSION_DEGREE>,
{
) -> FriProof<F, D> {
let n = lde_polynomial_values.values.len();
assert_eq!(lde_polynomial_coeffs.coeffs.len(), n);
@ -50,15 +47,12 @@ where
}
}
fn fri_committed_trees<F: Field>(
fn fri_committed_trees<F: Field + Extendable<D>, const D: usize>(
polynomial_coeffs: &PolynomialCoeffs<F::Extension>,
polynomial_values: &PolynomialValues<F::Extension>,
challenger: &mut Challenger<F>,
config: &FriConfig,
) -> (Vec<MerkleTree<F>>, PolynomialCoeffs<F::Extension>)
where
F: Extendable<EXTENSION_DEGREE>,
{
) -> (Vec<MerkleTree<F>>, PolynomialCoeffs<F::Extension>) {
let mut values = polynomial_values.clone();
let mut coeffs = polynomial_coeffs.clone();
@ -120,25 +114,25 @@ fn fri_proof_of_work<F: Field>(current_hash: Hash<F>, config: &FriConfig) -> F {
.expect("Proof of work failed.")
}
fn fri_prover_query_rounds<F: Field + Extendable<EXTENSION_DEGREE>>(
fn fri_prover_query_rounds<F: Field + Extendable<D>, const D: usize>(
initial_merkle_trees: &[&MerkleTree<F>],
trees: &[MerkleTree<F>],
challenger: &mut Challenger<F>,
n: usize,
config: &FriConfig,
) -> Vec<FriQueryRound<F>> {
) -> Vec<FriQueryRound<F, D>> {
(0..config.num_query_rounds)
.map(|_| fri_prover_query_round(initial_merkle_trees, trees, challenger, n, config))
.collect()
}
fn fri_prover_query_round<F: Field + Extendable<EXTENSION_DEGREE>>(
fn fri_prover_query_round<F: Field + Extendable<D>, const D: usize>(
initial_merkle_trees: &[&MerkleTree<F>],
trees: &[MerkleTree<F>],
challenger: &mut Challenger<F>,
n: usize,
config: &FriConfig,
) -> FriQueryRound<F> {
) -> FriQueryRound<F, D> {
let mut query_steps = Vec::new();
let x = challenger.get_challenge();
let mut x_index = x.to_canonical_u64() as usize % n;

View File

@ -13,16 +13,13 @@ use anyhow::{ensure, Result};
/// 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<F: Field>(
fn compute_evaluation<F: Field + Extendable<D>, const D: usize>(
x: F,
old_x_index: usize,
arity_bits: usize,
last_evals: &[F::Extension],
beta: F::Extension,
) -> F::Extension
where
F: Extendable<EXTENSION_DEGREE>,
{
) -> F::Extension {
debug_assert_eq!(last_evals.len(), 1 << arity_bits);
let g = F::primitive_root_of_unity(arity_bits);
@ -43,14 +40,11 @@ where
interpolate(&points, beta, &barycentric_weights)
}
fn fri_verify_proof_of_work<F: Field>(
proof: &FriProof<F>,
fn fri_verify_proof_of_work<F: Field + Extendable<D>, const D: usize>(
proof: &FriProof<F, D>,
challenger: &mut Challenger<F>,
config: &FriConfig,
) -> Result<()>
where
F: Extendable<EXTENSION_DEGREE>,
{
) -> Result<()> {
let hash = hash_n_to_1(
challenger
.get_hash()
@ -70,20 +64,17 @@ where
Ok(())
}
pub fn verify_fri_proof<F: Field>(
pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
purported_degree_log: usize,
// Point-evaluation pairs for polynomial commitments.
points: &[(F::Extension, F::Extension)],
// Scaling factor to combine polynomials.
alpha: F::Extension,
initial_merkle_roots: &[Hash<F>],
proof: &FriProof<F>,
proof: &FriProof<F, D>,
challenger: &mut Challenger<F>,
config: &FriConfig,
) -> Result<()>
where
F: Extendable<EXTENSION_DEGREE>,
{
) -> Result<()> {
let total_arities = config.reduction_arity_bits.iter().sum::<usize>();
ensure!(
purported_degree_log
@ -149,17 +140,14 @@ fn fri_verify_initial_proof<F: Field>(
Ok(())
}
fn fri_combine_initial<F: Field>(
fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
proof: &FriInitialTreeProof<F>,
alpha: F::Extension,
interpolant: &PolynomialCoeffs<F::Extension>,
points: &[(F::Extension, F::Extension)],
subgroup_x: F,
config: &FriConfig,
) -> F::Extension
where
F: Extendable<EXTENSION_DEGREE>,
{
) -> F::Extension {
let e = proof
.evals_proofs
.iter()
@ -175,21 +163,18 @@ where
numerator / denominator
}
fn fri_verifier_query_round<F: Field>(
fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>(
interpolant: &PolynomialCoeffs<F::Extension>,
points: &[(F::Extension, F::Extension)],
alpha: F::Extension,
initial_merkle_roots: &[Hash<F>],
proof: &FriProof<F>,
proof: &FriProof<F, D>,
challenger: &mut Challenger<F>,
n: usize,
betas: &[F::Extension],
round_proof: &FriQueryRound<F>,
round_proof: &FriQueryRound<F, D>,
config: &FriConfig,
) -> Result<()>
where
F: Extendable<EXTENSION_DEGREE>,
{
) -> Result<()> {
let mut evaluations: Vec<Vec<F::Extension>> = Vec::new();
let x = challenger.get_challenge();
let mut domain_size = n;

View File

@ -15,7 +15,6 @@ use crate::timed;
use crate::util::{log2_strict, reverse_index_bits_in_place, transpose};
pub const SALT_SIZE: usize = 2;
pub const EXTENSION_DEGREE: usize = 2;
pub struct ListPolynomialCommitment<F: Field> {
pub polynomials: Vec<PolynomialCoeffs<F>>,
@ -77,14 +76,14 @@ impl<F: Field> ListPolynomialCommitment<F> {
&leaf[0..leaf.len() - if self.blinding { SALT_SIZE } else { 0 }]
}
pub fn open(
pub fn open<const D: usize>(
&self,
points: &[F::Extension],
challenger: &mut Challenger<F>,
config: &FriConfig,
) -> (OpeningProof<F>, Vec<Vec<F::Extension>>)
) -> (OpeningProof<F, D>, Vec<Vec<F::Extension>>)
where
F: Extendable<EXTENSION_DEGREE>,
F: Extendable<D>,
{
assert_eq!(self.rate_bits, config.rate_bits);
assert_eq!(config.blinding.len(), 1);
@ -152,14 +151,14 @@ impl<F: Field> ListPolynomialCommitment<F> {
)
}
pub fn batch_open(
pub fn batch_open<const D: usize>(
commitments: &[&Self],
points: &[F::Extension],
challenger: &mut Challenger<F>,
config: &FriConfig,
) -> (OpeningProof<F>, Vec<Vec<Vec<F::Extension>>>)
) -> (OpeningProof<F, D>, Vec<Vec<Vec<F::Extension>>>)
where
F: Extendable<EXTENSION_DEGREE>,
F: Extendable<D>,
{
let degree = commitments[0].degree;
assert_eq!(config.blinding.len(), commitments.len());
@ -250,14 +249,14 @@ impl<F: Field> ListPolynomialCommitment<F> {
)
}
pub fn batch_open_plonk(
pub fn batch_open_plonk<const D: usize>(
commitments: &[&Self; 5],
points: &[F::Extension],
challenger: &mut Challenger<F>,
config: &FriConfig,
) -> (OpeningProof<F>, Vec<OpeningSet<F::Extension>>)
) -> (OpeningProof<F, D>, Vec<OpeningSet<F::Extension>>)
where
F: Extendable<EXTENSION_DEGREE>,
F: Extendable<D>,
{
let (op, mut evaluations) = Self::batch_open(commitments, points, challenger, config);
let opening_sets = evaluations
@ -278,13 +277,13 @@ impl<F: Field> ListPolynomialCommitment<F> {
/// Given `points=(x_i)`, `evals=(y_i)` and `poly=P` with `P(x_i)=y_i`, computes the polynomial
/// `Q=(P-I)/Z` where `I` interpolates `(x_i, y_i)` and `Z` is the vanishing polynomial on `(x_i)`.
fn compute_quotient(
fn compute_quotient<const D: usize>(
points: &[F::Extension],
evals: &[F::Extension],
poly: &PolynomialCoeffs<F::Extension>,
) -> PolynomialCoeffs<F::Extension>
where
F: Extendable<EXTENSION_DEGREE>,
F: Extendable<D>,
{
let pairs = points
.iter()
@ -305,13 +304,13 @@ impl<F: Field> ListPolynomialCommitment<F> {
}
}
pub struct OpeningProof<F: Field + Extendable<EXTENSION_DEGREE>> {
fri_proof: FriProof<F>,
pub struct OpeningProof<F: Field + Extendable<D>, const D: usize> {
fri_proof: FriProof<F, D>,
// TODO: Get the degree from `CommonCircuitData` instead.
quotient_degree: usize,
}
impl<F: Field + Extendable<EXTENSION_DEGREE>> OpeningProof<F> {
impl<F: Field + Extendable<D>, const D: usize> OpeningProof<F, D> {
pub fn verify(
&self,
points: &[F::Extension],
@ -364,7 +363,7 @@ mod tests {
use super::*;
fn gen_random_test_case<F: Field + Extendable<EXTENSION_DEGREE>>(
fn gen_random_test_case<F: Field + Extendable<D>, const D: usize>(
k: usize,
degree_log: usize,
num_points: usize,
@ -396,10 +395,10 @@ mod tests {
num_query_rounds: 3,
blinding: vec![false],
};
let (polys, points) = gen_random_test_case::<F>(k, degree_log, num_points);
let (polys, points) = gen_random_test_case::<F, 2>(k, degree_log, num_points);
let lpc = ListPolynomialCommitment::new(polys, fri_config.rate_bits, false);
let (proof, evaluations) = lpc.open(&points, &mut Challenger::new(), &fri_config);
let (proof, evaluations) = lpc.open::<2>(&points, &mut Challenger::new(), &fri_config);
proof.verify(
&points,
&evaluations.into_iter().map(|e| vec![e]).collect::<Vec<_>>(),
@ -423,10 +422,10 @@ mod tests {
num_query_rounds: 3,
blinding: vec![true],
};
let (polys, points) = gen_random_test_case::<F>(k, degree_log, num_points);
let (polys, points) = gen_random_test_case::<F, 2>(k, degree_log, num_points);
let lpc = ListPolynomialCommitment::new(polys, fri_config.rate_bits, true);
let (proof, evaluations) = lpc.open(&points, &mut Challenger::new(), &fri_config);
let (proof, evaluations) = lpc.open::<2>(&points, &mut Challenger::new(), &fri_config);
proof.verify(
&points,
&evaluations.into_iter().map(|e| vec![e]).collect::<Vec<_>>(),
@ -452,15 +451,15 @@ mod tests {
num_query_rounds: 3,
blinding: vec![false, false, false],
};
let (polys0, _) = gen_random_test_case::<F>(k0, degree_log, num_points);
let (polys1, _) = gen_random_test_case::<F>(k0, degree_log, num_points);
let (polys2, points) = gen_random_test_case::<F>(k0, degree_log, num_points);
let (polys0, _) = gen_random_test_case::<F, 2>(k0, degree_log, num_points);
let (polys1, _) = gen_random_test_case::<F, 2>(k0, degree_log, num_points);
let (polys2, points) = gen_random_test_case::<F, 2>(k0, degree_log, num_points);
let lpc0 = ListPolynomialCommitment::new(polys0, fri_config.rate_bits, false);
let lpc1 = ListPolynomialCommitment::new(polys1, fri_config.rate_bits, false);
let lpc2 = ListPolynomialCommitment::new(polys2, fri_config.rate_bits, false);
let (proof, evaluations) = ListPolynomialCommitment::batch_open(
let (proof, evaluations) = ListPolynomialCommitment::batch_open::<2>(
&[&lpc0, &lpc1, &lpc2],
&points,
&mut Challenger::new(),
@ -495,15 +494,15 @@ mod tests {
num_query_rounds: 3,
blinding: vec![true, false, true],
};
let (polys0, _) = gen_random_test_case::<F>(k0, degree_log, num_points);
let (polys1, _) = gen_random_test_case::<F>(k0, degree_log, num_points);
let (polys2, points) = gen_random_test_case::<F>(k0, degree_log, num_points);
let (polys0, _) = gen_random_test_case::<F, 2>(k0, degree_log, num_points);
let (polys1, _) = gen_random_test_case::<F, 2>(k0, degree_log, num_points);
let (polys2, points) = gen_random_test_case::<F, 2>(k0, degree_log, num_points);
let lpc0 = ListPolynomialCommitment::new(polys0, fri_config.rate_bits, true);
let lpc1 = ListPolynomialCommitment::new(polys1, fri_config.rate_bits, false);
let lpc2 = ListPolynomialCommitment::new(polys2, fri_config.rate_bits, true);
let (proof, evaluations) = ListPolynomialCommitment::batch_open(
let (proof, evaluations) = ListPolynomialCommitment::batch_open::<2>(
&[&lpc0, &lpc1, &lpc2],
&points,
&mut Challenger::new(),

View File

@ -55,7 +55,7 @@ impl HashTarget {
}
}
pub struct Proof<F: Field + Extendable<EXTENSION_DEGREE>> {
pub struct Proof<F: Field + Extendable<D>, const D: usize> {
/// Merkle root of LDEs of wire values.
pub wires_root: Hash<F>,
/// Merkle root of LDEs of Z, in the context of Plonk's permutation argument.
@ -67,7 +67,7 @@ pub struct Proof<F: Field + Extendable<EXTENSION_DEGREE>> {
pub openings: Vec<OpeningSet<F::Extension>>,
/// A FRI argument for each FRI query.
pub opening_proof: OpeningProof<F>,
pub opening_proof: OpeningProof<F, D>,
}
pub struct ProofTarget {
@ -87,7 +87,7 @@ pub struct ProofTarget {
/// Evaluations and Merkle proof produced by the prover in a FRI query step.
// TODO: Implement FriQueryStepTarget
pub struct FriQueryStep<F: Field + Extendable<EXTENSION_DEGREE>> {
pub struct FriQueryStep<F: Field + Extendable<D>, const D: usize> {
pub evals: Vec<F::Extension>,
pub merkle_proof: MerkleProof<F>,
}
@ -101,16 +101,16 @@ pub struct FriInitialTreeProof<F: Field> {
/// Proof for a FRI query round.
// TODO: Implement FriQueryRoundTarget
pub struct FriQueryRound<F: Field + Extendable<EXTENSION_DEGREE>> {
pub struct FriQueryRound<F: Field + Extendable<D>, const D: usize> {
pub initial_trees_proof: FriInitialTreeProof<F>,
pub steps: Vec<FriQueryStep<F>>,
pub steps: Vec<FriQueryStep<F, D>>,
}
pub struct FriProof<F: Field + Extendable<EXTENSION_DEGREE>> {
pub struct FriProof<F: Field + Extendable<D>, const D: usize> {
/// A Merkle root for each reduced polynomial in the commit phase.
pub commit_phase_merkle_roots: Vec<Hash<F>>,
/// Query rounds proofs
pub query_round_proofs: Vec<FriQueryRound<F>>,
pub query_round_proofs: Vec<FriQueryRound<F, D>>,
/// The final polynomial in coefficient form.
pub final_poly: PolynomialCoeffs<F::Extension>,
/// Witness showing that the prover did PoW.

View File

@ -22,11 +22,11 @@ use crate::witness::PartialWitness;
/// Corresponds to constants - sigmas - wires - zs - quotient — polynomial commitments.
pub const PLONK_BLINDING: [bool; 5] = [false, false, true, true, true];
pub(crate) fn prove<F: Field + Extendable<EXTENSION_DEGREE>>(
pub(crate) fn prove<F: Field + Extendable<D>, const D: usize>(
prover_data: &ProverOnlyCircuitData<F>,
common_data: &CommonCircuitData<F>,
inputs: PartialWitness<F>,
) -> Proof<F> {
) -> Proof<F, D> {
let fri_config = &common_data.config.fri_config;
let start_proof_gen = Instant::now();