mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-21 15:13:11 +00:00
Add constants to the RAM gate
This commit is contained in:
parent
e50e668f7e
commit
e2de88d145
@ -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_routed_wires()
|
||||
.num_ram_wires()
|
||||
.max(interpolation_routed_wires);
|
||||
|
||||
assert!(
|
||||
|
||||
@ -159,7 +159,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn low_degree() {
|
||||
let num_consts = CircuitConfig::standard_recursion_config().constant_gate_size;
|
||||
let num_consts = CircuitConfig::standard_recursion_config().num_constants;
|
||||
let gate = ConstantGate { num_consts };
|
||||
test_low_degree::<GoldilocksField, _, 2>(gate)
|
||||
}
|
||||
@ -169,7 +169,7 @@ mod tests {
|
||||
const D: usize = 2;
|
||||
type C = PoseidonGoldilocksConfig;
|
||||
type F = <C as GenericConfig<D>>::F;
|
||||
let num_consts = CircuitConfig::standard_recursion_config().constant_gate_size;
|
||||
let num_consts = CircuitConfig::standard_recursion_config().num_constants;
|
||||
let gate = ConstantGate { num_consts };
|
||||
test_eval_fns::<F, C, _, D>(gate)
|
||||
}
|
||||
|
||||
@ -26,14 +26,16 @@ use crate::plonk::vars::{
|
||||
pub(crate) struct RandomAccessGate<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub bits: usize,
|
||||
pub num_copies: usize,
|
||||
pub num_extra_constants: usize,
|
||||
_phantom: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
fn new(num_copies: usize, bits: usize) -> Self {
|
||||
fn new(num_copies: usize, bits: usize, num_extra_constants: usize) -> Self {
|
||||
Self {
|
||||
bits,
|
||||
num_copies,
|
||||
num_extra_constants,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
@ -45,7 +47,7 @@ impl<F: RichField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
// Need `(2 + vec_size + bits) * num_copies` wires
|
||||
config.num_wires / (2 + vec_size + bits),
|
||||
);
|
||||
Self::new(max_copies, bits)
|
||||
Self::new(max_copies, bits, config.num_constants)
|
||||
}
|
||||
|
||||
fn vec_size(&self) -> usize {
|
||||
@ -68,12 +70,17 @@ impl<F: RichField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
(2 + self.vec_size()) * copy + 2 + i
|
||||
}
|
||||
|
||||
fn start_of_intermediate_wires(&self) -> usize {
|
||||
pub(crate) fn num_ram_wires(&self) -> usize {
|
||||
(2 + self.vec_size()) * self.num_copies
|
||||
}
|
||||
|
||||
pub(crate) fn num_routed_wires(&self) -> usize {
|
||||
self.start_of_intermediate_wires()
|
||||
fn wire_extra_constant(&self, i: usize) -> usize {
|
||||
debug_assert!(i < self.num_extra_constants);
|
||||
self.num_ram_wires() + i
|
||||
}
|
||||
|
||||
fn num_routed_wires(&self) -> usize {
|
||||
self.num_ram_wires() + self.num_extra_constants
|
||||
}
|
||||
|
||||
/// An intermediate wire where the prover gives the (purported) binary decomposition of the
|
||||
@ -81,7 +88,7 @@ impl<F: RichField + Extendable<D>, const D: usize> RandomAccessGate<F, D> {
|
||||
pub fn wire_bit(&self, i: usize, copy: usize) -> usize {
|
||||
debug_assert!(i < self.bits);
|
||||
debug_assert!(copy < self.num_copies);
|
||||
self.start_of_intermediate_wires() + copy * self.bits + i
|
||||
self.num_routed_wires() + copy * self.bits + i
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,6 +136,11 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
|
||||
constraints.push(list_items[0] - claimed_element);
|
||||
}
|
||||
|
||||
constraints.extend(
|
||||
(0..self.num_extra_constants)
|
||||
.map(|i| vars.local_constants[i] - vars.local_wires[self.wire_extra_constant(i)]),
|
||||
);
|
||||
|
||||
constraints
|
||||
}
|
||||
|
||||
@ -189,14 +201,22 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
|
||||
constraints.push(builder.sub_extension(list_items[0], claimed_element));
|
||||
}
|
||||
|
||||
constraints.extend((0..self.num_extra_constants).map(|i| {
|
||||
builder.sub_extension(
|
||||
vars.local_constants[i],
|
||||
vars.local_wires[self.wire_extra_constant(i)],
|
||||
)
|
||||
}));
|
||||
|
||||
constraints
|
||||
}
|
||||
|
||||
fn generators(
|
||||
&self,
|
||||
gate_index: usize,
|
||||
_local_constants: &[F],
|
||||
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(
|
||||
@ -204,6 +224,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for RandomAccessGa
|
||||
gate_index,
|
||||
gate: *self,
|
||||
copy,
|
||||
constants: constants.to_vec(),
|
||||
}
|
||||
.adapter(),
|
||||
);
|
||||
@ -270,6 +291,10 @@ impl<F: RichField + Extendable<D>, const D: usize> PackedEvaluableBase<F, D>
|
||||
debug_assert_eq!(list_items.len(), 1);
|
||||
yield_constr.one(list_items[0] - claimed_element);
|
||||
}
|
||||
yield_constr.many(
|
||||
(0..self.num_extra_constants)
|
||||
.map(|i| vars.local_constants[i] - vars.local_wires[self.wire_extra_constant(i)]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,6 +303,7 @@ 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>
|
||||
@ -323,6 +349,10 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,7 +374,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn low_degree() {
|
||||
test_low_degree::<GoldilocksField, _, 4>(RandomAccessGate::new(4, 4));
|
||||
test_low_degree::<GoldilocksField, _, 4>(RandomAccessGate::new(4, 4, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -352,7 +382,7 @@ mod tests {
|
||||
const D: usize = 2;
|
||||
type C = PoseidonGoldilocksConfig;
|
||||
type F = <C as GenericConfig<D>>::F;
|
||||
test_eval_fns::<F, C, _, D>(RandomAccessGate::new(4, 4))
|
||||
test_eval_fns::<F, C, _, D>(RandomAccessGate::new(4, 4, 1))
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -404,6 +434,7 @@ mod tests {
|
||||
let gate = RandomAccessGate::<F, D> {
|
||||
bits,
|
||||
num_copies,
|
||||
num_extra_constants: 1,
|
||||
_phantom: PhantomData,
|
||||
};
|
||||
|
||||
|
||||
@ -321,14 +321,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
return target;
|
||||
}
|
||||
|
||||
let num_consts = self.config.constant_gate_size;
|
||||
// We will fill this `ConstantGate` with zero constants initially.
|
||||
// These will be overwritten by `constant` as the gate instances are filled.
|
||||
let gate = ConstantGate { num_consts };
|
||||
let (gate, instance) = self.find_slot(gate, &[], &vec![F::ZERO; num_consts]);
|
||||
let target = Target::wire(gate, instance);
|
||||
self.gate_instances[gate].constants[instance] = c;
|
||||
|
||||
let target = self.add_virtual_target();
|
||||
self.constants_to_targets.insert(c, target);
|
||||
self.targets_to_constants.insert(target, c);
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ use crate::util::timing::TimingTree;
|
||||
pub struct CircuitConfig {
|
||||
pub num_wires: usize,
|
||||
pub num_routed_wires: usize,
|
||||
pub constant_gate_size: usize,
|
||||
pub num_constants: usize,
|
||||
/// Whether to use a dedicated gate for base field arithmetic, rather than using a single gate
|
||||
/// for both base field and extension field arithmetic.
|
||||
pub use_base_arithmetic_gate: bool,
|
||||
@ -64,7 +64,7 @@ impl CircuitConfig {
|
||||
Self {
|
||||
num_wires: 135,
|
||||
num_routed_wires: 80,
|
||||
constant_gate_size: 5,
|
||||
num_constants: 5,
|
||||
use_base_arithmetic_gate: true,
|
||||
security_bits: 100,
|
||||
num_challenges: 2,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user