mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-05-02 00:03:13 +00:00
Merge branch 'main' into gate_tree
# Conflicts: # src/circuit_data.rs # src/witness.rs
This commit is contained in:
commit
8aa9c7b816
@ -18,12 +18,6 @@ fn main() {
|
|||||||
env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init();
|
env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init();
|
||||||
|
|
||||||
bench_prove::<CrandallField, 4>();
|
bench_prove::<CrandallField, 4>();
|
||||||
|
|
||||||
// bench_field_mul::<CrandallField>();
|
|
||||||
|
|
||||||
// bench_fft();
|
|
||||||
println!();
|
|
||||||
// bench_gmimc::<CrandallField>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bench_prove<F: Field + Extendable<D>, const D: usize>() {
|
fn bench_prove<F: Field + Extendable<D>, const D: usize>() {
|
||||||
@ -51,12 +45,6 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() {
|
|||||||
|
|
||||||
builder.add_gate(ConstantGate::get(), vec![F::NEG_ONE]);
|
builder.add_gate(ConstantGate::get(), vec![F::NEG_ONE]);
|
||||||
|
|
||||||
// for _ in 0..(40 * 5) {
|
|
||||||
// builder.add_gate(
|
|
||||||
// FriConsistencyGate::new(2, 3, 13),
|
|
||||||
// vec![F::primitive_root_of_unity(13)]);
|
|
||||||
// }
|
|
||||||
|
|
||||||
let prover = builder.build_prover();
|
let prover = builder.build_prover();
|
||||||
let inputs = PartialWitness::new();
|
let inputs = PartialWitness::new();
|
||||||
prover.prove(inputs);
|
prover.prove(inputs);
|
||||||
|
|||||||
@ -319,11 +319,12 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
sigmas_root,
|
sigmas_root,
|
||||||
};
|
};
|
||||||
|
|
||||||
let generators = self.generators;
|
|
||||||
let prover_only = ProverOnlyCircuitData {
|
let prover_only = ProverOnlyCircuitData {
|
||||||
generators,
|
generators: self.generators,
|
||||||
constants_commitment,
|
constants_commitment,
|
||||||
sigmas_commitment,
|
sigmas_commitment,
|
||||||
|
copy_constraints: self.copy_constraints,
|
||||||
|
gate_instances: self.gate_instances,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The HashSet of gates will have a non-deterministic order. When converting to a Vec, we
|
// The HashSet of gates will have a non-deterministic order. When converting to a Vec, we
|
||||||
|
|||||||
@ -3,11 +3,12 @@ use anyhow::Result;
|
|||||||
use crate::field::extension_field::Extendable;
|
use crate::field::extension_field::Extendable;
|
||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
use crate::fri::FriConfig;
|
use crate::fri::FriConfig;
|
||||||
use crate::gates::gate::PrefixedGate;
|
use crate::gates::gate::{GateInstance, PrefixedGate};
|
||||||
use crate::generator::WitnessGenerator;
|
use crate::generator::WitnessGenerator;
|
||||||
use crate::polynomial::commitment::ListPolynomialCommitment;
|
use crate::polynomial::commitment::ListPolynomialCommitment;
|
||||||
use crate::proof::{Hash, HashTarget, Proof};
|
use crate::proof::{Hash, HashTarget, Proof};
|
||||||
use crate::prover::prove;
|
use crate::prover::prove;
|
||||||
|
use crate::target::Target;
|
||||||
use crate::verifier::verify;
|
use crate::verifier::verify;
|
||||||
use crate::witness::PartialWitness;
|
use crate::witness::PartialWitness;
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ impl CircuitConfig {
|
|||||||
|
|
||||||
/// Circuit data required by the prover or the verifier.
|
/// Circuit data required by the prover or the verifier.
|
||||||
pub struct CircuitData<F: Extendable<D>, const D: usize> {
|
pub struct CircuitData<F: Extendable<D>, const D: usize> {
|
||||||
pub(crate) prover_only: ProverOnlyCircuitData<F>,
|
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
|
||||||
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
|
pub(crate) verifier_only: VerifierOnlyCircuitData<F>,
|
||||||
pub(crate) common: CommonCircuitData<F, D>,
|
pub(crate) common: CommonCircuitData<F, D>,
|
||||||
}
|
}
|
||||||
@ -90,7 +91,7 @@ impl<F: Extendable<D>, const D: usize> CircuitData<F, D> {
|
|||||||
/// required, like LDEs of preprocessed polynomials. If more succinctness was desired, we could
|
/// required, like LDEs of preprocessed polynomials. If more succinctness was desired, we could
|
||||||
/// construct a more minimal prover structure and convert back and forth.
|
/// construct a more minimal prover structure and convert back and forth.
|
||||||
pub struct ProverCircuitData<F: Extendable<D>, const D: usize> {
|
pub struct ProverCircuitData<F: Extendable<D>, const D: usize> {
|
||||||
pub(crate) prover_only: ProverOnlyCircuitData<F>,
|
pub(crate) prover_only: ProverOnlyCircuitData<F, D>,
|
||||||
pub(crate) common: CommonCircuitData<F, D>,
|
pub(crate) common: CommonCircuitData<F, D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,12 +114,16 @@ impl<F: Extendable<D>, const D: usize> VerifierCircuitData<F, D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Circuit data required by the prover, but not the verifier.
|
/// Circuit data required by the prover, but not the verifier.
|
||||||
pub(crate) struct ProverOnlyCircuitData<F: Field> {
|
pub(crate) struct ProverOnlyCircuitData<F: Extendable<D>, const D: usize> {
|
||||||
pub generators: Vec<Box<dyn WitnessGenerator<F>>>,
|
pub generators: Vec<Box<dyn WitnessGenerator<F>>>,
|
||||||
/// Commitments to the constants polynomial.
|
/// Commitments to the constants polynomial.
|
||||||
pub constants_commitment: ListPolynomialCommitment<F>,
|
pub constants_commitment: ListPolynomialCommitment<F>,
|
||||||
/// Commitments to the sigma polynomial.
|
/// Commitments to the sigma polynomial.
|
||||||
pub sigmas_commitment: ListPolynomialCommitment<F>,
|
pub sigmas_commitment: ListPolynomialCommitment<F>,
|
||||||
|
/// The circuit's copy constraints.
|
||||||
|
pub copy_constraints: Vec<(Target, Target)>,
|
||||||
|
/// The concrete placement of each gate in the circuit.
|
||||||
|
pub gate_instances: Vec<GateInstance<F, D>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Circuit data required by the verifier, but not the prover.
|
/// Circuit data required by the verifier, but not the prover.
|
||||||
|
|||||||
@ -126,32 +126,11 @@ pub(crate) fn fft_with_precomputation_power_of_2<F: Field>(
|
|||||||
PolynomialValues { values }
|
PolynomialValues { values }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn coset_fft<F: Field>(poly: PolynomialCoeffs<F>, shift: F) -> PolynomialValues<F> {
|
|
||||||
let mut points = fft(poly);
|
|
||||||
let mut shift_exp_i = F::ONE;
|
|
||||||
for p in points.values.iter_mut() {
|
|
||||||
*p *= shift_exp_i;
|
|
||||||
shift_exp_i *= shift;
|
|
||||||
}
|
|
||||||
points
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn ifft<F: Field>(poly: PolynomialValues<F>) -> PolynomialCoeffs<F> {
|
pub(crate) fn ifft<F: Field>(poly: PolynomialValues<F>) -> PolynomialCoeffs<F> {
|
||||||
let precomputation = fft_precompute(poly.len());
|
let precomputation = fft_precompute(poly.len());
|
||||||
ifft_with_precomputation_power_of_2(poly, &precomputation)
|
ifft_with_precomputation_power_of_2(poly, &precomputation)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn coset_ifft<F: Field>(poly: PolynomialValues<F>, shift: F) -> PolynomialCoeffs<F> {
|
|
||||||
let shift_inv = shift.inverse();
|
|
||||||
let mut shift_inv_exp_i = F::ONE;
|
|
||||||
let mut coeffs = ifft(poly);
|
|
||||||
for c in coeffs.coeffs.iter_mut() {
|
|
||||||
*c *= shift_inv_exp_i;
|
|
||||||
shift_inv_exp_i *= shift_inv;
|
|
||||||
}
|
|
||||||
coeffs
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::field::crandall_field::CrandallField;
|
use crate::field::crandall_field::CrandallField;
|
||||||
|
|||||||
@ -385,8 +385,6 @@ mod tests {
|
|||||||
|
|
||||||
let x = FF::rand();
|
let x = FF::rand();
|
||||||
let y = FF::rand();
|
let y = FF::rand();
|
||||||
let x = FF::TWO;
|
|
||||||
let y = FF::ONE;
|
|
||||||
let z = x / y;
|
let z = x / y;
|
||||||
let xt = builder.constant_extension(x);
|
let xt = builder.constant_extension(x);
|
||||||
let yt = builder.constant_extension(y);
|
let yt = builder.constant_extension(y);
|
||||||
|
|||||||
@ -323,6 +323,8 @@ mod tests {
|
|||||||
use crate::gates::gmimc::{GMiMCGate, W};
|
use crate::gates::gmimc::{GMiMCGate, W};
|
||||||
use crate::generator::generate_partial_witness;
|
use crate::generator::generate_partial_witness;
|
||||||
use crate::gmimc::gmimc_permute_naive;
|
use crate::gmimc::gmimc_permute_naive;
|
||||||
|
use crate::permutation_argument::TargetPartitions;
|
||||||
|
use crate::target::Target;
|
||||||
use crate::wire::Wire;
|
use crate::wire::Wire;
|
||||||
use crate::witness::PartialWitness;
|
use crate::witness::PartialWitness;
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use std::collections::{HashMap, HashSet};
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
|
use crate::permutation_argument::TargetPartitions;
|
||||||
use crate::target::Target;
|
use crate::target::Target;
|
||||||
use crate::witness::PartialWitness;
|
use crate::witness::PartialWitness;
|
||||||
|
|
||||||
@ -24,10 +25,7 @@ pub(crate) fn generate_partial_witness<F: Field>(
|
|||||||
|
|
||||||
// Build a list of "pending" generators which are queued to be run. Initially, all generators
|
// Build a list of "pending" generators which are queued to be run. Initially, all generators
|
||||||
// are queued.
|
// are queued.
|
||||||
let mut pending_generator_indices = HashSet::new();
|
let mut pending_generator_indices: HashSet<_> = (0..generators.len()).collect();
|
||||||
for i in 0..generators.len() {
|
|
||||||
pending_generator_indices.insert(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We also track a list of "expired" generators which have already returned false.
|
// We also track a list of "expired" generators which have already returned false.
|
||||||
let mut expired_generator_indices = HashSet::new();
|
let mut expired_generator_indices = HashSet::new();
|
||||||
@ -58,6 +56,11 @@ pub(crate) fn generate_partial_witness<F: Field>(
|
|||||||
|
|
||||||
pending_generator_indices = next_pending_generator_indices;
|
pending_generator_indices = next_pending_generator_indices;
|
||||||
}
|
}
|
||||||
|
assert_eq!(
|
||||||
|
expired_generator_indices.len(),
|
||||||
|
generators.len(),
|
||||||
|
"Some generators weren't run."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A generator participates in the generation of the witness.
|
/// A generator participates in the generation of the witness.
|
||||||
|
|||||||
@ -321,6 +321,7 @@ mod tests {
|
|||||||
use crate::field::crandall_field::CrandallField;
|
use crate::field::crandall_field::CrandallField;
|
||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
use crate::generator::generate_partial_witness;
|
use crate::generator::generate_partial_witness;
|
||||||
|
use crate::permutation_argument::TargetPartitions;
|
||||||
use crate::plonk_challenger::{Challenger, RecursiveChallenger};
|
use crate::plonk_challenger::{Challenger, RecursiveChallenger};
|
||||||
use crate::target::Target;
|
use crate::target::Target;
|
||||||
use crate::witness::PartialWitness;
|
use crate::witness::PartialWitness;
|
||||||
|
|||||||
@ -20,7 +20,7 @@ use crate::wire::Wire;
|
|||||||
use crate::witness::PartialWitness;
|
use crate::witness::PartialWitness;
|
||||||
|
|
||||||
pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||||
prover_data: &ProverOnlyCircuitData<F>,
|
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||||
common_data: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
inputs: PartialWitness<F>,
|
inputs: PartialWitness<F>,
|
||||||
) -> Proof<F, D> {
|
) -> Proof<F, D> {
|
||||||
@ -31,10 +31,17 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
|||||||
let mut witness = inputs;
|
let mut witness = inputs;
|
||||||
info!("Running {} generators", prover_data.generators.len());
|
info!("Running {} generators", prover_data.generators.len());
|
||||||
timed!(
|
timed!(
|
||||||
generate_partial_witness(&mut witness, &prover_data.generators),
|
generate_partial_witness(&mut witness, &prover_data.generators,),
|
||||||
"to generate witness"
|
"to generate witness"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
timed!(
|
||||||
|
witness
|
||||||
|
.check_copy_constraints(&prover_data.copy_constraints, &prover_data.gate_instances)
|
||||||
|
.unwrap(), // TODO: Change return value to `Result` and use `?` here.
|
||||||
|
"to check copy constraints"
|
||||||
|
);
|
||||||
|
|
||||||
let config = &common_data.config;
|
let config = &common_data.config;
|
||||||
let num_wires = config.num_wires;
|
let num_wires = config.num_wires;
|
||||||
let num_challenges = config.num_challenges;
|
let num_challenges = config.num_challenges;
|
||||||
@ -159,7 +166,7 @@ fn compute_z<F: Extendable<D>, const D: usize>(
|
|||||||
|
|
||||||
fn compute_vanishing_polys<F: Extendable<D>, const D: usize>(
|
fn compute_vanishing_polys<F: Extendable<D>, const D: usize>(
|
||||||
common_data: &CommonCircuitData<F, D>,
|
common_data: &CommonCircuitData<F, D>,
|
||||||
prover_data: &ProverOnlyCircuitData<F>,
|
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||||
wires_commitment: &ListPolynomialCommitment<F>,
|
wires_commitment: &ListPolynomialCommitment<F>,
|
||||||
plonk_zs_commitment: &ListPolynomialCommitment<F>,
|
plonk_zs_commitment: &ListPolynomialCommitment<F>,
|
||||||
betas: &[F],
|
betas: &[F],
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
use anyhow::{ensure, Result};
|
||||||
|
|
||||||
use crate::field::extension_field::target::ExtensionTarget;
|
use crate::field::extension_field::target::ExtensionTarget;
|
||||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||||
use crate::field::field::Field;
|
use crate::field::field::Field;
|
||||||
|
use crate::gates::gate::GateInstance;
|
||||||
use crate::target::Target;
|
use crate::target::Target;
|
||||||
use crate::wire::Wire;
|
use crate::wire::Wire;
|
||||||
|
|
||||||
@ -121,6 +124,31 @@ impl<F: Field> PartialWitness<F> {
|
|||||||
self.set_target(target, value);
|
self.set_target(target, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks that the copy constraints are satisfied in the witness.
|
||||||
|
pub fn check_copy_constraints<const D: usize>(
|
||||||
|
&self,
|
||||||
|
copy_constraints: &[(Target, Target)],
|
||||||
|
gate_instances: &[GateInstance<F, D>],
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
F: Extendable<D>,
|
||||||
|
{
|
||||||
|
for &(a, b) in copy_constraints {
|
||||||
|
// TODO: Take care of public inputs once they land.
|
||||||
|
if let (Target::Wire(wa), Target::Wire(wb)) = (a, b) {
|
||||||
|
let va = self.target_values.get(&a).copied().unwrap_or(F::ZERO);
|
||||||
|
let vb = self.target_values.get(&b).copied().unwrap_or(F::ZERO);
|
||||||
|
ensure!(
|
||||||
|
va == vb,
|
||||||
|
"Copy constraint between wire {} of gate #{} (`{}`) and wire {} of gate #{} (`{}`) is not satisfied. \
|
||||||
|
Got values of {} and {} respectively.",
|
||||||
|
wa.input, wa.gate, gate_instances[wa.gate].gate_type.0.id(), wb.input, wb.gate,
|
||||||
|
gate_instances[wb.gate].gate_type.0.id(), va, vb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field> Default for PartialWitness<F> {
|
impl<F: Field> Default for PartialWitness<F> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user