From dfad7708af81187c9636fce11685e34de9ee6f6d Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 10 Nov 2021 11:50:58 -0800 Subject: [PATCH] merge --- src/gadgets/biguint.rs | 7 ++++--- src/gadgets/curve.rs | 23 +++++++++++++++++------ src/gadgets/nonnative.rs | 31 +++++++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/gadgets/biguint.rs b/src/gadgets/biguint.rs index fb7eb4e0..2d7ed693 100644 --- a/src/gadgets/biguint.rs +++ b/src/gadgets/biguint.rs @@ -160,9 +160,10 @@ impl, const D: usize> CircuitBuilder { a: &BigUintTarget, b: &BigUintTarget, ) -> (BigUintTarget, BigUintTarget) { - let num_limbs = a.limbs.len(); - let div = self.add_virtual_biguint_target(num_limbs); - let rem = self.add_virtual_biguint_target(num_limbs); + let a_len = a.limbs.len(); + let b_len = b.limbs.len(); + let div = self.add_virtual_biguint_target(a_len - b_len + 1); + let rem = self.add_virtual_biguint_target(b_len); self.add_simple_generator(BigUintDivRemGenerator:: { a: a.clone(), diff --git a/src/gadgets/curve.rs b/src/gadgets/curve.rs index abb1b39a..bf9a1ac0 100644 --- a/src/gadgets/curve.rs +++ b/src/gadgets/curve.rs @@ -1,6 +1,6 @@ use crate::curve::curve_types::{AffinePoint, Curve}; use crate::field::extension_field::Extendable; -use crate::field::field_types::RichField; +use crate::field::field_types::{Field, RichField}; use crate::gadgets::nonnative::ForeignFieldTarget; use crate::plonk::circuit_builder::CircuitBuilder; @@ -60,7 +60,11 @@ impl, const D: usize> CircuitBuilder { } } - pub fn curve_double(&mut self, p: &AffinePointTarget) -> AffinePointTarget { + pub fn curve_double( + &mut self, + p: &AffinePointTarget, + p_orig: AffinePoint, + ) -> AffinePointTarget { let AffinePointTarget { x, y } = p; let double_y = self.add_nonnative(y, y); let inv_double_y = self.inv_nonnative(&double_y); @@ -94,6 +98,8 @@ impl, const D: usize> CircuitBuilder { } mod tests { + use std::ops::Neg; + use anyhow::Result; use crate::curve::curve_types::{AffinePoint, Curve}; @@ -167,14 +173,19 @@ mod tests { let mut builder = CircuitBuilder::::new(config); let g = Secp256K1::GENERATOR_AFFINE; + let neg_g = g.neg(); let g_target = builder.constant_affine_point(g); let neg_g_target = builder.curve_neg(&g_target); - let double_g = builder.curve_double(&g_target); - let double_neg_g = builder.curve_double(&neg_g_target); + let double_g = g.double(); + let double_g_other_target = builder.constant_affine_point(double_g); + builder.curve_assert_valid(&double_g_other_target); - builder.curve_assert_valid(&double_g); - builder.curve_assert_valid(&double_neg_g); + let double_g_target = builder.curve_double(&g_target, g); + let double_neg_g_target = builder.curve_double(&neg_g_target, neg_g); + + builder.curve_assert_valid(&double_g_target); + builder.curve_assert_valid(&double_neg_g_target); let data = builder.build(); let proof = data.prove(pw).unwrap(); diff --git a/src/gadgets/nonnative.rs b/src/gadgets/nonnative.rs index d6b20f14..a3fa7fcd 100644 --- a/src/gadgets/nonnative.rs +++ b/src/gadgets/nonnative.rs @@ -81,6 +81,7 @@ impl, const D: usize> CircuitBuilder { &mut self, x: &NonNativeTarget, ) -> NonNativeTarget { + // TODO: zero - x would be more efficient but doesn't seem to work? let neg_one = FF::order() - BigUint::one(); let neg_one_target = self.constant_biguint(&neg_one); let neg_one_ff = self.biguint_to_nonnative(&neg_one_target); @@ -90,11 +91,11 @@ impl, const D: usize> CircuitBuilder { pub fn inv_nonnative( &mut self, - x: &ForeignFieldTarget, - ) -> ForeignFieldTarget { + x: &NonNativeTarget, + ) -> NonNativeTarget { let num_limbs = x.value.num_limbs(); let inv_biguint = self.add_virtual_biguint_target(num_limbs); - let inv = ForeignFieldTarget:: { + let inv = NonNativeTarget:: { value: inv_biguint, _phantom: PhantomData, }; @@ -107,7 +108,7 @@ impl, const D: usize> CircuitBuilder { let product = self.mul_nonnative(&x, &inv); let one = self.constant_nonnative(FF::ONE); - self.connect_nonnative_reduced(&product, &one); + self.connect_nonnative(&product, &one); inv } @@ -264,4 +265,26 @@ mod tests { let proof = data.prove(pw).unwrap(); verify(proof, &data.verifier_only, &data.common) } + + #[test] + fn test_nonnative_inv() -> Result<()> { + type FF = Secp256K1Base; + let x_ff = FF::rand(); + let inv_x_ff = x_ff.inverse(); + + type F = CrandallField; + let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + let x = builder.constant_nonnative(x_ff); + let inv_x = builder.inv_nonnative(&x); + + let inv_x_expected = builder.constant_nonnative(inv_x_ff); + builder.connect_nonnative(&inv_x, &inv_x_expected); + + let data = builder.build(); + let proof = data.prove(pw).unwrap(); + verify(proof, &data.verifier_only, &data.common) + } }