mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-02-16 20:03:08 +00:00
Works everywhere except Waksman
This commit is contained in:
parent
cdea0d9f96
commit
ff949f40bc
@ -4,6 +4,7 @@ use plonky2_field::extension_field::Extendable;
|
|||||||
use plonky2_field::field_types::PrimeField;
|
use plonky2_field::field_types::PrimeField;
|
||||||
|
|
||||||
use crate::gates::arithmetic_base::ArithmeticGate;
|
use crate::gates::arithmetic_base::ArithmeticGate;
|
||||||
|
use crate::gates::batchable::GateRef;
|
||||||
use crate::gates::exponentiation::ExponentiationGate;
|
use crate::gates::exponentiation::ExponentiationGate;
|
||||||
use crate::hash::hash_types::RichField;
|
use crate::hash::hash_types::RichField;
|
||||||
use crate::iop::target::{BoolTarget, Target};
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
@ -78,7 +79,8 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_base_arithmetic_operation(&mut self, operation: BaseArithmeticOperation<F>) -> Target {
|
fn add_base_arithmetic_operation(&mut self, operation: BaseArithmeticOperation<F>) -> Target {
|
||||||
let (gate, i) = self.find_base_arithmetic_gate(operation.const_0, operation.const_1);
|
let gate = ArithmeticGate::new_from_config(&self.config);
|
||||||
|
let (gate, i) = self.find_slot(gate, vec![operation.const_0, operation.const_1]);
|
||||||
let wires_multiplicand_0 = Target::wire(gate, ArithmeticGate::wire_ith_multiplicand_0(i));
|
let wires_multiplicand_0 = Target::wire(gate, ArithmeticGate::wire_ith_multiplicand_0(i));
|
||||||
let wires_multiplicand_1 = Target::wire(gate, ArithmeticGate::wire_ith_multiplicand_1(i));
|
let wires_multiplicand_1 = Target::wire(gate, ArithmeticGate::wire_ith_multiplicand_1(i));
|
||||||
let wires_addend = Target::wire(gate, ArithmeticGate::wire_ith_addend(i));
|
let wires_addend = Target::wire(gate, ArithmeticGate::wire_ith_addend(i));
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use plonky2_field::field_types::{Field, PrimeField};
|
|||||||
use plonky2_util::bits_u64;
|
use plonky2_util::bits_u64;
|
||||||
|
|
||||||
use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
|
use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
|
||||||
|
use crate::gates::batchable::GateRef;
|
||||||
use crate::gates::multiplication_extension::MulExtensionGate;
|
use crate::gates::multiplication_extension::MulExtensionGate;
|
||||||
use crate::hash::hash_types::RichField;
|
use crate::hash::hash_types::RichField;
|
||||||
use crate::iop::ext_target::{ExtensionAlgebraTarget, ExtensionTarget};
|
use crate::iop::ext_target::{ExtensionAlgebraTarget, ExtensionTarget};
|
||||||
@ -60,7 +61,8 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
operation: ExtensionArithmeticOperation<F, D>,
|
operation: ExtensionArithmeticOperation<F, D>,
|
||||||
) -> ExtensionTarget<D> {
|
) -> ExtensionTarget<D> {
|
||||||
let (gate, i) = self.find_arithmetic_gate(operation.const_0, operation.const_1);
|
let gate = ArithmeticExtensionGate::new_from_config(&self.config);
|
||||||
|
let (gate, i) = self.find_slot(gate, vec![operation.const_0, operation.const_1]);
|
||||||
let wires_multiplicand_0 = ExtensionTarget::from_range(
|
let wires_multiplicand_0 = ExtensionTarget::from_range(
|
||||||
gate,
|
gate,
|
||||||
ArithmeticExtensionGate::<D>::wires_ith_multiplicand_0(i),
|
ArithmeticExtensionGate::<D>::wires_ith_multiplicand_0(i),
|
||||||
@ -83,7 +85,8 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
operation: ExtensionArithmeticOperation<F, D>,
|
operation: ExtensionArithmeticOperation<F, D>,
|
||||||
) -> ExtensionTarget<D> {
|
) -> ExtensionTarget<D> {
|
||||||
let (gate, i) = self.find_mul_gate(operation.const_0);
|
let gate = MulExtensionGate::new_from_config(&self.config);
|
||||||
|
let (gate, i) = self.find_slot(gate, vec![operation.const_0]);
|
||||||
let wires_multiplicand_0 =
|
let wires_multiplicand_0 =
|
||||||
ExtensionTarget::from_range(gate, MulExtensionGate::<D>::wires_ith_multiplicand_0(i));
|
ExtensionTarget::from_range(gate, MulExtensionGate::<D>::wires_ith_multiplicand_0(i));
|
||||||
let wires_multiplicand_1 =
|
let wires_multiplicand_1 =
|
||||||
|
|||||||
@ -78,7 +78,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let gate = U32ArithmeticGate::<F, D>::new_from_config(&self.config);
|
let gate = U32ArithmeticGate::<F, D>::new_from_config(&self.config);
|
||||||
let (gate_index, copy) = self.find_u32_arithmetic_gate();
|
let (gate_index, copy) = self.find_slot(gate, vec![]);
|
||||||
|
|
||||||
self.connect(
|
self.connect(
|
||||||
Target::wire(gate_index, gate.wire_ith_multiplicand_0(copy)),
|
Target::wire(gate_index, gate.wire_ith_multiplicand_0(copy)),
|
||||||
@ -138,7 +138,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
borrow: U32Target,
|
borrow: U32Target,
|
||||||
) -> (U32Target, U32Target) {
|
) -> (U32Target, U32Target) {
|
||||||
let gate = U32SubtractionGate::<F, D>::new_from_config(&self.config);
|
let gate = U32SubtractionGate::<F, D>::new_from_config(&self.config);
|
||||||
let (gate_index, copy) = self.find_u32_subtraction_gate();
|
let (gate_index, copy) = self.find_slot(gate, vec![]);
|
||||||
|
|
||||||
self.connect(Target::wire(gate_index, gate.wire_ith_input_x(copy)), x.0);
|
self.connect(Target::wire(gate_index, gate.wire_ith_input_x(copy)), x.0);
|
||||||
self.connect(Target::wire(gate_index, gate.wire_ith_input_y(copy)), y.0);
|
self.connect(Target::wire(gate_index, gate.wire_ith_input_y(copy)), y.0);
|
||||||
|
|||||||
@ -17,8 +17,8 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
if vec_size == 1 {
|
if vec_size == 1 {
|
||||||
return self.connect(claimed_element, v[0]);
|
return self.connect(claimed_element, v[0]);
|
||||||
}
|
}
|
||||||
let (gate_index, copy) = self.find_random_access_gate(bits);
|
|
||||||
let dummy_gate = RandomAccessGate::<F, D>::new_from_config(&self.config, bits);
|
let dummy_gate = RandomAccessGate::<F, D>::new_from_config(&self.config, bits);
|
||||||
|
let (gate_index, copy) = self.find_slot(dummy_gate, vec![]);
|
||||||
|
|
||||||
v.iter().enumerate().for_each(|(i, &val)| {
|
v.iter().enumerate().for_each(|(i, &val)| {
|
||||||
self.connect(
|
self.connect(
|
||||||
|
|||||||
@ -19,7 +19,7 @@ use crate::plonk::vars::{
|
|||||||
|
|
||||||
/// A gate which can perform a weighted multiply-add, i.e. `result = c0 x y + c1 z`. If the config
|
/// A gate which can perform a weighted multiply-add, i.e. `result = c0 x y + c1 z`. If the config
|
||||||
/// supports enough routed wires, it can support several such operations in one gate.
|
/// supports enough routed wires, it can support several such operations in one gate.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ArithmeticGate {
|
pub struct ArithmeticGate {
|
||||||
/// Number of arithmetic operations performed by an arithmetic gate.
|
/// Number of arithmetic operations performed by an arithmetic gate.
|
||||||
pub num_ops: usize,
|
pub num_ops: usize,
|
||||||
|
|||||||
@ -17,7 +17,7 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
|||||||
|
|
||||||
/// A gate which can perform a weighted multiply-add, i.e. `result = c0 x y + c1 z`. If the config
|
/// A gate which can perform a weighted multiply-add, i.e. `result = c0 x y + c1 z`. If the config
|
||||||
/// supports enough routed wires, it can support several such operations in one gate.
|
/// supports enough routed wires, it can support several such operations in one gate.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ArithmeticExtensionGate<const D: usize> {
|
pub struct ArithmeticExtensionGate<const D: usize> {
|
||||||
/// Number of arithmetic operations performed by an arithmetic gate.
|
/// Number of arithmetic operations performed by an arithmetic gate.
|
||||||
pub num_ops: usize,
|
pub num_ops: usize,
|
||||||
|
|||||||
@ -12,6 +12,8 @@ use crate::iop::target::Target;
|
|||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
|
||||||
pub trait BatchableGate<F: RichField + Extendable<D>, const D: usize>: Gate<F, D> {
|
pub trait BatchableGate<F: RichField + Extendable<D>, const D: usize>: Gate<F, D> {
|
||||||
|
fn num_ops(&self) -> usize;
|
||||||
|
|
||||||
// TODO: It would be nice to have a `Parameters` associated type.
|
// TODO: It would be nice to have a `Parameters` associated type.
|
||||||
fn fill_gate(
|
fn fill_gate(
|
||||||
&self,
|
&self,
|
||||||
@ -21,8 +23,9 @@ pub trait BatchableGate<F: RichField + Extendable<D>, const D: usize>: Gate<F, D
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct CurrentSlot<F: RichField + Extendable<D>, const D: usize> {
|
pub struct CurrentSlot<F: RichField + Extendable<D>, const D: usize> {
|
||||||
current_slot: HashMap<Vec<F>, (usize, usize)>,
|
pub current_slot: HashMap<Vec<F>, (usize, usize)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -76,6 +79,10 @@ pub trait MultiOpsGate<F: RichField + Extendable<D>, const D: usize>: Gate<F, D>
|
|||||||
impl<F: RichField + Extendable<D>, G: MultiOpsGate<F, D>, const D: usize> BatchableGate<F, D>
|
impl<F: RichField + Extendable<D>, G: MultiOpsGate<F, D>, const D: usize> BatchableGate<F, D>
|
||||||
for G
|
for G
|
||||||
{
|
{
|
||||||
|
fn num_ops(&self) -> usize {
|
||||||
|
self.num_ops()
|
||||||
|
}
|
||||||
|
|
||||||
fn fill_gate(
|
fn fill_gate(
|
||||||
&self,
|
&self,
|
||||||
params: &[F],
|
params: &[F],
|
||||||
|
|||||||
@ -173,6 +173,7 @@ pub trait Gate<F: RichField + Extendable<D>, const D: usize>: 'static + Send + S
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
/// A gate along with any constants used to configure it.
|
/// A gate along with any constants used to configure it.
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct GateInstance<F: RichField + Extendable<D>, const D: usize> {
|
pub struct GateInstance<F: RichField + Extendable<D>, const D: usize> {
|
||||||
pub gate_ref: GateRef<F, D>,
|
pub gate_ref: GateRef<F, D>,
|
||||||
pub constants: Vec<F>,
|
pub constants: Vec<F>,
|
||||||
|
|||||||
@ -17,7 +17,7 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
|||||||
|
|
||||||
/// A gate which can perform a weighted multiplication, i.e. `result = c0 x y`. If the config
|
/// A gate which can perform a weighted multiplication, i.e. `result = c0 x y`. If the config
|
||||||
/// supports enough routed wires, it can support several such operations in one gate.
|
/// supports enough routed wires, it can support several such operations in one gate.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MulExtensionGate<const D: usize> {
|
pub struct MulExtensionGate<const D: usize> {
|
||||||
/// Number of multiplications performed by the gate.
|
/// Number of multiplications performed by the gate.
|
||||||
pub num_ops: usize,
|
pub num_ops: usize,
|
||||||
|
|||||||
@ -84,9 +84,6 @@ pub struct CircuitBuilder<F: RichField + Extendable<D>, const D: usize> {
|
|||||||
/// Memoized results of `arithmetic_extension` calls.
|
/// Memoized results of `arithmetic_extension` calls.
|
||||||
pub(crate) arithmetic_results: HashMap<ExtensionArithmeticOperation<F, D>, ExtensionTarget<D>>,
|
pub(crate) arithmetic_results: HashMap<ExtensionArithmeticOperation<F, D>, ExtensionTarget<D>>,
|
||||||
|
|
||||||
// yo: Vec<Yo<F, D, dyn Copy>>,
|
|
||||||
batched_gates: BatchedGates<F, D>,
|
|
||||||
|
|
||||||
current_slots: HashMap<GateRef<F, D>, CurrentSlot<F, D>>,
|
current_slots: HashMap<GateRef<F, D>, CurrentSlot<F, D>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +103,6 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
base_arithmetic_results: HashMap::new(),
|
base_arithmetic_results: HashMap::new(),
|
||||||
arithmetic_results: HashMap::new(),
|
arithmetic_results: HashMap::new(),
|
||||||
targets_to_constants: HashMap::new(),
|
targets_to_constants: HashMap::new(),
|
||||||
batched_gates: BatchedGates::new(),
|
|
||||||
current_slots: HashMap::new(),
|
current_slots: HashMap::new(),
|
||||||
};
|
};
|
||||||
builder.check_config();
|
builder.check_config();
|
||||||
@ -193,6 +189,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
|
|
||||||
/// Adds a gate to the circuit, and returns its index.
|
/// Adds a gate to the circuit, and returns its index.
|
||||||
pub fn add_gate<G: BatchableGate<F, D>>(&mut self, gate_type: G, constants: Vec<F>) -> usize {
|
pub fn add_gate<G: BatchableGate<F, D>>(&mut self, gate_type: G, constants: Vec<F>) -> usize {
|
||||||
|
// println!("{} {}", self.num_gates(), gate_type.id());
|
||||||
self.check_gate_compatibility(&gate_type);
|
self.check_gate_compatibility(&gate_type);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
gate_type.num_constants(),
|
gate_type.num_constants(),
|
||||||
@ -307,7 +304,11 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (gate, instance) = self.constant_gate_instance();
|
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);
|
let target = Target::wire(gate, instance);
|
||||||
self.gate_instances[gate].constants[instance] = c;
|
self.gate_instances[gate].constants[instance] = c;
|
||||||
|
|
||||||
@ -373,6 +374,44 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_slot<G: BatchableGate<F, D> + Clone>(
|
||||||
|
&mut self,
|
||||||
|
gate: G,
|
||||||
|
params: Vec<F>,
|
||||||
|
) -> (usize, usize) {
|
||||||
|
let num_gates = self.num_gates();
|
||||||
|
let num_ops = gate.num_ops();
|
||||||
|
let gate_ref = GateRef::new(gate.clone());
|
||||||
|
let gate_slot = self
|
||||||
|
.current_slots
|
||||||
|
.entry(gate_ref.clone())
|
||||||
|
.or_insert(CurrentSlot {
|
||||||
|
current_slot: HashMap::new(),
|
||||||
|
});
|
||||||
|
let slot = gate_slot.current_slot.get(¶ms);
|
||||||
|
let res = if let Some(&s) = slot {
|
||||||
|
s
|
||||||
|
} else {
|
||||||
|
self.add_gate(gate, params.clone());
|
||||||
|
(num_gates, 0)
|
||||||
|
};
|
||||||
|
if res.1 == num_ops - 1 {
|
||||||
|
self.current_slots
|
||||||
|
.get_mut(&gate_ref)
|
||||||
|
.unwrap()
|
||||||
|
.current_slot
|
||||||
|
.remove(¶ms);
|
||||||
|
} else {
|
||||||
|
self.current_slots
|
||||||
|
.get_mut(&gate_ref)
|
||||||
|
.unwrap()
|
||||||
|
.current_slot
|
||||||
|
.insert(params, (res.0, res.1 + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
fn fri_params(&self, degree_bits: usize) -> FriParams {
|
fn fri_params(&self, degree_bits: usize) -> FriParams {
|
||||||
let fri_config = &self.config.fri_config;
|
let fri_config = &self.config.fri_config;
|
||||||
let reduction_arity_bits = fri_config.reduction_strategy.reduction_arity_bits(
|
let reduction_arity_bits = fri_config.reduction_strategy.reduction_arity_bits(
|
||||||
@ -815,337 +854,337 @@ impl<F: RichField + Extendable<D>, const D: usize> BatchedGates<F, D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||||
/// Finds the last available arithmetic gate with the given constants or add one if there aren't any.
|
// /// Finds the last available arithmetic gate with the given constants or add one if there aren't any.
|
||||||
/// Returns `(g,i)` such that there is an arithmetic gate with the given constants at index
|
// /// Returns `(g,i)` such that there is an arithmetic gate with the given constants at index
|
||||||
/// `g` and the gate's `i`-th operation is available.
|
// /// `g` and the gate's `i`-th operation is available.
|
||||||
pub(crate) fn find_base_arithmetic_gate(&mut self, const_0: F, const_1: F) -> (usize, usize) {
|
// pub(crate) fn find_base_arithmetic_gate(&mut self, const_0: F, const_1: F) -> (usize, usize) {
|
||||||
let (gate, i) = self
|
// let (gate, i) = self
|
||||||
.batched_gates
|
// .batched_gates
|
||||||
.free_base_arithmetic
|
// .free_base_arithmetic
|
||||||
.get(&(const_0, const_1))
|
// .get(&(const_0, const_1))
|
||||||
.copied()
|
// .copied()
|
||||||
.unwrap_or_else(|| {
|
// .unwrap_or_else(|| {
|
||||||
let gate = self.add_gate(
|
// let gate = self.add_gate(
|
||||||
ArithmeticGate::new_from_config(&self.config),
|
// ArithmeticGate::new_from_config(&self.config),
|
||||||
vec![const_0, const_1],
|
// vec![const_0, const_1],
|
||||||
);
|
// );
|
||||||
(gate, 0)
|
// (gate, 0)
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
// Update `free_arithmetic` with new values.
|
// // Update `free_arithmetic` with new values.
|
||||||
if i < ArithmeticGate::num_ops(&self.config) - 1 {
|
// if i < ArithmeticGate::num_ops(&self.config) - 1 {
|
||||||
self.batched_gates
|
// self.batched_gates
|
||||||
.free_base_arithmetic
|
// .free_base_arithmetic
|
||||||
.insert((const_0, const_1), (gate, i + 1));
|
// .insert((const_0, const_1), (gate, i + 1));
|
||||||
} else {
|
// } else {
|
||||||
self.batched_gates
|
// self.batched_gates
|
||||||
.free_base_arithmetic
|
// .free_base_arithmetic
|
||||||
.remove(&(const_0, const_1));
|
// .remove(&(const_0, const_1));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
(gate, i)
|
// (gate, i)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Finds the last available arithmetic gate with the given constants or add one if there aren't any.
|
// /// Finds the last available arithmetic gate with the given constants or add one if there aren't any.
|
||||||
/// Returns `(g,i)` such that there is an arithmetic gate with the given constants at index
|
// /// Returns `(g,i)` such that there is an arithmetic gate with the given constants at index
|
||||||
/// `g` and the gate's `i`-th operation is available.
|
// /// `g` and the gate's `i`-th operation is available.
|
||||||
pub(crate) fn find_arithmetic_gate(&mut self, const_0: F, const_1: F) -> (usize, usize) {
|
// pub(crate) fn find_arithmetic_gate(&mut self, const_0: F, const_1: F) -> (usize, usize) {
|
||||||
let (gate, i) = self
|
// let (gate, i) = self
|
||||||
.batched_gates
|
// .batched_gates
|
||||||
.free_arithmetic
|
// .free_arithmetic
|
||||||
.get(&(const_0, const_1))
|
// .get(&(const_0, const_1))
|
||||||
.copied()
|
// .copied()
|
||||||
.unwrap_or_else(|| {
|
// .unwrap_or_else(|| {
|
||||||
let gate = self.add_gate(
|
// let gate = self.add_gate(
|
||||||
ArithmeticExtensionGate::new_from_config(&self.config),
|
// ArithmeticExtensionGate::new_from_config(&self.config),
|
||||||
vec![const_0, const_1],
|
// vec![const_0, const_1],
|
||||||
);
|
// );
|
||||||
(gate, 0)
|
// (gate, 0)
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
// Update `free_arithmetic` with new values.
|
// // Update `free_arithmetic` with new values.
|
||||||
if i < ArithmeticExtensionGate::<D>::num_ops(&self.config) - 1 {
|
// if i < ArithmeticExtensionGate::<D>::num_ops(&self.config) - 1 {
|
||||||
self.batched_gates
|
// self.batched_gates
|
||||||
.free_arithmetic
|
// .free_arithmetic
|
||||||
.insert((const_0, const_1), (gate, i + 1));
|
// .insert((const_0, const_1), (gate, i + 1));
|
||||||
} else {
|
// } else {
|
||||||
self.batched_gates
|
// self.batched_gates
|
||||||
.free_arithmetic
|
// .free_arithmetic
|
||||||
.remove(&(const_0, const_1));
|
// .remove(&(const_0, const_1));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
(gate, i)
|
// (gate, i)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Finds the last available arithmetic gate with the given constants or add one if there aren't any.
|
// /// Finds the last available arithmetic gate with the given constants or add one if there aren't any.
|
||||||
/// Returns `(g,i)` such that there is an arithmetic gate with the given constants at index
|
// /// Returns `(g,i)` such that there is an arithmetic gate with the given constants at index
|
||||||
/// `g` and the gate's `i`-th operation is available.
|
// /// `g` and the gate's `i`-th operation is available.
|
||||||
pub(crate) fn find_mul_gate(&mut self, const_0: F) -> (usize, usize) {
|
// pub(crate) fn find_mul_gate(&mut self, const_0: F) -> (usize, usize) {
|
||||||
let (gate, i) = self
|
// let (gate, i) = self
|
||||||
.batched_gates
|
// .batched_gates
|
||||||
.free_mul
|
// .free_mul
|
||||||
.get(&const_0)
|
// .get(&const_0)
|
||||||
.copied()
|
// .copied()
|
||||||
.unwrap_or_else(|| {
|
// .unwrap_or_else(|| {
|
||||||
let gate = self.add_gate(
|
// let gate = self.add_gate(
|
||||||
MulExtensionGate::new_from_config(&self.config),
|
// MulExtensionGate::new_from_config(&self.config),
|
||||||
vec![const_0],
|
// vec![const_0],
|
||||||
);
|
// );
|
||||||
(gate, 0)
|
// (gate, 0)
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
// Update `free_arithmetic` with new values.
|
// // Update `free_arithmetic` with new values.
|
||||||
if i < MulExtensionGate::<D>::num_ops(&self.config) - 1 {
|
// if i < MulExtensionGate::<D>::num_ops(&self.config) - 1 {
|
||||||
self.batched_gates.free_mul.insert(const_0, (gate, i + 1));
|
// self.batched_gates.free_mul.insert(const_0, (gate, i + 1));
|
||||||
} else {
|
// } else {
|
||||||
self.batched_gates.free_mul.remove(&const_0);
|
// self.batched_gates.free_mul.remove(&const_0);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
(gate, i)
|
// (gate, i)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Finds the last available random access gate with the given `vec_size` or add one if there aren't any.
|
// /// Finds the last available random access gate with the given `vec_size` or add one if there aren't any.
|
||||||
/// Returns `(g,i)` such that there is a random access gate with the given `vec_size` at index
|
// /// Returns `(g,i)` such that there is a random access gate with the given `vec_size` at index
|
||||||
/// `g` and the gate's `i`-th random access is available.
|
// /// `g` and the gate's `i`-th random access is available.
|
||||||
pub(crate) fn find_random_access_gate(&mut self, bits: usize) -> (usize, usize) {
|
// pub(crate) fn find_random_access_gate(&mut self, bits: usize) -> (usize, usize) {
|
||||||
let (gate, i) = self
|
// let (gate, i) = self
|
||||||
.batched_gates
|
// .batched_gates
|
||||||
.free_random_access
|
// .free_random_access
|
||||||
.get(&bits)
|
// .get(&bits)
|
||||||
.copied()
|
// .copied()
|
||||||
.unwrap_or_else(|| {
|
// .unwrap_or_else(|| {
|
||||||
let gate = self.add_gate(
|
// let gate = self.add_gate(
|
||||||
RandomAccessGate::new_from_config(&self.config, bits),
|
// RandomAccessGate::new_from_config(&self.config, bits),
|
||||||
vec![],
|
// vec![],
|
||||||
);
|
// );
|
||||||
(gate, 0)
|
// (gate, 0)
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
// Update `free_random_access` with new values.
|
// // Update `free_random_access` with new values.
|
||||||
if i + 1 < RandomAccessGate::<F, D>::new_from_config(&self.config, bits).num_copies {
|
// if i + 1 < RandomAccessGate::<F, D>::new_from_config(&self.config, bits).num_copies {
|
||||||
self.batched_gates
|
// self.batched_gates
|
||||||
.free_random_access
|
// .free_random_access
|
||||||
.insert(bits, (gate, i + 1));
|
// .insert(bits, (gate, i + 1));
|
||||||
} else {
|
// } else {
|
||||||
self.batched_gates.free_random_access.remove(&bits);
|
// self.batched_gates.free_random_access.remove(&bits);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
(gate, i)
|
// (gate, i)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
pub fn find_switch_gate(&mut self, chunk_size: usize) -> (SwitchGate<F, D>, usize, usize) {
|
// pub fn find_switch_gate(&mut self, chunk_size: usize) -> (SwitchGate<F, D>, usize, usize) {
|
||||||
if self.batched_gates.current_switch_gates.len() < chunk_size {
|
// if self.batched_gates.current_switch_gates.len() < chunk_size {
|
||||||
self.batched_gates.current_switch_gates.extend(vec![
|
// self.batched_gates.current_switch_gates.extend(vec![
|
||||||
None;
|
// None;
|
||||||
chunk_size
|
// chunk_size
|
||||||
- self
|
// - self
|
||||||
.batched_gates
|
// .batched_gates
|
||||||
.current_switch_gates
|
// .current_switch_gates
|
||||||
.len()
|
// .len()
|
||||||
]);
|
// ]);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
let (gate, gate_index, next_copy) =
|
// let (gate, gate_index, next_copy) =
|
||||||
match self.batched_gates.current_switch_gates[chunk_size - 1].clone() {
|
// match self.batched_gates.current_switch_gates[chunk_size - 1].clone() {
|
||||||
None => {
|
// None => {
|
||||||
let gate = SwitchGate::<F, D>::new_from_config(&self.config, chunk_size);
|
// let gate = SwitchGate::<F, D>::new_from_config(&self.config, chunk_size);
|
||||||
let gate_index = self.add_gate(gate.clone(), vec![]);
|
// let gate_index = self.add_gate(gate.clone(), vec![]);
|
||||||
(gate, gate_index, 0)
|
// (gate, gate_index, 0)
|
||||||
}
|
// }
|
||||||
Some((gate, idx, next_copy)) => (gate, idx, next_copy),
|
// Some((gate, idx, next_copy)) => (gate, idx, next_copy),
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
let num_copies = gate.num_copies;
|
// let num_copies = gate.num_copies;
|
||||||
|
//
|
||||||
if next_copy == num_copies - 1 {
|
// if next_copy == num_copies - 1 {
|
||||||
self.batched_gates.current_switch_gates[chunk_size - 1] = None;
|
// self.batched_gates.current_switch_gates[chunk_size - 1] = None;
|
||||||
} else {
|
// } else {
|
||||||
self.batched_gates.current_switch_gates[chunk_size - 1] =
|
// self.batched_gates.current_switch_gates[chunk_size - 1] =
|
||||||
Some((gate.clone(), gate_index, next_copy + 1));
|
// Some((gate.clone(), gate_index, next_copy + 1));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
(gate, gate_index, next_copy)
|
// (gate, gate_index, next_copy)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
pub(crate) fn find_u32_arithmetic_gate(&mut self) -> (usize, usize) {
|
// pub(crate) fn find_u32_arithmetic_gate(&mut self) -> (usize, usize) {
|
||||||
let (gate_index, copy) = match self.batched_gates.current_u32_arithmetic_gate {
|
// let (gate_index, copy) = match self.batched_gates.current_u32_arithmetic_gate {
|
||||||
None => {
|
// None => {
|
||||||
let gate = U32ArithmeticGate::new_from_config(&self.config);
|
// let gate = U32ArithmeticGate::new_from_config(&self.config);
|
||||||
let gate_index = self.add_gate(gate, vec![]);
|
// let gate_index = self.add_gate(gate, vec![]);
|
||||||
(gate_index, 0)
|
// (gate_index, 0)
|
||||||
}
|
// }
|
||||||
Some((gate_index, copy)) => (gate_index, copy),
|
// Some((gate_index, copy)) => (gate_index, copy),
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
if copy == U32ArithmeticGate::<F, D>::num_ops(&self.config) - 1 {
|
// if copy == U32ArithmeticGate::<F, D>::num_ops(&self.config) - 1 {
|
||||||
self.batched_gates.current_u32_arithmetic_gate = None;
|
// self.batched_gates.current_u32_arithmetic_gate = None;
|
||||||
} else {
|
// } else {
|
||||||
self.batched_gates.current_u32_arithmetic_gate = Some((gate_index, copy + 1));
|
// self.batched_gates.current_u32_arithmetic_gate = Some((gate_index, copy + 1));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
(gate_index, copy)
|
// (gate_index, copy)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
pub(crate) fn find_u32_subtraction_gate(&mut self) -> (usize, usize) {
|
// pub(crate) fn find_u32_subtraction_gate(&mut self) -> (usize, usize) {
|
||||||
let (gate_index, copy) = match self.batched_gates.current_u32_subtraction_gate {
|
// let (gate_index, copy) = match self.batched_gates.current_u32_subtraction_gate {
|
||||||
None => {
|
// None => {
|
||||||
let gate = U32SubtractionGate::new_from_config(&self.config);
|
// let gate = U32SubtractionGate::new_from_config(&self.config);
|
||||||
let gate_index = self.add_gate(gate, vec![]);
|
// let gate_index = self.add_gate(gate, vec![]);
|
||||||
(gate_index, 0)
|
// (gate_index, 0)
|
||||||
}
|
// }
|
||||||
Some((gate_index, copy)) => (gate_index, copy),
|
// Some((gate_index, copy)) => (gate_index, copy),
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
if copy == U32SubtractionGate::<F, D>::num_ops(&self.config) - 1 {
|
// if copy == U32SubtractionGate::<F, D>::num_ops(&self.config) - 1 {
|
||||||
self.batched_gates.current_u32_subtraction_gate = None;
|
// self.batched_gates.current_u32_subtraction_gate = None;
|
||||||
} else {
|
// } else {
|
||||||
self.batched_gates.current_u32_subtraction_gate = Some((gate_index, copy + 1));
|
// self.batched_gates.current_u32_subtraction_gate = Some((gate_index, copy + 1));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
(gate_index, copy)
|
// (gate_index, copy)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Returns the gate index and copy index of a free `ConstantGate` slot, potentially adding a
|
// /// Returns the gate index and copy index of a free `ConstantGate` slot, potentially adding a
|
||||||
/// new `ConstantGate` if needed.
|
// /// new `ConstantGate` if needed.
|
||||||
fn constant_gate_instance(&mut self) -> (usize, usize) {
|
// fn constant_gate_instance(&mut self) -> (usize, usize) {
|
||||||
if self.batched_gates.free_constant.is_none() {
|
// if self.batched_gates.free_constant.is_none() {
|
||||||
let num_consts = self.config.constant_gate_size;
|
// let num_consts = self.config.constant_gate_size;
|
||||||
// We will fill this `ConstantGate` with zero constants initially.
|
// // We will fill this `ConstantGate` with zero constants initially.
|
||||||
// These will be overwritten by `constant` as the gate instances are filled.
|
// // These will be overwritten by `constant` as the gate instances are filled.
|
||||||
let gate = self.add_gate(ConstantGate { num_consts }, vec![F::ZERO; num_consts]);
|
// let gate = self.add_gate(ConstantGate { num_consts }, vec![F::ZERO; num_consts]);
|
||||||
self.batched_gates.free_constant = Some((gate, 0));
|
// self.batched_gates.free_constant = Some((gate, 0));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
let (gate, instance) = self.batched_gates.free_constant.unwrap();
|
// let (gate, instance) = self.batched_gates.free_constant.unwrap();
|
||||||
if instance + 1 < self.config.constant_gate_size {
|
// if instance + 1 < self.config.constant_gate_size {
|
||||||
self.batched_gates.free_constant = Some((gate, instance + 1));
|
// self.batched_gates.free_constant = Some((gate, instance + 1));
|
||||||
} else {
|
// } else {
|
||||||
self.batched_gates.free_constant = None;
|
// self.batched_gates.free_constant = None;
|
||||||
}
|
// }
|
||||||
(gate, instance)
|
// (gate, instance)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Fill the remaining unused arithmetic operations with zeros, so that all
|
// /// Fill the remaining unused arithmetic operations with zeros, so that all
|
||||||
/// `ArithmeticGate` are run.
|
// /// `ArithmeticGate` are run.
|
||||||
fn fill_base_arithmetic_gates(&mut self) {
|
// fn fill_base_arithmetic_gates(&mut self) {
|
||||||
let zero = self.zero();
|
// let zero = self.zero();
|
||||||
for ((c0, c1), (_gate, i)) in self.batched_gates.free_base_arithmetic.clone() {
|
// for ((c0, c1), (_gate, i)) in self.batched_gates.free_base_arithmetic.clone() {
|
||||||
for _ in i..ArithmeticGate::num_ops(&self.config) {
|
// for _ in i..ArithmeticGate::num_ops(&self.config) {
|
||||||
// If we directly wire in zero, an optimization will skip doing anything and return
|
// // If we directly wire in zero, an optimization will skip doing anything and return
|
||||||
// zero. So we pass in a virtual target and connect it to zero afterward.
|
// // zero. So we pass in a virtual target and connect it to zero afterward.
|
||||||
let dummy = self.add_virtual_target();
|
// let dummy = self.add_virtual_target();
|
||||||
self.arithmetic(c0, c1, dummy, dummy, dummy);
|
// self.arithmetic(c0, c1, dummy, dummy, dummy);
|
||||||
self.connect(dummy, zero);
|
// self.connect(dummy, zero);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
assert!(self.batched_gates.free_base_arithmetic.is_empty());
|
// assert!(self.batched_gates.free_base_arithmetic.is_empty());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Fill the remaining unused arithmetic operations with zeros, so that all
|
// /// Fill the remaining unused arithmetic operations with zeros, so that all
|
||||||
/// `ArithmeticExtensionGenerator`s are run.
|
// /// `ArithmeticExtensionGenerator`s are run.
|
||||||
fn fill_arithmetic_gates(&mut self) {
|
// fn fill_arithmetic_gates(&mut self) {
|
||||||
let zero = self.zero_extension();
|
// let zero = self.zero_extension();
|
||||||
for ((c0, c1), (_gate, i)) in self.batched_gates.free_arithmetic.clone() {
|
// for ((c0, c1), (_gate, i)) in self.batched_gates.free_arithmetic.clone() {
|
||||||
for _ in i..ArithmeticExtensionGate::<D>::num_ops(&self.config) {
|
// for _ in i..ArithmeticExtensionGate::<D>::num_ops(&self.config) {
|
||||||
// If we directly wire in zero, an optimization will skip doing anything and return
|
// // If we directly wire in zero, an optimization will skip doing anything and return
|
||||||
// zero. So we pass in a virtual target and connect it to zero afterward.
|
// // zero. So we pass in a virtual target and connect it to zero afterward.
|
||||||
let dummy = self.add_virtual_extension_target();
|
// let dummy = self.add_virtual_extension_target();
|
||||||
self.arithmetic_extension(c0, c1, dummy, dummy, dummy);
|
// self.arithmetic_extension(c0, c1, dummy, dummy, dummy);
|
||||||
self.connect_extension(dummy, zero);
|
// self.connect_extension(dummy, zero);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
assert!(self.batched_gates.free_arithmetic.is_empty());
|
// assert!(self.batched_gates.free_arithmetic.is_empty());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Fill the remaining unused arithmetic operations with zeros, so that all
|
// /// Fill the remaining unused arithmetic operations with zeros, so that all
|
||||||
/// `ArithmeticExtensionGenerator`s are run.
|
// /// `ArithmeticExtensionGenerator`s are run.
|
||||||
fn fill_mul_gates(&mut self) {
|
// fn fill_mul_gates(&mut self) {
|
||||||
let zero = self.zero_extension();
|
// let zero = self.zero_extension();
|
||||||
for (c0, (_gate, i)) in self.batched_gates.free_mul.clone() {
|
// for (c0, (_gate, i)) in self.batched_gates.free_mul.clone() {
|
||||||
for _ in i..MulExtensionGate::<D>::num_ops(&self.config) {
|
// for _ in i..MulExtensionGate::<D>::num_ops(&self.config) {
|
||||||
// If we directly wire in zero, an optimization will skip doing anything and return
|
// // If we directly wire in zero, an optimization will skip doing anything and return
|
||||||
// zero. So we pass in a virtual target and connect it to zero afterward.
|
// // zero. So we pass in a virtual target and connect it to zero afterward.
|
||||||
let dummy = self.add_virtual_extension_target();
|
// let dummy = self.add_virtual_extension_target();
|
||||||
self.arithmetic_extension(c0, F::ZERO, dummy, dummy, zero);
|
// self.arithmetic_extension(c0, F::ZERO, dummy, dummy, zero);
|
||||||
self.connect_extension(dummy, zero);
|
// self.connect_extension(dummy, zero);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
assert!(self.batched_gates.free_mul.is_empty());
|
// assert!(self.batched_gates.free_mul.is_empty());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Fill the remaining unused random access operations with zeros, so that all
|
// /// Fill the remaining unused random access operations with zeros, so that all
|
||||||
/// `RandomAccessGenerator`s are run.
|
// /// `RandomAccessGenerator`s are run.
|
||||||
fn fill_random_access_gates(&mut self) {
|
// fn fill_random_access_gates(&mut self) {
|
||||||
let zero = self.zero();
|
// let zero = self.zero();
|
||||||
for (bits, (_, i)) in self.batched_gates.free_random_access.clone() {
|
// for (bits, (_, i)) in self.batched_gates.free_random_access.clone() {
|
||||||
let max_copies =
|
// let max_copies =
|
||||||
RandomAccessGate::<F, D>::new_from_config(&self.config, bits).num_copies;
|
// RandomAccessGate::<F, D>::new_from_config(&self.config, bits).num_copies;
|
||||||
for _ in i..max_copies {
|
// for _ in i..max_copies {
|
||||||
self.random_access(zero, zero, vec![zero; 1 << bits]);
|
// self.random_access(zero, zero, vec![zero; 1 << bits]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Fill the remaining unused switch gates with dummy values, so that all
|
// /// Fill the remaining unused switch gates with dummy values, so that all
|
||||||
/// `SwitchGenerator`s are run.
|
// /// `SwitchGenerator`s are run.
|
||||||
fn fill_switch_gates(&mut self) {
|
// fn fill_switch_gates(&mut self) {
|
||||||
let zero = self.zero();
|
// let zero = self.zero();
|
||||||
|
//
|
||||||
for chunk_size in 1..=self.batched_gates.current_switch_gates.len() {
|
// for chunk_size in 1..=self.batched_gates.current_switch_gates.len() {
|
||||||
if let Some((gate, gate_index, mut copy)) =
|
// if let Some((gate, gate_index, mut copy)) =
|
||||||
self.batched_gates.current_switch_gates[chunk_size - 1].clone()
|
// self.batched_gates.current_switch_gates[chunk_size - 1].clone()
|
||||||
{
|
// {
|
||||||
while copy < gate.num_copies {
|
// while copy < gate.num_copies {
|
||||||
for element in 0..chunk_size {
|
// for element in 0..chunk_size {
|
||||||
let wire_first_input =
|
// let wire_first_input =
|
||||||
Target::wire(gate_index, gate.wire_first_input(copy, element));
|
// Target::wire(gate_index, gate.wire_first_input(copy, element));
|
||||||
let wire_second_input =
|
// let wire_second_input =
|
||||||
Target::wire(gate_index, gate.wire_second_input(copy, element));
|
// Target::wire(gate_index, gate.wire_second_input(copy, element));
|
||||||
let wire_switch_bool =
|
// let wire_switch_bool =
|
||||||
Target::wire(gate_index, gate.wire_switch_bool(copy));
|
// Target::wire(gate_index, gate.wire_switch_bool(copy));
|
||||||
self.connect(zero, wire_first_input);
|
// self.connect(zero, wire_first_input);
|
||||||
self.connect(zero, wire_second_input);
|
// self.connect(zero, wire_second_input);
|
||||||
self.connect(zero, wire_switch_bool);
|
// self.connect(zero, wire_switch_bool);
|
||||||
}
|
// }
|
||||||
copy += 1;
|
// copy += 1;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Fill the remaining unused U32 arithmetic operations with zeros, so that all
|
// /// Fill the remaining unused U32 arithmetic operations with zeros, so that all
|
||||||
/// `U32ArithmeticGenerator`s are run.
|
// /// `U32ArithmeticGenerator`s are run.
|
||||||
fn fill_u32_arithmetic_gates(&mut self) {
|
// fn fill_u32_arithmetic_gates(&mut self) {
|
||||||
let zero = self.zero_u32();
|
// let zero = self.zero_u32();
|
||||||
if let Some((_gate_index, copy)) = self.batched_gates.current_u32_arithmetic_gate {
|
// if let Some((_gate_index, copy)) = self.batched_gates.current_u32_arithmetic_gate {
|
||||||
for _ in copy..U32ArithmeticGate::<F, D>::num_ops(&self.config) {
|
// for _ in copy..U32ArithmeticGate::<F, D>::num_ops(&self.config) {
|
||||||
let dummy = self.add_virtual_u32_target();
|
// let dummy = self.add_virtual_u32_target();
|
||||||
self.mul_add_u32(dummy, dummy, dummy);
|
// self.mul_add_u32(dummy, dummy, dummy);
|
||||||
self.connect_u32(dummy, zero);
|
// self.connect_u32(dummy, zero);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Fill the remaining unused U32 subtraction operations with zeros, so that all
|
// /// Fill the remaining unused U32 subtraction operations with zeros, so that all
|
||||||
/// `U32SubtractionGenerator`s are run.
|
// /// `U32SubtractionGenerator`s are run.
|
||||||
fn fill_u32_subtraction_gates(&mut self) {
|
// fn fill_u32_subtraction_gates(&mut self) {
|
||||||
let zero = self.zero_u32();
|
// let zero = self.zero_u32();
|
||||||
if let Some((_gate_index, copy)) = self.batched_gates.current_u32_subtraction_gate {
|
// if let Some((_gate_index, copy)) = self.batched_gates.current_u32_subtraction_gate {
|
||||||
for _i in copy..U32SubtractionGate::<F, D>::num_ops(&self.config) {
|
// for _i in copy..U32SubtractionGate::<F, D>::num_ops(&self.config) {
|
||||||
let dummy = self.add_virtual_u32_target();
|
// let dummy = self.add_virtual_u32_target();
|
||||||
self.sub_u32(dummy, dummy, dummy);
|
// self.sub_u32(dummy, dummy, dummy);
|
||||||
self.connect_u32(dummy, zero);
|
// self.connect_u32(dummy, zero);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fn fill_batched_gates(&mut self) {
|
fn fill_batched_gates(&mut self) {
|
||||||
self.fill_arithmetic_gates();
|
let instances = self.gate_instances.clone();
|
||||||
self.fill_base_arithmetic_gates();
|
for gate in instances {
|
||||||
self.fill_mul_gates();
|
if let Some(slot) = self.current_slots.get(&gate.gate_ref) {
|
||||||
self.fill_random_access_gates();
|
let cloned = slot.clone();
|
||||||
self.fill_switch_gates();
|
gate.gate_ref.0.fill_gate(&gate.constants, &cloned, self);
|
||||||
self.fill_u32_arithmetic_gates();
|
}
|
||||||
self.fill_u32_subtraction_gates();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -79,32 +79,33 @@ fn create_switch<F: RichField + Extendable<D>, const D: usize>(
|
|||||||
|
|
||||||
let chunk_size = a1.len();
|
let chunk_size = a1.len();
|
||||||
|
|
||||||
let (gate, gate_index, next_copy) = builder.find_switch_gate(chunk_size);
|
todo!()
|
||||||
|
// let (gate, gate_index, next_copy) = builder.find_switch_gate(chunk_size);
|
||||||
|
//
|
||||||
|
// let mut c = Vec::new();
|
||||||
|
// let mut d = Vec::new();
|
||||||
|
// for e in 0..chunk_size {
|
||||||
|
// builder.connect(
|
||||||
|
// a1[e],
|
||||||
|
// Target::wire(gate_index, gate.wire_first_input(next_copy, e)),
|
||||||
|
// );
|
||||||
|
// builder.connect(
|
||||||
|
// a2[e],
|
||||||
|
// Target::wire(gate_index, gate.wire_second_input(next_copy, e)),
|
||||||
|
// );
|
||||||
|
// c.push(Target::wire(
|
||||||
|
// gate_index,
|
||||||
|
// gate.wire_first_output(next_copy, e),
|
||||||
|
// ));
|
||||||
|
// d.push(Target::wire(
|
||||||
|
// gate_index,
|
||||||
|
// gate.wire_second_output(next_copy, e),
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
|
||||||
let mut c = Vec::new();
|
// let switch = Target::wire(gate_index, gate.wire_switch_bool(next_copy));
|
||||||
let mut d = Vec::new();
|
//
|
||||||
for e in 0..chunk_size {
|
// (switch, c, d)
|
||||||
builder.connect(
|
|
||||||
a1[e],
|
|
||||||
Target::wire(gate_index, gate.wire_first_input(next_copy, e)),
|
|
||||||
);
|
|
||||||
builder.connect(
|
|
||||||
a2[e],
|
|
||||||
Target::wire(gate_index, gate.wire_second_input(next_copy, e)),
|
|
||||||
);
|
|
||||||
c.push(Target::wire(
|
|
||||||
gate_index,
|
|
||||||
gate.wire_first_output(next_copy, e),
|
|
||||||
));
|
|
||||||
d.push(Target::wire(
|
|
||||||
gate_index,
|
|
||||||
gate.wire_second_output(next_copy, e),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let switch = Target::wire(gate_index, gate.wire_switch_bool(next_copy));
|
|
||||||
|
|
||||||
(switch, c, d)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_permutation_recursive<F: RichField + Extendable<D>, const D: usize>(
|
fn assert_permutation_recursive<F: RichField + Extendable<D>, const D: usize>(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user