Fields
The field type corresponds to the native field type of the proving backend.
The size of a Noir field depends on the elliptic curve's finite field for the proving backend adopted. For example, a field would be a 254-bit integer when paired with the default backend that spans the Grumpkin curve.
Fields support integer arithmetic:
fn main(x : Field, y : Field) {
let z = x + y;
}
x, y and z are all private fields in this example. Using the let keyword we defined a new private value z constrained to be equal to x + y.
If proving efficiency is of priority, fields should be used as a default for solving problems. Smaller integer types (e.g. u64) incur extra range constraints.
Security Considerations for Field Arithmetic
Field arithmetic wraps around the field modulus without any overflow checks. This means operations like addition and multiplication can silently produce unexpected results if the values exceed the field modulus. For example, adding 1 to the maximum field value wraps back to 0 with no error.
Many use cases require standard integer arithmetic (e.g., enforcing that balance does not go negative). In these programs using explicitly sized integer types is necessary to catch overflows when proving a Noir program.
Methods
After declaring a Field, you can use these common methods on it:
to_le_bits
Transforms the field into an array of bits, Little Endian.
pub fn to_le_bits<let N: u32>(self: Self) -> [bool; N] {
example:
fn test_to_le_bits() {
let field = 2;
let bits: [bool; 8] = field.to_le_bits();
assert_eq(bits, [false, true, false, false, false, false, false, false]);
}
to_be_bits
Transforms the field into an array of bits, Big Endian.
pub fn to_be_bits<let N: u32>(self: Self) -> [bool; N] {
example:
fn test_to_be_bits() {
let field = 2;
let bits: [bool; 8] = field.to_be_bits();
assert_eq(bits, [false, false, false, false, false, false, true, false]);
}
to_le_bytes
Transforms into an array of bytes, Little Endian
pub fn to_le_bytes<let N: u32>(self: Self) -> [u8; N] {
example:
fn test_to_le_bytes() {
let field = 2;
let bytes: [u8; 8] = field.to_le_bytes();
assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);
assert_eq(Field::from_le_bytes::<8>(bytes), field);
}
to_be_bytes
Transforms into an array of bytes, Big Endian
pub fn to_be_bytes<let N: u32>(self: Self) -> [u8; N] {
example:
fn test_to_be_bytes() {
let field = 2;
let bytes: [u8; 8] = field.to_be_bytes();
assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);
assert_eq(Field::from_be_bytes::<8>(bytes), field);
}
pow_32
Returns the value to the power of the specified exponent
fn pow_32(self, exponent: Field) -> Field
example:
fn main() {
let field = 2
let pow = field.pow_32(4);
assert(pow == 16);
}
assert_max_bit_size
Adds a constraint to specify that the field can be represented with bit_size number of bits
pub fn assert_max_bit_size<let BIT_SIZE: u32>(self) {
example:
fn main() {
let field = 2
field.assert_max_bit_size::<32>();
}
sgn0
Parity of (prime) Field element, i.e. sgn0(x mod p) = false if x ∈ {0, ..., p-1} is even, otherwise sgn0(x mod p) = true.
fn sgn0(self) -> bool
lt
Returns true if the field is less than the other field
pub fn lt(self, another: Field) -> bool