From 20fc5e2da559261c31d6b8f2c3097184286e6186 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 16 Feb 2022 11:36:51 -0800 Subject: [PATCH] merge fixes --- plonky2/src/curve/glv.rs | 28 +- plonky2/src/gadgets/curve_windowed_mul.rs | 2 +- plonky2/src/gadgets/nonnative.rs | 9 +- plonky2/src/plonk/circuit_builder.rs | 440 ---------------------- 4 files changed, 24 insertions(+), 455 deletions(-) diff --git a/plonky2/src/curve/glv.rs b/plonky2/src/curve/glv.rs index 591f61ea..11172be0 100644 --- a/plonky2/src/curve/glv.rs +++ b/plonky2/src/curve/glv.rs @@ -1,6 +1,6 @@ use num::rational::Ratio; use num::BigUint; -use plonky2_field::field_types::Field; +use plonky2_field::field_types::{Field, PrimeField}; use plonky2_field::secp256k1_base::Secp256K1Base; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; @@ -35,13 +35,19 @@ pub fn decompose_secp256k1_scalar( k: Secp256K1Scalar, ) -> (Secp256K1Scalar, Secp256K1Scalar, bool, bool) { let p = Secp256K1Scalar::order(); - let c1_biguint = Ratio::new(B2.to_biguint() * k.to_biguint(), p.clone()) - .round() - .to_integer(); + let c1_biguint = Ratio::new( + B2.to_canonical_biguint() * k.to_canonical_biguint(), + p.clone(), + ) + .round() + .to_integer(); let c1 = Secp256K1Scalar::from_biguint(c1_biguint); - let c2_biguint = Ratio::new(MINUS_B1.to_biguint() * k.to_biguint(), p.clone()) - .round() - .to_integer(); + let c2_biguint = Ratio::new( + MINUS_B1.to_canonical_biguint() * k.to_canonical_biguint(), + p.clone(), + ) + .round() + .to_integer(); let c2 = Secp256K1Scalar::from_biguint(c2_biguint); let k1_raw = k - c1 * A1 - c2 * A2; @@ -49,15 +55,15 @@ pub fn decompose_secp256k1_scalar( debug_assert!(k1_raw + S * k2_raw == k); let two = BigUint::from_slice(&[2]); - let k1_neg = k1_raw.to_biguint() > p.clone() / two.clone(); + let k1_neg = k1_raw.to_canonical_biguint() > p.clone() / two.clone(); let k1 = if k1_neg { - Secp256K1Scalar::from_biguint(p.clone() - k1_raw.to_biguint()) + Secp256K1Scalar::from_biguint(p.clone() - k1_raw.to_canonical_biguint()) } else { k1_raw }; - let k2_neg = k2_raw.to_biguint() > p.clone() / two; + let k2_neg = k2_raw.to_canonical_biguint() > p.clone() / two; let k2 = if k2_neg { - Secp256K1Scalar::from_biguint(p - k2_raw.to_biguint()) + Secp256K1Scalar::from_biguint(p - k2_raw.to_canonical_biguint()) } else { k2_raw }; diff --git a/plonky2/src/gadgets/curve_windowed_mul.rs b/plonky2/src/gadgets/curve_windowed_mul.rs index f4cebe0e..879e1ade 100644 --- a/plonky2/src/gadgets/curve_windowed_mul.rs +++ b/plonky2/src/gadgets/curve_windowed_mul.rs @@ -92,7 +92,7 @@ impl, const D: usize> CircuitBuilder { p: &AffinePointTarget, n: &NonNativeTarget, ) -> AffinePointTarget { - let hash_0 = KeccakHash::<25>::hash(&[F::ZERO], false); + let hash_0 = KeccakHash::<25>::hash_no_pad(&[F::ZERO]); let hash_0_scalar = C::ScalarField::from_biguint(BigUint::from_bytes_le( &GenericHashOut::::to_bytes(&hash_0), )); diff --git a/plonky2/src/gadgets/nonnative.rs b/plonky2/src/gadgets/nonnative.rs index 046931d2..910915d0 100644 --- a/plonky2/src/gadgets/nonnative.rs +++ b/plonky2/src/gadgets/nonnative.rs @@ -31,7 +31,10 @@ impl, const D: usize> CircuitBuilder { } } - pub fn nonnative_to_biguint(&mut self, x: &NonNativeTarget) -> BigUintTarget { + pub fn nonnative_to_canonical_biguint( + &mut self, + x: &NonNativeTarget, + ) -> BigUintTarget { x.value.clone() } @@ -118,7 +121,7 @@ impl, const D: usize> CircuitBuilder { } } - pub fn if_nonnative( + pub fn if_nonnative( &mut self, b: BoolTarget, x: &NonNativeTarget, @@ -300,7 +303,7 @@ impl, const D: usize> CircuitBuilder { } pub fn reduce_nonnative(&mut self, x: &NonNativeTarget) -> NonNativeTarget { - let x_biguint = self.nonnative_to_biguint(x); + let x_biguint = self.nonnative_to_canonical_biguint(x); self.reduce(&x_biguint) } diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index b3842539..63f45fec 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -847,443 +847,3 @@ impl, const D: usize> CircuitBuilder { } } } -<<<<<<< HEAD -======= - -/// Various gate types can contain multiple copies in a single Gate. This helper struct lets a -/// CircuitBuilder track such gates that are currently being "filled up." -pub struct BatchedGates, const D: usize> { - /// A map `(c0, c1) -> (g, i)` from constants `(c0,c1)` to an available arithmetic gate using - /// these constants with gate index `g` and already using `i` arithmetic operations. - pub(crate) free_arithmetic: HashMap<(F, F), (usize, usize)>, - pub(crate) free_base_arithmetic: HashMap<(F, F), (usize, usize)>, - - pub(crate) free_mul: HashMap, - - /// A map `b -> (g, i)` from `b` bits to an available random access gate of that size with gate - /// index `g` and already using `i` random accesses. - pub(crate) free_random_access: HashMap, - - /// `current_switch_gates[chunk_size - 1]` contains None if we have no switch gates with the value - /// chunk_size, and contains `(g, i, c)`, if the gate `g`, at index `i`, already contains `c` copies - /// of switches - pub(crate) current_switch_gates: Vec, usize, usize)>>, - - /// A map `n -> (g, i)` from `n` number of addends to an available `U32AddManyGate` of that size with gate - /// index `g` and already using `i` random accesses. - pub(crate) free_u32_add_many: HashMap, - - /// The `U32ArithmeticGate` currently being filled (so new u32 arithmetic operations will be added to this gate before creating a new one) - pub(crate) current_u32_arithmetic_gate: Option<(usize, 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)>, - - /// An available `ConstantGate` instance, if any. - pub(crate) free_constant: Option<(usize, usize)>, -} - -impl, const D: usize> BatchedGates { - pub fn new() -> Self { - Self { - free_arithmetic: HashMap::new(), - free_base_arithmetic: HashMap::new(), - free_mul: HashMap::new(), - free_random_access: HashMap::new(), - current_switch_gates: Vec::new(), - free_u32_add_many: HashMap::new(), - current_u32_arithmetic_gate: None, - current_u32_subtraction_gate: None, - free_constant: None, - } - } -} - -impl, const D: usize> CircuitBuilder { - /// 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 - /// `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) { - let (gate, i) = self - .batched_gates - .free_base_arithmetic - .get(&(const_0, const_1)) - .copied() - .unwrap_or_else(|| { - let gate = self.add_gate( - ArithmeticGate::new_from_config(&self.config), - vec![const_0, const_1], - ); - (gate, 0) - }); - - // Update `free_arithmetic` with new values. - if i < ArithmeticGate::num_ops(&self.config) - 1 { - self.batched_gates - .free_base_arithmetic - .insert((const_0, const_1), (gate, i + 1)); - } else { - self.batched_gates - .free_base_arithmetic - .remove(&(const_0, const_1)); - } - - (gate, i) - } - - /// 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 - /// `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) { - let (gate, i) = self - .batched_gates - .free_arithmetic - .get(&(const_0, const_1)) - .copied() - .unwrap_or_else(|| { - let gate = self.add_gate( - ArithmeticExtensionGate::new_from_config(&self.config), - vec![const_0, const_1], - ); - (gate, 0) - }); - - // Update `free_arithmetic` with new values. - if i < ArithmeticExtensionGate::::num_ops(&self.config) - 1 { - self.batched_gates - .free_arithmetic - .insert((const_0, const_1), (gate, i + 1)); - } else { - self.batched_gates - .free_arithmetic - .remove(&(const_0, const_1)); - } - - (gate, i) - } - - /// 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 - /// `g` and the gate's `i`-th operation is available. - pub(crate) fn find_mul_gate(&mut self, const_0: F) -> (usize, usize) { - let (gate, i) = self - .batched_gates - .free_mul - .get(&const_0) - .copied() - .unwrap_or_else(|| { - let gate = self.add_gate( - MulExtensionGate::new_from_config(&self.config), - vec![const_0], - ); - (gate, 0) - }); - - // Update `free_arithmetic` with new values. - if i < MulExtensionGate::::num_ops(&self.config) - 1 { - self.batched_gates.free_mul.insert(const_0, (gate, i + 1)); - } else { - self.batched_gates.free_mul.remove(&const_0); - } - - (gate, i) - } - - /// Finds the last available random access gate with the given `bits` or adds one if there aren't any. - /// Returns `(g,i)` such that there is a random access gate for the given `bits` at index - /// `g` and the gate's `i`-th random access is available. - pub(crate) fn find_random_access_gate(&mut self, bits: usize) -> (usize, usize) { - let (gate, i) = self - .batched_gates - .free_random_access - .get(&bits) - .copied() - .unwrap_or_else(|| { - let gate = self.add_gate( - RandomAccessGate::new_from_config(&self.config, bits), - vec![], - ); - (gate, 0) - }); - - // Update `free_random_access` with new values. - if i + 1 < RandomAccessGate::::new_from_config(&self.config, bits).num_copies { - self.batched_gates - .free_random_access - .insert(bits, (gate, i + 1)); - } else { - self.batched_gates.free_random_access.remove(&bits); - } - - (gate, i) - } - - pub fn find_switch_gate(&mut self, chunk_size: usize) -> (SwitchGate, usize, usize) { - if self.batched_gates.current_switch_gates.len() < chunk_size { - self.batched_gates.current_switch_gates.extend(vec![ - None; - chunk_size - - self - .batched_gates - .current_switch_gates - .len() - ]); - } - - let (gate, gate_index, next_copy) = - match self.batched_gates.current_switch_gates[chunk_size - 1].clone() { - None => { - let gate = SwitchGate::::new_from_config(&self.config, chunk_size); - let gate_index = self.add_gate(gate.clone(), vec![]); - (gate, gate_index, 0) - } - Some((gate, idx, next_copy)) => (gate, idx, next_copy), - }; - - let num_copies = gate.num_copies; - - if next_copy == num_copies - 1 { - self.batched_gates.current_switch_gates[chunk_size - 1] = None; - } else { - self.batched_gates.current_switch_gates[chunk_size - 1] = - Some((gate.clone(), gate_index, next_copy + 1)); - } - - (gate, gate_index, next_copy) - } - - /// Finds the last available U32 add-many gate with the given `num_addends` or adds one if there aren't any. - /// Returns `(g,i)` such that there is a `U32AddManyGate` for the given `num_addends` at index - /// `g` and the gate's `i`-th copy is available. - pub(crate) fn find_u32_add_many_gate(&mut self, num_addends: usize) -> (usize, usize) { - let (gate, i) = self - .batched_gates - .free_u32_add_many - .get(&num_addends) - .copied() - .unwrap_or_else(|| { - let gate = self.add_gate( - U32AddManyGate::new_from_config(&self.config, num_addends), - vec![], - ); - (gate, 0) - }); - - // Update `free_u32_add_many` with new values. - if i + 1 < U32AddManyGate::::new_from_config(&self.config, num_addends).num_ops { - self.batched_gates - .free_u32_add_many - .insert(num_addends, (gate, i + 1)); - } else { - self.batched_gates.free_u32_add_many.remove(&num_addends); - } - - (gate, i) - } - - pub(crate) fn find_u32_arithmetic_gate(&mut self) -> (usize, usize) { - let (gate_index, copy) = match self.batched_gates.current_u32_arithmetic_gate { - None => { - let gate = U32ArithmeticGate::new_from_config(&self.config); - let gate_index = self.add_gate(gate, vec![]); - (gate_index, 0) - } - Some((gate_index, copy)) => (gate_index, copy), - }; - - if copy == U32ArithmeticGate::::num_ops(&self.config) - 1 { - self.batched_gates.current_u32_arithmetic_gate = None; - } else { - self.batched_gates.current_u32_arithmetic_gate = Some((gate_index, copy + 1)); - } - - (gate_index, copy) - } - - pub(crate) fn find_u32_subtraction_gate(&mut self) -> (usize, usize) { - let (gate_index, copy) = match self.batched_gates.current_u32_subtraction_gate { - None => { - let gate = U32SubtractionGate::new_from_config(&self.config); - let gate_index = self.add_gate(gate, vec![]); - (gate_index, 0) - } - Some((gate_index, copy)) => (gate_index, copy), - }; - - if copy == U32SubtractionGate::::num_ops(&self.config) - 1 { - self.batched_gates.current_u32_subtraction_gate = None; - } else { - self.batched_gates.current_u32_subtraction_gate = Some((gate_index, copy + 1)); - } - - (gate_index, copy) - } - - /// 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) { - if self.batched_gates.free_constant.is_none() { - 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 = self.add_gate(ConstantGate { num_consts }, vec![F::ZERO; num_consts]); - self.batched_gates.free_constant = Some((gate, 0)); - } - - let (gate, instance) = self.batched_gates.free_constant.unwrap(); - if instance + 1 < self.config.constant_gate_size { - self.batched_gates.free_constant = Some((gate, instance + 1)); - } else { - self.batched_gates.free_constant = None; - } - (gate, instance) - } - - /// Fill the remaining unused arithmetic operations with zeros, so that all - /// `ArithmeticGate` are run. - fn fill_base_arithmetic_gates(&mut self) { - let zero = self.zero(); - for ((c0, c1), (_gate, i)) in self.batched_gates.free_base_arithmetic.clone() { - for _ in i..ArithmeticGate::num_ops(&self.config) { - // 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. - let dummy = self.add_virtual_target(); - self.arithmetic(c0, c1, dummy, dummy, dummy); - self.connect(dummy, zero); - } - } - assert!(self.batched_gates.free_base_arithmetic.is_empty()); - } - - /// Fill the remaining unused arithmetic operations with zeros, so that all - /// `ArithmeticExtensionGenerator`s are run. - fn fill_arithmetic_gates(&mut self) { - let zero = self.zero_extension(); - for ((c0, c1), (_gate, i)) in self.batched_gates.free_arithmetic.clone() { - for _ in i..ArithmeticExtensionGate::::num_ops(&self.config) { - // 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. - let dummy = self.add_virtual_extension_target(); - self.arithmetic_extension(c0, c1, dummy, dummy, dummy); - self.connect_extension(dummy, zero); - } - } - assert!(self.batched_gates.free_arithmetic.is_empty()); - } - - /// Fill the remaining unused arithmetic operations with zeros, so that all - /// `ArithmeticExtensionGenerator`s are run. - fn fill_mul_gates(&mut self) { - let zero = self.zero_extension(); - for (c0, (_gate, i)) in self.batched_gates.free_mul.clone() { - for _ in i..MulExtensionGate::::num_ops(&self.config) { - // 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. - let dummy = self.add_virtual_extension_target(); - self.arithmetic_extension(c0, F::ZERO, dummy, dummy, zero); - self.connect_extension(dummy, zero); - } - } - assert!(self.batched_gates.free_mul.is_empty()); - } - - /// Fill the remaining unused random access operations with zeros, so that all - /// `RandomAccessGenerator`s are run. - fn fill_random_access_gates(&mut self) { - let zero = self.zero(); - for (bits, (_, i)) in self.batched_gates.free_random_access.clone() { - let max_copies = - RandomAccessGate::::new_from_config(&self.config, bits).num_copies; - for _ in i..max_copies { - let result = self.random_access(zero, vec![zero; 1 << bits]); - self.connect(result, zero); - } - } - } - - /// Fill the remaining unused switch gates with dummy values, so that all - /// `SwitchGenerator`s are run. - fn fill_switch_gates(&mut self) { - let zero = self.zero(); - - for chunk_size in 1..=self.batched_gates.current_switch_gates.len() { - if let Some((gate, gate_index, mut copy)) = - self.batched_gates.current_switch_gates[chunk_size - 1].clone() - { - while copy < gate.num_copies { - for element in 0..chunk_size { - let wire_first_input = - Target::wire(gate_index, gate.wire_first_input(copy, element)); - let wire_second_input = - Target::wire(gate_index, gate.wire_second_input(copy, element)); - let wire_switch_bool = - Target::wire(gate_index, gate.wire_switch_bool(copy)); - self.connect(zero, wire_first_input); - self.connect(zero, wire_second_input); - self.connect(zero, wire_switch_bool); - } - copy += 1; - } - } - } - } - - /// Fill the remaining unused u32 add-many operations with zeros, so that all - /// `U32AddManyGenerator`s are run. - fn fill_u32_add_many_gates(&mut self) { - let zero = self.zero_u32(); - for (num_addends, (_, i)) in self.batched_gates.free_u32_add_many.clone() { - let max_copies = - U32AddManyGate::::new_from_config(&self.config, num_addends).num_ops; - for _ in i..max_copies { - let gate = U32AddManyGate::::new_from_config(&self.config, num_addends); - let (gate_index, copy) = self.find_u32_add_many_gate(num_addends); - - for j in 0..num_addends { - self.connect( - Target::wire(gate_index, gate.wire_ith_op_jth_addend(copy, j)), - zero.0, - ); - } - self.connect(Target::wire(gate_index, gate.wire_ith_carry(copy)), zero.0); - } - } - } - - /// Fill the remaining unused U32 arithmetic operations with zeros, so that all - /// `U32ArithmeticGenerator`s are run. - fn fill_u32_arithmetic_gates(&mut self) { - let zero = self.zero_u32(); - if let Some((_gate_index, copy)) = self.batched_gates.current_u32_arithmetic_gate { - for _ in copy..U32ArithmeticGate::::num_ops(&self.config) { - let dummy = self.add_virtual_u32_target(); - self.mul_add_u32(dummy, dummy, dummy); - self.connect_u32(dummy, zero); - } - } - } - - /// Fill the remaining unused U32 subtraction operations with zeros, so that all - /// `U32SubtractionGenerator`s are run. - fn fill_u32_subtraction_gates(&mut self) { - let zero = self.zero_u32(); - if let Some((_gate_index, copy)) = self.batched_gates.current_u32_subtraction_gate { - for _i in copy..U32SubtractionGate::::num_ops(&self.config) { - let dummy = self.add_virtual_u32_target(); - self.sub_u32(dummy, dummy, dummy); - self.connect_u32(dummy, zero); - } - } - } - - fn fill_batched_gates(&mut self) { - self.fill_arithmetic_gates(); - self.fill_base_arithmetic_gates(); - self.fill_mul_gates(); - self.fill_random_access_gates(); - self.fill_switch_gates(); - self.fill_u32_add_many_gates(); - self.fill_u32_arithmetic_gates(); - self.fill_u32_subtraction_gates(); - } -} ->>>>>>> aa48021 (windowed multiplication in circuit)