mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-02-06 23:13:13 +00:00
Merge pull request #314 from mir-protocol/remove_basesum_gates
Ensure only one `BaseSumGate` is instantiated
This commit is contained in:
commit
6463e4f4e7
@ -1,6 +1,5 @@
|
|||||||
use crate::field::extension_field::Extendable;
|
use crate::field::extension_field::Extendable;
|
||||||
use crate::field::field_types::RichField;
|
use crate::field::field_types::RichField;
|
||||||
use crate::gates::base_sum::BaseSumGate;
|
|
||||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
||||||
use crate::iop::target::{BoolTarget, Target};
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
use crate::iop::witness::{PartitionWitness, Witness};
|
use crate::iop::witness::{PartitionWitness, Witness};
|
||||||
@ -9,9 +8,7 @@ use crate::plonk::circuit_builder::CircuitBuilder;
|
|||||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||||
/// Checks that `x < 2^n_log` using a `BaseSumGate`.
|
/// Checks that `x < 2^n_log` using a `BaseSumGate`.
|
||||||
pub fn range_check(&mut self, x: Target, n_log: usize) {
|
pub fn range_check(&mut self, x: Target, n_log: usize) {
|
||||||
let gate = self.add_gate(BaseSumGate::<2>::new(n_log), vec![]);
|
self.split_le(x, n_log);
|
||||||
let sum = Target::wire(gate, BaseSumGate::<2>::WIRE_SUM);
|
|
||||||
self.connect(x, sum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first `num_low_bits` little-endian bits of `x`.
|
/// Returns the first `num_low_bits` little-endian bits of `x`.
|
||||||
|
|||||||
@ -13,7 +13,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
/// base-B limb of the element, with little-endian ordering.
|
/// base-B limb of the element, with little-endian ordering.
|
||||||
pub fn split_le_base<const B: usize>(&mut self, x: Target, num_limbs: usize) -> Vec<Target> {
|
pub fn split_le_base<const B: usize>(&mut self, x: Target, num_limbs: usize) -> Vec<Target> {
|
||||||
let gate_type = BaseSumGate::<B>::new(num_limbs);
|
let gate_type = BaseSumGate::<B>::new(num_limbs);
|
||||||
let gate = self.add_gate(gate_type.clone(), vec![]);
|
let gate = self.add_gate(gate_type, vec![]);
|
||||||
let sum = Target::wire(gate, BaseSumGate::<B>::WIRE_SUM);
|
let sum = Target::wire(gate, BaseSumGate::<B>::WIRE_SUM);
|
||||||
self.connect(x, sum);
|
self.connect(x, sum);
|
||||||
|
|
||||||
@ -48,13 +48,17 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
BaseSumGate::<2>::START_LIMBS + num_bits <= self.config.num_routed_wires,
|
BaseSumGate::<2>::START_LIMBS + num_bits <= self.config.num_routed_wires,
|
||||||
"Not enough routed wires."
|
"Not enough routed wires."
|
||||||
);
|
);
|
||||||
let gate_index = self.add_gate(BaseSumGate::<2>::new(num_bits), vec![]);
|
let gate_type = BaseSumGate::<2>::new_from_config::<F>(&self.config);
|
||||||
|
let gate_index = self.add_gate(gate_type, vec![]);
|
||||||
for (limb, wire) in bits
|
for (limb, wire) in bits
|
||||||
.clone()
|
.clone()
|
||||||
.zip(BaseSumGate::<2>::START_LIMBS..BaseSumGate::<2>::START_LIMBS + num_bits)
|
.zip(BaseSumGate::<2>::START_LIMBS..BaseSumGate::<2>::START_LIMBS + num_bits)
|
||||||
{
|
{
|
||||||
self.connect(limb.borrow().target, Target::wire(gate_index, wire));
|
self.connect(limb.borrow().target, Target::wire(gate_index, wire));
|
||||||
}
|
}
|
||||||
|
for l in gate_type.limbs().skip(num_bits) {
|
||||||
|
self.assert_zero(Target::wire(gate_index, l));
|
||||||
|
}
|
||||||
|
|
||||||
self.add_simple_generator(BaseSumGenerator::<2> {
|
self.add_simple_generator(BaseSumGenerator::<2> {
|
||||||
gate_index,
|
gate_index,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator};
|
|||||||
use crate::iop::target::{BoolTarget, Target};
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
use crate::iop::witness::{PartitionWitness, Witness};
|
use crate::iop::witness::{PartitionWitness, Witness};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::util::{bits_u64, ceil_div_usize};
|
use crate::util::ceil_div_usize;
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||||
/// Split the given integer into a list of wires, where each one represents a
|
/// Split the given integer into a list of wires, where each one represents a
|
||||||
@ -16,35 +16,36 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
if num_bits == 0 {
|
if num_bits == 0 {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
let bits_per_gate = (bits_u64(F::ORDER) - 1)
|
let gate_type = BaseSumGate::<2>::new_from_config::<F>(&self.config);
|
||||||
.min(self.config.num_routed_wires - BaseSumGate::<2>::START_LIMBS);
|
let k = ceil_div_usize(num_bits, gate_type.num_limbs);
|
||||||
let k = ceil_div_usize(num_bits, bits_per_gate);
|
|
||||||
let gates = (0..k)
|
let gates = (0..k)
|
||||||
.map(|_| self.add_gate(BaseSumGate::<2>::new(bits_per_gate), vec![]))
|
.map(|_| self.add_gate(gate_type, vec![]))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut bits = Vec::with_capacity(num_bits);
|
let mut bits = Vec::with_capacity(num_bits);
|
||||||
for &gate in &gates {
|
for &gate in &gates {
|
||||||
let start_limbs = BaseSumGate::<2>::START_LIMBS;
|
let start_limbs = BaseSumGate::<2>::START_LIMBS;
|
||||||
for limb_input in start_limbs..start_limbs + bits_per_gate {
|
for limb_input in start_limbs..start_limbs + gate_type.num_limbs {
|
||||||
// `new_unsafe` is safe here because BaseSumGate::<2> forces it to be in `{0, 1}`.
|
// `new_unsafe` is safe here because BaseSumGate::<2> forces it to be in `{0, 1}`.
|
||||||
bits.push(BoolTarget::new_unsafe(Target::wire(gate, limb_input)));
|
bits.push(BoolTarget::new_unsafe(Target::wire(gate, limb_input)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bits.drain(num_bits..);
|
for b in bits.drain(num_bits..) {
|
||||||
|
self.assert_zero(b.target);
|
||||||
|
}
|
||||||
|
|
||||||
let zero = self.zero();
|
let zero = self.zero();
|
||||||
let mut acc = zero;
|
let mut acc = zero;
|
||||||
for &gate in gates.iter().rev() {
|
for &gate in gates.iter().rev() {
|
||||||
let sum = Target::wire(gate, BaseSumGate::<2>::WIRE_SUM);
|
let sum = Target::wire(gate, BaseSumGate::<2>::WIRE_SUM);
|
||||||
acc = self.mul_const_add(F::from_canonical_usize(1 << bits_per_gate), acc, sum);
|
acc = self.mul_const_add(F::from_canonical_usize(1 << gate_type.num_limbs), acc, sum);
|
||||||
}
|
}
|
||||||
self.connect(acc, integer);
|
self.connect(acc, integer);
|
||||||
|
|
||||||
self.add_simple_generator(WireSplitGenerator {
|
self.add_simple_generator(WireSplitGenerator {
|
||||||
integer,
|
integer,
|
||||||
gates,
|
gates,
|
||||||
num_limbs: bits_per_gate,
|
num_limbs: gate_type.num_limbs,
|
||||||
});
|
});
|
||||||
|
|
||||||
bits
|
bits
|
||||||
|
|||||||
@ -2,19 +2,20 @@ use std::ops::Range;
|
|||||||
|
|
||||||
use crate::field::extension_field::target::ExtensionTarget;
|
use crate::field::extension_field::target::ExtensionTarget;
|
||||||
use crate::field::extension_field::Extendable;
|
use crate::field::extension_field::Extendable;
|
||||||
use crate::field::field_types::{Field, RichField};
|
use crate::field::field_types::{Field, PrimeField, RichField};
|
||||||
use crate::gates::gate::Gate;
|
use crate::gates::gate::Gate;
|
||||||
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
|
||||||
use crate::iop::target::Target;
|
use crate::iop::target::Target;
|
||||||
use crate::iop::witness::{PartitionWitness, Witness};
|
use crate::iop::witness::{PartitionWitness, Witness};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::circuit_data::CircuitConfig;
|
||||||
use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_recursive};
|
use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_recursive};
|
||||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||||
|
|
||||||
/// A gate which can decompose a number into base B little-endian limbs.
|
/// A gate which can decompose a number into base B little-endian limbs.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct BaseSumGate<const B: usize> {
|
pub struct BaseSumGate<const B: usize> {
|
||||||
num_limbs: usize,
|
pub num_limbs: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const B: usize> BaseSumGate<B> {
|
impl<const B: usize> BaseSumGate<B> {
|
||||||
@ -22,6 +23,12 @@ impl<const B: usize> BaseSumGate<B> {
|
|||||||
Self { num_limbs }
|
Self { num_limbs }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_from_config<F: PrimeField>(config: &CircuitConfig) -> Self {
|
||||||
|
let num_limbs = ((F::ORDER as f64).log(B as f64).floor() as usize)
|
||||||
|
.min(config.num_routed_wires - Self::START_LIMBS);
|
||||||
|
Self::new(num_limbs)
|
||||||
|
}
|
||||||
|
|
||||||
pub const WIRE_SUM: usize = 0;
|
pub const WIRE_SUM: usize = 0;
|
||||||
pub const START_LIMBS: usize = 1;
|
pub const START_LIMBS: usize = 1;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user