From 95c9a05dd5ec06bc734120b4a46be77b5c483bff Mon Sep 17 00:00:00 2001 From: Tom French Date: Mon, 17 Feb 2025 20:12:40 +0000 Subject: [PATCH 1/2] feat!: remove bigint from stdlib --- noir_stdlib/src/bigint.nr | 406 ------------------ noir_stdlib/src/lib.nr | 1 - .../bigint_from_too_many_le_bytes/Nargo.toml | 7 - .../bigint_from_too_many_le_bytes/src/main.nr | 22 - .../execution_success/bigint/Nargo.toml | 6 - .../execution_success/bigint/Prover.toml | 2 - .../execution_success/bigint/src/main.nr | 83 ---- .../comptime_blackbox/src/main.nr | 27 -- 8 files changed, 554 deletions(-) delete mode 100644 noir_stdlib/src/bigint.nr delete mode 100644 test_programs/execution_failure/bigint_from_too_many_le_bytes/Nargo.toml delete mode 100644 test_programs/execution_failure/bigint_from_too_many_le_bytes/src/main.nr delete mode 100644 test_programs/execution_success/bigint/Nargo.toml delete mode 100644 test_programs/execution_success/bigint/Prover.toml delete mode 100644 test_programs/execution_success/bigint/src/main.nr diff --git a/noir_stdlib/src/bigint.nr b/noir_stdlib/src/bigint.nr deleted file mode 100644 index 6ce3ea7d72a..00000000000 --- a/noir_stdlib/src/bigint.nr +++ /dev/null @@ -1,406 +0,0 @@ -use crate::cmp::Eq; -use crate::ops::{Add, Div, Mul, Sub}; - -global bn254_fq: [u8] = &[ - 0x47, 0xFD, 0x7C, 0xD8, 0x16, 0x8C, 0x20, 0x3C, 0x8d, 0xca, 0x71, 0x68, 0x91, 0x6a, 0x81, 0x97, - 0x5d, 0x58, 0x81, 0x81, 0xb6, 0x45, 0x50, 0xb8, 0x29, 0xa0, 0x31, 0xe1, 0x72, 0x4e, 0x64, 0x30, -]; -global bn254_fr: [u8] = &[ - 1, 0, 0, 240, 147, 245, 225, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, 69, - 80, 184, 41, 160, 49, 225, 114, 78, 100, 48, -]; -global secpk1_fr: [u8] = &[ - 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF, 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA, - 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -]; -global secpk1_fq: [u8] = &[ - 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -]; -global secpr1_fq: [u8] = &[ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -]; -global secpr1_fr: [u8] = &[ - 81, 37, 99, 252, 194, 202, 185, 243, 132, 158, 23, 167, 173, 250, 230, 188, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, -]; -// docs:start:big_int_definition -pub struct BigInt { - pointer: u32, - modulus: u32, -} -// docs:end:big_int_definition - -impl BigInt { - #[foreign(bigint_add)] - fn bigint_add(self, other: BigInt) -> BigInt {} - #[foreign(bigint_sub)] - fn bigint_sub(self, other: BigInt) -> BigInt {} - #[foreign(bigint_mul)] - fn bigint_mul(self, other: BigInt) -> BigInt {} - #[foreign(bigint_div)] - fn bigint_div(self, other: BigInt) -> BigInt {} - #[foreign(bigint_from_le_bytes)] - fn from_le_bytes(bytes: [u8], modulus: [u8]) -> BigInt {} - #[foreign(bigint_to_le_bytes)] - fn to_le_bytes(self) -> [u8; 32] {} - - fn check_32_bytes(self: Self, other: BigInt) -> bool { - let bytes = self.to_le_bytes(); - let o_bytes = other.to_le_bytes(); - let mut result = true; - for i in 0..32 { - result = result & (bytes[i] == o_bytes[i]); - } - result - } -} - -pub trait BigField { - fn from_le_bytes(bytes: [u8]) -> Self; - fn from_le_bytes_32(bytes: [u8; 32]) -> Self; - fn to_le_bytes(self) -> [u8]; -} - -pub struct Secpk1Fq { - array: [u8; 32], -} - -impl BigField for Secpk1Fq { - fn from_le_bytes(bytes: [u8]) -> Secpk1Fq { - assert(bytes.len() <= 32); - let mut array = [0; 32]; - for i in 0..bytes.len() { - array[i] = bytes[i]; - } - Secpk1Fq { array } - } - - fn from_le_bytes_32(bytes: [u8; 32]) -> Secpk1Fq { - Secpk1Fq { array: bytes } - } - - fn to_le_bytes(self) -> [u8] { - self.array - } -} - -impl Add for Secpk1Fq { - fn add(self: Self, other: Secpk1Fq) -> Secpk1Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); - Secpk1Fq { array: a.bigint_add(b).to_le_bytes() } - } -} -impl Sub for Secpk1Fq { - fn sub(self: Self, other: Secpk1Fq) -> Secpk1Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); - Secpk1Fq { array: a.bigint_sub(b).to_le_bytes() } - } -} -impl Mul for Secpk1Fq { - fn mul(self: Self, other: Secpk1Fq) -> Secpk1Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); - Secpk1Fq { array: a.bigint_mul(b).to_le_bytes() } - } -} -impl Div for Secpk1Fq { - fn div(self: Self, other: Secpk1Fq) -> Secpk1Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); - Secpk1Fq { array: a.bigint_div(b).to_le_bytes() } - } -} -impl Eq for Secpk1Fq { - fn eq(self: Self, other: Secpk1Fq) -> bool { - self.array == other.array - } -} - -pub struct Secpk1Fr { - array: [u8; 32], -} - -impl BigField for Secpk1Fr { - fn from_le_bytes(bytes: [u8]) -> Secpk1Fr { - assert(bytes.len() <= 32); - let mut array = [0; 32]; - for i in 0..bytes.len() { - array[i] = bytes[i]; - } - Secpk1Fr { array } - } - - fn from_le_bytes_32(bytes: [u8; 32]) -> Secpk1Fr { - Secpk1Fr { array: bytes } - } - - fn to_le_bytes(self) -> [u8] { - self.array - } -} - -impl Add for Secpk1Fr { - fn add(self: Self, other: Secpk1Fr) -> Secpk1Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fr); - Secpk1Fr { array: a.bigint_add(b).to_le_bytes() } - } -} -impl Sub for Secpk1Fr { - fn sub(self: Self, other: Secpk1Fr) -> Secpk1Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fr); - Secpk1Fr { array: a.bigint_sub(b).to_le_bytes() } - } -} -impl Mul for Secpk1Fr { - fn mul(self: Self, other: Secpk1Fr) -> Secpk1Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fr); - Secpk1Fr { array: a.bigint_mul(b).to_le_bytes() } - } -} -impl Div for Secpk1Fr { - fn div(self: Self, other: Secpk1Fr) -> Secpk1Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fr); - Secpk1Fr { array: a.bigint_div(b).to_le_bytes() } - } -} -impl Eq for Secpk1Fr { - fn eq(self: Self, other: Secpk1Fr) -> bool { - self.array == other.array - } -} - -pub struct Bn254Fr { - array: [u8; 32], -} - -impl BigField for Bn254Fr { - fn from_le_bytes(bytes: [u8]) -> Bn254Fr { - assert(bytes.len() <= 32); - let mut array = [0; 32]; - for i in 0..bytes.len() { - array[i] = bytes[i]; - } - Bn254Fr { array } - } - - fn from_le_bytes_32(bytes: [u8; 32]) -> Bn254Fr { - Bn254Fr { array: bytes } - } - - fn to_le_bytes(self) -> [u8] { - self.array - } -} - -impl Add for Bn254Fr { - fn add(self: Self, other: Bn254Fr) -> Bn254Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), bn254_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), bn254_fr); - Bn254Fr { array: a.bigint_add(b).to_le_bytes() } - } -} -impl Sub for Bn254Fr { - fn sub(self: Self, other: Bn254Fr) -> Bn254Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), bn254_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), bn254_fr); - Bn254Fr { array: a.bigint_sub(b).to_le_bytes() } - } -} -impl Mul for Bn254Fr { - fn mul(self: Self, other: Bn254Fr) -> Bn254Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), bn254_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), bn254_fr); - Bn254Fr { array: a.bigint_mul(b).to_le_bytes() } - } -} -impl Div for Bn254Fr { - fn div(self: Self, other: Bn254Fr) -> Bn254Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), bn254_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), bn254_fr); - Bn254Fr { array: a.bigint_div(b).to_le_bytes() } - } -} -impl Eq for Bn254Fr { - fn eq(self: Self, other: Bn254Fr) -> bool { - self.array == other.array - } -} - -pub struct Bn254Fq { - array: [u8; 32], -} - -impl BigField for Bn254Fq { - fn from_le_bytes(bytes: [u8]) -> Bn254Fq { - assert(bytes.len() <= 32); - let mut array = [0; 32]; - for i in 0..bytes.len() { - array[i] = bytes[i]; - } - Bn254Fq { array } - } - - fn from_le_bytes_32(bytes: [u8; 32]) -> Bn254Fq { - Bn254Fq { array: bytes } - } - - fn to_le_bytes(self) -> [u8] { - self.array - } -} - -impl Add for Bn254Fq { - fn add(self: Self, other: Bn254Fq) -> Bn254Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), bn254_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), bn254_fq); - Bn254Fq { array: a.bigint_add(b).to_le_bytes() } - } -} -impl Sub for Bn254Fq { - fn sub(self: Self, other: Bn254Fq) -> Bn254Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), bn254_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), bn254_fq); - Bn254Fq { array: a.bigint_sub(b).to_le_bytes() } - } -} -impl Mul for Bn254Fq { - fn mul(self: Self, other: Bn254Fq) -> Bn254Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), bn254_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), bn254_fq); - Bn254Fq { array: a.bigint_mul(b).to_le_bytes() } - } -} -impl Div for Bn254Fq { - fn div(self: Self, other: Bn254Fq) -> Bn254Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), bn254_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), bn254_fq); - Bn254Fq { array: a.bigint_div(b).to_le_bytes() } - } -} -impl Eq for Bn254Fq { - fn eq(self: Self, other: Bn254Fq) -> bool { - self.array == other.array - } -} - -pub struct Secpr1Fq { - array: [u8; 32], -} - -impl BigField for Secpr1Fq { - fn from_le_bytes(bytes: [u8]) -> Secpr1Fq { - assert(bytes.len() <= 32); - let mut array = [0; 32]; - for i in 0..bytes.len() { - array[i] = bytes[i]; - } - Secpr1Fq { array } - } - - fn from_le_bytes_32(bytes: [u8; 32]) -> Secpr1Fq { - Secpr1Fq { array: bytes } - } - - fn to_le_bytes(self) -> [u8] { - self.array - } -} - -impl Add for Secpr1Fq { - fn add(self: Self, other: Secpr1Fq) -> Secpr1Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpr1_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpr1_fq); - Secpr1Fq { array: a.bigint_add(b).to_le_bytes() } - } -} -impl Sub for Secpr1Fq { - fn sub(self: Self, other: Secpr1Fq) -> Secpr1Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpr1_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpr1_fq); - Secpr1Fq { array: a.bigint_sub(b).to_le_bytes() } - } -} -impl Mul for Secpr1Fq { - fn mul(self: Self, other: Secpr1Fq) -> Secpr1Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpr1_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpr1_fq); - Secpr1Fq { array: a.bigint_mul(b).to_le_bytes() } - } -} -impl Div for Secpr1Fq { - fn div(self: Self, other: Secpr1Fq) -> Secpr1Fq { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpr1_fq); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpr1_fq); - Secpr1Fq { array: a.bigint_div(b).to_le_bytes() } - } -} -impl Eq for Secpr1Fq { - fn eq(self: Self, other: Secpr1Fq) -> bool { - self.array == other.array - } -} - -pub struct Secpr1Fr { - array: [u8; 32], -} - -impl BigField for Secpr1Fr { - fn from_le_bytes(bytes: [u8]) -> Secpr1Fr { - assert(bytes.len() <= 32); - let mut array = [0; 32]; - for i in 0..bytes.len() { - array[i] = bytes[i]; - } - Secpr1Fr { array } - } - - fn from_le_bytes_32(bytes: [u8; 32]) -> Secpr1Fr { - Secpr1Fr { array: bytes } - } - - fn to_le_bytes(self) -> [u8] { - self.array - } -} - -impl Add for Secpr1Fr { - fn add(self: Self, other: Secpr1Fr) -> Secpr1Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpr1_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpr1_fr); - Secpr1Fr { array: a.bigint_add(b).to_le_bytes() } - } -} -impl Sub for Secpr1Fr { - fn sub(self: Self, other: Secpr1Fr) -> Secpr1Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpr1_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpr1_fr); - Secpr1Fr { array: a.bigint_sub(b).to_le_bytes() } - } -} -impl Mul for Secpr1Fr { - fn mul(self: Self, other: Secpr1Fr) -> Secpr1Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpr1_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpr1_fr); - Secpr1Fr { array: a.bigint_mul(b).to_le_bytes() } - } -} -impl Div for Secpr1Fr { - fn div(self: Self, other: Secpr1Fr) -> Secpr1Fr { - let a = BigInt::from_le_bytes(self.array.as_slice(), secpr1_fr); - let b = BigInt::from_le_bytes(other.array.as_slice(), secpr1_fr); - Secpr1Fr { array: a.bigint_div(b).to_le_bytes() } - } -} -impl Eq for Secpr1Fr { - fn eq(self: Self, other: Secpr1Fr) -> bool { - self.array == other.array - } -} diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index 4074e5e6920..d5c360792d9 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -20,7 +20,6 @@ pub mod ops; pub mod default; pub mod prelude; pub mod uint128; -pub mod bigint; pub mod runtime; pub mod meta; pub mod append; diff --git a/test_programs/execution_failure/bigint_from_too_many_le_bytes/Nargo.toml b/test_programs/execution_failure/bigint_from_too_many_le_bytes/Nargo.toml deleted file mode 100644 index cbdfc2d83d9..00000000000 --- a/test_programs/execution_failure/bigint_from_too_many_le_bytes/Nargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "bigint_from_too_many_le_bytes" -type = "bin" -authors = [""] -compiler_version = ">=0.31.0" - -[dependencies] \ No newline at end of file diff --git a/test_programs/execution_failure/bigint_from_too_many_le_bytes/src/main.nr b/test_programs/execution_failure/bigint_from_too_many_le_bytes/src/main.nr deleted file mode 100644 index 2d4587ee3d9..00000000000 --- a/test_programs/execution_failure/bigint_from_too_many_le_bytes/src/main.nr +++ /dev/null @@ -1,22 +0,0 @@ -use std::bigint::{bn254_fq, BigInt}; - -// TODO(https://github.com/noir-lang/noir/issues/5580): decide whether this is desired behavior -// -// Fails at execution time: -// -// error: Assertion failed: 'Index out of bounds' -// ┌─ std/cmp.nr:35:34 -// │ -// 35 │ result &= self[i].eq(other[i]); -// │ -------- -// │ -// = Call stack: -// 1. /Users/michaelklein/Coding/rust/noir/test_programs/compile_failure/bigint_from_too_many_le_bytes/src/main.nr:7:12 -// 2. std/cmp.nr:35:34 -// Failed assertion -fn main() { - let bytes: [u8] = bn254_fq.push_front(0x00); - let bigint = BigInt::from_le_bytes(bytes, bn254_fq); - let result_bytes = bigint.to_le_bytes(); - assert(bytes == result_bytes.as_slice()); -} diff --git a/test_programs/execution_success/bigint/Nargo.toml b/test_programs/execution_success/bigint/Nargo.toml deleted file mode 100644 index eee0920f188..00000000000 --- a/test_programs/execution_success/bigint/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "bigint" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/execution_success/bigint/Prover.toml b/test_programs/execution_success/bigint/Prover.toml deleted file mode 100644 index c50874a8613..00000000000 --- a/test_programs/execution_success/bigint/Prover.toml +++ /dev/null @@ -1,2 +0,0 @@ -x = [34,3,5,8,4] -y = [44,7,1,8,8] \ No newline at end of file diff --git a/test_programs/execution_success/bigint/src/main.nr b/test_programs/execution_success/bigint/src/main.nr deleted file mode 100644 index 2ccb446b8b4..00000000000 --- a/test_programs/execution_success/bigint/src/main.nr +++ /dev/null @@ -1,83 +0,0 @@ -use std::bigint; -use std::{bigint::Secpk1Fq, println}; - -fn main(mut x: [u8; 5], y: [u8; 5]) { - let a = bigint::Secpk1Fq::from_le_bytes(&[x[0], x[1], x[2], x[3], x[4]]); - let b = bigint::Secpk1Fq::from_le_bytes(&[y[0], y[1], y[2], y[3], y[4]]); - let mut a_be_bytes = [0; 32]; - let mut b_be_bytes = [0; 32]; - for i in 0..5 { - a_be_bytes[31 - i] = x[i]; - b_be_bytes[31 - i] = y[i]; - } - let a_field = std::field::bytes32_to_field(a_be_bytes); - let b_field = std::field::bytes32_to_field(b_be_bytes); - - // Regression for issue #4682 - let c = if x[0] != 0 { - test_unconstrained1(a, b) - } else { - // Safety: testing context - unsafe { - test_unconstrained2(a, b) - } - }; - assert(c.array[0] == std::wrapping_mul(x[0], y[0])); - - let a_bytes = a.to_le_bytes(); - let b_bytes = b.to_le_bytes(); - for i in 0..5 { - assert(a_bytes[i] == x[i]); - assert(b_bytes[i] == y[i]); - } - // Regression for issue #4578 - let d = a * b; - assert(d / b == a); - - let d = d - b; - let mut result = [0; 32]; - let result_slice: [u8; 32] = (a_field * b_field - b_field).to_le_bytes(); - for i in 0..32 { - result[i] = result_slice[i]; - } - let d1 = bigint::Secpk1Fq::from_le_bytes_32(result); - assert(d1 == d); - big_int_example(x[0], x[1]); - - // Regression for issue #4882 - let num_b: [u8; 32] = [ - 0, 0, 0, 240, 147, 245, 225, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, - 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48, - ]; - let num2_b: [u8; 7] = [126, 193, 45, 39, 188, 84, 11]; - let num = bigint::Bn254Fr::from_le_bytes(num_b.as_slice()); - let num2 = bigint::Bn254Fr::from_le_bytes(num2_b.as_slice()); - - let ret_b: [u8; 32] = [ - 131, 62, 210, 200, 215, 160, 214, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, - 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48, - ]; - let ret = bigint::Bn254Fr::from_le_bytes(ret_b.as_slice()); - assert(ret == num.mul(num2)); - let div = num.div(num2); - assert(div.mul(num2) == num); -} - -fn test_unconstrained1(a: Secpk1Fq, b: Secpk1Fq) -> Secpk1Fq { - let c = a * b; - c -} -unconstrained fn test_unconstrained2(a: Secpk1Fq, b: Secpk1Fq) -> Secpk1Fq { - let c = a + b; - test_unconstrained1(a, c) -} - -// docs:start:big_int_example -fn big_int_example(x: u8, y: u8) { - let a = Secpk1Fq::from_le_bytes(&[x, y, 0, 45, 2]); - let b = Secpk1Fq::from_le_bytes(&[y, x, 9]); - let c = (a + b) * b / a; - let d = c.to_le_bytes(); - println(d[0]); -} -// docs:end:big_int_example diff --git a/test_programs/noir_test_success/comptime_blackbox/src/main.nr b/test_programs/noir_test_success/comptime_blackbox/src/main.nr index c5ca59c7afc..446692c485b 100644 --- a/test_programs/noir_test_success/comptime_blackbox/src/main.nr +++ b/test_programs/noir_test_success/comptime_blackbox/src/main.nr @@ -1,33 +1,6 @@ //! Tests to show that the comptime interpreter implement blackbox functions. -use std::bigint; use std::embedded_curve_ops::{EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul}; -/// Test that all bigint operations work in comptime. -#[test] -fn test_bigint() { - let result: [u8] = comptime { - let a = bigint::Secpk1Fq::from_le_bytes(&[0, 1, 2, 3, 4]); - let b = bigint::Secpk1Fq::from_le_bytes(&[5, 6, 7, 8, 9]); - let c = (a + b) * b / a - a; - c.to_le_bytes() - }; - // Do the same calculation outside comptime. - let a = bigint::Secpk1Fq::from_le_bytes(&[0, 1, 2, 3, 4]); - let b = bigint::Secpk1Fq::from_le_bytes(&[5, 6, 7, 8, 9]); - let c = bigint::Secpk1Fq::from_le_bytes(result); - assert_eq(c, (a + b) * b / a - a); -} - -/// Test that to_le_radix returns an array. -#[test] -fn test_to_le_radix() { - comptime { - let field = 2; - let bytes: [u8; 8] = field.to_le_radix(256); - let _num = bigint::BigInt::from_le_bytes(bytes, bigint::bn254_fq); - }; -} - #[test] fn test_bitshift() { let c = comptime { From 24ff482de9ff05c37e64c7f1af05c4ab7b47a942 Mon Sep 17 00:00:00 2001 From: Tom French Date: Mon, 17 Feb 2025 21:52:14 +0000 Subject: [PATCH 2/2] . --- docs/docs/noir/standard_library/bigint.md | 110 ---------------------- 1 file changed, 110 deletions(-) delete mode 100644 docs/docs/noir/standard_library/bigint.md diff --git a/docs/docs/noir/standard_library/bigint.md b/docs/docs/noir/standard_library/bigint.md deleted file mode 100644 index cc7d6e1c8de..00000000000 --- a/docs/docs/noir/standard_library/bigint.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Big Integers -description: How to use big integers from Noir standard library -keywords: - [ - Big Integer, - Noir programming language, - Noir libraries, - ] ---- - -The BigInt module in the standard library exposes some class of integers which do not fit (well) into a Noir native field. It implements modulo arithmetic, modulo a 'big' prime number. - -:::note - -The module can currently be considered as `Field`s with fixed modulo sizes used by a set of elliptic curves, in addition to just the native curve. [More work](https://github.com/noir-lang/noir/issues/510) is needed to achieve arbitrarily sized big integers. - -:::note - -`nargo` can be built with `--profile release-pedantic` to enable extra overflow checks which may affect `BigInt` results in some cases. -Consider the [`noir-bignum`](https://github.com/noir-lang/noir-bignum) library for an optimized alternative approach. - -::: - -Currently 6 classes of integers (i.e 'big' prime numbers) are available in the module, namely: - -- BN254 Fq: Bn254Fq -- BN254 Fr: Bn254Fr -- Secp256k1 Fq: Secpk1Fq -- Secp256k1 Fr: Secpk1Fr -- Secp256r1 Fr: Secpr1Fr -- Secp256r1 Fq: Secpr1Fq - -Where XXX Fq and XXX Fr denote respectively the order of the base and scalar field of the (usual) elliptic curve XXX. -For instance the big integer 'Secpk1Fq' in the standard library refers to integers modulo $2^{256}-2^{32}-977$. - -Feel free to explore the source code for the other primes: - -#include_code big_int_definition noir_stdlib/src/bigint.nr rust - -## Example usage - -A common use-case is when constructing a big integer from its bytes representation, and performing arithmetic operations on it: - -#include_code big_int_example test_programs/execution_success/bigint/src/main.nr rust - -## Methods - -The available operations for each big integer are: - -### from_le_bytes - -Construct a big integer from its little-endian bytes representation. Example: - -```rust - // Construct a big integer from a slice of bytes - let a = Secpk1Fq::from_le_bytes(&[x, y, 0, 45, 2]); - // Construct a big integer from an array of 32 bytes - let a = Secpk1Fq::from_le_bytes_32([1;32]); - ``` - -Sure, here's the formatted version of the remaining methods: - -### to_le_bytes - -Return the little-endian bytes representation of a big integer. Example: - -```rust -let bytes = a.to_le_bytes(); -``` - -### add - -Add two big integers. Example: - -```rust -let sum = a + b; -``` - -### sub - -Subtract two big integers. Example: - -```rust -let difference = a - b; -``` - -### mul - -Multiply two big integers. Example: - -```rust -let product = a * b; -``` - -### div - -Divide two big integers. Note that division is field division and not euclidean division. Example: - -```rust -let quotient = a / b; -``` - -### eq - -Compare two big integers. Example: - -```rust -let are_equal = a == b; -```