Field Elements
A field element is a number in the BN254 scalar field — integers modulo the prime:
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617All arithmetic on field elements is modular: addition, subtraction, and multiplication wrap around at p, and division computes the modular inverse.
Int vs Field
Section titled “Int vs Field”| Int | Field | |
|---|---|---|
| Range | -2^59 to 2^59-1 | 0 to p-1 |
| Overflow | Runtime error | Wraps modulo p |
| Negation | -x | p - x |
| Division | Truncating (7 / 2 = 3) | Modular inverse (1/2 = (p+1)/2) |
| Storage | Inline (60-bit tagged) | Heap-allocated (256-bit Montgomery) |
Int and Field are distinct types. Mixing them in arithmetic is a runtime error:
0p3 + 5 // Error: Cannot mix Int and Field0p3 + 0p5 // OK: 0p8Creating Field Elements
Section titled “Creating Field Elements”Use the 0p prefix to create field elements. It works like 0x for hex:
let a = 0p42 // decimal field literallet b = 0pxFF // hex field literal (0px prefix)let c = 0pb1010 // binary field literal (0pb prefix)let d = 0p12345 // large decimalArithmetic
Section titled “Arithmetic”Field elements support +, -, *, /, ^, and ==:
let a = 0p10let b = 0p3
let sum = a + b // 0p13let diff = a - b // 0p7let prod = a * b // 0p30let quot = a / b // modular inverse of 3, times 10let pow = a ^ 5 // 10^5 mod p
// Negative exponents compute modular inverselet inv = a ^ -1 // same as 0p1 / aIn Circuits
Section titled “In Circuits”In circuit mode (prove {} blocks and circuit CLI), all values are field elements implicitly. Integer variables captured by a prove {} block are converted to field elements automatically:
let x = 42prove(x: Public) { // x is automatically converted to 0p42 inside the circuit assert_eq(x, 42)}This is the only place where Int→Field conversion happens implicitly. In regular VM execution, the conversion must always be explicit via 0p field literals.