From ede2ff3ef798e9c0a68fba3b5ac30f8821ba2c93 Mon Sep 17 00:00:00 2001 From: hdvanegasm Date: Wed, 13 Dec 2023 09:57:19 -0500 Subject: [PATCH] Implemented NOT and improved tests --- CHANGELOG.md | 2 +- ff/src/biginteger/mod.rs | 15 +++++++++++++- ff/src/biginteger/tests.rs | 40 ++++++++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44fc75479..996a31bfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,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`. +- [\#713](https://github.com/arkworks-rs/algebra/pull/713) (`ark-ff`) Add support for bitwise operations AND, OR, NOT, and XOR between `BigInteger`. ### Breaking changes diff --git a/ff/src/biginteger/mod.rs b/ff/src/biginteger/mod.rs index dd9f60fd3..311518f58 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}; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not}; use crate::{ bits::{BitIteratorBE, BitIteratorLE}, @@ -738,6 +738,18 @@ impl BitOr for BigInt { } } +impl Not for BigInt { + type Output = Self; + + fn not(self) -> Self::Output { + let mut result = Self::zero(); + for i in 0..N { + result.0[i] = !self.0[i]; + } + result + } +} + /// Compute the signed modulo operation on a u64 representation, returning the result. /// If n % modulus > modulus / 2, return modulus - n /// # Example @@ -800,6 +812,7 @@ pub trait BigInteger: + BitAnd + BitOrAssign + BitOr + + Not { /// Number of 64-bit limbs representing `Self`. const NUM_LIMBS: usize; diff --git a/ff/src/biginteger/tests.rs b/ff/src/biginteger/tests.rs index 9516b6a92..a81add88b 100644 --- a/ff/src/biginteger/tests.rs +++ b/ff/src/biginteger/tests.rs @@ -53,44 +53,54 @@ fn biginteger_arithmetic_test(a: B, b: B, zero: B) { // Test for BigInt's bitwise operations fn biginteger_bitwise_ops_test() { + let mut rng = ark_std::test_rng(); + // Test XOR // a xor a = 0 - let a: BigInt<4> = BigInt::from(4_u64); + let a: BigInt<4> = UniformRand::rand(&mut rng); let a_clone = a.clone(); assert_eq!(a ^ a_clone, BigInt::from(0_u64)); // Testing a xor b xor b - let a: BigInt<4> = BigInt::from(4_u64); - let b = BigInt::from(5_u64); + let a: BigInt<4> = UniformRand::rand(&mut rng); + let b: BigInt<4> = UniformRand::rand(&mut rng); + let a_clone = a.clone(); let b_clone = b.clone(); let xor_ab = a ^ b; - assert_eq!(xor_ab ^ b_clone, BigInt::from(4_u64)); + assert_eq!(xor_ab ^ b_clone, a_clone); // Test OR - // 1 or 1 = 1 - let a: BigInt<4> = BigInt::from(1_u64); + // a or a = a + let a: BigInt<4> = UniformRand::rand(&mut rng); let a_clone = a.clone(); - assert_eq!(a | a_clone, BigInt::from(1_u64)); + assert_eq!(a | a_clone, a); // Testing a or b or b - let a: BigInt<4> = BigInt::from(4_u64); - let b = BigInt::from(5_u64); + let a: BigInt<4> = UniformRand::rand(&mut rng); + let b: BigInt<4> = UniformRand::rand(&mut rng); let b_clone = b.clone(); let or_ab = a | b; - assert_eq!(or_ab | b_clone, BigInt::from(5_u64)); + assert_eq!(or_ab | b_clone, a | b); // Test AND // a and a = a - let a: BigInt<4> = BigInt::from(2_u64); + let a: BigInt<4> = UniformRand::rand(&mut rng); let a_clone = a.clone(); - assert_eq!(a & a_clone, BigInt::from(2_u64)); + assert_eq!(a & a_clone, a); // Testing a and a and b. - let a: BigInt<4> = BigInt::from(4_u64); - let b = BigInt::from(5_u64); + let a: BigInt<4> = UniformRand::rand(&mut rng); + let b: BigInt<4> = UniformRand::rand(&mut rng); let b_clone = b.clone(); let and_ab = a & b; - assert_eq!(and_ab & b_clone, BigInt::from(4_u64)); + assert_eq!(and_ab & b_clone, a & b); + + // Testing De Morgan's law + let a: BigInt<4> = UniformRand::rand(&mut rng); + let b = UniformRand::rand(&mut rng); + let de_morgan_lhs = !(a | b); + let de_morgan_rhs = (!a) & (!b); + assert_eq!(de_morgan_lhs, de_morgan_rhs); } // Test correctness of BigInteger's bit values