From f38aa218369a32ebcfe332607efb40a6d126c637 Mon Sep 17 00:00:00 2001 From: Tom French Date: Wed, 8 May 2024 14:05:53 +0100 Subject: [PATCH 1/3] feat: add `Not` trait to stdlib --- noir_stdlib/src/ops.nr | 2 +- noir_stdlib/src/ops/bit.nr | 19 +++++++++++++++++++ noir_stdlib/src/uint128.nr | 30 ++++++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/noir_stdlib/src/ops.nr b/noir_stdlib/src/ops.nr index d7ea1dfd484..8b1903cff0b 100644 --- a/noir_stdlib/src/ops.nr +++ b/noir_stdlib/src/ops.nr @@ -2,4 +2,4 @@ mod arith; mod bit; use arith::{Add, Sub, Mul, Div, Rem, Neg}; -use bit::{BitOr, BitAnd, BitXor, Shl, Shr}; +use bit::{Not, BitOr, BitAnd, BitXor, Shl, Shr}; diff --git a/noir_stdlib/src/ops/bit.nr b/noir_stdlib/src/ops/bit.nr index 8a3d20b1909..50c5e2c8251 100644 --- a/noir_stdlib/src/ops/bit.nr +++ b/noir_stdlib/src/ops/bit.nr @@ -1,3 +1,22 @@ +// docs:start:not-trait +trait Not { + fn not(self: Self) -> Self; +} +// docs:end:not-trait + +impl Not for bool { fn not(self) -> bool { !self } } + +impl Not for u64 { fn not(self) -> u64 { !self } } +impl Not for u32 { fn not(self) -> u32 { !self } } +impl Not for u16 { fn not(self) -> u16 { !self } } +impl Not for u8 { fn not(self) -> u8 { !self } } +impl Not for u1 { fn not(self) -> u1 { !self } } + +impl Not for i8 { fn not(self) -> i8 { !self } } +impl Not for i16 { fn not(self) -> i16 { !self } } +impl Not for i32 { fn not(self) -> i32 { !self } } +impl Not for i64 { fn not(self) -> i64 { !self } } + // docs:start:bitor-trait trait BitOr { fn bitor(self, other: Self) -> Self; diff --git a/noir_stdlib/src/uint128.nr b/noir_stdlib/src/uint128.nr index d0f38079e6f..9c61fc801f3 100644 --- a/noir_stdlib/src/uint128.nr +++ b/noir_stdlib/src/uint128.nr @@ -1,4 +1,4 @@ -use crate::ops::{Add, Sub, Mul, Div, Rem, BitOr, BitAnd, BitXor, Shl, Shr}; +use crate::ops::{Add, Sub, Mul, Div, Rem, Not, BitOr, BitAnd, BitXor, Shl, Shr}; use crate::cmp::{Eq, Ord, Ordering}; global pow64 : Field = 18446744073709551616; //2^64; @@ -228,11 +228,20 @@ impl Ord for U128 { } } +impl Not for U128 { + fn not(self) -> U128 { + U128 { + lo: (!(self.lo as u64)) as Field, + hi: (!(self.hi as u64)) as Field + } + } +} + impl BitOr for U128 { fn bitor(self, other: U128) -> U128 { U128 { lo: ((self.lo as u64) | (other.lo as u64)) as Field, - hi: ((self.hi as u64) | (other.hi as u64))as Field + hi: ((self.hi as u64) | (other.hi as u64)) as Field } } } @@ -284,3 +293,20 @@ impl Shr for U128 { self / U128::from_integer(y) } } + +mod test { + use crate::uint128::{U128, pow64}; + + #[test] + fn test_not() { + let num = U128::from_u64s_le(0, 0); + let not_num = num.not(); + + let max_u64: Field = pow64 - 1; + assert_eq(not_num.hi, max_u64); + assert_eq(not_num.lo, max_u64); + + let not_not_num = not_num.not(); + assert_eq(num, not_not_num); + } +} From c190176b92f76fd4c03ca3fa9c62098d073aee81 Mon Sep 17 00:00:00 2001 From: Tom French Date: Wed, 8 May 2024 15:54:26 +0100 Subject: [PATCH 2/3] chore: add docs entry --- docs/docs/noir/standard_library/traits.md | 9 +++++++++ noir_stdlib/src/ops/bit.nr | 2 ++ 2 files changed, 11 insertions(+) diff --git a/docs/docs/noir/standard_library/traits.md b/docs/docs/noir/standard_library/traits.md index 08370dde9e4..31eb663f4b3 100644 --- a/docs/docs/noir/standard_library/traits.md +++ b/docs/docs/noir/standard_library/traits.md @@ -241,6 +241,15 @@ impl Rem for i64 { fn rem(self, other: i64) -> i64 { self % other } } Implementations: #include_code neg-trait-impls noir_stdlib/src/ops/arith.nr rust +### `std::ops::Not` + +#include_code not-trait noir_stdlib/src/ops/bit.nr rust + +`Not::not` is equivalent to the unary bitwise NOT operator `!`. + +Implementations: +#include_code neg-trait-impls noir_stdlib/src/ops/bit.nr rust + ### `std::ops::{ BitOr, BitAnd, BitXor }` #include_code bitor-trait noir_stdlib/src/ops/bit.nr rust diff --git a/noir_stdlib/src/ops/bit.nr b/noir_stdlib/src/ops/bit.nr index 50c5e2c8251..8ab71eb76dd 100644 --- a/noir_stdlib/src/ops/bit.nr +++ b/noir_stdlib/src/ops/bit.nr @@ -4,6 +4,7 @@ trait Not { } // docs:end:not-trait +// docs:start:not-trait-impls impl Not for bool { fn not(self) -> bool { !self } } impl Not for u64 { fn not(self) -> u64 { !self } } @@ -16,6 +17,7 @@ impl Not for i8 { fn not(self) -> i8 { !self } } impl Not for i16 { fn not(self) -> i16 { !self } } impl Not for i32 { fn not(self) -> i32 { !self } } impl Not for i64 { fn not(self) -> i64 { !self } } +// docs:end:not-trait-impls // docs:start:bitor-trait trait BitOr { From 6c6ea83151f70da733b4a94e50c9d5da50af9387 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 8 May 2024 15:55:48 +0100 Subject: [PATCH 3/3] Update docs/docs/noir/standard_library/traits.md --- docs/docs/noir/standard_library/traits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/traits.md b/docs/docs/noir/standard_library/traits.md index 31eb663f4b3..96a7b8e2f22 100644 --- a/docs/docs/noir/standard_library/traits.md +++ b/docs/docs/noir/standard_library/traits.md @@ -248,7 +248,7 @@ Implementations: `Not::not` is equivalent to the unary bitwise NOT operator `!`. Implementations: -#include_code neg-trait-impls noir_stdlib/src/ops/bit.nr rust +#include_code not-trait-impls noir_stdlib/src/ops/bit.nr rust ### `std::ops::{ BitOr, BitAnd, BitXor }`