ECDSA merge

This commit is contained in:
Nicholas Ward 2022-01-20 16:11:04 -08:00
parent 07b71a9613
commit 3ba61a4e9c
6 changed files with 31 additions and 37 deletions

View File

@ -12,7 +12,7 @@ use crate::plonk::circuit_builder::CircuitBuilder;
#[derive(Clone, Debug)]
pub struct BigUintTarget {
pub limbs: Vec<BinaryTarget<30>>,
pub limbs: Vec<U32Target>,
}
impl BigUintTarget {
@ -20,25 +20,24 @@ impl BigUintTarget {
self.limbs.len()
}
pub fn get_limb(&self, i: usize) -> BinaryTarget<30> {
pub fn get_limb(&self, i: usize) -> U32Target {
self.limbs[i]
}
}
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
pub fn constant_biguint(&mut self, value: &BigUint) -> BigUintTarget {
let base = BigUint::from_u64(1 << 30).unwrap();
let base = BigUint::from_u64(1 << 32).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));
limb_values.push(rem.to_u64_digits()[0] as u32);
}
let limbs = limb_values
.iter()
.map(|&l| self.constant_binary(l))
.map(|&l| self.constant_u32(l))
.collect();
BigUintTarget { limbs }
@ -47,14 +46,14 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
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_binary(lhs.get_limb(i), rhs.get_limb(i));
self.connect_u32(lhs.get_limb(i), rhs.get_limb(i));
}
for i in min_limbs..lhs.num_limbs() {
self.assert_zero_binary(lhs.get_limb(i));
self.assert_zero_u32(lhs.get_limb(i));
}
for i in min_limbs..rhs.num_limbs() {
self.assert_zero_binary(rhs.get_limb(i));
self.assert_zero_u32(rhs.get_limb(i));
}
}
@ -66,14 +65,14 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
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_binary());
padded_b.limbs.push(self.zero_u32());
}
(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_binary());
padded_a.limbs.push(self.zero_u32());
}
(padded_a, b.clone())
@ -83,11 +82,11 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
pub fn cmp_biguint(&mut self, a: &BigUintTarget, b: &BigUintTarget) -> BoolTarget {
let (a, b) = self.pad_biguints(a, b);
self.list_le_30(a.limbs, b.limbs)
self.list_le_u32(a.limbs, b.limbs)
}
pub fn add_virtual_biguint_target(&mut self, num_limbs: usize) -> BigUintTarget {
let limbs = self.add_virtual_binary_targets(num_limbs);
let limbs = self.add_virtual_u32_targets(num_limbs);
BigUintTarget { limbs }
}
@ -97,16 +96,16 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let num_limbs = a.num_limbs().max(b.num_limbs());
let mut combined_limbs = vec![];
let mut carry = self.zero_binary();
let mut carry = self.zero_u32();
for i in 0..num_limbs {
let a_limb = (i < a.num_limbs())
.then(|| a.limbs[i])
.unwrap_or_else(|| self.zero_binary());
.unwrap_or_else(|| self.zero_u32());
let b_limb = (i < b.num_limbs())
.then(|| b.limbs[i])
.unwrap_or_else(|| self.zero_binary());
.unwrap_or_else(|| self.zero_u32());
let (new_limb, new_carry) = self.add_many_binary(&[carry, a_limb, b_limb]);
let (new_limb, new_carry) = self.add_many_u32(&[carry, a_limb, b_limb]);
carry = new_carry;
combined_limbs.push(new_limb);
}
@ -124,9 +123,9 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let mut result_limbs = vec![];
let mut borrow = self.zero_binary();
let mut borrow = self.zero_u32();
for i in 0..num_limbs {
let (result, new_borrow) = self.sub_binary(a.limbs[i], b.limbs[i], borrow);
let (result, new_borrow) = self.sub_u32(a.limbs[i], b.limbs[i], borrow);
result_limbs.push(result);
borrow = new_borrow;
}
@ -138,31 +137,27 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
pub fn mul_biguint(&mut self, a: &BigUintTarget, b: &BigUintTarget) -> BigUintTarget {
let before = self.num_gates();
let total_limbs = a.limbs.len() + b.limbs.len();
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_binary(a.limbs[i], b.limbs[j]);
let (product, carry) = self.mul_u32(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_binary();
let mut carry = self.zero_u32();
for summands in &mut to_add {
summands.push(carry);
let (new_result, new_carry) = self.add_many_binary(summands);
let (new_result, new_carry) = self.add_many_u32(summands);
combined_limbs.push(new_result);
carry = new_carry;
}
combined_limbs.push(carry);
println!("NUMBER OF GATES: {}", self.num_gates() - before);
BigUintTarget {
limbs: combined_limbs,
}

View File

@ -4,7 +4,7 @@ use crate::curve::curve_types::Curve;
use crate::field::extension_field::Extendable;
use crate::field::field_types::RichField;
use crate::gadgets::biguint::BigUintTarget;
use crate::gadgets::binary_arithmetic::BinaryTarget;
use crate::gadgets::arithmetic_u32::U32Target;
use crate::gadgets::curve::AffinePointTarget;
use crate::gadgets::nonnative::NonNativeTarget;
use crate::iop::target::{BoolTarget, Target};
@ -38,7 +38,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
for &bit in rev_bits {
sum = self.mul_add(two, sum, bit.target);
}
let limbs = vec![BinaryTarget::<30>(sum)];
let limbs = vec![U32Target(sum)];
let value = BigUintTarget { limbs };
NonNativeTarget {

View File

@ -59,11 +59,11 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
/// Helper function for comparing, specifically, lists of `U32Target`s.
pub fn list_le_30(&mut self, a: Vec<BinaryTarget<30>>, b: Vec<BinaryTarget<30>>) -> BoolTarget {
pub fn list_le_u32(&mut self, a: Vec<U32Target>, b: Vec<U32Target>) -> BoolTarget {
let a_targets: Vec<Target> = a.iter().map(|&t| t.0).collect();
let b_targets: Vec<Target> = b.iter().map(|&t| t.0).collect();
self.list_le(a_targets, b_targets, 30)
self.list_le(a_targets, b_targets, 32)
}
}

View File

@ -248,7 +248,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
pub fn bool_to_nonnative<FF: Field>(&mut self, b: &BoolTarget) -> NonNativeTarget<FF> {
let limbs = vec![BinaryTarget::<30>(b.target)];
let limbs = vec![U32Target(b.target)];
let value = BigUintTarget { limbs };
NonNativeTarget {

View File

@ -171,21 +171,20 @@ impl<F: Field> GeneratedValues<F> {
}
pub fn set_biguint_target(&mut self, target: BigUintTarget, value: BigUint) {
let base = BigUint::from_u64(1 << 30).unwrap();
let base = BigUint::from_u64(1 << 32).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));
limbs.push(rem.to_u64_digits()[0] as u32);
}
assert!(target.num_limbs() >= limbs.len());
limbs.resize(target.num_limbs(), F::ZERO);
limbs.resize(target.num_limbs(), 0);
for i in 0..target.num_limbs() {
self.set_binary_target(target.get_limb(i), limbs[i]);
self.set_u32_target(target.get_limb(i), limbs[i]);
}
}

View File

@ -65,7 +65,7 @@ pub trait Witness<F: Field> {
fn get_biguint_target(&self, target: BigUintTarget) -> BigUint {
let mut result = BigUint::zero();
let limb_base = BigUint::from_u64(1 << 30u64).unwrap();
let limb_base = BigUint::from_u64(1 << 32u64).unwrap();
for i in (0..target.num_limbs()).rev() {
let limb = target.get_limb(i);
result *= &limb_base;