updated for changes in main

This commit is contained in:
Nicholas Ward 2022-01-21 16:10:25 -08:00
parent 5de2b69558
commit 1035438df4
12 changed files with 101 additions and 173 deletions

View File

@ -2,8 +2,10 @@ use itertools::{unfold, Itertools};
use num::BigUint;
use crate::curve::curve_types::{AffinePoint, Curve, CurveScalar};
use crate::field::field_types::{Field, RichField};
use crate::hash::hashing::hash_n_to_1;
use crate::field::field_types::Field;
use crate::hash::hash_types::RichField;
use crate::hash::hashing::{hash_n_to_m, PlonkyPermutation};
use crate::hash::poseidon::PoseidonPermutation;
pub struct ECDSASignature<C: Curve> {
pub r: C::ScalarField,
@ -21,8 +23,8 @@ pub fn scalar_to_base<C: Curve>(x: C::ScalarField) -> C::BaseField {
C::BaseField::from_biguint(x.to_biguint())
}
pub fn hash_to_bits<F: RichField>(x: F, num_bits: usize) -> Vec<bool> {
let hashed = hash_n_to_1(vec![x], true);
pub fn hash_to_bits<F: RichField, P: PlonkyPermutation<F>>(x: F, num_bits: usize) -> Vec<bool> {
let hashed = hash_n_to_m::<F, P>(&vec![x], 1, true)[0];
let mut val = hashed.to_canonical_u64();
unfold((), move |_| {
@ -34,21 +36,26 @@ pub fn hash_to_bits<F: RichField>(x: F, num_bits: usize) -> Vec<bool> {
.collect()
}
pub fn hash_to_scalar<F: RichField, C: Curve>(x: F, num_bits: usize) -> C::ScalarField {
let h_bits = hash_to_bits(x, num_bits);
pub fn hash_to_scalar<F: RichField, C: Curve, P: PlonkyPermutation<F>>(
x: F,
num_bits: usize,
) -> C::ScalarField {
let h_bits = hash_to_bits::<F, P>(x, num_bits);
let h_vals: Vec<_> = h_bits
.iter()
.chunks(32)
.into_iter()
.map(|chunk| {
chunk.enumerate()
.fold(0u32, |acc, (pow, &bit)| acc + (bit as u32) * (2 << pow))
}).collect();
chunk
.enumerate()
.fold(0u32, |acc, (pow, &bit)| acc + (bit as u32) * (2 << pow))
})
.collect();
C::ScalarField::from_biguint(BigUint::new(h_vals))
}
pub fn sign_message<F: RichField, C: Curve>(msg: F, sk: ECDSASecretKey<C>) -> ECDSASignature<C> {
let h = hash_to_scalar::<F, C>(msg, 256);
let h = hash_to_scalar::<F, C, PoseidonPermutation>(msg, 256);
let k = C::ScalarField::rand();
let rr = (CurveScalar(k) * C::GENERATOR_PROJECTIVE).to_affine();
@ -65,7 +72,7 @@ pub fn verify_message<F: RichField, C: Curve>(
) -> bool {
let ECDSASignature { r, s } = sig;
let h = hash_to_scalar::<F, C>(msg, 256);
let h = hash_to_scalar::<F, C, PoseidonPermutation>(msg, 256);
let c = s.inverse();
let u1 = h * c;

View File

@ -1,8 +1,12 @@
use std::marker::PhantomData;
use plonky2_field::extension_field::Extendable;
use crate::gates::add_many_u32::U32AddManyGate;
use crate::gates::arithmetic_u32::U32ArithmeticGate;
use crate::gates::subtraction_u32::U32SubtractionGate;
use crate::hash::hash_types::RichField;
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
use crate::iop::target::Target;
use crate::iop::witness::{PartitionWitness, Witness};
use crate::plonk::circuit_builder::CircuitBuilder;
@ -243,16 +247,18 @@ mod tests {
use anyhow::Result;
use rand::{thread_rng, Rng};
use crate::field::goldilocks_field::GoldilocksField;
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::verifier::verify;
#[test]
pub fn test_add_many_u32s() -> Result<()> {
type F = GoldilocksField;
const D: usize = 4;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
const NUM_ADDENDS: usize = 15;
let config = CircuitConfig::standard_recursion_config();
@ -276,7 +282,7 @@ mod tests {
builder.connect_u32(result_low, expected_low);
builder.connect_u32(result_high, expected_high);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}

View File

@ -1,6 +1,6 @@
use std::marker::PhantomData;
use num::{BigUint, Integer};
use num::{BigUint, FromPrimitive, Integer, Zero};
use plonky2_field::extension_field::Extendable;
use crate::gadgets::arithmetic_u32::U32Target;

View File

@ -2,11 +2,12 @@ use std::marker::PhantomData;
use crate::curve::curve_types::Curve;
use crate::field::extension_field::Extendable;
use crate::field::field_types::RichField;
use crate::gadgets::arithmetic_u32::U32Target;
use crate::gadgets::biguint::BigUintTarget;
use crate::gadgets::curve::AffinePointTarget;
use crate::gadgets::nonnative::NonNativeTarget;
use crate::hash::hash_types::RichField;
use crate::hash::poseidon::PoseidonHash;
use crate::iop::target::{BoolTarget, Target};
use crate::plonk::circuit_builder::CircuitBuilder;
@ -21,7 +22,7 @@ pub struct ECDSASignatureTarget<C: Curve> {
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
pub fn hash_to_bits(&mut self, x: Target, num_bits: usize) -> Vec<BoolTarget> {
let inputs = vec![x];
let hashed = self.hash_n_to_m(inputs, 1, true)[0];
let hashed = self.hash_n_to_m::<PoseidonHash>(inputs, 1, true)[0];
self.split_le(hashed, num_bits)
}
@ -82,20 +83,22 @@ mod tests {
use crate::curve::ecdsa::{sign_message, ECDSAPublicKey, ECDSASecretKey, ECDSASignature};
use crate::curve::secp256k1::Secp256K1;
use crate::field::field_types::Field;
use crate::field::goldilocks_field::GoldilocksField;
use crate::field::secp256k1_scalar::Secp256K1Scalar;
use crate::gadgets::ecdsa::{ECDSAPublicKeyTarget, ECDSASignatureTarget};
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::verifier::verify;
#[test]
#[ignore]
fn test_ecdsa_circuit() -> Result<()> {
type F = GoldilocksField;
const D: usize = 4;
type C = Secp256K1;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type Curve = Secp256K1;
let config = CircuitConfig::standard_ecc_config();
@ -105,8 +108,8 @@ mod tests {
let msg = F::rand();
let msg_target = builder.constant(msg);
let sk = ECDSASecretKey::<C>(Secp256K1Scalar::rand());
let pk = ECDSAPublicKey((CurveScalar(sk.0) * C::GENERATOR_PROJECTIVE).to_affine());
let sk = ECDSASecretKey::<Curve>(Secp256K1Scalar::rand());
let pk = ECDSAPublicKey((CurveScalar(sk.0) * Curve::GENERATOR_PROJECTIVE).to_affine());
let pk_target = ECDSAPublicKeyTarget(builder.constant_affine_point(pk.0));
@ -122,7 +125,7 @@ mod tests {
builder.verify_message(msg_target, sig_target, pk_target);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}

View File

@ -2,7 +2,6 @@ pub mod arithmetic;
pub mod arithmetic_extension;
pub mod arithmetic_u32;
pub mod biguint;
pub mod binary_arithmetic;
pub mod curve;
pub mod ecdsa;
pub mod hash;

View File

@ -1,12 +1,14 @@
use std::marker::PhantomData;
use num::{BigUint, Zero};
use num::{BigUint, Integer, One, Zero};
use plonky2_field::{extension_field::Extendable, field_types::Field};
use plonky2_util::ceil_div_usize;
use crate::gadgets::arithmetic_u32::U32Target;
use crate::field::field_types::RichField;
use crate::gadgets::binary_arithmetic::BinaryTarget;
use crate::gadgets::biguint::BigUintTarget;
use crate::hash::hash_types::RichField;
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
use crate::iop::target::{BoolTarget, Target};
use crate::iop::witness::{PartitionWitness, Witness};
use crate::plonk::circuit_builder::CircuitBuilder;
@ -514,6 +516,7 @@ mod tests {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let x_ff = FF::rand();
let y_ff = FF::rand();
let sum_ff = x_ff + y_ff;
@ -537,6 +540,10 @@ mod tests {
#[test]
fn test_nonnative_many_adds() -> Result<()> {
type FF = Secp256K1Base;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let a_ff = FF::rand();
let b_ff = FF::rand();
let c_ff = FF::rand();
@ -549,7 +556,7 @@ mod tests {
let config = CircuitConfig::standard_ecc_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let mut builder = CircuitBuilder::<F, D>::new(config);
let a = builder.constant_nonnative(a_ff);
let b = builder.constant_nonnative(b_ff);
@ -565,7 +572,7 @@ mod tests {
let sum_expected = builder.constant_nonnative(sum_ff);
builder.connect_nonnative(&sum, &sum_expected);
let data = builder.build();
let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
@ -576,6 +583,7 @@ mod tests {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
let x_ff = FF::rand();
let mut y_ff = FF::rand();
while y_ff.to_biguint() > x_ff.to_biguint() {
@ -627,11 +635,13 @@ mod tests {
fn test_nonnative_many_muls_helper(num: usize) {
type FF = Secp256K1Base;
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type F = GoldilocksField;
let config = CircuitConfig::standard_ecc_config();
let mut unop_builder = CircuitBuilder::<F, 4>::new(config.clone());
let mut op_builder = CircuitBuilder::<F, 4>::new(config);
let mut unop_builder = CircuitBuilder::<F, D>::new(config.clone());
let mut op_builder = CircuitBuilder::<F, D>::new(config);
let ffs: Vec<_> = (0..num).map(|_| FF::rand()).collect();

View File

@ -1,5 +1,7 @@
use plonky2_field::extension_field::Extendable;
use crate::gadgets::arithmetic_u32::U32Target;
use crate::gates::range_check_u32::U32RangeCheckGate;
use crate::hash::hash_types::RichField;
use crate::iop::generator::{GeneratedValues, SimpleGenerator};
use crate::iop::target::{BoolTarget, Target};

View File

@ -1,11 +1,14 @@
use std::marker::PhantomData;
use itertools::unfold;
use plonky2_util::ceil_div_usize;
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable;
use crate::field::field_types::{Field, RichField};
use crate::field::field_types::Field;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
use crate::iop::ext_target::ExtensionTarget;
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
use crate::iop::target::Target;
use crate::iop::wire::Wire;
@ -13,7 +16,6 @@ use crate::iop::witness::{PartitionWitness, Witness};
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
use crate::util::ceil_div_usize;
const LOG2_MAX_NUM_ADDENDS: usize = 4;
const MAX_NUM_ADDENDS: usize = 16;
@ -128,8 +130,11 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32AddManyGate
constraints
}
fn eval_unfiltered_base(&self, vars: EvaluationVarsBase<F>) -> Vec<F> {
let mut constraints = Vec::with_capacity(self.num_constraints());
fn eval_unfiltered_base_one(
&self,
vars: EvaluationVarsBase<F>,
mut yield_constr: StridedConstraintConsumer<F>,
) {
for i in 0..self.num_ops {
let addends: Vec<F> = (0..self.num_addends)
.map(|j| vars.local_wires[self.wire_ith_op_jth_addend(i, j)])
@ -144,7 +149,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32AddManyGate
let base = F::from_canonical_u64(1 << 32u64);
let combined_output = output_carry * base + output_result;
constraints.push(combined_output - computed_output);
yield_constr.one(combined_output - computed_output);
let mut combined_result_limbs = F::ZERO;
let mut combined_carry_limbs = F::ZERO;
@ -155,7 +160,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32AddManyGate
let product = (0..max_limb)
.map(|x| this_limb - F::from_canonical_usize(x))
.product();
constraints.push(product);
yield_constr.one(product);
if j < Self::num_result_limbs() {
combined_result_limbs = base * combined_result_limbs + this_limb;
@ -163,11 +168,9 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32AddManyGate
combined_carry_limbs = base * combined_carry_limbs + this_limb;
}
}
constraints.push(combined_result_limbs - output_result);
constraints.push(combined_carry_limbs - output_carry);
yield_constr.one(combined_result_limbs - output_result);
yield_constr.one(combined_carry_limbs - output_carry);
}
constraints
}
fn eval_unfiltered_recursively(
@ -355,6 +358,7 @@ mod tests {
use crate::gates::gate::Gate;
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::hash::hash_types::HashOut;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::vars::EvaluationVars;
#[test]
@ -368,7 +372,10 @@ mod tests {
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<GoldilocksField, _, 4>(U32AddManyGate::<GoldilocksField, 4> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
test_eval_fns::<F, C, _, D>(U32AddManyGate::<GoldilocksField, D> {
num_addends: 4,
num_ops: 3,
_phantom: PhantomData,

View File

@ -7,8 +7,6 @@ pub mod arithmetic_extension;
pub mod arithmetic_u32;
pub mod assert_le;
pub mod base_sum;
pub mod binary_arithmetic;
pub mod binary_subtraction;
pub mod comparison;
pub mod constant;
pub mod exponentiation;

View File

@ -1,16 +1,19 @@
use std::marker::PhantomData;
use crate::field::extension_field::target::ExtensionTarget;
use plonky2_util::ceil_div_usize;
use crate::field::extension_field::Extendable;
use crate::field::field_types::{Field, RichField};
use crate::field::field_types::Field;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
use crate::iop::ext_target::ExtensionTarget;
use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator};
use crate::iop::target::Target;
use crate::iop::witness::{PartitionWitness, Witness};
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_recursive};
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
use crate::util::ceil_div_usize;
/// A gate which can decompose a number into base B little-endian limbs.
#[derive(Copy, Clone, Debug)]
@ -73,9 +76,11 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32RangeCheckG
constraints
}
fn eval_unfiltered_base(&self, vars: EvaluationVarsBase<F>) -> Vec<F> {
let mut constraints = Vec::with_capacity(self.num_constraints());
fn eval_unfiltered_base_one(
&self,
vars: EvaluationVarsBase<F>,
mut yield_constr: StridedConstraintConsumer<F>,
) {
let base = F::from_canonical_usize(Self::BASE);
for i in 0..self.num_input_limbs {
let input_limb = vars.local_wires[self.wire_ith_input_limb(i)];
@ -84,17 +89,15 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32RangeCheckG
.collect();
let computed_sum = reduce_with_powers(&aux_limbs, base);
constraints.push(computed_sum - input_limb);
yield_constr.one(computed_sum - input_limb);
for aux_limb in aux_limbs {
constraints.push(
yield_constr.one(
(0..Self::BASE)
.map(|i| aux_limb - F::from_canonical_usize(i))
.product(),
);
}
}
constraints
}
fn eval_unfiltered_recursively(
@ -217,6 +220,7 @@ mod tests {
use anyhow::Result;
use itertools::unfold;
use plonky2_util::ceil_div_usize;
use rand::Rng;
use crate::field::extension_field::quartic::QuarticExtension;
@ -226,8 +230,8 @@ mod tests {
use crate::gates::gate_testing::{test_eval_fns, test_low_degree};
use crate::gates::range_check_u32::U32RangeCheckGate;
use crate::hash::hash_types::HashOut;
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
use crate::plonk::vars::EvaluationVars;
use crate::util::ceil_div_usize;
#[test]
fn low_degree() {
@ -236,7 +240,10 @@ mod tests {
#[test]
fn eval_fns() -> Result<()> {
test_eval_fns::<GoldilocksField, _, 4>(U32RangeCheckGate::new(8))
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
test_eval_fns::<F, C, _, D>(U32RangeCheckGate::new(8))
}
fn test_gate_constraint(input_limbs: Vec<u64>) {

View File

@ -1,17 +1,16 @@
use std::fmt::Debug;
use std::marker::PhantomData;
use num::BigUint;
use num::{BigUint, FromPrimitive, Integer, Zero};
use plonky2_field::extension_field::{Extendable, FieldExtension};
use plonky2_field::field_types::Field;
use crate::gadgets::arithmetic_u32::U32Target;
use crate::gadgets::biguint::BigUintTarget;
use crate::gadgets::binary_arithmetic::BinaryTarget;
use crate::gadgets::nonnative::NonNativeTarget;
use crate::hash::hash_types::{HashOut, HashOutTarget, RichField};
use crate::iop::ext_target::ExtensionTarget;
use crate::iop::target::Target;
use crate::iop::target::{BoolTarget, Target};
use crate::iop::wire::Wire;
use crate::iop::witness::{PartialWitness, PartitionWitness, Witness};
use crate::plonk::circuit_data::{CommonCircuitData, ProverOnlyCircuitData};
@ -170,10 +169,6 @@ impl<F: Field> GeneratedValues<F> {
self.set_target(target.0, F::from_canonical_u32(value))
}
pub fn set_binary_target<const BITS: usize>(&mut self, target: BinaryTarget<BITS>, value: F) {
self.set_target(target.0, value)
}
pub fn set_biguint_target(&mut self, target: BigUintTarget, value: BigUint) {
let base = BigUint::from_u64(1 << 32).unwrap();
let mut limbs = Vec::new();

View File

@ -19,8 +19,6 @@ use crate::gadgets::polynomial::PolynomialCoeffsExtTarget;
use crate::gates::arithmetic_base::ArithmeticGate;
use crate::gates::arithmetic_extension::ArithmeticExtensionGate;
use crate::gates::arithmetic_u32::U32ArithmeticGate;
use crate::gates::binary_arithmetic::BinaryArithmeticGate;
use crate::gates::binary_subtraction::BinarySubtractionGate;
use crate::gates::constant::ConstantGate;
use crate::gates::gate::{Gate, GateInstance, GateRef, PrefixedGate};
use crate::gates::gate_tree::Tree;
@ -354,11 +352,6 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
U32Target(self.constant(F::from_canonical_u32(c)))
}
/// Returns a BinaryTarget for the value `c`, which is assumed to be at most BITS bits.
pub fn constant_binary<const BITS: usize>(&mut self, c: F) -> BinaryTarget<BITS> {
BinaryTarget(self.constant(c))
}
/// If the given target is a constant (i.e. it was created by the `constant(F)` method), returns
/// its constant value. Otherwise, returns `None`.
pub fn target_as_constant(&self, target: Target) -> Option<F> {
@ -838,11 +831,6 @@ pub struct BatchedGates<F: RichField + Extendable<D>, const D: usize> {
/// The `U32SubtractionGate` currently being filled (so new u32 subtraction operations will be added to this gate before creating a new one)
pub(crate) current_u32_subtraction_gate: Option<(usize, usize)>,
/// A map `b -> (g, i)` from `b` bits to an available `BinaryArithmeticGate` for number of bits `b`.
pub(crate) free_binary_arithmetic_gate: HashMap<usize, (usize, usize)>,
/// A map `b -> (g, i)` from `b` bits to an available `BinarySubtractionGate` for number of bits `b`.
pub(crate) free_binary_subtraction_gate: HashMap<usize, (usize, usize)>,
/// An available `ConstantGate` instance, if any.
pub(crate) free_constant: Option<(usize, usize)>,
}
@ -858,8 +846,6 @@ impl<F: RichField + Extendable<D>, const D: usize> BatchedGates<F, D> {
free_u32_add_many: HashMap::new(),
current_u32_arithmetic_gate: None,
current_u32_subtraction_gate: None,
free_binary_arithmetic_gate: HashMap::new(),
free_binary_subtraction_gate: HashMap::new(),
free_constant: None,
}
}
@ -1085,66 +1071,6 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
(gate_index, copy)
}
/// Finds the last available binary arithmetic with the given `bits` or add one if there aren't any.
/// Returns `(g,i)` such that there is a binary arithmetic for the given `bits` at index
/// `g` and the gate's `i`-th copy is available.
pub(crate) fn find_binary_arithmetic_gate<const BITS: usize>(&mut self) -> (usize, usize) {
let (gate, i) = self
.batched_gates
.free_binary_arithmetic_gate
.get(&BITS)
.copied()
.unwrap_or_else(|| {
let gate = self.add_gate(
BinaryArithmeticGate::<F, D, BITS>::new_from_config(&self.config),
vec![],
);
(gate, 0)
});
// Update `free_binary_arithmetic` with new values.
if i + 1 < BinaryArithmeticGate::<F, D, BITS>::new_from_config(&self.config).num_ops {
self.batched_gates
.free_binary_arithmetic_gate
.insert(BITS, (gate, i + 1));
} else {
self.batched_gates.free_binary_arithmetic_gate.remove(&BITS);
}
(gate, i)
}
/// Finds the last available binary subtraction with the given `bits` or add one if there aren't any.
/// Returns `(g,i)` such that there is a binary subtraction for the given `bits` at index
/// `g` and the gate's `i`-th copy is available.
pub(crate) fn find_binary_subtraction_gate<const BITS: usize>(&mut self) -> (usize, usize) {
let (gate, i) = self
.batched_gates
.free_binary_subtraction_gate
.get(&BITS)
.copied()
.unwrap_or_else(|| {
let gate = self.add_gate(
BinarySubtractionGate::<F, D, BITS>::new_from_config(&self.config),
vec![],
);
(gate, 0)
});
// Update `free_binary_subtraction` with new values.
if i + 1 < BinarySubtractionGate::<F, D, BITS>::new_from_config(&self.config).num_ops {
self.batched_gates
.free_binary_subtraction_gate
.insert(BITS, (gate, i + 1));
} else {
self.batched_gates
.free_binary_subtraction_gate
.remove(&BITS);
}
(gate, i)
}
/// Returns the gate index and copy index of a free `ConstantGate` slot, potentially adding a
/// new `ConstantGate` if needed.
fn constant_gate_instance(&mut self) -> (usize, usize) {
@ -1301,36 +1227,6 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
}
/// Fill the remaining unused binary arithmetic operations with zeros, so that all
/// `BinaryArithmeticGenerator`s are run.
fn fill_binary_arithmetic_gates(&mut self) {
let zero = self.zero_binary::<30>();
if let Some(&(_, i)) = self.batched_gates.free_binary_arithmetic_gate.get(&30) {
let max_copies =
BinaryArithmeticGate::<F, D, 30>::new_from_config(&self.config).num_ops;
for _ in i..max_copies {
let dummy = self.add_virtual_binary_target();
self.mul_add_binary(dummy, dummy, dummy);
self.connect_binary(dummy, zero);
}
}
}
/// Fill the remaining unused binary subtraction operations with zeros, so that all
/// `BinarySubtractionGenerator`s are run.
fn fill_binary_subtraction_gates(&mut self) {
let zero = self.zero_binary::<30>();
if let Some(&(_, i)) = self.batched_gates.free_binary_subtraction_gate.get(&30) {
let max_copies =
BinarySubtractionGate::<F, D, 30>::new_from_config(&self.config).num_ops;
for _ in i..max_copies {
let dummy = self.add_virtual_binary_target();
self.sub_binary(dummy, dummy, dummy);
self.connect_binary(dummy, zero);
}
}
}
fn fill_batched_gates(&mut self) {
self.fill_arithmetic_gates();
self.fill_base_arithmetic_gates();
@ -1340,7 +1236,5 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.fill_u32_add_many_gates();
self.fill_u32_arithmetic_gates();
self.fill_u32_subtraction_gates();
self.fill_binary_arithmetic_gates();
self.fill_binary_subtraction_gates();
}
}