mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-07 16:23:12 +00:00
Fixed GMiMC
This commit is contained in:
parent
ad24f5d4d1
commit
139430c549
@ -45,7 +45,7 @@ pub struct CircuitBuilder<F: Extendable<D>, const D: usize> {
|
||||
copy_constraints: Vec<(Target, Target)>,
|
||||
|
||||
/// Generators used to generate the witness.
|
||||
generators: Vec<Box<dyn WitnessGenerator<F>>>,
|
||||
pub generators: Vec<Box<dyn WitnessGenerator<F>>>,
|
||||
|
||||
constants_to_targets: HashMap<F, Target>,
|
||||
targets_to_constants: HashMap<Target, F>,
|
||||
|
||||
@ -11,6 +11,7 @@ use crate::polynomial::commitment::ListPolynomialCommitment;
|
||||
use crate::proof::{Hash, HashTarget, Proof};
|
||||
use crate::prover::prove;
|
||||
use crate::target::Target;
|
||||
use crate::util::marking::MarkedTargets;
|
||||
use crate::verifier::verify;
|
||||
use crate::witness::PartialWitness;
|
||||
|
||||
@ -77,7 +78,14 @@ pub struct CircuitData<F: Extendable<D>, const D: usize> {
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> CircuitData<F, D> {
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Proof<F, D> {
|
||||
prove(&self.prover_only, &self.common, inputs)
|
||||
prove(&self.prover_only, &self.common, inputs, vec![])
|
||||
}
|
||||
pub fn prove_marked(
|
||||
&self,
|
||||
inputs: PartialWitness<F>,
|
||||
marked: Vec<MarkedTargets>,
|
||||
) -> Proof<F, D> {
|
||||
prove(&self.prover_only, &self.common, inputs, marked)
|
||||
}
|
||||
|
||||
pub fn verify(&self, proof: Proof<F, D>) -> Result<()> {
|
||||
@ -99,7 +107,7 @@ pub struct ProverCircuitData<F: Extendable<D>, const D: usize> {
|
||||
|
||||
impl<F: Extendable<D>, const D: usize> ProverCircuitData<F, D> {
|
||||
pub fn prove(&self, inputs: PartialWitness<F>) -> Proof<F, D> {
|
||||
prove(&self.prover_only, &self.common, inputs)
|
||||
prove(&self.prover_only, &self.common, inputs, vec![])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -83,6 +83,9 @@ pub trait Gate<F: Extendable<D>, const D: usize>: 'static + Send + Sync {
|
||||
let filter = compute_filter_recursively(builder, prefix, vars.local_constants);
|
||||
vars.remove_prefix(prefix);
|
||||
self.eval_unfiltered_recursively(builder, vars)
|
||||
.into_iter()
|
||||
.map(|c| builder.mul_extension(filter, c))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn generators(
|
||||
|
||||
@ -129,16 +129,14 @@ impl<F: Extendable<D>, const D: usize, const R: usize> Gate<F, D> for GMiMCGate<
|
||||
let mut constraints = Vec::with_capacity(self.num_constraints());
|
||||
|
||||
let swap = vars.local_wires[Self::WIRE_SWAP];
|
||||
let one_ext = builder.one_extension();
|
||||
let not_swap = builder.sub_extension(swap, one_ext);
|
||||
constraints.push(builder.mul_extension(swap, not_swap));
|
||||
constraints.push(builder.mul_sub_extension(swap, swap, swap));
|
||||
|
||||
let old_index_acc = vars.local_wires[Self::WIRE_INDEX_ACCUMULATOR_OLD];
|
||||
let new_index_acc = vars.local_wires[Self::WIRE_INDEX_ACCUMULATOR_NEW];
|
||||
// computed_new_index_acc = 2 * old_index_acc + swap
|
||||
let two = builder.two();
|
||||
let double_old_index_acc = builder.scalar_mul_ext(two, old_index_acc);
|
||||
let computed_new_index_acc = builder.add_extension(double_old_index_acc, swap);
|
||||
let two = builder.convert_to_ext(two);
|
||||
let computed_new_index_acc = builder.mul_add_extension(two, old_index_acc, swap);
|
||||
constraints.push(builder.sub_extension(computed_new_index_acc, new_index_acc));
|
||||
|
||||
let mut state = Vec::with_capacity(12);
|
||||
@ -168,8 +166,10 @@ impl<F: Extendable<D>, const D: usize, const R: usize> Gate<F, D> for GMiMCGate<
|
||||
let constant = builder.constant_extension(self.constants[r].into());
|
||||
let cubing_input =
|
||||
builder.add_many_extension(&[state[active], addition_buffer, constant]);
|
||||
let square = builder.mul_extension(cubing_input, cubing_input);
|
||||
let f = builder.mul_extension(square, cubing_input);
|
||||
let cubing_input_wire = vars.local_wires[Self::wire_cubing_input(r)];
|
||||
constraints.push(builder.sub_extension(cubing_input, cubing_input_wire));
|
||||
let square = builder.mul_extension(cubing_input_wire, cubing_input_wire);
|
||||
let f = builder.mul_extension(square, cubing_input_wire);
|
||||
addition_buffer = builder.add_extension(addition_buffer, f);
|
||||
state[active] = builder.sub_extension(state[active], f);
|
||||
}
|
||||
@ -316,8 +316,10 @@ mod tests {
|
||||
use std::convert::TryInto;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::circuit_builder::CircuitBuilder;
|
||||
use crate::circuit_data::CircuitConfig;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::field::field::Field;
|
||||
use crate::gates::gate_testing::test_low_degree;
|
||||
use crate::gates::gmimc::{GMiMCGate, W};
|
||||
@ -325,6 +327,8 @@ mod tests {
|
||||
use crate::gmimc::gmimc_permute_naive;
|
||||
use crate::permutation_argument::TargetPartition;
|
||||
use crate::target::Target;
|
||||
use crate::vars::{EvaluationTargets, EvaluationVars};
|
||||
use crate::verifier::verify;
|
||||
use crate::wire::Wire;
|
||||
use crate::witness::PartialWitness;
|
||||
|
||||
@ -399,4 +403,47 @@ mod tests {
|
||||
let gate = Gate::with_constants(constants);
|
||||
test_low_degree(gate)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_evals() {
|
||||
type F = CrandallField;
|
||||
type FF = QuarticCrandallField;
|
||||
const R: usize = 101;
|
||||
let config = CircuitConfig::large_config();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let mut pw = PartialWitness::<F>::new();
|
||||
let constants = Arc::new([F::TWO; R]);
|
||||
type Gate = GMiMCGate<F, 4, R>;
|
||||
let gate = Gate::with_constants(constants);
|
||||
|
||||
let wires = FF::rand_vec(Gate::end());
|
||||
let vars = EvaluationVars {
|
||||
local_constants: &[],
|
||||
local_wires: &wires,
|
||||
};
|
||||
|
||||
let ev = gate.0.eval_unfiltered((vars));
|
||||
|
||||
let wires_t = builder.add_virtual_extension_targets(Gate::end());
|
||||
for i in 0..Gate::end() {
|
||||
pw.set_extension_target(wires_t[i], wires[i]);
|
||||
}
|
||||
let vars_t = EvaluationTargets {
|
||||
local_constants: &[],
|
||||
local_wires: &wires_t,
|
||||
};
|
||||
|
||||
let ev_t = gate.0.eval_unfiltered_recursively(&mut builder, vars_t);
|
||||
|
||||
assert_eq!(ev.len(), ev_t.len());
|
||||
for (e, e_t) in ev.into_iter().zip(ev_t) {
|
||||
let e_c = builder.constant_extension(e);
|
||||
builder.route_extension(e_c, e_t);
|
||||
}
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(pw);
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ use crate::polynomial::commitment::ListPolynomialCommitment;
|
||||
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
|
||||
use crate::proof::Proof;
|
||||
use crate::timed;
|
||||
use crate::util::marking::MarkedTargets;
|
||||
use crate::util::partial_products::partial_products;
|
||||
use crate::util::{log2_ceil, transpose};
|
||||
use crate::vanishing_poly::eval_vanishing_poly_base;
|
||||
@ -22,6 +23,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
inputs: PartialWitness<F>,
|
||||
marked: Vec<MarkedTargets>,
|
||||
) -> Proof<F, D> {
|
||||
let fri_config = &common_data.config.fri_config;
|
||||
let config = &common_data.config;
|
||||
@ -50,13 +52,10 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
.unwrap(), // TODO: Change return value to `Result` and use `?` here.
|
||||
"to check copy constraints"
|
||||
);
|
||||
|
||||
if degree > 7 {
|
||||
dbg!(witness.get_wire(8, 16));
|
||||
dbg!(witness.get_wire(8, 17));
|
||||
dbg!(witness.get_wire(8, 18));
|
||||
dbg!(witness.get_wire(8, 19));
|
||||
for m in marked {
|
||||
m.display(&witness);
|
||||
}
|
||||
|
||||
let wires_values: Vec<PolynomialValues<F>> = timed!(
|
||||
witness
|
||||
.wire_values
|
||||
|
||||
@ -7,6 +7,7 @@ use crate::field::field::Field;
|
||||
use crate::gates::gate::{GateRef, PrefixedGate};
|
||||
use crate::plonk_challenger::RecursiveChallenger;
|
||||
use crate::proof::{HashTarget, ProofTarget};
|
||||
use crate::util::marking::MarkedTargets;
|
||||
use crate::util::scaling::ReducingFactorTarget;
|
||||
use crate::vanishing_poly::eval_vanishing_poly_recursively;
|
||||
use crate::vars::EvaluationTargets;
|
||||
@ -22,6 +23,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
inner_config: &CircuitConfig,
|
||||
inner_verifier_data: &VerifierCircuitTarget,
|
||||
inner_common_data: &CommonCircuitData<F, D>,
|
||||
marked: &mut Vec<MarkedTargets>,
|
||||
) {
|
||||
assert!(self.config.num_wires >= MIN_WIRES);
|
||||
assert!(self.config.num_wires >= MIN_ROUTED_WIRES);
|
||||
@ -71,8 +73,14 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
&betas,
|
||||
&gammas,
|
||||
&alphas,
|
||||
marked,
|
||||
);
|
||||
|
||||
marked.push(MarkedTargets {
|
||||
name: "vanishing polys".into(),
|
||||
targets: Box::new(vanishing_polys_zeta[0].clone()),
|
||||
});
|
||||
|
||||
// let quotient_polys_zeta = &proof.openings.quotient_polys;
|
||||
// let zeta_pow_deg = self.exp_u64_extension(zeta, 1 << inner_common_data.degree_bits as u64);
|
||||
// let z_h_zeta = self.sub_extension(zeta_pow_deg, one);
|
||||
@ -318,6 +326,8 @@ mod tests {
|
||||
let config = CircuitConfig::large_config();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let zero = builder.zero();
|
||||
let hash = builder.hash_n_to_m(vec![zero], 2, true);
|
||||
let z = builder.mul(hash[0], hash[1]);
|
||||
let data = builder.build();
|
||||
(
|
||||
data.prove(PartialWitness::new()),
|
||||
@ -330,6 +340,7 @@ mod tests {
|
||||
let config = CircuitConfig::large_config();
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config.clone());
|
||||
let mut pw = PartialWitness::new();
|
||||
let mut marked = Vec::new();
|
||||
let pt = proof_to_proof_target(&proof, &mut builder);
|
||||
set_proof_target(&proof, &pt, &mut pw);
|
||||
|
||||
@ -338,11 +349,11 @@ mod tests {
|
||||
};
|
||||
pw.set_hash_target(inner_data.constants_sigmas_root, vd.constants_sigmas_root);
|
||||
|
||||
builder.add_recursive_verifier(pt, &config, &inner_data, &cd);
|
||||
builder.add_recursive_verifier(pt, &config, &inner_data, &cd, &mut marked);
|
||||
|
||||
dbg!(builder.num_gates());
|
||||
let data = builder.build();
|
||||
let recursive_proof = data.prove(pw);
|
||||
let recursive_proof = data.prove_marked(pw, marked);
|
||||
|
||||
verify(recursive_proof, &data.verifier_only, &data.common).unwrap();
|
||||
}
|
||||
|
||||
54
src/util/marking.rs
Normal file
54
src/util/marking.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::field::Field;
|
||||
use crate::proof::HashTarget;
|
||||
use crate::target::Target;
|
||||
use crate::witness::{PartialWitness, Witness};
|
||||
|
||||
pub trait Markable {
|
||||
fn targets(&self) -> Vec<Target>;
|
||||
}
|
||||
|
||||
impl Markable for Target {
|
||||
fn targets(&self) -> Vec<Target> {
|
||||
vec![*self]
|
||||
}
|
||||
}
|
||||
|
||||
impl<const D: usize> Markable for ExtensionTarget<D> {
|
||||
fn targets(&self) -> Vec<Target> {
|
||||
self.0.try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Markable for HashTarget {
|
||||
fn targets(&self) -> Vec<Target> {
|
||||
self.elements.try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Markable> Markable for Vec<M> {
|
||||
fn targets(&self) -> Vec<Target> {
|
||||
self.iter().flat_map(|m| m.targets()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MarkedTargets {
|
||||
pub targets: Box<dyn Markable>,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl MarkedTargets {
|
||||
pub fn display<F: Field>(&self, wit: &Witness<F>) {
|
||||
let targets = self.targets.targets();
|
||||
println!("Values for {}:", self.name);
|
||||
for &t in &targets {
|
||||
match t {
|
||||
Target::Wire(w) => println!("{}", wit.get_wire(w.gate, w.input)),
|
||||
_ => println!("Not a wire."),
|
||||
}
|
||||
}
|
||||
println!("End of values for {}", self.name);
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
pub mod marking;
|
||||
pub mod partial_products;
|
||||
pub mod scaling;
|
||||
pub(crate) mod timing;
|
||||
|
||||
@ -7,6 +7,7 @@ use crate::gates::gate::{Gate, GateRef, PrefixedGate};
|
||||
use crate::plonk_common;
|
||||
use crate::plonk_common::{eval_l_1_recursively, ZeroPolyOnCoset};
|
||||
use crate::target::Target;
|
||||
use crate::util::marking::MarkedTargets;
|
||||
use crate::util::partial_products::{check_partial_products, check_partial_products_recursively};
|
||||
use crate::util::scaling::ReducingFactorTarget;
|
||||
use crate::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
@ -94,7 +95,6 @@ pub(crate) fn eval_vanishing_poly<F: Extendable<D>, const D: usize>(
|
||||
constraint_terms,
|
||||
]
|
||||
.concat();
|
||||
dbg!(&vanishing_terms);
|
||||
|
||||
let alphas = &alphas.iter().map(|&a| a.into()).collect::<Vec<_>>();
|
||||
plonk_common::reduce_with_powers_multi(&vanishing_terms, alphas)
|
||||
@ -233,6 +233,7 @@ pub fn evaluate_gate_constraints_recursively<F: Extendable<D>, const D: usize>(
|
||||
gates: &[PrefixedGate<F, D>],
|
||||
num_gate_constraints: usize,
|
||||
vars: EvaluationTargets<D>,
|
||||
marked: &mut Vec<MarkedTargets>,
|
||||
) -> Vec<ExtensionTarget<D>> {
|
||||
let mut constraints = vec![builder.zero_extension(); num_gate_constraints];
|
||||
for gate in gates {
|
||||
@ -240,6 +241,10 @@ pub fn evaluate_gate_constraints_recursively<F: Extendable<D>, const D: usize>(
|
||||
.gate
|
||||
.0
|
||||
.eval_filtered_recursively(builder, vars, &gate.prefix);
|
||||
// marked.push(MarkedTargets {
|
||||
// name: gate.gate.0.id(),
|
||||
// targets: Box::new(gate_constraints.clone()),
|
||||
// });
|
||||
for (i, c) in gate_constraints.into_iter().enumerate() {
|
||||
constraints[i] = builder.add_extension(constraints[i], c);
|
||||
}
|
||||
@ -263,6 +268,7 @@ pub(crate) fn eval_vanishing_poly_recursively<F: Extendable<D>, const D: usize>(
|
||||
betas: &[Target],
|
||||
gammas: &[Target],
|
||||
alphas: &[Target],
|
||||
marked: &mut Vec<MarkedTargets>,
|
||||
) -> Vec<ExtensionTarget<D>> {
|
||||
let max_degree = common_data.quotient_degree_factor;
|
||||
let (num_prods, final_num_prod) = common_data.num_partial_products;
|
||||
@ -272,6 +278,7 @@ pub(crate) fn eval_vanishing_poly_recursively<F: Extendable<D>, const D: usize>(
|
||||
&common_data.gates,
|
||||
common_data.num_gate_constraints,
|
||||
vars,
|
||||
marked,
|
||||
);
|
||||
|
||||
// The L_1(x) (Z(x) - 1) vanishing terms.
|
||||
@ -343,7 +350,6 @@ pub(crate) fn eval_vanishing_poly_recursively<F: Extendable<D>, const D: usize>(
|
||||
constraint_terms,
|
||||
]
|
||||
.concat();
|
||||
dbg!(&vanishing_terms);
|
||||
|
||||
alphas
|
||||
.iter()
|
||||
|
||||
@ -56,6 +56,7 @@ pub(crate) fn verify<F: Extendable<D>, const D: usize>(
|
||||
&gammas,
|
||||
&alphas,
|
||||
);
|
||||
dbg!(vanishing_polys_zeta[0]);
|
||||
|
||||
// Check each polynomial identity, of the form `vanishing(x) = Z_H(x) quotient(x)`, at zeta.
|
||||
let quotient_polys_zeta = &proof.openings.quotient_polys;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user