From 46315e593c2dadb3fbc53fbd2ad09046748c2bdf Mon Sep 17 00:00:00 2001 From: onewayfunc Date: Sun, 18 Dec 2022 14:07:08 -0800 Subject: [PATCH 1/4] fix --- ff/src/fields/models/fp/montgomery_backend.rs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/ff/src/fields/models/fp/montgomery_backend.rs b/ff/src/fields/models/fp/montgomery_backend.rs index ac79f05fa..0771d5ba3 100644 --- a/ff/src/fields/models/fp/montgomery_backend.rs +++ b/ff/src/fields/models/fp/montgomery_backend.rs @@ -199,12 +199,14 @@ pub trait MontConfig: 'static + Sync + Send + Sized { } (a.0).0 = r; } + a.subtract_modulus(); } else { // Alternative implementation // Implements CIOS. - *a = a.mul_without_cond_subtract(b); + let (carry, res) = a.mul_without_cond_subtract(b); + *a = res; + a.subtract_modulus_with_carry(carry); } - a.subtract_modulus(); } #[inline(always)] @@ -734,7 +736,7 @@ impl, const N: usize> Fp, N> { } } - const fn mul_without_cond_subtract(mut self, other: &Self) -> Self { + const fn mul_without_cond_subtract(mut self, other: &Self) -> (bool, Self) { let (mut lo, mut hi) = ([0u64; N], [0u64; N]); crate::const_for!((i in 0..N) { let mut carry = 0; @@ -768,12 +770,12 @@ impl, const N: usize> Fp, N> { crate::const_for!((i in 0..N) { (self.0).0[i] = hi[i]; }); - self + (carry2 != 0, self) } - const fn mul(mut self, other: &Self) -> Self { - self = self.mul_without_cond_subtract(other); - self.const_subtract_modulus() + const fn mul(self, other: &Self) -> Self { + let (carry, res) = self.mul_without_cond_subtract(other); + res.const_subtract_modulus_with_carry(carry) } const fn const_is_valid(&self) -> bool { @@ -788,8 +790,8 @@ impl, const N: usize> Fp, N> { } #[inline] - const fn const_subtract_modulus(mut self) -> Self { - if !self.const_is_valid() { + const fn const_subtract_modulus_with_carry(mut self, carry: bool) -> Self { + if carry || !self.const_is_valid() { self.0 = Self::sub_with_borrow(&self.0, &T::MODULUS); } self From fa16d1ff962f9e7dceeef12e2c5abc463590065b Mon Sep 17 00:00:00 2001 From: weikengchen Date: Tue, 20 Dec 2022 16:07:06 -0800 Subject: [PATCH 2/4] use the spare bit --- ff/src/fields/models/fp/montgomery_backend.rs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/ff/src/fields/models/fp/montgomery_backend.rs b/ff/src/fields/models/fp/montgomery_backend.rs index 0771d5ba3..55b00b46b 100644 --- a/ff/src/fields/models/fp/montgomery_backend.rs +++ b/ff/src/fields/models/fp/montgomery_backend.rs @@ -205,7 +205,12 @@ pub trait MontConfig: 'static + Sync + Send + Sized { // Implements CIOS. let (carry, res) = a.mul_without_cond_subtract(b); *a = res; - a.subtract_modulus_with_carry(carry); + + if Self::MODULUS_HAS_SPARE_BIT { + a.subtract_modulus_with_carry(carry); + } else { + a.subtract_modulus(); + } } } @@ -775,7 +780,11 @@ impl, const N: usize> Fp, N> { const fn mul(self, other: &Self) -> Self { let (carry, res) = self.mul_without_cond_subtract(other); - res.const_subtract_modulus_with_carry(carry) + if T::MODULUS_HAS_SPARE_BIT { + res.const_subtract_modulus() + } else { + res.const_subtract_modulus_with_carry(carry) + } } const fn const_is_valid(&self) -> bool { @@ -789,6 +798,14 @@ impl, const N: usize> Fp, N> { false } + #[inline] + const fn const_subtract_modulus(mut self) -> Self { + if !self.const_is_valid() { + self.0 = Self::sub_with_borrow(&self.0, &T::MODULUS); + } + self + } + #[inline] const fn const_subtract_modulus_with_carry(mut self, carry: bool) -> Self { if carry || !self.const_is_valid() { From bde0c7c21fe98a0500875ff348c5523191a9cd03 Mon Sep 17 00:00:00 2001 From: weikengchen Date: Tue, 20 Dec 2022 19:12:27 -0800 Subject: [PATCH 3/4] mont macro --- ff/Cargo.toml | 2 +- ff/src/fields/models/fp/montgomery_backend.rs | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/ff/Cargo.toml b/ff/Cargo.toml index ab37cbaad..32c8af5ee 100644 --- a/ff/Cargo.toml +++ b/ff/Cargo.toml @@ -28,7 +28,7 @@ digest = { version = "0.10", default-features = false, features = ["alloc"] } itertools = { version = "0.10", default-features = false } [dev-dependencies] -ark-test-curves = { version = "^0.3.0", path = "../test-curves", default-features = false, features = [ "bls12_381_curve", "mnt6_753"] } +ark-test-curves = { version = "^0.3.0", path = "../test-curves", default-features = false, features = [ "bls12_381_curve", "mnt6_753", "secp256k1"] } blake2 = { version = "0.10", default-features = false } sha3 = { version = "0.10", default-features = false } sha2 = { version = "0.10", default-features = false } diff --git a/ff/src/fields/models/fp/montgomery_backend.rs b/ff/src/fields/models/fp/montgomery_backend.rs index 55b00b46b..adf5ad4ea 100644 --- a/ff/src/fields/models/fp/montgomery_backend.rs +++ b/ff/src/fields/models/fp/montgomery_backend.rs @@ -818,3 +818,42 @@ impl, const N: usize> Fp, N> { a.const_sub_with_borrow(b).0 } } + +#[cfg(test)] +mod test { + use num_bigint::{BigInt, Sign, BigUint}; + use ark_test_curves::secp256k1::Fr; + use ark_std::str::FromStr; + use ark_std::string::String; + use ark_std::vec::Vec; + + #[test] + fn test_mont_macro_correctness() { + let (is_positive, limbs) = str_to_limbs_u64("111192936301596926984056301862066282284536849596023571352007112326586892541694"); + let t = Fr::from_sign_and_limbs(is_positive, &limbs); + + let result: BigUint = t.into(); + let expected = BigUint::from_str("111192936301596926984056301862066282284536849596023571352007112326586892541694").unwrap(); + + assert_eq!(result, expected); + } + + fn str_to_limbs_u64(num: &str) -> (bool, Vec) { + let (sign, digits) = BigInt::from_str(num) + .expect("could not parse to bigint") + .to_radix_le(16); + let limbs = digits + .chunks(16) + .map(|chunk| { + let mut this = 0u64; + for (i, hexit) in chunk.iter().enumerate() { + this += (*hexit as u64) << (4 * i); + } + this + }) + .collect::>(); + + let sign_is_positive = sign != Sign::Minus; + (sign_is_positive, limbs) + } +} \ No newline at end of file From 86e9d2e26cedc00deb2557e42ca740818680dadc Mon Sep 17 00:00:00 2001 From: weikengchen Date: Tue, 20 Dec 2022 19:16:01 -0800 Subject: [PATCH 4/4] remove unused --- ff/src/fields/models/fp/montgomery_backend.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ff/src/fields/models/fp/montgomery_backend.rs b/ff/src/fields/models/fp/montgomery_backend.rs index adf5ad4ea..0b38ff7be 100644 --- a/ff/src/fields/models/fp/montgomery_backend.rs +++ b/ff/src/fields/models/fp/montgomery_backend.rs @@ -821,19 +821,23 @@ impl, const N: usize> Fp, N> { #[cfg(test)] mod test { - use num_bigint::{BigInt, Sign, BigUint}; - use ark_test_curves::secp256k1::Fr; use ark_std::str::FromStr; - use ark_std::string::String; use ark_std::vec::Vec; + use ark_test_curves::secp256k1::Fr; + use num_bigint::{BigInt, BigUint, Sign}; #[test] fn test_mont_macro_correctness() { - let (is_positive, limbs) = str_to_limbs_u64("111192936301596926984056301862066282284536849596023571352007112326586892541694"); + let (is_positive, limbs) = str_to_limbs_u64( + "111192936301596926984056301862066282284536849596023571352007112326586892541694", + ); let t = Fr::from_sign_and_limbs(is_positive, &limbs); let result: BigUint = t.into(); - let expected = BigUint::from_str("111192936301596926984056301862066282284536849596023571352007112326586892541694").unwrap(); + let expected = BigUint::from_str( + "111192936301596926984056301862066282284536849596023571352007112326586892541694", + ) + .unwrap(); assert_eq!(result, expected); } @@ -856,4 +860,4 @@ mod test { let sign_is_positive = sign != Sign::Minus; (sign_is_positive, limbs) } -} \ No newline at end of file +}