From 39300bcf0142d9e45721c5ef9a27ffb68b68b2af Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 30 Nov 2021 15:00:12 -0800 Subject: [PATCH] fixed Secp256K1Scalar --- src/field/field_testing.rs | 13 +++++++ src/field/secp256k1_base.rs | 7 ++++ src/field/secp256k1_scalar.rs | 11 +++++- src/gadgets/curve.rs | 71 ++++++++++++++++------------------- 4 files changed, 61 insertions(+), 41 deletions(-) diff --git a/src/field/field_testing.rs b/src/field/field_testing.rs index 767a3cf2..b4ee0595 100644 --- a/src/field/field_testing.rs +++ b/src/field/field_testing.rs @@ -84,6 +84,19 @@ macro_rules! test_field_arithmetic { assert_eq!(base.exp_biguint(&pow), base.exp_biguint(&big_pow)); assert_ne!(base.exp_biguint(&pow), base.exp_biguint(&big_pow_wrong)); } + + #[test] + fn inverses() { + type F = $field; + + let x = F::rand(); + let x1 = x.inverse(); + let x2 = x1.inverse(); + let x3 = x2.inverse(); + + assert_eq!(x, x2); + assert_eq!(x1, x3); + } } }; } diff --git a/src/field/secp256k1_base.rs b/src/field/secp256k1_base.rs index acb1df4e..b3fb0148 100644 --- a/src/field/secp256k1_base.rs +++ b/src/field/secp256k1_base.rs @@ -241,3 +241,10 @@ impl DivAssign for Secp256K1Base { *self = *self / rhs; } } + +#[cfg(test)] +mod tests { + use crate::test_field_arithmetic; + + test_field_arithmetic!(crate::field::secp256k1_base::Secp256K1Base); +} diff --git a/src/field/secp256k1_scalar.rs b/src/field/secp256k1_scalar.rs index 0c406b86..f4f2e6ab 100644 --- a/src/field/secp256k1_scalar.rs +++ b/src/field/secp256k1_scalar.rs @@ -80,7 +80,7 @@ impl Field for Secp256K1Scalar { const NEG_ONE: Self = Self([ 0xBFD25E8CD0364140, 0xBAAEDCE6AF48A03B, - 0xFFFFFFFFFFFFFC2F, + 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, ]); @@ -105,7 +105,7 @@ impl Field for Secp256K1Scalar { fn order() -> BigUint { BigUint::from_slice(&[ - 0xD0364141, 0xBFD25E8C, 0xAF48A03B, 0xBAAEDCE6, 0xFFFFFC2F, 0xFFFFFFFF, 0xFFFFFFFF, + 0xD0364141, 0xBFD25E8C, 0xAF48A03B, 0xBAAEDCE6, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, ]) } @@ -251,3 +251,10 @@ impl DivAssign for Secp256K1Scalar { *self = *self / rhs; } } + +#[cfg(test)] +mod tests { + use crate::test_field_arithmetic; + + test_field_arithmetic!(crate::field::secp256k1_scalar::Secp256K1Scalar); +} diff --git a/src/gadgets/curve.rs b/src/gadgets/curve.rs index fe2e186a..e5602c5f 100644 --- a/src/gadgets/curve.rs +++ b/src/gadgets/curve.rs @@ -18,17 +18,6 @@ impl AffinePointTarget { } } -const WINDOW_BITS: usize = 4; -const BASE: usize = 1 << WINDOW_BITS; - -fn digits_per_scalar() -> usize { - (C::ScalarField::BITS + WINDOW_BITS - 1) / WINDOW_BITS -} - -pub struct MulPrecomputationTarget { - powers: Vec>, -} - impl, const D: usize> CircuitBuilder { pub fn constant_affine_point( &mut self, @@ -138,25 +127,6 @@ impl, const D: usize> CircuitBuilder { } } - pub fn mul_precompute( - &mut self, - p: &AffinePointTarget, - ) -> MulPrecomputationTarget { - let num_digits = digits_per_scalar::(); - - let mut powers = Vec::with_capacity(num_digits); - powers.push(p.clone()); - for i in 1..num_digits { - let mut power_i = powers[i - 1].clone(); - for _j in 0..WINDOW_BITS { - power_i = self.curve_double(&power_i); - } - powers.push(power_i); - } - - MulPrecomputationTarget { powers } - } - pub fn curve_scalar_mul( &mut self, p: &AffinePointTarget, @@ -182,15 +152,10 @@ impl, const D: usize> CircuitBuilder { let result_plus_2_i_p = self.curve_add(&result, &two_i_times_p); - let result_x = result.x; - let result_y = result.y; - let result_plus_2_i_p_x = result_plus_2_i_p.x; - let result_plus_2_i_p_y = result_plus_2_i_p.y; - - let new_x_if_bit = self.mul_nonnative(bit, &result_plus_2_i_p_x); - let new_x_if_not_bit = self.mul_nonnative(¬_bit, &result_x); - let new_y_if_bit = self.mul_nonnative(bit, &result_plus_2_i_p_y); - let new_y_if_not_bit = self.mul_nonnative(¬_bit, &result_y); + let new_x_if_bit = self.mul_nonnative(bit, &result_plus_2_i_p.x); + let new_x_if_not_bit = self.mul_nonnative(¬_bit, &result.x); + let new_y_if_bit = self.mul_nonnative(bit, &result_plus_2_i_p.y); + let new_y_if_not_bit = self.mul_nonnative(¬_bit, &result.y); let new_x = self.add_nonnative(&new_x_if_bit, &new_x_if_not_bit); let new_y = self.add_nonnative(&new_y_if_bit, &new_y_if_not_bit); @@ -371,4 +336,32 @@ mod tests { verify(proof, &data.verifier_only, &data.common) } + + #[test] + fn test_curve_random() -> Result<()> { + type F = GoldilocksField; + const D: usize = 4; + + let config = CircuitConfig { + num_routed_wires: 33, + ..CircuitConfig::standard_recursion_config() + }; + + let pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + let rando = + (CurveScalar(Secp256K1Scalar::rand()) * Secp256K1::GENERATOR_PROJECTIVE).to_affine(); + let randot = builder.constant_affine_point(rando); + + let two_target = builder.constant_nonnative(Secp256K1Scalar::TWO); + let randot_doubled = builder.curve_double(&randot); + let randot_times_two = builder.curve_scalar_mul(&randot, &two_target); + builder.connect_affine_point(&randot_doubled, &randot_times_two); + + let data = builder.build(); + let proof = data.prove(pw).unwrap(); + + verify(proof, &data.verifier_only, &data.common) + } }