Uint256
zisklib 256-bit unsigned integer routines. Every value is a
[u64; 4] array in little-endian limb order. Each operation has the
familiar checked_ / wrapping_ / overflowing_ / saturating_
variants modulo 2^256, plus full division, exponentiation, and
modular arithmetic.
Overview
Fixed-width 256-bit unsigned integer operations. Each value is
[u64; 4] little-endian (limb 0 = LSB), matching EVM word layout and
the arith256 / arith256_mod precompiles. Each arithmetic operation
comes in up to four mode variants mirroring Rust's standard library:
checked_* returns None on overflow / division-by-zero,
overflowing_* returns the wrapped result plus an overflow flag,
wrapping_* discards overflow, and saturating_* clamps to MAX_256
or ZERO_256. For arbitrary-precision work see the lower-level
bigint module; uint256 is the fixed-width,
application-facing API with explicit overflow semantics.
Sections at a glance:
| Section | Provides | Depends on |
|---|---|---|
| Addition and subtraction | *_add256, *_sub256, *_neg256 in checked / overflowing / wrapping / saturating variants. | — |
| Multiplication and inversion | *_mul256, *_square256, inv256 (multiplicative inverse mod 2²⁵⁶). | — |
| Division and remainder | checked_div256 / checked_rem256, div_rem256, div_ceil256, wrapping_div256 / wrapping_rem256. | — |
| Modular arithmetic | reduce_mod256, add_mod256, mul_mod256, square_mod256, inv_mod256. | Multiplication, division |
| Exponentiation | checked_/overflowing_/wrapping_/saturating_pow256, pow_mod256. | Multiplication, modular |
Modular helpers (reduce_mod256, add_mod256, mul_mod256,
square_mod256, pow_mod256) silently return zero when modulus is
zero. Division by zero panics in the wrapping_ and div_rem forms;
use checked_div256 / checked_rem256 to avoid that.
Addition and subtraction
Linear 256-bit arithmetic: addition, subtraction, and negation
(equivalent to subtraction from zero). All three are available in
checked_, overflowing_, wrapping_, and saturating_ forms.
Overflow occurs when the true sum exceeds 2^256 - 1; underflow
occurs when a < b. Negation is exact only for a == 0 — every
other input wraps in two's-complement and is reported as overflow.
Computes a + b modulo 2^256. Returns None on overflow.
pub fn checked_add256(a: &[u64; 4], b: &[u64; 4]) -> Option<[u64; 4]>
Parameters
| Name | Type | Description |
|---|---|---|
a | &[u64; 4] | First addend. |
b | &[u64; 4] | Second addend. |
Returns
| Type | Description |
|---|---|
Option<[u64; 4]> | Some(a + b) if no overflow, None otherwise. |
Example
let sum = zisklib::checked_add256(&a, &b).expect("overflow");
Multiplication and inversion
Nonlinear 256-bit arithmetic: multiplication, squaring, and the
multiplicative inverse modulo 2^256. Multiplication and squaring
expose the full mode matrix (checked_, overflowing_,
wrapping_, saturating_); overflow means the full 512-bit product
has non-zero high limbs. \1 returns Some(x) such
that a · x ≡ 1 (mod 2^256), which exists if and only if a is
odd — even inputs (including zero) yield None.
Computes a · b modulo 2^256. Returns None if the full
512-bit product does not fit in 256 bits.
pub fn checked_mul256(a: &[u64; 4], b: &[u64; 4]) -> Option<[u64; 4]>
Parameters
| Name | Type | Description |
|---|---|---|
a | &[u64; 4] | First factor. |
b | &[u64; 4] | Second factor. |
Returns
| Type | Description |
|---|---|
Option<[u64; 4]> | Some(a · b) if no overflow, None otherwise. |
Example
let prod = zisklib::checked_mul256(&a, &b).expect("overflow");
Division and remainder
Euclidean division of 256-bit values: quotient, remainder, the
combined div_rem256 form, and a ceiling variant. The quotient and
remainder are hinted out of circuit and Euclid's lemma
(a = q·b + r, r < b) is verified in-circuit. Division by zero
behavior depends on the variant: checked_div256 and
checked_rem256 return None, while wrapping_div256,
wrapping_rem256, div_rem256, and div_ceil256 panic.
Computes a / b. Returns None when b == 0.
pub fn checked_div256(a: &[u64; 4], b: &[u64; 4]) -> Option<[u64; 4]>
Parameters
| Name | Type | Description |
|---|---|---|
a | &[u64; 4] | Dividend. |
b | &[u64; 4] | Divisor. |
Returns
| Type | Description |
|---|---|
Option<[u64; 4]> | Some(a / b) if b != 0, None otherwise. |
Example
let q = zisklib::checked_div256(&a, &b).expect("div by zero");
Modular arithmetic
Arithmetic over Z / modulusZ for a 256-bit modulus, dispatched
through the arith256_mod syscall: reduction, modular add, multiply,
square, and inversion. The modular add/mul/square/reduce helpers
silently return ZERO_256 when
modulus == 0 rather than panicking; \1
returns None when gcd(a, modulus) != 1 (no inverse exists).
These are the building blocks for ad-hoc prime-field arithmetic at
the 256-bit width.
Reduces a modulo modulus. Returns
ZERO_256 when modulus == 0.
pub fn reduce_mod256(a: &[u64; 4], modulus: &[u64; 4]) -> [u64; 4]
Parameters
| Name | Type | Description |
|---|---|---|
a | &[u64; 4] | Value to reduce. |
modulus | &[u64; 4] | Modulus. |
Returns
| Type | Description |
|---|---|
[u64; 4] | a mod modulus, or 0 when modulus == 0. |
Example
let r = zisklib::reduce_mod256(&a, &p);
Exponentiation
Repeated multiplication via left-to-right square-and-multiply over a
hinted binary decomposition of the exponent. The non-modular forms
(checked_pow256, overflowing_pow256, wrapping_pow256,
saturating_pow256) work modulo 2^256 with the usual overflow
semantics; \1 takes a
squaring-only fast path when exp is a power of two.
\1 is the modular variant and returns
ZERO_256 when modulus == 0.
Computes base^exp modulo 2^256. Returns None on overflow.
pub fn checked_pow256(
base: &[u64; 4],
exp: &[u64; 4],
) -> Option<[u64; 4]>
Parameters
| Name | Type | Description |
|---|---|---|
base | &[u64; 4] | Base. |
exp | &[u64; 4] | Exponent. |
Returns
| Type | Description |
|---|---|
Option<[u64; 4]> | Some(base^exp) if no overflow, None otherwise. |
Example
let p = zisklib::checked_pow256(&base, &exp).expect("overflow");