nonnative tests

This commit is contained in:
Nicholas Ward 2021-10-27 11:46:16 -07:00
parent ee5619b847
commit bbcda969e5
2 changed files with 76 additions and 8 deletions

View File

@ -52,7 +52,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
}
pub fn pad_biguints<'a>(
pub fn pad_biguints(
&mut self,
a: BigUintTarget,
b: BigUintTarget,
@ -141,12 +141,11 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
pub fn mul_biguint(&mut self, a: &BigUintTarget, b: &BigUintTarget) -> BigUintTarget {
let num_limbs = a.limbs.len();
debug_assert!(b.limbs.len() == num_limbs);
let total_limbs = a.limbs.len() + b.limbs.len();
let mut to_add = vec![vec![]; 2 * num_limbs];
for i in 0..num_limbs {
for j in 0..num_limbs {
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]);
to_add[i + j].push(product);
to_add[i + j + 1].push(carry);
@ -155,7 +154,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let mut combined_limbs = vec![];
let mut carry = self.zero_u32();
for i in 0..2 * num_limbs {
for i in 0..total_limbs {
to_add[i].push(carry);
let (new_result, new_carry) = self.add_many_u32(to_add[i].clone());
combined_limbs.push(new_result);
@ -243,7 +242,7 @@ mod tests {
use num::{BigUint, FromPrimitive, Integer};
use crate::{
field::{crandall_field::CrandallField, field_types::PrimeField},
field::crandall_field::CrandallField,
iop::witness::PartialWitness,
plonk::{circuit_builder::CircuitBuilder, circuit_data::CircuitConfig, verifier::verify},
};

View File

@ -21,12 +21,44 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
.collect()
}
pub fn biguint_to_ff<FF: Field>(&mut self, x: &BigUintTarget) -> ForeignFieldTarget<FF> {
ForeignFieldTarget {
limbs: x.limbs.clone(),
_phantom: PhantomData,
}
}
pub fn ff_to_biguint<FF: Field>(&mut self, x: &ForeignFieldTarget<FF>) -> BigUintTarget {
BigUintTarget {
limbs: x.limbs.clone(),
}
}
pub fn constant_ff<FF: Field>(&mut self, x: FF) -> ForeignFieldTarget<FF> {
let x_biguint = self.constant_biguint(&x.to_biguint());
self.biguint_to_ff(&x_biguint)
}
// Assert that two ForeignFieldTarget's, both assumed to be in reduced form, are equal.
pub fn connect_ff_reduced<FF: Field>(
&mut self,
lhs: &ForeignFieldTarget<FF>,
rhs: &ForeignFieldTarget<FF>,
) {
let min_limbs = lhs.limbs.len().min(rhs.limbs.len());
for i in 0..min_limbs {
self.connect_u32(lhs.limbs[i], rhs.limbs[i]);
}
for i in min_limbs..lhs.limbs.len() {
self.assert_zero_u32(lhs.limbs[i]);
}
for i in min_limbs..rhs.limbs.len() {
self.assert_zero_u32(rhs.limbs[i]);
}
}
// Add two `ForeignFieldTarget`s.
pub fn add_nonnative<FF: Field>(
&mut self,
@ -82,3 +114,40 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.reduce(&x_biguint)
}
}
#[cfg(test)]
mod tests {
use anyhow::Result;
use crate::field::crandall_field::CrandallField;
use crate::field::field_types::Field;
use crate::field::secp256k1::Secp256K1Base;
use crate::iop::witness::PartialWitness;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::CircuitConfig;
use crate::plonk::verifier::verify;
#[test]
fn test_nonnative_add() -> Result<()> {
type FF = Secp256K1Base;
let x_ff = FF::rand();
let y_ff = FF::rand();
let sum_ff = x_ff + y_ff;
type F = CrandallField;
let config = CircuitConfig::large_config();
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, 4>::new(config);
let x = builder.constant_ff(x_ff);
let y = builder.constant_ff(y_ff);
let sum = builder.add_nonnative(&x, &y);
let sum_expected = builder.constant_ff(sum_ff);
builder.connect_ff_reduced(&sum, &sum_expected);
let data = builder.build();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
}