Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: removed unnecessary brillig code for range constraining from_field #103

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ jobs:
run: |
npm install -g bbup
bbup -nv 1.0.0-beta.0

sudo apt install libc++-dev


- name: Build Noir benchmark programs
run: nargo export

Expand All @@ -47,3 +49,4 @@ jobs:
# delete the comment in case changes no longer impact circuit sizes
delete: ${{ !steps.gates_diff.outputs.markdown }}
message: ${{ steps.gates_diff.outputs.markdown }}

1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
run: nargo test

format:
needs: [noir-version-list]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
needs: [noir-version-list]

runs-on: ubuntu-latest
steps:
- name: Checkout sources
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 = ">=1.0.0"
compiler_version = ">=0.36.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?


[dependencies]
82 changes: 41 additions & 41 deletions src/bignum.nr
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,39 @@ pub struct BigNum<let N: u32, let MOD_BITS: u32, Params> {
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;
pub fn one() -> Self;
pub fn derive_from_seed<let SeedBytes: u32>(seed: [u8; SeedBytes]) -> Self;
pub unconstrained fn __derive_from_seed<let SeedBytes: u32>(seed: [u8; SeedBytes]) -> Self;
pub fn from_slice(limbs: [Field]) -> Self;
pub fn from_be_bytes<let NBytes: u32>(x: [u8; NBytes]) -> Self;
pub fn to_le_bytes<let NBytes: u32>(self) -> [u8; NBytes];

pub fn modulus() -> Self;
pub fn modulus_bits(self) -> u32;
pub fn num_limbs(self) -> u32;
pub fn get_limbs_slice(self) -> [Field];
pub fn get_limb(self, idx: u32) -> Field;
pub fn set_limb(&mut self, idx: u32, value: Field);

pub unconstrained fn __eq(self, other: Self) -> bool;
pub unconstrained fn __is_zero(self) -> bool;

pub unconstrained fn __neg(self) -> Self;
pub unconstrained fn __add(self, other: Self) -> Self;
pub unconstrained fn __sub(self, other: Self) -> Self;
pub unconstrained fn __mul(self, other: Self) -> Self;
pub unconstrained fn __div(self, other: Self) -> Self;
pub unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self);
pub unconstrained fn __invmod(self) -> Self;
pub unconstrained fn __pow(self, exponent: Self) -> Self;

pub unconstrained fn __batch_invert<let M: u32>(to_invert: [Self; M]) -> [Self; M];
pub unconstrained fn __batch_invert_slice<let M: u32>(to_invert: [Self]) -> [Self];

pub unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option<Self>;

pub unconstrained fn __compute_quadratic_expression<let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32>(
fn new() -> Self;
fn one() -> Self;
fn derive_from_seed<let SeedBytes: u32>(seed: [u8; SeedBytes]) -> Self;
unconstrained fn __derive_from_seed<let SeedBytes: u32>(seed: [u8; SeedBytes]) -> Self;
fn from_slice(limbs: [Field]) -> Self;
fn from_be_bytes<let NBytes: u32>(x: [u8; NBytes]) -> Self;
fn to_le_bytes<let NBytes: u32>(self) -> [u8; NBytes];

fn modulus() -> Self;
fn modulus_bits(self) -> u32;
fn num_limbs(self) -> u32;
fn get_limbs_slice(self) -> [Field];
fn get_limb(self, idx: u32) -> Field;
fn set_limb(&mut self, idx: u32, value: Field);

unconstrained fn __eq(self, other: Self) -> bool;
unconstrained fn __is_zero(self) -> bool;

unconstrained fn __neg(self) -> Self;
unconstrained fn __add(self, other: Self) -> Self;
unconstrained fn __sub(self, other: Self) -> Self;
unconstrained fn __mul(self, other: Self) -> Self;
unconstrained fn __div(self, other: Self) -> Self;
unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self);
unconstrained fn __invmod(self) -> Self;
unconstrained fn __pow(self, exponent: Self) -> Self;

unconstrained fn __batch_invert<let M: u32>(to_invert: [Self; M]) -> [Self; M];
unconstrained fn __batch_invert_slice<let M: u32>(to_invert: [Self]) -> [Self];

unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option<Self>;

