From 32518ebaddb5b2d5cfdc532ce87876cf809301bf Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Wed, 20 Dec 2023 15:23:49 -0500 Subject: [PATCH 1/4] Deprecation of `muln()` --- ff/src/biginteger/mod.rs | 56 +++++++++++++++++++++++++++++++++++++- ff/src/biginteger/tests.rs | 26 ++++++++++++++++-- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index d0b9e626c..2d46ceb5e 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -1,5 +1,6 @@ use core::ops::{ - BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shr, ShrAssign, + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl, ShlAssign, Shr, + ShrAssign, }; use crate::{ @@ -779,6 +780,56 @@ impl Shr for BigInt { } } +impl ShlAssign for BigInt { + /// Computes the bitwise shift left 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 overflow will be chopped + /// off. + fn shl_assign(&mut self, mut rhs: u32) { + if rhs >= (64 * N) as u32 { + *self = Self::from(0u64); + return; + } + + while rhs >= 64 { + let mut t = 0; + for i in 0..N { + core::mem::swap(&mut t, &mut self.0[i]); + } + rhs -= 64; + } + + if rhs > 0 { + let mut t = 0; + #[allow(unused)] + for i in 0..N { + let a = &mut self.0[i]; + let t2 = *a >> (64 - rhs); + *a <<= rhs; + *a |= t; + t = t2; + } + } + } +} + +impl Shl for BigInt { + type Output = Self; + + /// Computes the bitwise shift left 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 overflow will be chopped + /// off. + fn shl(mut self, rhs: u32) -> Self::Output { + self <<= rhs; + self + } +} + impl Not for BigInt { type Output = Self; @@ -861,6 +912,8 @@ pub trait BigInteger: + for<'a> BitOr<&'a Self, Output = Self> + Shr + ShrAssign + + Shl + + ShlAssign { /// Number of 64-bit limbs representing `Self`. const NUM_LIMBS: usize; @@ -956,6 +1009,7 @@ 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 f3fe5360f..9c65eb4c3 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 <<= 0; assert_eq!(a_mul1, a); // a * 2 = a + a @@ -72,6 +72,27 @@ 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(64u64); + assert_eq!(a << 2, B::from(256u64)); + + // Testing saturated overflow + let a = B::rand(&mut rng); + assert_eq!(a << ((B::NUM_LIMBS as u32) * 64), B::from(0u64)); + + // Test null bits + 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(); @@ -125,7 +146,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 <<= 5; let thirty_two = one; // 0th bit of BigInteger representing 32 is not 1 assert!(!thirty_two.get_bit(0)); @@ -162,6 +183,7 @@ fn test_biginteger(zero: B) { biginteger_conversion_test::(); biginteger_bitwise_ops_test::(); biginteger_shr::(); + biginteger_shl::(); } #[test] From c8edc22b32263a16483e369e2cc5eb551d45137e Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Wed, 20 Dec 2023 15:29:32 -0500 Subject: [PATCH 2/4] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be58d6d1e..329c8ad3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [\#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 `divn()`. Instead, it is implemented the trait `core::ops::Shr`. +- [\#739](https://github.com/arkworks-rs/algebra/pull/739) (`ark-ff`) Deprecate the use of `muln()`. Instead, it is implemented the trait `core::ops::Shl`. ### Breaking changes From 29423be5864f9e12a6a41e12fd20b4188be74e7c Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Wed, 20 Dec 2023 12:59:16 -0800 Subject: [PATCH 3/4] Tweak documentation and README --- CHANGELOG.md | 4 ++-- ff/src/biginteger/mod.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 329c8ad3f..d637f5c57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,8 @@ - [\#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 `divn()`. Instead, it is implemented the trait `core::ops::Shr`. -- [\#739](https://github.com/arkworks-rs/algebra/pull/739) (`ark-ff`) Deprecate the use of `muln()`. Instead, it is implemented the trait `core::ops::Shl`. +- [\#736](https://github.com/arkworks-rs/algebra/pull/736) (`ark-ff`) Deprecate `divn()`, and use `core::ops::{Shr, ShrAssign}` instead. +- [\#739](https://github.com/arkworks-rs/algebra/pull/739) (`ark-ff`) Deprecate `muln()`, and use `core::ops::{Shl, ShlAssign}` instead. ### Breaking changes diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index 2d46ceb5e..dd5253881 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -784,7 +784,7 @@ impl ShlAssign for BigInt { /// Computes the bitwise shift left 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 + /// operation does *not* return an overflow error if the number of bits /// shifted is larger than N * 64. Instead, the overflow will be chopped /// off. fn shl_assign(&mut self, mut rhs: u32) { From d4dbbb9c991d27e3a2bb6b3f31c2e3d329380f54 Mon Sep 17 00:00:00 2001 From: Pratyush Mishra Date: Wed, 20 Dec 2023 12:59:34 -0800 Subject: [PATCH 4/4] Tweak --- 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 dd5253881..0dff0129f 100644 --- a/ff/src/biginteger/mod.rs +++ b/ff/src/biginteger/mod.rs @@ -821,7 +821,7 @@ impl Shl for BigInt { /// Computes the bitwise shift left 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 + /// operation does *not* return an overflow error if the number of bits /// shifted is larger than N * 64. Instead, the overflow will be chopped /// off. fn shl(mut self, rhs: u32) -> Self::Output {