From b5c6ce20d8a5705127f3b0c33a17e77750fc91c2 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Fri, 3 Jan 2025 19:46:37 -0300 Subject: [PATCH] feat!: remove redefinition of arithmetic methods on `BigNumTrait` (#84) --- .github/workflows/test.yml | 2 +- Nargo.toml | 2 +- README.md | 4 ++-- src/bignum.nr | 34 ++++++++++++++-------------------- src/fns/constrained_ops.nr | 3 ++- src/fns/unconstrained_ops.nr | 2 +- src/runtime_bignum.nr | 31 +++++++++++-------------------- src/tests/bignum_test.nr | 8 ++++---- 8 files changed, 36 insertions(+), 50 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1db5d1ed..fba3f1b3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ on: env: CARGO_TERM_COLOR: always - MINIMUM_NOIR_VERSION: v0.36.0 + MINIMUM_NOIR_VERSION: v1.0.0-beta.0 jobs: noir-version-list: diff --git a/Nargo.toml b/Nargo.toml index 337a2e09..1c3c348f 100644 --- a/Nargo.toml +++ b/Nargo.toml @@ -2,6 +2,6 @@ name = "bignum" type = "lib" authors = [""] -compiler_version = ">=0.36.0" +compiler_version = ">=1.0.0" [dependencies] diff --git a/README.md b/README.md index 39cfd91b..17df8719 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,11 @@ TODO ## Noir Version Compatibility -This library is tested with all stable releases since 0.36.0 as well as nightly. +This library is tested with all stable releases since 1.0.0-beta.0 as well as nightly. ## Dependencies -- Noir ≥v0.36.0 +- Noir ≥v1.0.0-beta.0 - Barretenberg ≥v0.56.1 Refer to [Noir's docs](https://noir-lang.org/docs/getting_started/installation/) and [Barretenberg's docs](https://github.com/AztecProtocol/aztec-packages/blob/master/barretenberg/cpp/src/barretenberg/bb/readme.md#installation) for installation steps. diff --git a/src/bignum.nr b/src/bignum.nr index 52002bd7..1f54d498 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -6,20 +6,22 @@ use crate::fns::{ constrained_ops::{ add, assert_is_not_equal, conditional_select, derive_from_seed, div, eq, mul, neg, sub, udiv, udiv_mod, umod, validate_in_field, validate_in_range, - }, expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, + }, + expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, serialization::{from_be_bytes, to_le_bytes}, unconstrained_ops::{ __add, __batch_invert, __batch_invert_slice, __derive_from_seed, __div, __eq, __invmod, __is_zero, __mul, __neg, __pow, __sub, __tonelli_shanks_sqrt, __udiv_mod, }, }; +use std::ops::{Add, Div, Mul, Neg, Sub}; pub struct BigNum { pub limbs: [Field; N], } // We aim to avoid needing to add a generic parameter to this trait, for this reason we do not allow // accessing the limbs of the bignum except through slices. -pub trait BigNumTrait { +pub trait BigNumTrait: Neg + Add + Sub + Mul + Div + Eq { // TODO: this crashes the compiler? v0.32 // fn default() -> Self { std::default::Default::default () } pub fn new() -> Self; @@ -79,19 +81,6 @@ pub trait BigNumTrait { pub fn validate_in_range(self); pub fn validate_in_field(self); - pub fn neg(self) -> Self; - pub fn add(self, other: Self) -> Self { - self + other - } - pub fn sub(self, other: Self) -> Self { - self - other - } - pub fn mul(self, other: Self) -> Self { - self * other - } - pub fn div(self, other: Self) -> Self { - self / other - } pub fn udiv_mod(self, divisor: Self) -> (Self, Self); pub fn udiv(self, divisor: Self) -> Self; pub fn umod(self, divisor: Self) -> Self; @@ -99,6 +88,16 @@ pub trait BigNumTrait { pub fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; } +impl Neg for BigNum +where + Params: BigNumParamsGetter, +{ + fn neg(self) -> Self { + let params = Params::get_params(); + Self { limbs: neg::<_, MOD_BITS>(params, self.limbs) } + } +} + impl BigNumTrait for BigNum where Params: BigNumParamsGetter, @@ -286,11 +285,6 @@ where assert_is_not_equal(params, self.limbs, other.limbs); } - fn neg(self) -> Self { - let params = Params::get_params(); - Self { limbs: neg::<_, MOD_BITS>(params, self.limbs) } - } - fn udiv_mod(self, divisor: Self) -> (Self, Self) { let params = Params::get_params(); let (q, r) = udiv_mod::<_, MOD_BITS>(params, self.limbs, divisor.limbs); diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index 758e23dc..30ded4ea 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -5,7 +5,8 @@ use crate::fns::{ unconstrained_helpers::{ __add_with_flags, __neg_with_flags, __sub_with_flags, __validate_gt_remainder, __validate_in_field_compute_borrow_flags, - }, unconstrained_ops::{__div, __mul, __udiv_mod}, + }, + unconstrained_ops::{__div, __mul, __udiv_mod}, }; /** diff --git a/src/fns/unconstrained_ops.nr b/src/fns/unconstrained_ops.nr index 68e12df0..e2322fa2 100644 --- a/src/fns/unconstrained_ops.nr +++ b/src/fns/unconstrained_ops.nr @@ -207,7 +207,7 @@ pub(crate) unconstrained fn __invmod( ) -> [Field; N] { let one: [Field; N] = __one::(); let one_u60: U60Repr = U60Repr::from(one); - let exp_u60 = params.modulus_u60.sub(one_u60.add(one_u60)); + let exp_u60 = params.modulus_u60 - (one_u60 + one_u60); let exp = U60Repr::into(exp_u60); __pow::<_, MOD_BITS>(params, val, exp) } diff --git a/src/runtime_bignum.nr b/src/runtime_bignum.nr index 0325ca54..3cdc9c0e 100644 --- a/src/runtime_bignum.nr +++ b/src/runtime_bignum.nr @@ -5,13 +5,15 @@ use crate::fns::{ constrained_ops::{ add, assert_is_not_equal, conditional_select, derive_from_seed, div, eq, mul, neg, sub, udiv, udiv_mod, umod, validate_in_field, validate_in_range, - }, expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, + }, + expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, serialization::{from_be_bytes, to_le_bytes}, unconstrained_ops::{ __add, __batch_invert, __batch_invert_slice, __derive_from_seed, __div, __eq, __invmod, __is_zero, __mul, __neg, __pow, __sub, __tonelli_shanks_sqrt, __udiv_mod, }, }; +use std::ops::{Add, Div, Mul, Neg, Sub}; pub struct RuntimeBigNum { pub limbs: [Field; N], @@ -22,7 +24,7 @@ impl RuntimeBigNum {} // All functions prefixed `__` are unconstrained! // They're not actually decorated as `unconstrained` because to return the `params` (as part of Self) from an `unconstrained` fn would cause range constraints. Instead, each `__` fn wraps a call to an unconstrained fn, so that the already-range-constrained `params` can be inserted into Self after the unconstrained call. -pub(crate) trait RuntimeBigNumTrait { +pub(crate) trait RuntimeBigNumTrait: Neg + Add + Sub + Mul + Div + Eq { pub fn new(params: BigNumParams) -> Self; pub fn one(params: BigNumParams) -> Self; pub fn derive_from_seed( @@ -105,19 +107,6 @@ pub(crate) trait RuntimeBigNumTrait { pub fn validate_in_range(self); // pub fn validate_gt(self, lhs: Self, rhs: Self); - pub fn neg(self) -> Self; - pub fn add(lhs: Self, rhs: Self) -> Self { - lhs + rhs - } - pub fn sub(lhs: Self, rhs: Self) -> Self { - lhs - rhs - } - pub fn mul(lhs: Self, rhs: Self) -> Self { - lhs * rhs - } - pub fn div(lhs: Self, rhs: Self) -> Self { - lhs / rhs - } pub fn udiv_mod(numerator: Self, divisor: Self) -> (Self, Self); pub fn udiv(numerator: Self, divisor: Self) -> Self; pub fn umod(numerator: Self, divisor: Self) -> Self; @@ -125,6 +114,13 @@ pub(crate) trait RuntimeBigNumTrait { pub fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self; } +impl Neg for RuntimeBigNum { + fn neg(self) -> Self { + let params = self.params; + Self { limbs: neg::<_, MOD_BITS>(params, self.limbs), params } + } +} + impl RuntimeBigNumTrait for RuntimeBigNum { fn new(params: BigNumParams) -> Self { @@ -359,11 +355,6 @@ impl RuntimeBigNumTrait for RuntimeB assert_is_not_equal(params, self.limbs, other.limbs); } - fn neg(self) -> Self { - let params = self.params; - Self { limbs: neg::<_, MOD_BITS>(params, self.limbs), params } - } - fn udiv_mod(self, divisor: Self) -> (Self, Self) { let params = self.params; assert(params == divisor.params); diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index ffc8f524..72da0d2a 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -275,7 +275,7 @@ where // // // 929 gates for a 2048 bit mul fn test_mul() where - BN: BigNumTrait + std::ops::Mul + std::ops::Add, + BN: BigNumTrait, { let a: BN = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; let b: BN = unsafe { BN::__derive_from_seed([4, 5, 6, 7]) }; @@ -287,7 +287,7 @@ where fn test_add() where - BN: BigNumTrait + std::ops::Add + std::ops::Mul + std::cmp::Eq, + BN: BigNumTrait, { let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; let b: BN = unsafe { BN::__derive_from_seed([4, 5, 6, 7]) }; @@ -315,7 +315,7 @@ where fn test_div() where - BN: BigNumTrait + std::ops::Div + std::ops::Mul + std::ops::Add + std::cmp::Eq, + BN: BigNumTrait, { let a = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; let b = unsafe { BN::__derive_from_seed([4, 5, 6, 7]) }; @@ -326,7 +326,7 @@ where fn test_invmod() where - BN: BigNumTrait + std::cmp::Eq, + BN: BigNumTrait, { let u = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) }; for _ in 0..1 {