unconstrained fn __compute_quadratic_expression<let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32>(
lhs: [[Self; LHS_N]; NUM_PRODUCTS],
lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],
rhs: [[Self; RHS_N]; NUM_PRODUCTS],
Expand All @@ -65,7 +65,7 @@ pub trait BigNumTrait: Neg + Add + Sub + Mul + Div + Eq {
add_flags: [bool; ADD_N],
) -> (Self, Self);

pub fn evaluate_quadratic_expression<let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32>(
fn evaluate_quadratic_expression<let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32>(
lhs: [[Self; LHS_N]; NUM_PRODUCTS],
lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],
rhs: [[Self; RHS_N]; NUM_PRODUCTS],
Expand All @@ -74,15 +74,15 @@ pub trait BigNumTrait: Neg + Add + Sub + Mul + Div + Eq {
add_flags: [bool; ADD_N],
);

pub fn assert_is_not_equal(self, other: Self);
pub fn validate_in_range(self);
pub fn validate_in_field(self);
fn assert_is_not_equal(self, other: Self);
fn validate_in_range(self);
fn validate_in_field(self);

pub fn udiv_mod(self, divisor: Self) -> (Self, Self);
pub fn udiv(self, divisor: Self) -> Self;
pub fn umod(self, divisor: Self) -> Self;
fn udiv_mod(self, divisor: Self) -> (Self, Self);
fn udiv(self, divisor: Self) -> Self;
fn umod(self, divisor: Self) -> Self;

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

impl<let N: u32, let MOD_BITS: u32, Params> std::convert::From<Field> for BigNum<N, MOD_BITS, Params>
Expand Down
34 changes: 29 additions & 5 deletions src/fns/constrained_ops.nr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::fns::{
expressions::evaluate_quadratic_expression,
unconstrained_helpers::{
__add_with_flags, __from_field, __neg_with_flags, __sub_with_flags, __validate_gt_remainder,
__validate_in_field_compute_borrow_flags,
__validate_in_field_compute_borrow_flags, __validate_in_grumpkin_compute_borrow_flags,
},
unconstrained_ops::{__div, __mul, __udiv_mod},
};
Expand Down Expand Up @@ -45,18 +45,18 @@ pub(crate) fn from_field<let N: u32, let MOD_BITS: u32>(
grumpkin_modulus[0] = 0x33e84879b9709143e1f593f0000001;
grumpkin_modulus[1] = 0x4e72e131a029b85045b68181585d28;
grumpkin_modulus[2] = 0x3064;
validate_gt::<N, 254>(grumpkin_modulus, result);
validate_gt::<N, MOD_BITS>(grumpkin_modulus, result);
// validate that the limbs are in range
validate_in_range::<N, 254>(result);
validate_in_range::<N, MOD_BITS>(result);
}
// validate the limbs sum up to the field value
let field_val = if N < 2 {
result[0]
} else if N == 2 {
validate_in_range::<N, 254>(result);
validate_in_range::<N, MOD_BITS>(result);
result[0] + result[1] * TWO_POW_120
} else {
validate_in_range::<N, 254>(result);
validate_in_range::<N, MOD_BITS>(result);
result[0] + result[1] * TWO_POW_120 + result[2] * TWO_POW_120 * TWO_POW_120
};
assert(field_val == field);
Expand Down Expand Up @@ -267,6 +267,30 @@ pub(crate) fn validate_in_field<let N: u32, let MOD_BITS: u32>(
validate_in_range::<_, MOD_BITS>(compare);
}

pub(crate) fn validate_in_grumpkin<let N: u32, let MOD_BITS: u32>(limbs: [Field; N]) {
// N.B. need to combine with validate_in_range if `self` limbs have not been range constrained
let mut grumpkin_modulus = [0; N];
grumpkin_modulus[0] = 0x33e84879b9709143e1f593f0000001;
grumpkin_modulus[1] = 0x4e72e131a029b85045b68181585d28;
grumpkin_modulus[2] = 0x3064;

let mut p_grumpkin_minus_self: [Field; N] = [0; N];
for i in 0..N {
p_grumpkin_minus_self[i] = grumpkin_modulus[i] - limbs[i];
}
let borrow_flags = unsafe { __validate_in_grumpkin_compute_borrow_flags(limbs) };
let two_pow_120: Field = 0x1000000000000000000000000000000;
p_grumpkin_minus_self[0] += borrow_flags[0] as Field * two_pow_120;
for i in 1..N - 1 {
p_grumpkin_minus_self[i] +=
(borrow_flags[i] as Field * two_pow_120 - borrow_flags[i - 1] as Field);
}
p_grumpkin_minus_self[N - 1] -= borrow_flags[N - 2] as Field;
let mut compare = limbs;
compare = p_grumpkin_minus_self;
validate_in_range::<_, MOD_BITS>(compare);
}

/**
* @brief Validate a BigNum instance is correctly range constrained to contain no more than Params::modulus_bits()
**/
Expand Down
15 changes: 15 additions & 0 deletions src/fns/unconstrained_helpers.nr
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,21 @@ pub(crate) unconstrained fn __validate_in_field_compute_borrow_flags<let N: u32,
flags
}

