From 82ce3ea8b2c1202a97ef2f20fa543bf7e8660f52 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 20 Jan 2022 16:07:54 -0800 Subject: [PATCH] ECDSA merge --- plonky2/src/gadgets/biguint.rs | 50 ++++++++++++---------- plonky2/src/gadgets/ecdsa.rs | 4 +- plonky2/src/gadgets/multiple_comparison.rs | 13 ++---- plonky2/src/gadgets/nonnative.rs | 12 +++--- plonky2/src/iop/generator.rs | 15 +++++-- 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/plonky2/src/gadgets/biguint.rs b/plonky2/src/gadgets/biguint.rs index 77013d27..289a9589 100644 --- a/plonky2/src/gadgets/biguint.rs +++ b/plonky2/src/gadgets/biguint.rs @@ -12,7 +12,7 @@ use crate::plonk::circuit_builder::CircuitBuilder; #[derive(Clone, Debug)] pub struct BigUintTarget { - pub limbs: Vec, + pub limbs: Vec>, } impl BigUintTarget { @@ -20,15 +20,23 @@ impl BigUintTarget { self.limbs.len() } - pub fn get_limb(&self, i: usize) -> U32Target { + pub fn get_limb(&self, i: usize) -> BinaryTarget<30> { self.limbs[i] } } impl, const D: usize> CircuitBuilder { pub fn constant_biguint(&mut self, value: &BigUint) -> BigUintTarget { - let limb_values = value.to_u32_digits(); - let limbs = limb_values.iter().map(|&l| self.constant_u32(l)).collect(); + let base = BigUint::from_u64(1 << 30).unwrap(); + let mut limb_values = Vec::new(); + let mut current = value.clone(); + while current > BigUint::zero() { + let (div, rem) = current.div_rem(&base); + current = div; + let rem_u64 = rem.to_u64_digits()[0]; + limb_values.push(F::from_canonical_u64(rem_u64)); + } + let limbs = limb_values.iter().map(|&l| self.constant_binary(l)).collect(); BigUintTarget { limbs } } @@ -36,14 +44,14 @@ impl, const D: usize> CircuitBuilder { pub fn connect_biguint(&mut self, lhs: &BigUintTarget, rhs: &BigUintTarget) { let min_limbs = lhs.num_limbs().min(rhs.num_limbs()); for i in 0..min_limbs { - self.connect_u32(lhs.get_limb(i), rhs.get_limb(i)); + self.connect_binary(lhs.get_limb(i), rhs.get_limb(i)); } for i in min_limbs..lhs.num_limbs() { - self.assert_zero_u32(lhs.get_limb(i)); + self.assert_zero_binary(lhs.get_limb(i)); } for i in min_limbs..rhs.num_limbs() { - self.assert_zero_u32(rhs.get_limb(i)); + self.assert_zero_binary(rhs.get_limb(i)); } } @@ -55,14 +63,14 @@ impl, const D: usize> CircuitBuilder { if a.num_limbs() > b.num_limbs() { let mut padded_b = b.clone(); for _ in b.num_limbs()..a.num_limbs() { - padded_b.limbs.push(self.zero_u32()); + padded_b.limbs.push(self.zero_binary()); } (a.clone(), padded_b) } else { let mut padded_a = a.clone(); for _ in a.num_limbs()..b.num_limbs() { - padded_a.limbs.push(self.zero_u32()); + padded_a.limbs.push(self.zero_binary()); } (padded_a, b.clone()) @@ -72,13 +80,11 @@ impl, const D: usize> CircuitBuilder { pub fn cmp_biguint(&mut self, a: &BigUintTarget, b: &BigUintTarget) -> BoolTarget { let (a, b) = self.pad_biguints(a, b); - self.list_le_u32(a.limbs, b.limbs) + self.list_le_binary::<30>(a.limbs, b.limbs) } pub fn add_virtual_biguint_target(&mut self, num_limbs: usize) -> BigUintTarget { - let limbs = (0..num_limbs) - .map(|_| self.add_virtual_u32_target()) - .collect(); + let limbs = self.add_virtual_binary_targets(num_limbs); BigUintTarget { limbs } } @@ -88,16 +94,16 @@ impl, const D: usize> CircuitBuilder { let num_limbs = a.num_limbs().max(b.num_limbs()); let mut combined_limbs = vec![]; - let mut carry = self.zero_u32(); + let mut carry = self.zero_binary(); for i in 0..num_limbs { let a_limb = (i < a.num_limbs()) .then(|| a.limbs[i]) - .unwrap_or_else(|| self.zero_u32()); + .unwrap_or_else(|| self.zero_binary()); let b_limb = (i < b.num_limbs()) .then(|| b.limbs[i]) - .unwrap_or_else(|| self.zero_u32()); + .unwrap_or_else(|| self.zero_binary()); - let (new_limb, new_carry) = self.add_many_u32(&[carry, a_limb, b_limb]); + let (new_limb, new_carry) = self.add_many_binary(&[carry, a_limb, b_limb]); carry = new_carry; combined_limbs.push(new_limb); } @@ -115,9 +121,9 @@ impl, const D: usize> CircuitBuilder { let mut result_limbs = vec![]; - let mut borrow = self.zero_u32(); + let mut borrow = self.zero_binary(); for i in 0..num_limbs { - let (result, new_borrow) = self.sub_u32(a.limbs[i], b.limbs[i], borrow); + let (result, new_borrow) = self.sub_binary(a.limbs[i], b.limbs[i], borrow); result_limbs.push(result); borrow = new_borrow; } @@ -134,17 +140,17 @@ impl, const D: usize> CircuitBuilder { let mut to_add = vec![vec![]; total_limbs]; for i in 0..a.limbs.len() { for j in 0..b.limbs.len() { - let (product, carry) = self.mul_u32(a.limbs[i], b.limbs[j]); + let (product, carry) = self.mul_binary(a.limbs[i], b.limbs[j]); to_add[i + j].push(product); to_add[i + j + 1].push(carry); } } let mut combined_limbs = vec![]; - let mut carry = self.zero_u32(); + let mut carry = self.zero_binary(); for summands in &mut to_add { summands.push(carry); - let (new_result, new_carry) = self.add_many_u32(summands); + let (new_result, new_carry) = self.add_many_binary(summands); combined_limbs.push(new_result); carry = new_carry; } diff --git a/plonky2/src/gadgets/ecdsa.rs b/plonky2/src/gadgets/ecdsa.rs index 362fbc6d..20fca13d 100644 --- a/plonky2/src/gadgets/ecdsa.rs +++ b/plonky2/src/gadgets/ecdsa.rs @@ -3,7 +3,7 @@ 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::binary_arithmetic::BinaryTarget; use crate::gadgets::biguint::BigUintTarget; use crate::gadgets::curve::AffinePointTarget; use crate::gadgets::nonnative::NonNativeTarget; @@ -38,7 +38,7 @@ impl, const D: usize> CircuitBuilder { for &bit in rev_bits { sum = self.mul_add(two, sum, bit.target); } - let limbs = vec![U32Target(sum)]; + let limbs = vec![BinaryTarget::<30>(sum)]; let value = BigUintTarget { limbs }; NonNativeTarget { diff --git a/plonky2/src/gadgets/multiple_comparison.rs b/plonky2/src/gadgets/multiple_comparison.rs index 70afcab5..acb157e5 100644 --- a/plonky2/src/gadgets/multiple_comparison.rs +++ b/plonky2/src/gadgets/multiple_comparison.rs @@ -59,15 +59,10 @@ impl, const D: usize> CircuitBuilder { } /// Helper function for comparing, specifically, lists of `U32Target`s. - pub fn list_le_u32(&mut self, a: Vec, b: Vec) -> BoolTarget { - // let a_targets = a.iter().map(|&t| t.0).collect(); - // let b_targets = b.iter().map(|&t| t.0).collect(); - // self.list_le(a_targets, b_targets, 32) - - let num = a.len() / 2; - let a_targets = self.add_virtual_targets(num); - let b_targets = self.add_virtual_targets(num); - self.list_le(a_targets, b_targets, 32) + pub fn list_le_binary(&mut self, a: Vec>, b: Vec>) -> BoolTarget { + let a_targets = a.iter().map(|&t| t.0).collect(); + let b_targets = b.iter().map(|&t| t.0).collect(); + self.list_le(a_targets, b_targets, BITS) } } diff --git a/plonky2/src/gadgets/nonnative.rs b/plonky2/src/gadgets/nonnative.rs index cca22fd1..946bf35a 100644 --- a/plonky2/src/gadgets/nonnative.rs +++ b/plonky2/src/gadgets/nonnative.rs @@ -5,10 +5,8 @@ use plonky2_field::{extension_field::Extendable, field_types::Field}; use plonky2_util::ceil_div_usize; use crate::gadgets::arithmetic_u32::U32Target; -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::field::field_types::RichField; +use crate::gadgets::binary_arithmetic::BinaryTarget; use crate::iop::witness::{PartitionWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; @@ -197,7 +195,7 @@ impl, const D: usize> CircuitBuilder { } /// Returns `x % |FF|` as a `NonNativeTarget`. - fn reduce_by_bits(&mut self, x: &BigUintTarget) -> NonNativeTarget { + /*fn reduce_by_bits(&mut self, x: &BigUintTarget) -> NonNativeTarget { println!("NUM LIMBS: {}", x.limbs.len()); let before = self.num_gates(); @@ -248,7 +246,7 @@ impl, const D: usize> CircuitBuilder { value, _phantom: PhantomData, } - } + }*/ #[allow(dead_code)] fn reduce_nonnative(&mut self, x: &NonNativeTarget) -> NonNativeTarget { @@ -257,7 +255,7 @@ impl, const D: usize> CircuitBuilder { } pub fn bool_to_nonnative(&mut self, b: &BoolTarget) -> NonNativeTarget { - let limbs = vec![U32Target(b.target)]; + let limbs = vec![BinaryTarget::<30>(b.target)]; let value = BigUintTarget { limbs }; NonNativeTarget { diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index 994ba62b..70f99d54 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -171,12 +171,21 @@ impl GeneratedValues { } pub fn set_biguint_target(&mut self, target: BigUintTarget, value: BigUint) { - let mut limbs = value.to_u32_digits(); + let base = BigUint::from_u64(1 << 30).unwrap(); + let mut limbs = Vec::new(); + let mut current = value.clone(); + while current > BigUint::zero() { + let (div, rem) = current.div_rem(&base); + current = div; + let rem_u64 = rem.to_u64_digits()[0]; + limbs.push(F::from_canonical_u64(rem_u64)); + } + assert!(target.num_limbs() >= limbs.len()); - limbs.resize(target.num_limbs(), 0); + limbs.resize(target.num_limbs(), F::ZERO); for i in 0..target.num_limbs() { - self.set_u32_target(target.get_limb(i), limbs[i]); + self.set_binary_target(target.get_limb(i), limbs[i]); } }