Field Arithmetic: M31 → CM31 → QM31
Deep dive into the Mersenne-31 field tower implementation in Solidity — M31 base field, CM31 complex extension, and QM31 quartic SecureField.
Overview
The Circle STARK verifier operates over a three-level algebraic extension tower built on the Mersenne-31 prime. This page covers the mathematical definitions, Solidity implementation details, packing conventions, and test vectors for each level.
All arithmetic is implemented in M31Lib.sol (311 lines).
1. M31 — The Base Field
Definition
This is the largest Mersenne prime that fits in 31 bits. Elements are integers in .
Why Mersenne-31?
Mersenne primes enable shift-based modular reduction. For any product (at most 62 bits):
Proof: Write . Then .
The result may be , requiring at most one subtraction. This is dramatically cheaper than general modular reduction.
Solidity Implementation
// M31 addition: single add + conditional subtract
function m31Add(uint32 a, uint32 b) internal pure returns (uint32) {
uint256 sum = uint256(a) + uint256(b);
if (sum >= P) sum -= P;
return uint32(sum);
}
// M31 multiplication: Mersenne reduction
function m31Mul(uint32 a, uint32 b) internal pure returns (uint32) {
uint256 product = uint256(a) * uint256(b);
uint256 lo = product & P; // low 31 bits
uint256 hi = product >> 31; // high bits
uint256 r = lo + hi;
if (r >= P) r -= P;
return uint32(r);
}
// M31 inversion via Fermat: a^(p-2) mod p
function m31Inv(uint32 a) internal pure returns (uint32) {
require(a != 0, "M31: division by zero");
return m31Exp(a, P - 2);
}Test Vectors
| Operation | Input | Result |
|---|---|---|
m31Add(P-1, 1) | ||
m31Add(P-1, P-1) | ||
m31Mul(2, 2) | ||
m31Mul(P-1, P-1) | ||
m31Inv(2) |
2. CM31 — Complex Extension
Definition
Elements are where and .
This is the Gaussian integers modulo . The polynomial is irreducible over because is a quadratic non-residue modulo (since ).
Packing Convention
CM31 is packed into uint64:
- Low 32 bits: real part ()
- High 32 bits: imaginary part ()
function cm31Pack(uint32 real, uint32 imag) internal pure returns (uint64) {
return uint64(real) | (uint64(imag) << 32);
}Arithmetic
Multiplication: Standard complex multiplication
4 M31 multiplications + 1 addition + 1 subtraction.
Conjugation: . Negates only the imaginary part.
Inversion: Uses the norm identity
cm31Neg vs cm31Conj
These are distinct operations:
cm31Neg(a + bi)= — negates both partscm31Conj(a + bi)= — negates only imaginary
This distinction is critical for QM31 complex conjugation (see Section 3).
3. QM31 — Quartic Extension (SecureField)
Definition
Elements are where (CM31) and .
QM31 is Stwo's SecureField — the field used for all random challenges, ensuring they are drawn from a space of size .
Packing Convention
QM31 is packed into uint128:
- Low 64 bits: first CM31 component ()
- High 64 bits: second CM31 component ()
Which expands to four M31 values:
- Bits [0..31]: (real part of )
- Bits [32..63]: (imaginary part of )
- Bits [64..95]: (real part of )
- Bits [96..127]: (imaginary part of )
Complex Conjugation
Bug Alert: Common Mistake
The initial implementation performed element-wise CM31 conjugation: . This is incorrect.
Stwo defines complex conjugation for QM31 as negating the entire second CM31:
For :
| Operation | Result | Description |
|---|---|---|
| QM31 conjugate (correct) | Negate entire second CM31 | |
| CM31 conjugate on each half (wrong) | Negate imaginary of each CM31 |
function _conjQ(uint128 q) internal pure returns (uint128) {
return M31Lib.qm31Pack(
M31Lib.qm31First(q), // Keep first CM31 unchanged
M31Lib.cm31Neg(M31Lib.qm31Second(q)) // Negate ENTIRE second CM31
);
}This matters because the complex conjugate appears in every DEEP quotient line equation — a wrong conjugate corrupts the entire FRI input.
4. Circle Point Arithmetic
Group Operation
The identity is . The generator is with .
Doubling (x-coordinate only)
For FRI line domains, only the x-coordinate after doubling is needed:
5. Gas Costs
| Operation | Gas | Notes |
|---|---|---|
| M31 add/sub | ~30 | Single conditional branch |
| M31 mul | ~50 | Mersenne reduction |
| M31 inv | ~4,000 | 31 iterations of square-and-multiply |
| CM31 mul | ~250 | 4 M31 muls + 2 M31 adds |
| CM31 inv | ~5,000 | 2 M31 muls + 1 M31 inv |
| QM31 mul | ~1,200 | 4 CM31 muls + CM31-by-R + 2 CM31 adds |
| QM31 inv | ~7,000 | 2 CM31 muls + 1 CM31 inv + 1 CM31 neg |
| Circle point add | ~300 | 4 M31 muls + 1 M31 add + 1 M31 sub |
| Circle scalar mul (31-bit) | ~10,000 | ~31 iterations of add + double |
QM31 multiplication is the dominant cost in the verifier — it appears in every quotient accumulation and every FRI fold.
From SNARKs to STARKs: Post-Quantum Privacy
Why UPP uses Circle STARKs for its post-quantum vault — which components are vulnerable to quantum attacks, and the migration phases.
Circle FRI Protocol
FRI verification adapted for circle-group domains — the folding scheme at the heart of the STARK verifier.