pub(crate) unconstrained fn __validate_in_grumpkin_compute_borrow_flags<let N: u32, let MOD_BITS: u32>(
val: [Field; N],
) -> [bool; N] {
let mut flags: [bool; N] = [false; N];
let mut grumpkin_modulus = [0; N];
grumpkin_modulus[0] = 0x33e84879b9709143e1f593f0000001;
grumpkin_modulus[1] = 0x4e72e131a029b85045b68181585d28;
grumpkin_modulus[2] = 0x3064;
flags[0] = grumpkin_modulus[0].lt(val[0]);
for i in 1..N - 1 {
flags[i] = grumpkin_modulus[i].lt(val[i] + flags[i - 1] as Field);
}
flags
}

pub(crate) unconstrained fn __validate_gt_remainder<let N: u32>(
lhs: [Field; N],
rhs: [Field; N],
Expand Down
2 changes: 1 addition & 1 deletion src/params.nr
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct BigNumParams<let N: u32, let MOD_BITS: u32> {

// To be implemented by the user for any BigNum they define, or within the predefined BigNums in the `fields/` dir.
pub trait BigNumParamsGetter<let N: u32, let MOD_BITS: u32> {
pub fn get_params() -> BigNumParams<N, MOD_BITS>;
fn get_params() -> BigNumParams<N, MOD_BITS>;
}

impl<let N: u32, let MOD_BITS: u32> BigNumParams<N, MOD_BITS> {
Expand Down
71 changes: 34 additions & 37 deletions src/runtime_bignum.nr
Original file line number Diff line number Diff line change
Expand Up @@ -25,61 +25,58 @@ 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>: 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>(
fn new(params: BigNumParams<N, MOD_BITS>) -> Self;
fn one(params: BigNumParams<N, MOD_BITS>) -> Self;
fn derive_from_seed<let SeedBytes: u32>(
params: BigNumParams<N, MOD_BITS>,
seed: [u8; SeedBytes],
) -> Self;
pub unconstrained fn __derive_from_seed<let SeedBytes: u32>(
unconstrained fn __derive_from_seed<let SeedBytes: u32>(
params: BigNumParams<N, MOD_BITS>,
seed: [u8; SeedBytes],
) -> Self;
pub fn from_slice(params: BigNumParams<N, MOD_BITS>, limbs: [Field]) -> Self;
pub fn from_array(params: BigNumParams<N, MOD_BITS>, limbs: [Field; N]) -> Self;
pub fn from_be_bytes<let NBytes: u32>(
params: BigNumParams<N, MOD_BITS>,
x: [u8; NBytes],
) -> Self;
fn from_slice(params: BigNumParams<N, MOD_BITS>, limbs: [Field]) -> Self;
fn from_array(params: BigNumParams<N, MOD_BITS>, limbs: [Field; N]) -> Self;
fn from_be_bytes<let NBytes: u32>(params: BigNumParams<N, MOD_BITS>, x: [u8; NBytes]) -> Self;

pub fn to_le_bytes<let NBytes: u32>(self) -> [u8; NBytes];
fn to_le_bytes<let NBytes: u32>(self) -> [u8; NBytes];

pub fn modulus(self) -> Self;
pub fn modulus_bits() -> u32;
pub fn num_limbs() -> u32;
fn modulus(self) -> Self;
fn modulus_bits() -> u32;
fn num_limbs() -> u32;
// pub fn get(self) -> [Field];
pub fn get_limbs(self) -> [Field; N];
pub fn get_limb(self, idx: u32) -> Field;
pub fn set_limb(&mut self, idx: u32, value: Field);
fn get_limbs(self) -> [Field; N];
fn get_limb(self, idx: u32) -> Field;
fn set_limb(&mut self, idx: u32, value: Field);

unconstrained fn __eq(self, other: Self) -> bool;
unconstrained fn __is_zero(self) -> bool;

// unconstrained
pub fn __neg(self) -> Self;
fn __neg(self) -> Self;
// unconstrained
pub fn __add(self, other: Self) -> Self;
fn __add(self, other: Self) -> Self;
// unconstrained
pub fn __sub(self, other: Self) -> Self;
fn __sub(self, other: Self) -> Self;
// unconstrained
pub fn __mul(self, other: Self) -> Self;
fn __mul(self, other: Self) -> Self;
// unconstrained
pub fn __div(self, other: Self) -> Self;
fn __div(self, other: Self) -> Self;
// unconstrained
pub fn __udiv_mod(self, divisor: Self) -> (Self, Self);
fn __udiv_mod(self, divisor: Self) -> (Self, Self);
// unconstrained
pub fn __invmod(self) -> Self;
fn __invmod(self) -> Self;
// unconstrained
pub fn __pow(self, exponent: Self) -> Self;
fn __pow(self, exponent: Self) -> Self;

// unconstrained
pub fn __batch_invert<let M: u32>(x: [Self; M]) -> [Self; M];
fn __batch_invert<let M: u32>(x: [Self; M]) -> [Self; M];
unconstrained fn __batch_invert_slice<let M: u32>(to_invert: [Self]) -> [Self];

pub fn __tonelli_shanks_sqrt(self) -> std::option::Option<Self>;
fn __tonelli_shanks_sqrt(self) -> std::option::Option<Self>;

// unconstrained
pub fn __compute_quadratic_expression<let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32>(
fn __compute_quadratic_expression<let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32>(
params: BigNumParams<N, MOD_BITS>,
lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS],
lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],
Expand All @@ -89,7 +86,7 @@ pub(crate) trait RuntimeBigNumTrait<let N: u32, let MOD_BITS: u32>: Neg + Add +
linear_flags: [bool; ADD_N],
) -> (Self, Self);

pub fn evaluate_quadratic_expression<let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32>(
fn evaluate_quadratic_expression<let LHS_N: u32, let RHS_N: u32, let NUM_PRODUCTS: u32, let ADD_N: u32>(
params: BigNumParams<N, MOD_BITS>,
lhs_terms: [[Self; LHS_N]; NUM_PRODUCTS],
lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],
Expand All @@ -99,19 +96,19 @@ pub(crate) trait RuntimeBigNumTrait<let N: u32, let MOD_BITS: u32>: Neg + Add +
linear_flags: [bool; ADD_N],
);

pub fn eq(lhs: Self, rhs: Self) -> bool {
fn eq(lhs: Self, rhs: Self) -> bool {
lhs == rhs
}
pub fn assert_is_not_equal(self, other: Self);
pub fn validate_in_field(self);
pub fn validate_in_range(self);
fn assert_is_not_equal(self, other: Self);
fn validate_in_field(self);
fn validate_in_range(self);
// pub fn validate_gt(self, lhs: Self, rhs: Self);

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;
fn udiv_mod(numerator: Self, divisor: Self) -> (Self, Self);
fn udiv(numerator: Self, divisor: Self) -> Self;
fn umod(numerator: Self, divisor: Self) -> Self;

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

impl<let N: u32, let MOD_BITS: u32> Neg for RuntimeBigNum<N, MOD_BITS> {
Expand Down
1 change: 1 addition & 0 deletions src/tests/bignum_test.nr
Original file line number Diff line number Diff line change
Expand Up @@ -815,3 +815,4 @@ fn test_from_field_3_digits() {
};
assert(result == expected);
}

Loading