From c861c10a5be55d1a814bbb598fa99710e5ad0e63 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 2 Nov 2021 12:42:42 -0700 Subject: [PATCH] nonnative neg --- src/gadgets/biguint.rs | 2 +- src/gadgets/nonnative.rs | 45 +++++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/gadgets/biguint.rs b/src/gadgets/biguint.rs index 8369bfc4..a4b9a2d0 100644 --- a/src/gadgets/biguint.rs +++ b/src/gadgets/biguint.rs @@ -30,7 +30,7 @@ impl, const D: usize> CircuitBuilder { let limb_values = value.to_u32_digits(); let limbs = limb_values .iter() - .map(|l| self.constant(F::from_canonical_u32(l))) + .map(|&l| U32Target(self.constant(F::from_canonical_u32(l)))) .collect(); BigUintTarget { limbs } diff --git a/src/gadgets/nonnative.rs b/src/gadgets/nonnative.rs index 86d886fc..0b02b6a8 100644 --- a/src/gadgets/nonnative.rs +++ b/src/gadgets/nonnative.rs @@ -1,8 +1,9 @@ use std::marker::PhantomData; +use num::{BigUint, One}; + use crate::field::field_types::RichField; use crate::field::{extension_field::Extendable, field_types::Field}; -use crate::gadgets::arithmetic_u32::U32Target; use crate::gadgets::biguint::BigUintTarget; use crate::plonk::circuit_builder::CircuitBuilder; @@ -12,15 +13,6 @@ pub struct ForeignFieldTarget { } impl, const D: usize> CircuitBuilder { - pub fn order_u32_limbs(&mut self) -> Vec { - let modulus = FF::order(); - let limbs = modulus.to_u32_digits(); - limbs - .iter() - .map(|&limb| self.constant_u32(F::from_canonical_u32(limb))) - .collect() - } - pub fn biguint_to_ff(&mut self, x: &BigUintTarget) -> ForeignFieldTarget { ForeignFieldTarget { value: x.clone(), @@ -84,6 +76,17 @@ impl, const D: usize> CircuitBuilder { self.reduce(&result) } + pub fn neg_nonnative( + &mut self, + x: &ForeignFieldTarget, + ) -> ForeignFieldTarget { + let neg_one = FF::order() - BigUint::one(); + let neg_one_target = self.constant_biguint(&neg_one); + let neg_one_ff = self.biguint_to_ff(&neg_one_target); + + self.mul_nonnative(&neg_one_ff, x) + } + /// Returns `x % |FF|` as a `ForeignFieldTarget`. fn reduce(&mut self, x: &BigUintTarget) -> ForeignFieldTarget { let modulus = FF::order(); @@ -188,4 +191,26 @@ mod tests { let proof = data.prove(pw).unwrap(); verify(proof, &data.verifier_only, &data.common) } + + #[test] + fn test_nonnative_neg() -> Result<()> { + type FF = Secp256K1Base; + let x_ff = FF::rand(); + let neg_x_ff = -x_ff; + + type F = CrandallField; + let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + let x = builder.constant_ff(x_ff); + let neg_x = builder.neg_nonnative(&x); + + let neg_x_expected = builder.constant_ff(neg_x_ff); + builder.connect_ff_reduced(&neg_x, &neg_x_expected); + + let data = builder.build(); + let proof = data.prove(pw).unwrap(); + verify(proof, &data.verifier_only, &data.common) + } }