ECDSA merge

This commit is contained in:
Nicholas Ward 2022-01-20 16:07:54 -08:00
parent 08fa4031ba
commit 82ce3ea8b2
5 changed files with 51 additions and 43 deletions

View File

@ -12,7 +12,7 @@ use crate::plonk::circuit_builder::CircuitBuilder;
#[derive(Clone, Debug)]
pub struct BigUintTarget {
pub limbs: Vec<U32Target>,
pub limbs: Vec<BinaryTarget<30>>,
}
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<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
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<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_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<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_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<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_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<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_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<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
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<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
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;
}

View File

@ -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<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![U32Target(sum)];
let limbs = vec![BinaryTarget::<30>(sum)];
let value = BigUintTarget { limbs };
NonNativeTarget {

View File

@ -59,15 +59,10 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
/// Helper function for comparing, specifically, lists of `U32Target`s.
pub fn list_le_u32(&mut self, a: Vec<U32Target>, b: Vec<U32Target>) -> 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<const BITS: usize>(&mut self, a: Vec<BinaryTarget<BITS>>, b: Vec<BinaryTarget<BITS>>) -> 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)
}
}

View File

@ -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<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
/// Returns `x % |FF|` as a `NonNativeTarget`.
fn reduce_by_bits<FF: Field>(&mut self, x: &BigUintTarget) -> NonNativeTarget<FF> {
/*fn reduce_by_bits<FF: Field>(&mut self, x: &BigUintTarget) -> NonNativeTarget<FF> {
println!("NUM LIMBS: {}", x.limbs.len());
let before = self.num_gates();
@ -248,7 +246,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
value,
_phantom: PhantomData,
}
}
}*/
#[allow(dead_code)]
fn reduce_nonnative<FF: Field>(&mut self, x: &NonNativeTarget<FF>) -> NonNativeTarget<FF> {
@ -257,7 +255,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![U32Target(b.target)];
let limbs = vec![BinaryTarget::<30>(b.target)];
let value = BigUintTarget { limbs };
NonNativeTarget {

View File

@ -171,12 +171,21 @@ impl<F: Field> GeneratedValues<F> {
}
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]);
}
}