Skip to content

Commit

Permalink
feat!: remove redefinition of arithmetic methods on BigNumTrait (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored Jan 3, 2025
1 parent bc8767a commit b5c6ce2
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion Nargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
name = "bignum"
type = "lib"
authors = [""]
compiler_version = ">=0.36.0"
compiler_version = ">=1.0.0"

[dependencies]
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
34 changes: 14 additions & 20 deletions src/bignum.nr
Original file line number Diff line number Diff line change
Expand Up @@ -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<let N: u32, let MOD_BITS: u32, Params> {
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;
Expand Down Expand Up @@ -79,26 +81,23 @@ 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;

pub fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self;
}

impl<let N: u32, let MOD_BITS: u32, Params> Neg for BigNum<N, MOD_BITS, Params>
where
Params: BigNumParamsGetter<N, MOD_BITS>,
{
fn neg(self) -> Self {
let params = Params::get_params();
Self { limbs: neg::<_, MOD_BITS>(params, self.limbs) }
}
}

impl<let N: u32, let MOD_BITS: u32, Params> BigNumTrait for BigNum<N, MOD_BITS, Params>
where
Params: BigNumParamsGetter<N, MOD_BITS>,
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/fns/constrained_ops.nr
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/fns/unconstrained_ops.nr
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ pub(crate) unconstrained fn __invmod<let N: u32, let MOD_BITS: u32>(
) -> [Field; N] {
let one: [Field; N] = __one::<N>();
let one_u60: U60Repr<N, 2> = 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)
}
Expand Down
31 changes: 11 additions & 20 deletions src/runtime_bignum.nr
Original file line number Diff line number Diff line change
Expand Up @@ -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<let N: u32, let MOD_BITS: u32> {
pub limbs: [Field; N],
Expand All @@ -22,7 +24,7 @@ impl<let N: u32, let MOD_BITS: u32> RuntimeBigNum<N, MOD_BITS> {}

// 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<let N: u32, let MOD_BITS: u32> {
pub(crate) trait RuntimeBigNumTrait<let N: u32, let MOD_BITS: u32>: Neg + Add + Sub + Mul + Div + Eq {
pub fn new(params: BigNumParams<N, MOD_BITS>) -> Self;
pub fn one(params: BigNumParams<N, MOD_BITS>) -> Self;
pub fn derive_from_seed<let SeedBytes: u32>(
Expand Down Expand Up @@ -105,26 +107,20 @@ pub(crate) trait RuntimeBigNumTrait<let N: u32, let MOD_BITS: u32> {
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;

pub fn conditional_select(lhs: Self, rhs: Self, predicate: bool) -> Self;
}

impl<let N: u32, let MOD_BITS: u32> Neg for RuntimeBigNum<N, MOD_BITS> {
fn neg(self) -> Self {
let params = self.params;
Self { limbs: neg::<_, MOD_BITS>(params, self.limbs), params }
}
}

impl<let N: u32, let MOD_BITS: u32> RuntimeBigNumTrait<N, MOD_BITS> for RuntimeBigNum<N, MOD_BITS> {

fn new(params: BigNumParams<N, MOD_BITS>) -> Self {
Expand Down Expand Up @@ -359,11 +355,6 @@ impl<let N: u32, let MOD_BITS: u32> RuntimeBigNumTrait<N, MOD_BITS> 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);
Expand Down
8 changes: 4 additions & 4 deletions src/tests/bignum_test.nr
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ where
// // // 929 gates for a 2048 bit mul
fn test_mul<let N: u32, BN>()
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]) };
Expand All @@ -287,7 +287,7 @@ where

fn test_add<let N: u32, BN>()
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]) };
Expand Down Expand Up @@ -315,7 +315,7 @@ where

fn test_div<let N: u32, BN>()
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]) };
Expand All @@ -326,7 +326,7 @@ where

fn test_invmod<let N: u32, BN>()
where
BN: BigNumTrait + std::cmp::Eq,
BN: BigNumTrait,
{
let u = unsafe { BN::__derive_from_seed([1, 2, 3, 4]) };
for _ in 0..1 {
Expand Down

0 comments on commit b5c6ce2

Please sign in to comment.