Skip to main content
Version: dev

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.

to_le_bits
pub fn to_le_bits<let N: u32>(self: Self) -> [bool; N] {

Source code: noir_stdlib/src/field/mod.nr#L29-L31

example:

to_le_bits_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]);
}

Source code: noir_stdlib/src/field/mod.nr#L356-L362

to_be_bits

Transforms the field into an array of bits, Big Endian.

to_be_bits
pub fn to_be_bits<let N: u32>(self: Self) -> [bool; N] {

Source code: noir_stdlib/src/field/mod.nr#L61-L63

example:

to_be_bits_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]);
}

Source code: noir_stdlib/src/field/mod.nr#L347-L353

to_le_bytes

Transforms into an array of bytes, Little Endian

to_le_bytes
pub fn to_le_bytes<let N: u32>(self: Self) -> [u8; N] {

Source code: noir_stdlib/src/field/mod.nr#L93-L95

example:

to_le_bytes_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);
}

Source code: noir_stdlib/src/field/mod.nr#L375-L382

to_be_bytes

Transforms into an array of bytes, Big Endian

to_be_bytes
pub fn to_be_bytes<let N: u32>(self: Self) -> [u8; N] {

Source code: noir_stdlib/src/field/mod.nr#L130-L132

example:

to_be_bytes_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);
}

Source code: noir_stdlib/src/field/mod.nr#L365-L372

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

assert_max_bit_size
pub fn assert_max_bit_size<let BIT_SIZE: u32>(self) {

Source code: noir_stdlib/src/field/mod.nr#L10-L12

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