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

feat(std_lib)!: modulus bits and modulus bytes methods #697

Merged
merged 16 commits into from
Jan 31, 2023
Merged
5 changes: 5 additions & 0 deletions crates/nargo/tests/test_data/modulus/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
35 changes: 35 additions & 0 deletions crates/nargo/tests/test_data/modulus/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
bn254_modulus = [
48,
100,
78,
114,
225,
49,
160,
41,
184,
80,
69,
182,
129,
129,
88,
93,
40,
51,
232,
72,
121,
185,
112,
145,
67,
225,
245,
147,
240,
0,
0,
1,
]
return = ""
15 changes: 15 additions & 0 deletions crates/nargo/tests/test_data/modulus/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use dep::std;

fn main(bn254_modulus : [u8; 32]) -> pub Field {
let modulus_size = std::modulus_bits();

// NOTE: The constraints used in this circuit will only work when testing nargo with the plonk bn254 backend
constrain modulus_size == 254;

let modulus_be_byte_array = std::modulus_be_byte_array();
for i in 0..32 {
constrain modulus_be_byte_array[i] == bn254_modulus[i];
}

modulus_size
}
24 changes: 23 additions & 1 deletion crates/noirc_frontend/src/monomorphisation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use acvm::FieldElement;
use iter_extended::{btree_map, vecmap};
use std::collections::{BTreeMap, HashMap, VecDeque};

Expand Down Expand Up @@ -552,7 +553,7 @@ impl Monomorphiser {
}))
}

/// Try to evaluate certain builtin functions (currently only 'arraylen')
/// Try to evaluate certain builtin functions (currently only 'arraylen', 'modulus_bits')
/// at their callsite.
/// NOTE: Evaluating at the callsite means we cannot track aliased functions.
/// E.g. `let f = std::array::len; f(arr)` will fail to evaluate.
Expand All @@ -573,6 +574,27 @@ impl Monomorphiser {
ast::Type::Field,
)))
}
Definition::Builtin(opcode) if opcode == "modulus_bits" => {
Some(ast::Expression::Literal(ast::Literal::Integer(
(FieldElement::max_num_bits() as u128).into(),
ast::Type::Field,
)))
}
Definition::Builtin(opcode) if opcode == "modulus_be_byte_array" => {
let modulus = FieldElement::modulus();
let bytes = modulus.to_bytes_be();
let bytes_as_expr = vecmap(bytes, |byte| {
ast::Expression::Literal(ast::Literal::Integer(
(byte as u128).into(),
ast::Type::Integer(crate::Signedness::Unsigned, 8),
))
});
let arr_literal = ast::ArrayLiteral {
contents: bytes_as_expr,
element_type: ast::Type::Integer(crate::Signedness::Unsigned, 8),
};
Some(ast::Expression::Literal(ast::Literal::Array(arr_literal)))
}
_ => None,
},
_ => None,
Expand Down
4 changes: 4 additions & 0 deletions noir_stdlib/src/lib.nr
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ fn to_le_bytes(x : Field, byte_size: u32) -> [u8] {
//_radix must be less than 256
fn to_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {}

#[builtin(modulus_bits)]
fn modulus_bits() -> comptime Field {}

#[builtin(modulus_be_byte_array)]
fn modulus_be_byte_array() -> [u8] {}

// Returns base^exponent.
// ^ means to the power of and not xor
Expand Down