From bbe5bd5f4843788855c05ccdc851a312b7332ce5 Mon Sep 17 00:00:00 2001 From: guipublic Date: Wed, 6 Mar 2024 11:02:47 +0000 Subject: [PATCH 1/7] document big integers --- docs/docs/noir/standard_library/bigint.md | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) create 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 new file mode 100644 index 00000000000..6a1b7cd732e --- /dev/null +++ b/docs/docs/noir/standard_library/bigint.md @@ -0,0 +1,67 @@ +--- +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. +Currently only 6 class of integers (i.e 'big' prime numbers) are available throughout 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$ + +In order to use it, you need first to import the module: +```rust +use dep::std::bigint::Secpk1Fq; +``` + +Then you can construct a big integer from its bytes representation, and perform arithmetic operations on it: +```rust + 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(); + dep::std::println(d[0]); +``` + +Here is the list of available operations: +- from_le_bytes: construct a big integer from its little-endian bytes representation +```rust + let a = Secpk1Fq::from_le_bytes([x, y, 0, 45, 2]); + ``` +- to_le_bytes: return the little-endian bytes representation of a big integer +```rust + a.to_le_bytes(); + ``` +- add: add two big integers +```rust +a + b; + ``` +- sub: subtract two big integers + ```rust +a - b; + ``` +- mul: multiply two big integers +```rust +a * b; + ``` +- div: divide two big integers +Note that division is field division and not euclidean division. +```rust +a / b; + ``` +- eq: compare two big integers +```rust +a == b; + ``` From d700f5c84662305cb37666abf1074382989f758f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro=20Sousa?= Date: Wed, 6 Mar 2024 13:58:49 +0000 Subject: [PATCH 2/7] adding some suggestions, thanks gui --- docs/.markdownlint.json | 3 + docs/docs/noir/standard_library/bigint.md | 96 ++++++++++++++++------- noir_stdlib/src/bigint.nr | 2 + 3 files changed, 72 insertions(+), 29 deletions(-) create mode 100644 docs/.markdownlint.json diff --git a/docs/.markdownlint.json b/docs/.markdownlint.json new file mode 100644 index 00000000000..40896b4542f --- /dev/null +++ b/docs/.markdownlint.json @@ -0,0 +1,3 @@ +{ + "no-missing-space-atx": false +} diff --git a/docs/docs/noir/standard_library/bigint.md b/docs/docs/noir/standard_library/bigint.md index 6a1b7cd732e..b0bceb7b96d 100644 --- a/docs/docs/noir/standard_library/bigint.md +++ b/docs/docs/noir/standard_library/bigint.md @@ -11,6 +11,7 @@ keywords: 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. Currently only 6 class of integers (i.e 'big' prime numbers) are available throughout the module, namely: + - BN254 Fq: Bn254Fq - BN254 Fr: Bn254Fr - Secp256k1 Fq: Secpk1Fq @@ -19,49 +20,86 @@ Currently only 6 class of integers (i.e 'big' prime numbers) are available throu - 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$ +For instance the big integer 'Secpk1Fq' in the standard library refers to integers modulo $2^{256}-2^{32}-977$. -In order to use it, you need first to import the module: -```rust -use dep::std::bigint::Secpk1Fq; -``` +Feel free to explore the source code for the other primes: + +#include_code curve_order_base 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: -Then you can construct a big integer from its bytes representation, and perform arithmetic operations on it: ```rust +use dep::std::{bigint::Secpk1Fq, println}; + +fn main() { 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(); - dep::std::println(d[0]); + println(d[0]); +} ``` -Here is the list of available operations: -- from_le_bytes: construct a big integer from its little-endian bytes representation +## Methods + +The available operations for each big integer are: + +### from_le_bytes + +Construct a big integer from its little-endian bytes representation. Example: + ```rust let a = Secpk1Fq::from_le_bytes([x, y, 0, 45, 2]); ``` -- to_le_bytes: return the little-endian bytes representation of a big integer + +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 - a.to_le_bytes(); - ``` -- add: add two big integers +let bytes = a.to_le_bytes(); +``` + +### add + +Add two big integers. Example: + ```rust -a + b; - ``` -- sub: subtract two big integers - ```rust -a - b; - ``` -- mul: multiply two big integers +let sum = a + b; +``` + +### sub + +Subtract two big integers. Example: + ```rust -a * b; - ``` -- div: divide two big integers -Note that division is field division and not euclidean division. +let difference = a - b; +``` + +### mul + +Multiply two big integers. Example: + ```rust -a / b; - ``` -- eq: compare two big integers +let product = a * b; +``` + +### div + +Divide two big integers. Note that division is field division and not euclidean division. Example: + ```rust -a == b; - ``` +let quotient = a / b; +``` + +### eq + +Compare two big integers. Example: + +```rust +let are_equal = a == b; +``` diff --git a/noir_stdlib/src/bigint.nr b/noir_stdlib/src/bigint.nr index 98237a54779..e7fc28ba39b 100644 --- a/noir_stdlib/src/bigint.nr +++ b/noir_stdlib/src/bigint.nr @@ -1,6 +1,7 @@ use crate::ops::{Add, Sub, Mul, Div}; use crate::cmp::Eq; +// docs:start:curve_order_base global bn254_fq = [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 = [0x01, 0x00, 0x00, 0x00, 0x3F, 0x59, 0x1F, 0x43, 0x09, 0x97, 0xB9, 0x79, 0x48, 0xE8, 0x33, 0x28, @@ -13,6 +14,7 @@ global secpr1_fq = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF]; global secpr1_fr = [0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3, 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,0xFF, 0xFF, 0xFF, 0xFF]; +// docs:end:curve_order_base struct BigInt { pointer: u32, From 46b88e426367fe683b1feefdc8643c7f9c147b75 Mon Sep 17 00:00:00 2001 From: guipublic <47281315+guipublic@users.noreply.github.com> Date: Fri, 8 Mar 2024 11:30:09 +0100 Subject: [PATCH 3/7] Update docs/docs/noir/standard_library/bigint.md Co-authored-by: Savio <72797635+Savio-Sou@users.noreply.github.com> --- docs/docs/noir/standard_library/bigint.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/bigint.md b/docs/docs/noir/standard_library/bigint.md index b0bceb7b96d..9956259dc6a 100644 --- a/docs/docs/noir/standard_library/bigint.md +++ b/docs/docs/noir/standard_library/bigint.md @@ -10,7 +10,14 @@ keywords: --- 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. -Currently only 6 class of integers (i.e 'big' prime numbers) are available throughout the module, namely: + +:::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. + +::: + +Currently 6 classes of integers (i.e 'big' prime numbers) are available in the module, namely: - BN254 Fq: Bn254Fq - BN254 Fr: Bn254Fr From 9477d3ef986eaea2bf26bcf17508b4c15f458c9c Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 11 Mar 2024 09:07:22 +0000 Subject: [PATCH 4/7] add secpk and secpr to the dictionary --- cspell.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cspell.json b/cspell.json index a96e3de901a..d961b600f40 100644 --- a/cspell.json +++ b/cspell.json @@ -154,6 +154,8 @@ "sdiv", "secp256k1", "secp256r1", + "Secpk", + "Secpr", "signedness", "signorecello", "smol", From de03e9c142c57597cdca195bfd9191ff81d9194f Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 11 Mar 2024 09:14:40 +0000 Subject: [PATCH 5/7] fix example --- docs/docs/noir/standard_library/bigint.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/bigint.md b/docs/docs/noir/standard_library/bigint.md index 9956259dc6a..2fb4512a02a 100644 --- a/docs/docs/noir/standard_library/bigint.md +++ b/docs/docs/noir/standard_library/bigint.md @@ -40,7 +40,7 @@ A common use-case is when constructing a big integer from its bytes representati ```rust use dep::std::{bigint::Secpk1Fq, println}; -fn main() { +fn main(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; From 4e71f915a970d76c730faffaaef4ec49a0071c35 Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 11 Mar 2024 16:45:09 +0000 Subject: [PATCH 6/7] use code snippet for bigint doc --- docs/docs/noir/standard_library/bigint.md | 12 +----------- test_programs/execution_success/bigint/src/main.nr | 12 ++++++++++++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/docs/noir/standard_library/bigint.md b/docs/docs/noir/standard_library/bigint.md index 2fb4512a02a..7d7931840cf 100644 --- a/docs/docs/noir/standard_library/bigint.md +++ b/docs/docs/noir/standard_library/bigint.md @@ -37,17 +37,7 @@ Feel free to explore the source code for the other primes: A common use-case is when constructing a big integer from its bytes representation, and performing arithmetic operations on it: -```rust -use dep::std::{bigint::Secpk1Fq, println}; - -fn main(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]); -} -``` +#include_code big_int_example test_programs/execution_success/bigint/src/main.nr rust ## Methods diff --git a/test_programs/execution_success/bigint/src/main.nr b/test_programs/execution_success/bigint/src/main.nr index b93fec370e5..f8b7aa5f7d7 100644 --- a/test_programs/execution_success/bigint/src/main.nr +++ b/test_programs/execution_success/bigint/src/main.nr @@ -1,4 +1,5 @@ use dep::std::bigint; +use dep::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]]); @@ -13,4 +14,15 @@ fn main(mut x: [u8; 5], y: [u8; 5]) { let d = a * b - b; let d1 = bigint::Secpk1Fq::from_le_bytes(597243850900842442924.to_le_bytes(10)); assert(d1 == d); + big_int_example(x[0], x[1]); } + +// 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 From e7825b3f38ff40dd43aaab2024630c35001db452 Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 11 Mar 2024 18:46:56 +0000 Subject: [PATCH 7/7] comment ex. which does not verify (temporarily) --- test_programs/execution_success/bigint/src/main.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_programs/execution_success/bigint/src/main.nr b/test_programs/execution_success/bigint/src/main.nr index f8b7aa5f7d7..b6c23276c15 100644 --- a/test_programs/execution_success/bigint/src/main.nr +++ b/test_programs/execution_success/bigint/src/main.nr @@ -14,7 +14,7 @@ fn main(mut x: [u8; 5], y: [u8; 5]) { let d = a * b - b; let d1 = bigint::Secpk1Fq::from_le_bytes(597243850900842442924.to_le_bytes(10)); assert(d1 == d); - big_int_example(x[0], x[1]); + // big_int_example(x[0], x[1]); } // docs:start:big_int_example