From 8c73c5fcc08bb68c77dfcc03b8411d2c2b4c6a6e Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Tue, 19 Dec 2023 17:15:16 -0500 Subject: [PATCH 01/14] Deprecating `divn` and `muln`. Implemented `Shr` and `Shl` --- curves/bls12_381/src/fields/tests.rs | 12 +- ec/src/scalar_mul/variable_base/mod.rs | 2 +- ff/src/biginteger/mod.rs | 171 ++++++++++--------------- ff/src/biginteger/tests.rs | 45 ++++++- 4 files changed, 118 insertions(+), 112 deletions(-) diff --git a/curves/bls12_381/src/fields/tests.rs b/curves/bls12_381/src/fields/tests.rs index 00fde4163..c25ac42a3 100644 --- a/curves/bls12_381/src/fields/tests.rs +++ b/curves/bls12_381/src/fields/tests.rs @@ -818,7 +818,7 @@ fn test_fq_repr_div2() { } #[test] -fn test_fq_repr_divn() { +fn test_fq_repr_shr() { let mut a = BigInt::new([ 0xaa5cdd6172847ffd, 0x43242c06aed55287, @@ -827,7 +827,7 @@ fn test_fq_repr_divn() { 0x16080cf4071e0b05, 0x1225f2901aea514e, ]); - a.divn(0); + a = a >> 0; assert_eq!( a, BigInt::new([ @@ -839,7 +839,7 @@ fn test_fq_repr_divn() { 0x1225f2901aea514e, ]) ); - a.divn(1); + a = a >> 1; assert_eq!( a, BigInt::new([ @@ -851,7 +851,7 @@ fn test_fq_repr_divn() { 0x912f9480d7528a7, ]) ); - a.divn(50); + a = a >> 50; assert_eq!( a, BigInt::new([ @@ -863,7 +863,7 @@ fn test_fq_repr_divn() { 0x244, ]) ); - a.divn(130); + a = a >> 130; assert_eq!( a, BigInt::new([ @@ -875,7 +875,7 @@ fn test_fq_repr_divn() { 0x0, ]) ); - a.divn(64); + a = a >> 64; assert_eq!( a, BigInt::new([0x4067a038f0582e2a, 0x2f9480d7528a70b0, 0x91, 0x0, 0x0, 0x0]) diff --git a/ec/src/scalar_mul/variable_base/mod.rs b/ec/src/scalar_mul/variable_base/mod.rs index 469805f55..9492c9a3e 100644 --- a/ec/src/scalar_mul/variable_base/mod.rs +++ b/ec/src/scalar_mul/variable_base/mod.rs @@ -197,7 +197,7 @@ fn msm_bigint( // We right-shift by w_start, thus getting rid of the // lower bits. - scalar.divn(w_start as u32); + scalar = scalar >> w_start as u32; // We mod the remaining bits by 2^{window size}, thus taking `c` bits. let scalar = scalar.as_ref()[0] % (1 << c); diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index e7c07ac37..09f4a1f88 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -1,4 +1,4 @@ -use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not}; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl, Shr}; use crate::{ bits::{BitIteratorBE, BitIteratorLE}, @@ -390,34 +390,6 @@ impl BigInteger for BigInt { } } - #[inline] - fn muln(&mut self, mut n: u32) { - if n >= (64 * N) as u32 { - *self = Self::from(0u64); - return; - } - - while n >= 64 { - let mut t = 0; - for i in 0..N { - core::mem::swap(&mut t, &mut self.0[i]); - } - n -= 64; - } - - if n > 0 { - let mut t = 0; - #[allow(unused)] - for i in 0..N { - let a = &mut self.0[i]; - let t2 = *a >> (64 - n); - *a <<= n; - *a |= t; - t = t2; - } - } - } - #[inline] fn div2(&mut self) { let mut t = 0; @@ -430,34 +402,6 @@ impl BigInteger for BigInt { } } - #[inline] - fn divn(&mut self, mut n: u32) { - if n >= (64 * N) as u32 { - *self = Self::from(0u64); - return; - } - - while n >= 64 { - let mut t = 0; - for i in 0..N { - core::mem::swap(&mut t, &mut self.0[N - i - 1]); - } - n -= 64; - } - - if n > 0 { - let mut t = 0; - #[allow(unused)] - for i in 0..N { - let a = &mut self.0[N - i - 1]; - let t2 = *a << (64 - n); - *a >>= n; - *a |= t; - t = t2; - } - } - } - #[inline] fn is_odd(&self) -> bool { self.0[0] & 1 == 1 @@ -729,6 +673,72 @@ impl, const N: usize> BitOr for BigInt { } } +impl Shr for BigInt { + type Output = Self; + + fn shr(self, mut rhs: u32) -> Self::Output { + let mut data = self.0.clone(); + + if rhs >= (64 * N) as u32 { + return Self::from(0u64); + } + + while rhs >= 64 { + let mut t = 0; + for i in 0..N { + core::mem::swap(&mut t, &mut data[N - i - 1]); + } + rhs -= 64; + } + + if rhs > 0 { + let mut t = 0; + for i in 0..N { + let a = &mut data[N - i - 1]; + let t2 = *a << (64 - rhs); + *a >>= rhs; + *a |= t; + t = t2; + } + } + Self::new(data) + } +} + +impl Shl for BigInt { + type Output = Self; + + fn shl(self, mut rhs: u32) -> Self::Output { + if rhs >= (64 * N) as u32 { + return Self::from(0u64); + } + + let mut data = self.0.clone(); + + while rhs >= 64 { + let mut t = 0; + for i in 0..N { + core::mem::swap(&mut t, &mut data[i]); + } + rhs -= 64; + } + + if rhs > 0 { + let mut t = 0; + #[allow(unused)] + for i in 0..N { + let a = &mut data[i]; + let t2 = *a >> (64 - rhs); + *a <<= rhs; + *a |= t; + t = t2; + } + } + + Self::new(data) + } +} + impl Not for BigInt { type Output = Self; @@ -809,6 +819,8 @@ pub trait BigInteger: + for<'a> BitOrAssign<&'a Self> + BitOr + for<'a> BitOr<&'a Self, Output = Self> + + Shr + + Shl { /// Number of 64-bit limbs representing `Self`. const NUM_LIMBS: usize; @@ -881,31 +893,6 @@ pub trait BigInteger: /// ``` fn mul2(&mut self) -> bool; - /// Performs a leftwise bitshift of this number by n bits, effectively multiplying - /// it by 2^n. Overflow is ignored. - /// # Example - /// - /// ``` - /// use ark_ff::{biginteger::BigInteger64 as B, BigInteger as _}; - /// - /// // Basic - /// let mut one_mul = B::from(1u64); - /// one_mul.muln(5); - /// assert_eq!(one_mul, B::from(32u64)); - /// - /// // Edge-Case - /// let mut zero = B::from(0u64); - /// zero.muln(5); - /// assert_eq!(zero, B::from(0u64)); - /// - /// let mut arr: [bool; 64] = [false; 64]; - /// arr[4] = true; - /// let mut mul = B::from_bits_be(&arr); - /// mul.muln(5); - /// assert_eq!(mul, B::from(0u64)); - /// ``` - fn muln(&mut self, amt: u32); - /// Performs a rightwise bitshift of this number, effectively dividing /// it by 2. /// # Example @@ -929,26 +916,6 @@ pub trait BigInteger: /// ``` fn div2(&mut self); - /// Performs a rightwise bitshift of this number by some amount. - /// # Example - /// - /// ``` - /// use ark_ff::{biginteger::BigInteger64 as B, BigInteger as _}; - /// - /// // Basic - /// let (mut one, mut thirty_two_div) = (B::from(1u64), B::from(32u64)); - /// thirty_two_div.divn(5); - /// assert_eq!(one, thirty_two_div); - /// - /// // Edge-Case - /// let mut arr: [bool; 64] = [false; 64]; - /// arr[4] = true; - /// let mut div = B::from_bits_le(&arr); - /// div.divn(5); - /// assert_eq!(div, B::from(0u64)); - /// ``` - fn divn(&mut self, amt: u32); - /// Returns true iff this number is odd. /// # Example /// diff --git a/ff/src/biginteger/tests.rs b/ff/src/biginteger/tests.rs index fd381efcf..1423886b1 100644 --- a/ff/src/biginteger/tests.rs +++ b/ff/src/biginteger/tests.rs @@ -40,7 +40,7 @@ fn biginteger_arithmetic_test(a: B, b: B, zero: B) { // a * 1 = a let mut a_mul1 = a; - a_mul1.muln(0); + a_mul1 = a_mul1 << 0; assert_eq!(a_mul1, a); // a * 2 = a + a @@ -51,6 +51,43 @@ fn biginteger_arithmetic_test(a: B, b: B, zero: B) { assert_eq!(a_mul2, a_plus_a); } +fn biginteger_shr() { + let mut rng = ark_std::test_rng(); + let a = B::rand(&mut rng); + assert_eq!(a >> 0, a); + + // Binary simple test + let a = B::from(256u64); + assert_eq!(a >> 2, B::from(64u64)); + + // Test saturated underflow + let a = B::from(1u64); + assert_eq!(a >> 5, B::from(0u64)); + + // Test null bits + let a = B::rand(&mut rng); + let b = a >> 3; + assert_eq!(b.get_bit(B::NUM_LIMBS * 64 - 1), false); + assert_eq!(b.get_bit(B::NUM_LIMBS * 64 - 2), false); + assert_eq!(b.get_bit(B::NUM_LIMBS * 64 - 3), false); +} + +fn biginteger_shl() { + let mut rng = ark_std::test_rng(); + let a = B::rand(&mut rng); + assert_eq!(a << 0, a); + + // Binary simple test + let a = B::from(256u64); + assert_eq!(a << 2, B::from(1024u64)); + + let a = B::rand(&mut rng); + let b = a << 3; + assert_eq!(b.get_bit(0), false); + assert_eq!(b.get_bit(1), false); + assert_eq!(b.get_bit(2), false); +} + // Test for BigInt's bitwise operations fn biginteger_bitwise_ops_test() { let mut rng = ark_std::test_rng(); @@ -104,7 +141,7 @@ fn biginteger_bits_test() { assert!(one.get_bit(0)); // 1st bit of BigInteger representing 1 is not 1 assert!(!one.get_bit(1)); - one.muln(5); + one = one << 5; let thirty_two = one; // 0th bit of BigInteger representing 32 is not 1 assert!(!thirty_two.get_bit(0)); @@ -139,7 +176,9 @@ fn test_biginteger(zero: B) { biginteger_arithmetic_test(a, b, zero); biginteger_bits_test::(); biginteger_conversion_test::(); - biginteger_bitwise_ops_test::() + biginteger_bitwise_ops_test::(); + biginteger_shr::(); + biginteger_shl::(); } #[test] From 9df39fe0a530276cb36d52076c8eed9603def54b Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Tue, 19 Dec 2023 17:36:25 -0500 Subject: [PATCH 02/14] Keeping the old implementations for retro-compatibility. --- ff/src/biginteger/mod.rs | 103 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index 09f4a1f88..b2abd0173 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -390,6 +390,34 @@ impl BigInteger for BigInt { } } + #[inline] + fn muln(&mut self, mut n: u32) { + if n >= (64 * N) as u32 { + *self = Self::from(0u64); + return; + } + + while n >= 64 { + let mut t = 0; + for i in 0..N { + core::mem::swap(&mut t, &mut self.0[i]); + } + n -= 64; + } + + if n > 0 { + let mut t = 0; + #[allow(unused)] + for i in 0..N { + let a = &mut self.0[i]; + let t2 = *a >> (64 - n); + *a <<= n; + *a |= t; + t = t2; + } + } + } + #[inline] fn div2(&mut self) { let mut t = 0; @@ -402,6 +430,34 @@ impl BigInteger for BigInt { } } + #[inline] + fn divn(&mut self, mut n: u32) { + if n >= (64 * N) as u32 { + *self = Self::from(0u64); + return; + } + + while n >= 64 { + let mut t = 0; + for i in 0..N { + core::mem::swap(&mut t, &mut self.0[N - i - 1]); + } + n -= 64; + } + + if n > 0 { + let mut t = 0; + #[allow(unused)] + for i in 0..N { + let a = &mut self.0[N - i - 1]; + let t2 = *a << (64 - n); + *a >>= n; + *a |= t; + t = t2; + } + } + } + #[inline] fn is_odd(&self) -> bool { self.0[0] & 1 == 1 @@ -893,6 +949,32 @@ pub trait BigInteger: /// ``` fn mul2(&mut self) -> bool; + /// Performs a leftwise bitshift of this number by n bits, effectively multiplying + /// it by 2^n. Overflow is ignored. + /// # Example + /// + /// ``` + /// use ark_ff::{biginteger::BigInteger64 as B, BigInteger as _}; + /// + /// // Basic + /// let mut one_mul = B::from(1u64); + /// one_mul.muln(5); + /// assert_eq!(one_mul, B::from(32u64)); + /// + /// // Edge-Case + /// let mut zero = B::from(0u64); + /// zero.muln(5); + /// assert_eq!(zero, B::from(0u64)); + /// + /// let mut arr: [bool; 64] = [false; 64]; + /// arr[4] = true; + /// let mut mul = B::from_bits_be(&arr); + /// mul.muln(5); + /// assert_eq!(mul, B::from(0u64)); + /// ``` + #[deprecated(note="please use the operator `<<` instead")] + fn muln(&mut self, amt: u32); + /// Performs a rightwise bitshift of this number, effectively dividing /// it by 2. /// # Example @@ -916,6 +998,27 @@ pub trait BigInteger: /// ``` fn div2(&mut self); + /// Performs a rightwise bitshift of this number by some amount. + /// # Example + /// + /// ``` + /// use ark_ff::{biginteger::BigInteger64 as B, BigInteger as _}; + /// + /// // Basic + /// let (mut one, mut thirty_two_div) = (B::from(1u64), B::from(32u64)); + /// thirty_two_div.divn(5); + /// assert_eq!(one, thirty_two_div); + /// + /// // Edge-Case + /// let mut arr: [bool; 64] = [false; 64]; + /// arr[4] = true; + /// let mut div = B::from_bits_le(&arr); + /// div.divn(5); + /// assert_eq!(div, B::from(0u64)); + /// ``` + #[deprecated(note="please use the operator `>>` instead")] + fn divn(&mut self, amt: u32); + /// Returns true iff this number is odd. /// # Example /// From 79775addfa4657b02f2a59ed641834902f53ef22 Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Tue, 19 Dec 2023 17:47:05 -0500 Subject: [PATCH 03/14] Formatting source code --- ff/src/biginteger/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index b2abd0173..b6007908f 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -972,7 +972,7 @@ pub trait BigInteger: /// mul.muln(5); /// assert_eq!(mul, B::from(0u64)); /// ``` - #[deprecated(note="please use the operator `<<` instead")] + #[deprecated(note = "please use the operator `<<` instead")] fn muln(&mut self, amt: u32); /// Performs a rightwise bitshift of this number, effectively dividing @@ -1016,7 +1016,7 @@ pub trait BigInteger: /// div.divn(5); /// assert_eq!(div, B::from(0u64)); /// ``` - #[deprecated(note="please use the operator `>>` instead")] + #[deprecated(since = "0.4.2", note = "please use the operator `>>` instead")] fn divn(&mut self, amt: u32); /// Returns true iff this number is odd. From 9af3e14f54ce81a39c027ab3365fd7efda256276 Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Tue, 19 Dec 2023 17:53:10 -0500 Subject: [PATCH 04/14] Added `since` tag --- ff/src/biginteger/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index b6007908f..86ccc951b 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -972,7 +972,7 @@ pub trait BigInteger: /// mul.muln(5); /// assert_eq!(mul, B::from(0u64)); /// ``` - #[deprecated(note = "please use the operator `<<` instead")] + #[deprecated(since = "0.4.2", note = "please use the operator `<<` instead")] fn muln(&mut self, amt: u32); /// Performs a rightwise bitshift of this number, effectively dividing From c3005562add93e7464e30c1a096451645808e7f8 Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Tue, 19 Dec 2023 17:56:51 -0500 Subject: [PATCH 05/14] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 579c9e9be..cf23c0952 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [\#689](https://github.com/arkworks-rs/algebra/pull/689) (`ark-serialize`) Add `CanonicalSerialize` and `CanonicalDeserialize` impls for `VecDeque` and `LinkedList`. - [\#693](https://github.com/arkworks-rs/algebra/pull/693) (`ark-serialize`) Add `serialize_to_vec!` convenience macro. - [\#713](https://github.com/arkworks-rs/algebra/pull/713) (`ark-ff`) Add support for bitwise operations AND, OR, and XOR between `BigInteger`. +- [\#736](https://github.com/arkworks-rs/algebra/pull/736) (`ark-ff`) Deprecate the use of `muln()` and `divn()`. Instead, it is implemented the traits `core::ops::Shl` and `core::ops::Shr` respectively. ### Breaking changes From f58114382ab9e55c220b56842b3487a91d34ee42 Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Tue, 19 Dec 2023 18:28:56 -0500 Subject: [PATCH 06/14] Modified test to re-run checks --- ff/src/biginteger/tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ff/src/biginteger/tests.rs b/ff/src/biginteger/tests.rs index 1423886b1..54e11d5b7 100644 --- a/ff/src/biginteger/tests.rs +++ b/ff/src/biginteger/tests.rs @@ -82,10 +82,11 @@ fn biginteger_shl() { assert_eq!(a << 2, B::from(1024u64)); let a = B::rand(&mut rng); - let b = a << 3; + let b = a << 4; assert_eq!(b.get_bit(0), false); assert_eq!(b.get_bit(1), false); assert_eq!(b.get_bit(2), false); + assert_eq!(b.get_bit(2), false); } // Test for BigInt's bitwise operations From 98df35dc29e017ec66cc210b920c3240252ba4fc Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Wed, 20 Dec 2023 09:05:03 -0500 Subject: [PATCH 07/14] Rolling back `core::ops::Shl` --- ff/src/biginteger/mod.rs | 38 +------------------------------------- ff/src/biginteger/tests.rs | 22 ++-------------------- 2 files changed, 3 insertions(+), 57 deletions(-) diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index 86ccc951b..ecdbe0f6f 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -1,4 +1,4 @@ -use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl, Shr}; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shr}; use crate::{ bits::{BitIteratorBE, BitIteratorLE}, @@ -761,40 +761,6 @@ impl Shr for BigInt { } } -impl Shl for BigInt { - type Output = Self; - - fn shl(self, mut rhs: u32) -> Self::Output { - if rhs >= (64 * N) as u32 { - return Self::from(0u64); - } - - let mut data = self.0.clone(); - - while rhs >= 64 { - let mut t = 0; - for i in 0..N { - core::mem::swap(&mut t, &mut data[i]); - } - rhs -= 64; - } - - if rhs > 0 { - let mut t = 0; - #[allow(unused)] - for i in 0..N { - let a = &mut data[i]; - let t2 = *a >> (64 - rhs); - *a <<= rhs; - *a |= t; - t = t2; - } - } - - Self::new(data) - } -} - impl Not for BigInt { type Output = Self; @@ -876,7 +842,6 @@ pub trait BigInteger: + BitOr + for<'a> BitOr<&'a Self, Output = Self> + Shr - + Shl { /// Number of 64-bit limbs representing `Self`. const NUM_LIMBS: usize; @@ -972,7 +937,6 @@ pub trait BigInteger: /// mul.muln(5); /// assert_eq!(mul, B::from(0u64)); /// ``` - #[deprecated(since = "0.4.2", note = "please use the operator `<<` instead")] fn muln(&mut self, amt: u32); /// Performs a rightwise bitshift of this number, effectively dividing diff --git a/ff/src/biginteger/tests.rs b/ff/src/biginteger/tests.rs index 54e11d5b7..f3fe5360f 100644 --- a/ff/src/biginteger/tests.rs +++ b/ff/src/biginteger/tests.rs @@ -40,7 +40,7 @@ fn biginteger_arithmetic_test(a: B, b: B, zero: B) { // a * 1 = a let mut a_mul1 = a; - a_mul1 = a_mul1 << 0; + a_mul1.muln(0); assert_eq!(a_mul1, a); // a * 2 = a + a @@ -72,23 +72,6 @@ fn biginteger_shr() { assert_eq!(b.get_bit(B::NUM_LIMBS * 64 - 3), false); } -fn biginteger_shl() { - let mut rng = ark_std::test_rng(); - let a = B::rand(&mut rng); - assert_eq!(a << 0, a); - - // Binary simple test - let a = B::from(256u64); - assert_eq!(a << 2, B::from(1024u64)); - - let a = B::rand(&mut rng); - let b = a << 4; - assert_eq!(b.get_bit(0), false); - assert_eq!(b.get_bit(1), false); - assert_eq!(b.get_bit(2), false); - assert_eq!(b.get_bit(2), false); -} - // Test for BigInt's bitwise operations fn biginteger_bitwise_ops_test() { let mut rng = ark_std::test_rng(); @@ -142,7 +125,7 @@ fn biginteger_bits_test() { assert!(one.get_bit(0)); // 1st bit of BigInteger representing 1 is not 1 assert!(!one.get_bit(1)); - one = one << 5; + one.muln(5); let thirty_two = one; // 0th bit of BigInteger representing 32 is not 1 assert!(!thirty_two.get_bit(0)); @@ -179,7 +162,6 @@ fn test_biginteger(zero: B) { biginteger_conversion_test::(); biginteger_bitwise_ops_test::(); biginteger_shr::(); - biginteger_shl::(); } #[test] From 33299d28e4b9baf3527cb80f78e07bed94883a5c Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Wed, 20 Dec 2023 10:12:50 -0500 Subject: [PATCH 08/14] Removed test against old curve repository I removed the test against the old `algebra` repository to avoid conflicts in the CI. --- .github/workflows/ci.yml | 67 +--------------------------------------- 1 file changed, 1 insertion(+), 66 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89de240c8..6f5066c9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -395,69 +395,4 @@ jobs: --exclude ark-algebra-test-templates \ --exclude ark-algebra-bench-templates \ --exclude ark-poly-benches \ - --target aarch64-unknown-none" - - test_against_curves: - name: Test against curves - runs-on: ubuntu-latest - env: - RUSTFLAGS: -Dwarnings - strategy: - matrix: - curve: - - bls12_377 - - bls12_381 - - bn254 - - pallas - - bw6_761 - - mnt4_298 - - mnt6_298 - - ed_on_bls12_377 - steps: - - name: Checkout curves - uses: actions/checkout@v4 - with: - repository: arkworks-rs/curves - path: curves - - - name: Checkout algebra - uses: actions/checkout@v4 - with: - path: ark-algebra - - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - - name: Patch cargo.toml - run: | - if grep -q "\[patch.crates-io\]" curves/Cargo.toml ; then - MATCH=$(awk '/\[patch.crates-io\]/{ print NR; exit }' curves/Cargo.toml); - sed -i "$MATCH,\$d" curves/Cargo.toml - fi - { - echo "[patch.crates-io]"; - echo "ark-ff = { path = '../ark-algebra/ff' }"; - echo "ark-serialize = { path = '../ark-algebra/serialize' }"; - echo "ark-ff-macros = { path = '../ark-algebra/ff-macros' }"; - echo "ark-ff-asm = { path = '../ark-algebra/ff-asm' }"; - echo "ark-ec = { path = '../ark-algebra/ec' }"; - echo "ark-algebra-bench-templates = { path = '../ark-algebra/bench-templates' }" - echo "ark-algebra-test-templates = { path = '../ark-algebra/test-templates' }" - echo "ark-bls12-377 = { git = 'https://github.com/arkworks-rs/curves' }" - echo "ark-bls12-381 = { git = 'https://github.com/arkworks-rs/curves' }" - echo "ark-bn254 = { git = 'https://github.com/arkworks-rs/curves' }" - echo "ark-pallas = { git = 'https://github.com/arkworks-rs/curves' }" - echo "ark-bw6-761 = { git = 'https://github.com/arkworks-rs/curves' }" - echo "ark-mnt4-298 = { git = 'https://github.com/arkworks-rs/curves' }" - echo "ark-mnt6-298 = { git = 'https://github.com/arkworks-rs/curves' }" - echo "ark-ed-on-bls12-377 = { git = 'https://github.com/arkworks-rs/curves' }" - echo "ark-std = { git = 'https://github.com/arkworks-rs/std' }" - echo "ark-r1cs-std = { git = 'https://github.com/arkworks-rs/r1cs-std' }" - } >> curves/Cargo.toml - - - name: Test on ${{ matrix.curve }} - run: "cd curves/${{ matrix.curve }} && cargo test --all-features" + --target aarch64-unknown-none" \ No newline at end of file From 320ddb96834a3f1d22902d708e976fe31091138c Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Wed, 20 Dec 2023 10:42:32 -0500 Subject: [PATCH 09/14] Added documentation and corrected CHANGELOG.md --- CHANGELOG.md | 2 +- ff/src/biginteger/mod.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf23c0952..be58d6d1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - [\#689](https://github.com/arkworks-rs/algebra/pull/689) (`ark-serialize`) Add `CanonicalSerialize` and `CanonicalDeserialize` impls for `VecDeque` and `LinkedList`. - [\#693](https://github.com/arkworks-rs/algebra/pull/693) (`ark-serialize`) Add `serialize_to_vec!` convenience macro. - [\#713](https://github.com/arkworks-rs/algebra/pull/713) (`ark-ff`) Add support for bitwise operations AND, OR, and XOR between `BigInteger`. -- [\#736](https://github.com/arkworks-rs/algebra/pull/736) (`ark-ff`) Deprecate the use of `muln()` and `divn()`. Instead, it is implemented the traits `core::ops::Shl` and `core::ops::Shr` respectively. +- [\#736](https://github.com/arkworks-rs/algebra/pull/736) (`ark-ff`) Deprecate the use of `divn()`. Instead, it is implemented the trait `core::ops::Shr`. ### Breaking changes diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index ecdbe0f6f..57dff476c 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -732,6 +732,11 @@ impl, const N: usize> BitOr for BigInt { impl Shr for BigInt { type Output = Self; + /// Computes bitwise shift right operation. + /// + /// Differently from the built-in numeric types (u8, u32, u64, etc.) this + /// operation does *not* return an underflow error if the number of bits + /// shifted is larger than N * 64. fn shr(self, mut rhs: u32) -> Self::Output { let mut data = self.0.clone(); From e86611694a90bb926e848ba4974fdd34ffa6a713 Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Wed, 20 Dec 2023 10:48:47 -0500 Subject: [PATCH 10/14] Correct style --- ff/src/biginteger/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index 57dff476c..4f459f395 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -733,7 +733,7 @@ impl Shr for BigInt { type Output = Self; /// Computes bitwise shift right operation. - /// + /// /// Differently from the built-in numeric types (u8, u32, u64, etc.) this /// operation does *not* return an underflow error if the number of bits /// shifted is larger than N * 64. From 4a638cea1b79542e38e4b3fb0ffd5e9518c388a7 Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Wed, 20 Dec 2023 11:06:17 -0500 Subject: [PATCH 11/14] Added a more specific documentation --- ff/src/biginteger/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index 4f459f395..fe77cca1b 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -736,7 +736,8 @@ impl Shr for BigInt { /// /// Differently from the built-in numeric types (u8, u32, u64, etc.) this /// operation does *not* return an underflow error if the number of bits - /// shifted is larger than N * 64. + /// shifted is larger than N * 64. Instead the result will be saturated to + /// zero. fn shr(self, mut rhs: u32) -> Self::Output { let mut data = self.0.clone(); From 9e71f1e9c770f4bb91f933f3b88be898f67316cc Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Wed, 20 Dec 2023 09:33:16 -0800 Subject: [PATCH 12/14] Use `ShrAssign` where appropriate --- curves/bls12_381/src/fields/tests.rs | 10 ++++---- ec/src/scalar_mul/variable_base/mod.rs | 2 +- ff/src/biginteger/mod.rs | 33 +++++++++++++++++--------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/curves/bls12_381/src/fields/tests.rs b/curves/bls12_381/src/fields/tests.rs index c25ac42a3..b6dfa5820 100644 --- a/curves/bls12_381/src/fields/tests.rs +++ b/curves/bls12_381/src/fields/tests.rs @@ -827,7 +827,7 @@ fn test_fq_repr_shr() { 0x16080cf4071e0b05, 0x1225f2901aea514e, ]); - a = a >> 0; + a >>= 0; assert_eq!( a, BigInt::new([ @@ -839,7 +839,7 @@ fn test_fq_repr_shr() { 0x1225f2901aea514e, ]) ); - a = a >> 1; + a >>= 1; assert_eq!( a, BigInt::new([ @@ -851,7 +851,7 @@ fn test_fq_repr_shr() { 0x912f9480d7528a7, ]) ); - a = a >> 50; + a >>= 50; assert_eq!( a, BigInt::new([ @@ -863,7 +863,7 @@ fn test_fq_repr_shr() { 0x244, ]) ); - a = a >> 130; + a >>= 130; assert_eq!( a, BigInt::new([ @@ -875,7 +875,7 @@ fn test_fq_repr_shr() { 0x0, ]) ); - a = a >> 64; + a >>= 64; assert_eq!( a, BigInt::new([0x4067a038f0582e2a, 0x2f9480d7528a70b0, 0x91, 0x0, 0x0, 0x0]) diff --git a/ec/src/scalar_mul/variable_base/mod.rs b/ec/src/scalar_mul/variable_base/mod.rs index 9492c9a3e..3c6694a72 100644 --- a/ec/src/scalar_mul/variable_base/mod.rs +++ b/ec/src/scalar_mul/variable_base/mod.rs @@ -197,7 +197,7 @@ fn msm_bigint( // We right-shift by w_start, thus getting rid of the // lower bits. - scalar = scalar >> w_start as u32; + scalar >>= w_start as u32; // We mod the remaining bits by 2^{window size}, thus taking `c` bits. let scalar = scalar.as_ref()[0] % (1 << c); diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index fe77cca1b..d2e836dca 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -1,4 +1,4 @@ -use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shr}; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shr, ShrAssign}; use crate::{ bits::{BitIteratorBE, BitIteratorLE}, @@ -729,18 +729,14 @@ impl, const N: usize> BitOr for BigInt { } } -impl Shr for BigInt { - type Output = Self; - - /// Computes bitwise shift right operation. +impl ShrAssign for BigInt { + /// Computes the bitwise shift right operation in place. /// /// Differently from the built-in numeric types (u8, u32, u64, etc.) this /// operation does *not* return an underflow error if the number of bits /// shifted is larger than N * 64. Instead the result will be saturated to /// zero. - fn shr(self, mut rhs: u32) -> Self::Output { - let mut data = self.0.clone(); - + fn shr_assign(&mut self, mut rhs: u32) { if rhs >= (64 * N) as u32 { return Self::from(0u64); } @@ -748,7 +744,7 @@ impl Shr for BigInt { while rhs >= 64 { let mut t = 0; for i in 0..N { - core::mem::swap(&mut t, &mut data[N - i - 1]); + core::mem::swap(&mut t, &mut self[N - i - 1]); } rhs -= 64; } @@ -756,14 +752,28 @@ impl Shr for BigInt { if rhs > 0 { let mut t = 0; for i in 0..N { - let a = &mut data[N - i - 1]; + let a = &mut self[N - i - 1]; let t2 = *a << (64 - rhs); *a >>= rhs; *a |= t; t = t2; } } - Self::new(data) + } +} + +impl Shr for BigInt { + type Output = Self; + + /// Computes bitwise shift right operation. + /// + /// Differently from the built-in numeric types (u8, u32, u64, etc.) this + /// operation does *not* return an underflow error if the number of bits + /// shifted is larger than N * 64. Instead the result will be saturated to + /// zero. + fn shr(mut self, mut rhs: u32) -> Self::Output { + self >>= rhs; + self } } @@ -848,6 +858,7 @@ pub trait BigInteger: + BitOr + for<'a> BitOr<&'a Self, Output = Self> + Shr + + ShrAssign { /// Number of 64-bit limbs representing `Self`. const NUM_LIMBS: usize; From 3e4322f453d4df25825b3ac3ad291e918eb2110f Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Wed, 20 Dec 2023 09:39:42 -0800 Subject: [PATCH 13/14] Fix compile error --- ff/src/biginteger/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index d2e836dca..7d5165ee0 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -738,13 +738,13 @@ impl ShrAssign for BigInt { /// zero. fn shr_assign(&mut self, mut rhs: u32) { if rhs >= (64 * N) as u32 { - return Self::from(0u64); + *self = Self::from(0u64); } while rhs >= 64 { let mut t = 0; for i in 0..N { - core::mem::swap(&mut t, &mut self[N - i - 1]); + core::mem::swap(&mut t, &mut self.0[N - i - 1]); } rhs -= 64; } @@ -752,7 +752,7 @@ impl ShrAssign for BigInt { if rhs > 0 { let mut t = 0; for i in 0..N { - let a = &mut self[N - i - 1]; + let a = &mut self.0[N - i - 1]; let t2 = *a << (64 - rhs); *a >>= rhs; *a |= t; From bd0fb186acc4b7ba4d5bf9c754ee6c9f982b4384 Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Wed, 20 Dec 2023 12:49:59 -0500 Subject: [PATCH 14/14] Fixes --- Cargo.toml | 10 ++++------ ff/src/biginteger/mod.rs | 8 +++++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5727c4ed8..947399ace 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,13 +14,13 @@ members = [ "test-curves", "test-templates", ] +exclude = ["curves/**"] resolver = "2" [workspace.package] version = "0.4.2" authors = [ "arkworks contributors" ] homepage = "https://arkworks.rs" -exclude = ["curves/**"] repository = "https://github.com/arkworks-rs/algebra" categories = ["cryptography"] include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT", "doc/katex-header.html"] @@ -31,6 +31,9 @@ rust-version = "1.70" [workspace.metadata.docs.rs] rustdoc-args = [ "--html-in-header katex-header.html" ] +[workspace.metadata.release] +dependent-version = "fix" + [workspace.dependencies] ark-ec = { version = "0.4.2", path = "./ec", default-features = false } ark-ff = { version = "0.4.2", path = "./ff", default-features = false } @@ -71,8 +74,6 @@ proc-macro2 = "1.0" quote = "1.0" syn = "1.0" -resolver = "2" - [profile.release] opt-level = 3 lto = "thin" @@ -97,6 +98,3 @@ lto = "thin" incremental = true debug-assertions = true debug = true - -[workspace.metadata.release] -dependent-version = "fix" diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index 7d5165ee0..d0b9e626c 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -1,4 +1,6 @@ -use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shr, ShrAssign}; +use core::ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shr, ShrAssign, +}; use crate::{ bits::{BitIteratorBE, BitIteratorLE}, @@ -759,7 +761,7 @@ impl ShrAssign for BigInt { t = t2; } } - } + } } impl Shr for BigInt { @@ -771,7 +773,7 @@ impl Shr for BigInt { /// operation does *not* return an underflow error if the number of bits /// shifted is larger than N * 64. Instead the result will be saturated to /// zero. - fn shr(mut self, mut rhs: u32) -> Self::Output { + fn shr(mut self, rhs: u32) -> Self::Output { self >>= rhs; self }