Skip to content

Commit

Permalink
chore: document big integers (#4487)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves #4205 

## Summary\*

Add a section on standard library documentation

## Additional Context



## Documentation\*

Check one:
- [ ] No documentation needed.
- [X] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: José Pedro Sousa <[email protected]>
Co-authored-by: Savio <[email protected]>
  • Loading branch information
3 people authored Mar 11, 2024
1 parent b94adb9 commit c6e6efd
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@
"sdiv",
"secp256k1",
"secp256r1",
"Secpk",
"Secpr",
"signedness",
"signorecello",
"smol",
Expand Down
3 changes: 3 additions & 0 deletions docs/.markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"no-missing-space-atx": false
}
102 changes: 102 additions & 0 deletions docs/docs/noir/standard_library/bigint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
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.

:::

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 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:

#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
let a = Secpk1Fq::from_le_bytes([x, y, 0, 45, 2]);
```

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;
```
2 changes: 2 additions & 0 deletions noir_stdlib/src/bigint.nr
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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,
Expand Down
12 changes: 12 additions & 0 deletions test_programs/execution_success/bigint/src/main.nr
Original file line number Diff line number Diff line change
@@ -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]]);
Expand All @@ -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

0 comments on commit c6e6efd

Please sign in to comment.