mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-04-05 11:13:07 +00:00
semi-working
This commit is contained in:
parent
e2de88d145
commit
f81e32f8b4
@ -86,7 +86,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
let min_wires = random_access.num_wires().max(interpolation_wires);
|
||||
let min_routed_wires = random_access
|
||||
.num_ram_wires()
|
||||
.num_routed_wires()
|
||||
.max(interpolation_routed_wires);
|
||||
|
||||
assert!(
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use std::ops::Range;
|
||||
|
||||
use plonky2_field::extension_field::Extendable;
|
||||
use plonky2_field::field_types::Field;
|
||||
use plonky2_field::packed_field::PackedField;
|
||||
@ -111,6 +113,12 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for ConstantGate {
|
||||
fn num_constraints(&self) -> usize {
|
||||
self.num_consts
|
||||
}
|
||||
|
||||
fn extra_constants(&self) -> Vec<(usize, usize)> {
|
||||
(0..self.num_consts)
|
||||
.map(|i| (self.const_input(i), self.wire_output(i)))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D> for ConstantGate {
|
||||
|
||||
@ -180,6 +180,10 @@ pub trait Gate<F: RichField + Extendable<D>, const D: usize>: 'static + Send + S
|
||||
self.generators(0, &vec![F::ZERO; self.num_constants()])
|
||||
.len()
|
||||
}
|
||||
|
||||
fn extra_constants(&self) -> Vec<(usize, usize)> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper around an `Rc<Gate>` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs.
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Range;
|
||||
|
||||
use itertools::Itertools;
|
||||
use plonky2_field::extension_field::Extendable;
|
||||
@ -20,6 +21,7 @@ use crate::plonk::vars::{
|
||||
EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch,
|
||||
EvaluationVarsBasePacked,
|
||||
};
|
||||
use crate::with_context;
|
||||
|
||||
/// A gate for checking that a particular element of a list matches a given value.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -70,7 +72,7 @@ impl<F: RichField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
(2 + self.vec_size()) * copy + 2 + i
|
||||
}
|
||||
|
||||
pub(crate) fn num_ram_wires(&self) -> usize {
|
||||
fn num_ram_wires(&self) -> usize {
|
||||
(2 + self.vec_size()) * self.num_copies
|
||||
}
|
||||
|
||||
@ -79,7 +81,7 @@ impl<F: RichField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
self.num_ram_wires() + i
|
||||
}
|
||||
|
||||
fn num_routed_wires(&self) -> usize {
|
||||
pub fn num_routed_wires(&self) -> usize {
|
||||
self.num_ram_wires() + self.num_extra_constants
|
||||
}
|
||||
|
||||
@ -216,7 +218,6 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
|
||||
gate_index: usize,
|
||||
local_constants: &[F],
|
||||
) -> Vec<Box<dyn WitnessGenerator<F>>> {
|
||||
let constants = local_constants[..self.num_extra_constants].to_vec();
|
||||
(0..self.num_copies)
|
||||
.map(|copy| {
|
||||
let g: Box<dyn WitnessGenerator<F>> = Box::new(
|
||||
@ -224,12 +225,23 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
|
||||
gate_index,
|
||||
gate: *self,
|
||||
copy,
|
||||
constants: constants.to_vec(),
|
||||
}
|
||||
.adapter(),
|
||||
);
|
||||
g
|
||||
})
|
||||
.chain((0..self.num_extra_constants).map(|i| {
|
||||
let g: Box<dyn WitnessGenerator<F>> = Box::new(
|
||||
RandomAccessExtraConstantsGenerator {
|
||||
gate_index,
|
||||
gate: *self,
|
||||
i,
|
||||
constant: local_constants[i],
|
||||
}
|
||||
.adapter(),
|
||||
);
|
||||
g
|
||||
}))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -238,7 +250,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
|
||||
}
|
||||
|
||||
fn num_constants(&self) -> usize {
|
||||
0
|
||||
self.num_extra_constants
|
||||
}
|
||||
|
||||
fn degree(&self) -> usize {
|
||||
@ -247,7 +259,17 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
|
||||
|
||||
fn num_constraints(&self) -> usize {
|
||||
let constraints_per_copy = self.bits + 2;
|
||||
self.num_copies * constraints_per_copy
|
||||
self.num_copies * constraints_per_copy + self.num_extra_constants
|
||||
}
|
||||
|
||||
fn num_ops(&self) -> usize {
|
||||
self.num_copies
|
||||
}
|
||||
|
||||
fn extra_constants(&self) -> Vec<(usize, usize)> {
|
||||
(0..self.num_extra_constants)
|
||||
.map(|i| (i, self.wire_extra_constant(i)))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +325,6 @@ struct RandomAccessGenerator<F: RichField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: RandomAccessGate<F, D>,
|
||||
copy: usize,
|
||||
constants: Vec<F>,
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
@ -349,10 +370,30 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
let bit = F::from_bool(((access_index >> i) & 1) != 0);
|
||||
set_local_wire(self.gate.wire_bit(i, copy), bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i, &c) in self.constants.iter().enumerate() {
|
||||
set_local_wire(self.gate.wire_extra_constant(i), c);
|
||||
}
|
||||
#[derive(Debug)]
|
||||
struct RandomAccessExtraConstantsGenerator<F: RichField + Extendable<D>, const D: usize> {
|
||||
gate_index: usize,
|
||||
gate: RandomAccessGate<F, D>,
|
||||
i: usize,
|
||||
constant: F,
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
|
||||
for RandomAccessExtraConstantsGenerator<F, D>
|
||||
{
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn run_once(&self, _witness: &PartitionWitness<F>, out_buffer: &mut GeneratedValues<F>) {
|
||||
let wire = Wire {
|
||||
gate: self.gate_index,
|
||||
input: self.gate.wire_extra_constant(self.i),
|
||||
};
|
||||
out_buffer.set_wire(wire, self.constant);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ use std::cmp::max;
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::time::Instant;
|
||||
|
||||
use itertools::{EitherOrBoth, Itertools};
|
||||
use log::{debug, info, Level};
|
||||
use plonky2_field::cosets::get_unique_coset_shifts;
|
||||
use plonky2_field::extension_field::{Extendable, FieldExtension};
|
||||
@ -83,6 +84,9 @@ pub struct CircuitBuilder<F: RichField + Extendable<D>, const D: usize> {
|
||||
|
||||
/// Map between gate type and the current gate of this type with available slots.
|
||||
current_slots: HashMap<GateRef<F, D>, CurrentSlot<F, D>>,
|
||||
|
||||
/// gate_index, constant_index, target_index
|
||||
constants_slots: Vec<(usize, usize, usize)>,
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
@ -102,6 +106,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
arithmetic_results: HashMap::new(),
|
||||
targets_to_constants: HashMap::new(),
|
||||
current_slots: HashMap::new(),
|
||||
constants_slots: Vec::new(),
|
||||
};
|
||||
builder.check_config();
|
||||
builder
|
||||
@ -206,16 +211,23 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
}
|
||||
|
||||
/// Adds a gate to the circuit, and returns its index.
|
||||
pub fn add_gate<G: Gate<F, D>>(&mut self, gate_type: G, constants: Vec<F>) -> usize {
|
||||
pub fn add_gate<G: Gate<F, D>>(&mut self, gate_type: G, mut constants: Vec<F>) -> usize {
|
||||
self.check_gate_compatibility(&gate_type);
|
||||
assert_eq!(
|
||||
gate_type.num_constants(),
|
||||
constants.len(),
|
||||
"Number of constants doesn't match."
|
||||
);
|
||||
// assert_eq!(
|
||||
// gate_type.num_constants(),
|
||||
// constants.len(),
|
||||
// "Number of constants doesn't match."
|
||||
// );
|
||||
|
||||
assert!(constants.len() <= gate_type.num_constants());
|
||||
constants.resize(gate_type.num_constants(), F::ZERO);
|
||||
|
||||
let index = self.gate_instances.len();
|
||||
|
||||
for (ci, ti) in gate_type.extra_constants() {
|
||||
self.constants_slots.push((index, ci, ti));
|
||||
}
|
||||
|
||||
// Note that we can't immediately add this gate's generators, because the list of constants
|
||||
// could be modified later, i.e. in the case of `ConstantGate`. We will add them later in
|
||||
// `build` instead.
|
||||
@ -240,6 +252,13 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
gate.num_wires(),
|
||||
self.config.num_wires
|
||||
);
|
||||
assert!(
|
||||
gate.num_constants() <= self.config.num_constants,
|
||||
"{:?} requires {} constants, but our CircuitConfig has only {}",
|
||||
gate.id(),
|
||||
gate.num_constants(),
|
||||
self.config.num_constants
|
||||
);
|
||||
}
|
||||
|
||||
pub fn connect_extension(&mut self, src: ExtensionTarget<D>, dst: ExtensionTarget<D>) {
|
||||
@ -643,6 +662,28 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
self.connect(hash_part, Target::wire(pi_gate, wire))
|
||||
}
|
||||
|
||||
// Fill constants
|
||||
while self.constants_to_targets.len() > self.constants_slots.len() {
|
||||
dbg!("lfg");
|
||||
self.add_gate(
|
||||
ConstantGate {
|
||||
num_consts: self.config.num_constants,
|
||||
},
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
dbg!(self.constants_to_targets.len(), self.constants_slots.len());
|
||||
|
||||
for ((c, t), (gate_index, const_wire, target_wire)) in self
|
||||
.constants_to_targets
|
||||
.clone()
|
||||
.into_iter()
|
||||
.zip(self.constants_slots.clone())
|
||||
{
|
||||
self.gate_instances[gate_index].constants[const_wire] = c;
|
||||
self.generate_copy(Target::wire(gate_index, target_wire), t);
|
||||
}
|
||||
|
||||
info!(
|
||||
"Degree before blinding & padding: {}",
|
||||
self.gate_instances.len()
|
||||
|
||||
@ -64,7 +64,7 @@ impl CircuitConfig {
|
||||
Self {
|
||||
num_wires: 135,
|
||||
num_routed_wires: 80,
|
||||
num_constants: 5,
|
||||
num_constants: 2,
|
||||
use_base_arithmetic_gate: true,
|
||||
security_bits: 100,
|
||||
num_challenges: 2,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user