From 4a412c106a91d8812fd7ea8fc629bb4703621af3 Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Wed, 8 Jan 2025 14:31:01 +0000 Subject: [PATCH 01/15] changed the workflow and the compiler version requirement --- .github/workflows/test.yml | 14 +++++++------- Nargo.toml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ef999484..7cdb1806 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ on: env: CARGO_TERM_COLOR: always - MINIMUM_NOIR_VERSION: v1.0.0-beta.0 + MINIMUM_NOIR_VERSION: v0.36.0 jobs: noir-version-list: @@ -16,10 +16,11 @@ jobs: runs-on: ubuntu-latest outputs: noir_versions: ${{ steps.get_versions.outputs.versions }} + steps: - name: Checkout sources id: get_versions - run: | + run: | # gh returns the Noir releases in reverse chronological order so we keep all releases published after the minimum supported version. VERSIONS=$(gh release list -R noir-lang/noir --exclude-pre-releases --json tagName -q 'map(.tagName) | index(env.MINIMUM_NOIR_VERSION) as $index | if $index then .[0:$index+1] else [env.MINIMUM_NOIR_VERSION] end') echo "versions=$VERSIONS" @@ -50,6 +51,7 @@ jobs: run: nargo test format: + needs: [noir-version-list] runs-on: ubuntu-latest steps: - name: Checkout sources @@ -58,13 +60,11 @@ jobs: - name: Install Nargo uses: noir-lang/noirup@v0.1.3 with: - toolchain: ${{ env.MINIMUM_NOIR_VERSION }} - + toolchain: ${{needs.noir-version-list.outputs.noir_versions[0] }} - name: Run formatter run: nargo fmt --check - -# This is a job which depends on all test jobs and reports the overall status. + # This is a job which depends on all test jobs and reports the overall status. # This allows us to add/remove test jobs without having to update the required workflows. tests-end: name: Noir End @@ -85,4 +85,4 @@ jobs: fi env: # We treat any cancelled, skipped or failing jobs as a failure for the workflow as a whole. - FAIL: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }} + FAIL: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }} \ No newline at end of file diff --git a/Nargo.toml b/Nargo.toml index 1c3c348f..337a2e09 100644 --- a/Nargo.toml +++ b/Nargo.toml @@ -2,6 +2,6 @@ name = "bignum" type = "lib" authors = [""] -compiler_version = ">=1.0.0" +compiler_version = ">=0.36.0" [dependencies] From 535277678f10de47c2a624958a449a3b73d6b8c2 Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Thu, 16 Jan 2025 13:09:50 +0000 Subject: [PATCH 02/15] built from main --- src/bignum.nr | 8 +++++- src/fns/constrained_ops.nr | 31 +++++++++++++++++++++ src/tests/bignum_test.nr | 56 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/bignum.nr b/src/bignum.nr index 7b76f263..bb0f7ee4 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -5,7 +5,7 @@ use crate::params::BigNumParamsGetter; use crate::fns::{ constrained_ops::{ add, assert_is_not_equal, conditional_select, derive_from_seed, div, eq, from_field, mul, - neg, sub, udiv, udiv_mod, umod, validate_in_field, validate_in_range, + neg, sub, udiv, udiv_mod, umod, validate_in_field, validate_in_range, to_field }, expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, serialization::{from_be_bytes, to_le_bytes}, @@ -31,6 +31,7 @@ pub trait BigNumTrait: Neg + Add + Sub + Mul + Div + Eq { pub fn from_slice(limbs: [Field]) -> Self; pub fn from_be_bytes(x: [u8; NBytes]) -> Self; pub fn to_le_bytes(self) -> [u8; NBytes]; + pub fn to_field(self) -> Field; pub fn modulus() -> Self; pub fn modulus_bits(self) -> u32; @@ -137,6 +138,11 @@ where Self { limbs: limbs.as_array() } } + pub fn to_field(self) -> Field { + to_field::<_, MOD_BITS>(Params::get_params(), self.limbs) + } + + fn from_be_bytes(x: [u8; NBytes]) -> Self { Self { limbs: from_be_bytes::<_, MOD_BITS, _>(x) } } diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index 5d49c3b9..7c098e65 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -35,6 +35,37 @@ use crate::params::BigNumParams as P; * We use a hash function that can be modelled as a random oracle * This function *should* produce an output that is a uniformly randomly distributed value modulo BigNum::modulus() **/ +pub(crate) fn to_field( + params: P, + limbs: [Field; N], +) -> Field { + let TWO_POW_120 = 0x1000000000000000000000000000000; + // let mut field: Field = 0; + if N > 2 { + // validate that the limbs is less than the modulus the grumpkin modulus + let mut grumpkin_modulus = [0; N]; + grumpkin_modulus[0] = 0x33e84879b9709143e1f593f0000001; + grumpkin_modulus[1] = 0x4e72e131a029b85045b68181585d28; + grumpkin_modulus[2] = 0x3064; + validate_gt::(grumpkin_modulus, limbs); + // validate that the limbs are in range + validate_in_range::(limbs); + } + // validate the limbs sum up to the field value + let field_val = if N < 2 { + limbs[0] + } else if N == 2 { + validate_in_range::(limbs); + limbs[0] + limbs[1] * TWO_POW_120 + } else { + validate_in_range::(limbs); + limbs[0] + limbs[1] * TWO_POW_120 + limbs[2] * TWO_POW_120 * TWO_POW_120 + }; + field_val + // assert that the conversion is possible, i.e. the bignum is less than grumpkin field modulus + +} + pub(crate) fn from_field( params: P, field: Field, diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index 2a4ba115..d5d4a572 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -816,3 +816,59 @@ fn test_from_field_3_digits() { assert(result == expected); } + + + +#[test] +fn test_to_field_one() { + let field: Field = 1; + let bn = Fq::one(); + let result = bn.to_field(); + assert(result == field); +} + +#[test] +fn test_to_field_one_digit() { + let field: Field = 1066513542066841864585910935480267774; + let bn = Fq { limbs: [0xcd672d695ef3129e4c40867a7173fe, 0x0, 0x0] }; + let result = bn.to_field(); + assert(result == field); +} + +#[test] +fn test_to_field_two_digits() { + let field: Field = 697955470585821007263499235110798476786097877002667034107578965871052378; + let bn = Fq { limbs: [0x5a10b956d41840745e0a9f6e34465a, 0x65209b74583b912262843211905e41, + 0x0] }; + let result = bn.to_field(); + assert(result == field); + +} + +#[test] +fn test_to_field_three_digits() { + let field: Field = 2330301921655783950764183713945533646391233209687308929386184468126823563744; + let bn = Fq { limbs: [0x862cf8ea69d6c70c9cc8d8871b41e0, 0xe7763528201566c2fc8d93973cf1b4, + 0x526] }; + let result = bn.to_field(); + assert(result == field); + +} + +#[test(should_fail_with = "BigNum::validate_gt check fails")] +fn test_to_field_three_digits_overflow() { + let bn: Fq = BigNum { limbs: [0x4e6405505a33bb9b9c0563df2bd59a, + 0x48dbe03a9bb4865ba961e41ef9dded, 0x3a36] }; + let result = bn.to_field(); +} + +#[test(should_fail_with = "BigNum::validate_gt check fails")] +fn test_to_field_too_many_digits() { + let bn: BN381 = BN381 { + limbs: [0xea1742447ee9d92f9f18e1c80a481e, 0x3d89ad3d3ae85f3f482a08435c93ec, + 0x1e9f, 0x1] + }; + let result = bn.to_field(); +} + + From 510e455206369607195da7e505fd50f1bc578854 Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Thu, 16 Jan 2025 13:14:57 +0000 Subject: [PATCH 03/15] formatter and removing unwanted changes to the workflow --- .github/workflows/test.yml | 4 ++-- Nargo.toml | 2 +- src/bignum.nr | 7 +++---- src/fns/constrained_ops.nr | 4 ++-- src/tests/bignum_test.nr | 28 +++++++++++----------------- 5 files changed, 19 insertions(+), 26 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7cdb1806..b60a67c6 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: @@ -60,7 +60,7 @@ jobs: - name: Install Nargo uses: noir-lang/noirup@v0.1.3 with: - toolchain: ${{needs.noir-version-list.outputs.noir_versions[0] }} + toolchain: ${{ env.MINIMUM_NOIR_VERSION }} - name: Run formatter run: nargo fmt --check 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/src/bignum.nr b/src/bignum.nr index bb0f7ee4..8c7dc8d5 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -5,7 +5,7 @@ use crate::params::BigNumParamsGetter; use crate::fns::{ constrained_ops::{ add, assert_is_not_equal, conditional_select, derive_from_seed, div, eq, from_field, mul, - neg, sub, udiv, udiv_mod, umod, validate_in_field, validate_in_range, to_field + neg, sub, to_field, udiv, udiv_mod, umod, validate_in_field, validate_in_range, }, expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, serialization::{from_be_bytes, to_le_bytes}, @@ -138,11 +138,10 @@ where Self { limbs: limbs.as_array() } } - pub fn to_field(self) -> Field { - to_field::<_, MOD_BITS>(Params::get_params(), self.limbs) + fn to_field(self) -> Field { + to_field::<_, MOD_BITS>(Params::get_params(), self.limbs) } - fn from_be_bytes(x: [u8; NBytes]) -> Self { Self { limbs: from_be_bytes::<_, MOD_BITS, _>(x) } } diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index 7c098e65..ea365dcf 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -61,8 +61,8 @@ pub(crate) fn to_field( validate_in_range::(limbs); limbs[0] + limbs[1] * TWO_POW_120 + limbs[2] * TWO_POW_120 * TWO_POW_120 }; - field_val - // assert that the conversion is possible, i.e. the bignum is less than grumpkin field modulus + field_val + // assert that the conversion is possible, i.e. the bignum is less than grumpkin field modulus } diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index d5d4a572..e81b2390 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -816,13 +816,10 @@ fn test_from_field_3_digits() { assert(result == expected); } - - - #[test] fn test_to_field_one() { let field: Field = 1; - let bn = Fq::one(); + let bn = Fq::one(); let result = bn.to_field(); assert(result == field); } @@ -837,38 +834,35 @@ fn test_to_field_one_digit() { #[test] fn test_to_field_two_digits() { - let field: Field = 697955470585821007263499235110798476786097877002667034107578965871052378; - let bn = Fq { limbs: [0x5a10b956d41840745e0a9f6e34465a, 0x65209b74583b912262843211905e41, - 0x0] }; + let field: Field = 697955470585821007263499235110798476786097877002667034107578965871052378; + let bn = + Fq { limbs: [0x5a10b956d41840745e0a9f6e34465a, 0x65209b74583b912262843211905e41, 0x0] }; let result = bn.to_field(); assert(result == field); - } #[test] fn test_to_field_three_digits() { - let field: Field = 2330301921655783950764183713945533646391233209687308929386184468126823563744; - let bn = Fq { limbs: [0x862cf8ea69d6c70c9cc8d8871b41e0, 0xe7763528201566c2fc8d93973cf1b4, - 0x526] }; + let field: Field = 2330301921655783950764183713945533646391233209687308929386184468126823563744; + let bn = + Fq { limbs: [0x862cf8ea69d6c70c9cc8d8871b41e0, 0xe7763528201566c2fc8d93973cf1b4, 0x526] }; let result = bn.to_field(); assert(result == field); - } #[test(should_fail_with = "BigNum::validate_gt check fails")] fn test_to_field_three_digits_overflow() { - let bn: Fq = BigNum { limbs: [0x4e6405505a33bb9b9c0563df2bd59a, - 0x48dbe03a9bb4865ba961e41ef9dded, 0x3a36] }; + let bn: Fq = BigNum { + limbs: [0x4e6405505a33bb9b9c0563df2bd59a, 0x48dbe03a9bb4865ba961e41ef9dded, 0x3a36], + }; let result = bn.to_field(); } #[test(should_fail_with = "BigNum::validate_gt check fails")] fn test_to_field_too_many_digits() { let bn: BN381 = BN381 { - limbs: [0xea1742447ee9d92f9f18e1c80a481e, 0x3d89ad3d3ae85f3f482a08435c93ec, - 0x1e9f, 0x1] + limbs: [0xea1742447ee9d92f9f18e1c80a481e, 0x3d89ad3d3ae85f3f482a08435c93ec, 0x1e9f, 0x1], }; let result = bn.to_field(); } - From d65a69b71fd6fb53b7c65fa34d0bf27aae60937e Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Thu, 16 Jan 2025 13:15:44 +0000 Subject: [PATCH 04/15] removed unneeded needs from test.yml --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b60a67c6..89f73642 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,7 +51,6 @@ jobs: run: nargo test format: - needs: [noir-version-list] runs-on: ubuntu-latest steps: - name: Checkout sources From 23d95a864d87390b42f82e38af7f539bbf5830ef Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Thu, 16 Jan 2025 13:55:34 +0000 Subject: [PATCH 05/15] fixed issues with the assertions --- src/fns/constrained_ops.nr | 18 ++++++++---------- src/tests/bignum_test.nr | 17 +++++++++++++---- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index ea365dcf..49064694 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -47,23 +47,21 @@ pub(crate) fn to_field( grumpkin_modulus[0] = 0x33e84879b9709143e1f593f0000001; grumpkin_modulus[1] = 0x4e72e131a029b85045b68181585d28; grumpkin_modulus[2] = 0x3064; - validate_gt::(grumpkin_modulus, limbs); + validate_gt::(grumpkin_modulus, limbs); // validate that the limbs are in range - validate_in_range::(limbs); + validate_in_range::(limbs); } // validate the limbs sum up to the field value let field_val = if N < 2 { limbs[0] } else if N == 2 { - validate_in_range::(limbs); + validate_in_range::(limbs); limbs[0] + limbs[1] * TWO_POW_120 } else { - validate_in_range::(limbs); + // validate_in_range::(limbs); limbs[0] + limbs[1] * TWO_POW_120 + limbs[2] * TWO_POW_120 * TWO_POW_120 }; field_val - // assert that the conversion is possible, i.e. the bignum is less than grumpkin field modulus - } pub(crate) fn from_field( @@ -83,18 +81,18 @@ pub(crate) fn from_field( grumpkin_modulus[0] = 0x33e84879b9709143e1f593f0000001; grumpkin_modulus[1] = 0x4e72e131a029b85045b68181585d28; grumpkin_modulus[2] = 0x3064; - validate_gt::(grumpkin_modulus, result); + validate_gt::(grumpkin_modulus, result); // validate that the limbs are in range - validate_in_range::(result); + validate_in_range::(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::(result); + validate_in_range::(result); result[0] + result[1] * TWO_POW_120 } else { - validate_in_range::(result); + validate_in_range::(result); result[0] + result[1] * TWO_POW_120 + result[2] * TWO_POW_120 * TWO_POW_120 }; assert(field_val == field); diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index e81b2390..405954b0 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -1,7 +1,6 @@ -use crate::utils::u60_representation::U60Repr; - use crate::bignum::BigNum; use crate::bignum::BigNumTrait; +use crate::utils::u60_representation::U60Repr; use crate::params::BigNumParams; use crate::params::BigNumParamsGetter; @@ -9,6 +8,7 @@ use crate::params::BigNumParamsGetter; use crate::fields::bls12_381Fq::BLS12_381_Fq_Params; use crate::fields::bn254Fq::BN254_Fq_Params; use crate::fields::U256::U256Params; +use std::bigint::Bn254Fq; struct Test2048Params {} @@ -816,6 +816,16 @@ fn test_from_field_3_digits() { assert(result == expected); } +#[test] +fn test_from_field_3_digits_BLS381() { + let field: Field = -1; + let result = BN381::from(field); + let expected: BN381 = BigNum { + limbs: [0x33e84879b9709143e1f593f0000000, 0x4e72e131a029b85045b68181585d28, 0x3064, 0x0], + }; + assert(result == expected); +} + #[test] fn test_to_field_one() { let field: Field = 1; @@ -858,11 +868,10 @@ fn test_to_field_three_digits_overflow() { let result = bn.to_field(); } -#[test(should_fail_with = "BigNum::validate_gt check fails")] +#[test(should_fail_with = "BigNum::validate_in_range check fails")] fn test_to_field_too_many_digits() { let bn: BN381 = BN381 { limbs: [0xea1742447ee9d92f9f18e1c80a481e, 0x3d89ad3d3ae85f3f482a08435c93ec, 0x1e9f, 0x1], }; let result = bn.to_field(); } - From f57177616e378b62b6e605687329f7571e241366 Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Thu, 16 Jan 2025 14:02:05 +0000 Subject: [PATCH 06/15] fixed the error message --- src/tests/bignum_test.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index 405954b0..62b43ef3 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -868,7 +868,7 @@ fn test_to_field_three_digits_overflow() { let result = bn.to_field(); } -#[test(should_fail_with = "BigNum::validate_in_range check fails")] +#[test(should_fail_with = "BigNum::validate_gt check fails")] fn test_to_field_too_many_digits() { let bn: BN381 = BN381 { limbs: [0xea1742447ee9d92f9f18e1c80a481e, 0x3d89ad3d3ae85f3f482a08435c93ec, 0x1e9f, 0x1], From 37a0723d3ec2012d2ca99cfffa038e587234268e Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Tue, 21 Jan 2025 10:54:08 +0000 Subject: [PATCH 07/15] added composition tests for from and to_field --- src/fns/constrained_ops.nr | 3 --- src/tests/bignum_test.nr | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index 1b89072b..fae245f0 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -28,7 +28,6 @@ use crate::params::BigNumParams as P; * umod */ - pub(crate) fn to_field( params: P, limbs: [Field; N], @@ -58,8 +57,6 @@ pub(crate) fn to_field( field_val } - - pub(crate) fn from_field( params: P, field: Field, diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index 89b3c3ce..677db774 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -816,7 +816,6 @@ fn test_from_field_3_digits() { assert(result == expected); } - #[test] fn test_from_field_3_digits_BLS381() { let field: Field = -1; @@ -877,3 +876,38 @@ fn test_to_field_too_many_digits() { let result = bn.to_field(); } +#[test] +fn test_from_to_field_1() { + let a = 20192735083400333763152317277081729935089452774154199134677444560763605803197; + let b = Fq::from(a); + let c = b.to_field(); + assert(c == a); +} + +#[test] +fn test_from_to_field_2() { + let a = 14303970258849913684902154884389710461666851233307022345291062877970713998175; + let b = BN381::from(a); + let c = b.to_field(); + assert(c == a); +} + +#[test] +fn test_to_from_field_1() { + let a: Fq = BigNum { + limbs: [0x3c768db7732ea1b536c06ae66bce70, 0xb9936c1401d91e7e9e1138375650b4, 0x8c8], + }; + let b = a.to_field(); + let c = Fq::from(b); + assert(a == c); +} + +#[test] +fn test_to_from_field_2() { + let a: BN381 = BigNum { + limbs: [0xd7562bf2b1fe13d458685c96a46d28, 0x2079950acd45bb43a9beeba69d5dc9, 0x18ca, 0x0], + }; + let b = a.to_field(); + let c = BN381::from(b); + assert(a == c); +} From bdb65a57375982ca49d6d559e4583f3227b42ed1 Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Tue, 21 Jan 2025 14:49:23 +0000 Subject: [PATCH 08/15] added a small comment --- src/bignum.nr | 17 ++++++++++++----- src/fns/constrained_ops.nr | 2 +- src/tests/bignum_test.nr | 27 +++++++++++++++------------ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 3cf7ccbf..78efebdf 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -5,7 +5,7 @@ use crate::params::BigNumParamsGetter; use crate::fns::{ constrained_ops::{ add, assert_is_not_equal, conditional_select, derive_from_seed, div, eq, from_field, mul, - neg, sub, to_field, udiv, udiv_mod, umod, validate_in_field, validate_in_range, + neg, sub, limbs_to_field, udiv, udiv_mod, umod, validate_in_field, validate_in_range, }, expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, serialization::{from_be_bytes, to_le_bytes}, @@ -31,7 +31,6 @@ pub trait BigNumTrait: Neg + Add + Sub + Mul + Div + Eq { pub fn from_slice(limbs: [Field]) -> Self; pub fn from_be_bytes(x: [u8; NBytes]) -> Self; pub fn to_le_bytes(self) -> [u8; NBytes]; - pub fn to_field(self) -> Field; pub fn modulus() -> Self; pub fn modulus_bits(self) -> u32; @@ -135,9 +134,6 @@ where Self { limbs: limbs.as_array() } } - fn to_field(self) -> Field { - to_field::<_, MOD_BITS>(Params::get_params(), self.limbs) - } fn from_be_bytes(x: [u8; NBytes]) -> Self { Self { limbs: from_be_bytes::<_, MOD_BITS, _>(x) } @@ -379,3 +375,14 @@ where } } + +// @Brief: Convert a BigNum to a Field +// we decided to not add this to the BigNumTrait as it is might lead to bad use cases of it +pub(crate) fn to_field(input: BigNum) -> Field +where + Params: BigNumParamsGetter, +{ + limbs_to_field(Params::get_params(), input.limbs) +} + + diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index fae245f0..cbf86e88 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -28,7 +28,7 @@ use crate::params::BigNumParams as P; * umod */ -pub(crate) fn to_field( +pub(crate) fn limbs_to_field( params: P, limbs: [Field; N], ) -> Field { diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index 677db774..f2057b47 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -1,4 +1,5 @@ use crate::bignum::BigNum; +use crate::bignum::to_field; use crate::bignum::BigNumTrait; use crate::utils::u60_representation::U60Repr; @@ -826,11 +827,13 @@ fn test_from_field_3_digits_BLS381() { assert(result == expected); } + + #[test] fn test_to_field_one() { let field: Field = 1; let bn = Fq::one(); - let result = bn.to_field(); + let result = to_field(bn); assert(result == field); } @@ -838,7 +841,7 @@ fn test_to_field_one() { fn test_to_field_one_digit() { let field: Field = 1066513542066841864585910935480267774; let bn = Fq { limbs: [0xcd672d695ef3129e4c40867a7173fe, 0x0, 0x0] }; - let result = bn.to_field(); + let result = to_field(bn); assert(result == field); } @@ -847,7 +850,7 @@ fn test_to_field_two_digits() { let field: Field = 697955470585821007263499235110798476786097877002667034107578965871052378; let bn = Fq { limbs: [0x5a10b956d41840745e0a9f6e34465a, 0x65209b74583b912262843211905e41, 0x0] }; - let result = bn.to_field(); + let result = to_field(bn); assert(result == field); } @@ -856,7 +859,7 @@ fn test_to_field_three_digits() { let field: Field = 2330301921655783950764183713945533646391233209687308929386184468126823563744; let bn = Fq { limbs: [0x862cf8ea69d6c70c9cc8d8871b41e0, 0xe7763528201566c2fc8d93973cf1b4, 0x526] }; - let result = bn.to_field(); + let result = to_field(bn); assert(result == field); } @@ -865,7 +868,7 @@ fn test_to_field_three_digits_overflow() { let bn: Fq = BigNum { limbs: [0x4e6405505a33bb9b9c0563df2bd59a, 0x48dbe03a9bb4865ba961e41ef9dded, 0x3a36], }; - let result = bn.to_field(); + let result = to_field(bn); } #[test(should_fail_with = "BigNum::validate_gt check fails")] @@ -873,22 +876,21 @@ fn test_to_field_too_many_digits() { let bn: BN381 = BN381 { limbs: [0xea1742447ee9d92f9f18e1c80a481e, 0x3d89ad3d3ae85f3f482a08435c93ec, 0x1e9f, 0x1], }; - let result = bn.to_field(); + let result = to_field(bn); } #[test] fn test_from_to_field_1() { let a = 20192735083400333763152317277081729935089452774154199134677444560763605803197; let b = Fq::from(a); - let c = b.to_field(); + let c = to_field(b); assert(c == a); } #[test] -fn test_from_to_field_2() { - let a = 14303970258849913684902154884389710461666851233307022345291062877970713998175; +fn test_from_to_field_fuzz(a: Field) { let b = BN381::from(a); - let c = b.to_field(); + let c = to_field(b); assert(c == a); } @@ -897,7 +899,7 @@ fn test_to_from_field_1() { let a: Fq = BigNum { limbs: [0x3c768db7732ea1b536c06ae66bce70, 0xb9936c1401d91e7e9e1138375650b4, 0x8c8], }; - let b = a.to_field(); + let b = to_field(a); let c = Fq::from(b); assert(a == c); } @@ -907,7 +909,8 @@ fn test_to_from_field_2() { let a: BN381 = BigNum { limbs: [0xd7562bf2b1fe13d458685c96a46d28, 0x2079950acd45bb43a9beeba69d5dc9, 0x18ca, 0x0], }; - let b = a.to_field(); + let b = to_field(a); let c = BN381::from(b); assert(a == c); } + From 161f657daa87b670c11d10ebb201f6faa5a4ef5e Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Tue, 21 Jan 2025 14:55:20 +0000 Subject: [PATCH 09/15] fmt --- src/bignum.nr | 13 ++++++------- src/tests/bignum_test.nr | 4 +--- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 78efebdf..f123a093 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -4,8 +4,8 @@ use crate::params::BigNumParamsGetter; use crate::fns::{ constrained_ops::{ - add, assert_is_not_equal, conditional_select, derive_from_seed, div, eq, from_field, mul, - neg, sub, limbs_to_field, udiv, udiv_mod, umod, validate_in_field, validate_in_range, + add, assert_is_not_equal, conditional_select, derive_from_seed, div, eq, from_field, + limbs_to_field, mul, neg, sub, udiv, udiv_mod, umod, validate_in_field, validate_in_range, }, expressions::{__compute_quadratic_expression, evaluate_quadratic_expression}, serialization::{from_be_bytes, to_le_bytes}, @@ -134,7 +134,6 @@ where Self { limbs: limbs.as_array() } } - fn from_be_bytes(x: [u8; NBytes]) -> Self { Self { limbs: from_be_bytes::<_, MOD_BITS, _>(x) } } @@ -375,14 +374,14 @@ where } } - -// @Brief: Convert a BigNum to a Field +// @Brief: Convert a BigNum to a Field // we decided to not add this to the BigNumTrait as it is might lead to bad use cases of it -pub(crate) fn to_field(input: BigNum) -> Field +pub(crate) fn to_field( + input: BigNum, +) -> Field where Params: BigNumParamsGetter, { limbs_to_field(Params::get_params(), input.limbs) } - diff --git a/src/tests/bignum_test.nr b/src/tests/bignum_test.nr index f2057b47..05dd00b9 100644 --- a/src/tests/bignum_test.nr +++ b/src/tests/bignum_test.nr @@ -1,6 +1,6 @@ use crate::bignum::BigNum; -use crate::bignum::to_field; use crate::bignum::BigNumTrait; +use crate::bignum::to_field; use crate::utils::u60_representation::U60Repr; use crate::params::BigNumParams; @@ -827,8 +827,6 @@ fn test_from_field_3_digits_BLS381() { assert(result == expected); } - - #[test] fn test_to_field_one() { let field: Field = 1; From 1445466ecee6c6f7f5d54d553b1e24681adaae85 Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Tue, 21 Jan 2025 16:39:44 +0000 Subject: [PATCH 10/15] changed the comment and visibility --- src/bignum.nr | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index f123a093..8b6512f1 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -374,9 +374,13 @@ where } } -// @Brief: Convert a BigNum to a Field -// we decided to not add this to the BigNumTrait as it is might lead to bad use cases of it -pub(crate) fn to_field( +/** + * @brief to_field converts a BigNum to a Field, conditioned on the bignum fitting in a field element + * we have opted to not add this to the BigNumTrait as it might lead to bad usage of it + * i.e. using this function with modulus larger than the Grumpkin modulus would lead to runtime errors, if the bignum is not deliberately picked to be in range, e.g. the bignum is the output of a hash function. + * for such use cases we advise developers to use comptime assertions to ensure the modulus is not larger than the Grumpkin modulus + **/ +pub fn to_field( input: BigNum, ) -> Field where From 057ce7006af39a1581cec9a9703e70b38d482a9b Mon Sep 17 00:00:00 2001 From: Khashayar Barooti Date: Tue, 21 Jan 2025 16:40:24 +0000 Subject: [PATCH 11/15] formatter --- src/bignum.nr | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index 8b6512f1..c463b803 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -380,9 +380,7 @@ where * i.e. using this function with modulus larger than the Grumpkin modulus would lead to runtime errors, if the bignum is not deliberately picked to be in range, e.g. the bignum is the output of a hash function. * for such use cases we advise developers to use comptime assertions to ensure the modulus is not larger than the Grumpkin modulus **/ -pub fn to_field( - input: BigNum, -) -> Field +pub fn to_field(input: BigNum) -> Field where Params: BigNumParamsGetter, { From caa79ca03c73bb2feaeea6d139b90375d22e5ddb Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 27 Jan 2025 14:13:25 +0000 Subject: [PATCH 12/15] Update src/bignum.nr --- src/bignum.nr | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bignum.nr b/src/bignum.nr index c463b803..3f9190c0 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -374,12 +374,11 @@ where } } -/** - * @brief to_field converts a BigNum to a Field, conditioned on the bignum fitting in a field element - * we have opted to not add this to the BigNumTrait as it might lead to bad usage of it - * i.e. using this function with modulus larger than the Grumpkin modulus would lead to runtime errors, if the bignum is not deliberately picked to be in range, e.g. the bignum is the output of a hash function. - * for such use cases we advise developers to use comptime assertions to ensure the modulus is not larger than the Grumpkin modulus - **/ +/// `to_field` converts a BigNum to a Field, conditioned on the bignum fitting in a field element +/// +/// we have opted to not add this to the BigNumTrait as it might lead to bad usage of it +/// i.e. using this function with modulus larger than the Grumpkin modulus would lead to runtime errors, if the bignum is not deliberately picked to be in range, e.g. the bignum is the output of a hash function. +/// for such use cases we advise developers to use comptime assertions to ensure the modulus is not larger than the Grumpkin modulus pub fn to_field(input: BigNum) -> Field where Params: BigNumParamsGetter, From 84bc03725467f20d938072b96576c3aa89d29b63 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 27 Jan 2025 14:45:23 +0000 Subject: [PATCH 13/15] Update src/fns/constrained_ops.nr --- src/fns/constrained_ops.nr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index 7f16f75c..c4f32d0c 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -33,7 +33,6 @@ pub(crate) fn limbs_to_field( limbs: [Field; N], ) -> Field { let TWO_POW_120 = 0x1000000000000000000000000000000; - // let mut field: Field = 0; if N > 2 { // validate that the limbs is less than the modulus the grumpkin modulus let mut grumpkin_modulus = [0; N]; From 16f4e9124f2fd66576c332d2c688087bdea47b20 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 27 Jan 2025 14:46:04 +0000 Subject: [PATCH 14/15] Update src/fns/constrained_ops.nr --- src/fns/constrained_ops.nr | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index c4f32d0c..0c79a567 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -44,7 +44,7 @@ pub(crate) fn limbs_to_field( validate_in_range::(limbs); } // validate the limbs sum up to the field value - let field_val = if N < 2 { + if N < 2 { limbs[0] } else if N == 2 { validate_in_range::(limbs); @@ -52,8 +52,7 @@ pub(crate) fn limbs_to_field( } else { // validate_in_range::(limbs); limbs[0] + limbs[1] * TWO_POW_120 + limbs[2] * TWO_POW_120 * TWO_POW_120 - }; - field_val + } } pub(crate) fn from_field( From c60ee2f377641ff6f3b189dd00be9637aa9be507 Mon Sep 17 00:00:00 2001 From: Tom French Date: Mon, 27 Jan 2025 14:48:09 +0000 Subject: [PATCH 15/15] . --- src/bignum.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bignum.nr b/src/bignum.nr index 3f9190c0..05707c76 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -377,7 +377,7 @@ where /// `to_field` converts a BigNum to a Field, conditioned on the bignum fitting in a field element /// /// we have opted to not add this to the BigNumTrait as it might lead to bad usage of it -/// i.e. using this function with modulus larger than the Grumpkin modulus would lead to runtime errors, if the bignum is not deliberately picked to be in range, e.g. the bignum is the output of a hash function. +/// i.e. using this function with modulus larger than the Grumpkin modulus would lead to runtime errors, if the bignum is not deliberately picked to be in range, e.g. the bignum is the output of a hash function. /// for such use cases we advise developers to use comptime assertions to ensure the modulus is not larger than the Grumpkin modulus pub fn to_field(input: BigNum) -> Field where