Skip to main content
Version: 0.15 (unstable)

Unsigned 128-bit integer operations

Module miden::core::math::u128 contains a set of procedures which can be used to perform unsigned 128-bit integer operations. These operations fall into the following categories:

  • Arithmetic operations - addition, subtraction, multiplication, division.
  • Comparison operations - equality, less than, greater than etc.
  • Bitwise operations - binary AND, OR, XOR, NOT, bit shifts and rotations, leading/trailing zero/one counts.

When placed on the stack, a 128-bit integer is encoded using four 32-bit limbs (elements) in little-endian limb order: the least-significant limb is on top of the stack. For example, a u128 value a with limbs a0..a3 would be positioned on the stack like so:

[a0, a1, a2, a3, ...]

where a0 is the least-significant 32-bit limb and a3 is the most significant.

The procedures in this module assume that the input values are represented using valid 32-bit limbs, but this is not checked. Using invalid inputs may produce undefined results.

Arithmetic operations

ProcedureDescription
wrapping_addPerforms addition of two unsigned 128-bit integers discarding the overflow.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, ...]
where c = (a + b) % 2^128
overflowing_addPerforms addition of two unsigned 128-bit integers preserving the overflow.

Stack transition: [b0..b3, a0..a3, ...] -> [overflow, c0..c3, ...]
where c = (a + b) % 2^128
widening_addPerforms addition of two unsigned 128-bit integers preserving the overflow with sum on top.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, overflow, ...]
where c = (a + b) % 2^128
wrapping_subPerforms subtraction of two unsigned 128-bit integers discarding the underflow.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, ...]
where c = (a - b) % 2^128
overflowing_subPerforms subtraction of two unsigned 128-bit integers preserving the underflow.

Stack transition: [b0..b3, a0..a3, ...] -> [underflow, c0..c3, ...]
where c = (a - b) % 2^128
wrapping_mulPerforms multiplication of two unsigned 128-bit integers discarding the overflow.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, ...]
where c = (a * b) % 2^128
overflowing_mulPerforms multiplication of two unsigned 128-bit integers preserving the overflow.

Stack transition: [b0..b3, a0..a3, ...] -> [overflow, c0..c3, ...]
where c = (a * b) % 2^128
widening_mulPerforms multiplication of two unsigned 128-bit integers preserving the overflow with sum on top.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, overflow, ...]
where c = (a * b) % 2^128
divPerforms division of two unsigned 128-bit integers discarding the remainder.

Stack transition: [b0..b3, a0..a3, ...] -> [q0..q3, ...]
where q = a / b. Fails if b = 0.
modPerforms modulo operation of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [r0..r3, ...]
where r = a % b. Fails if b = 0.
divmodPerforms divmod operation of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [r0..r3, q0..q3, ...]
where q = a / b, r = a % b. Fails if b = 0.

Comparison operations

ProcedureDescription
eqPerforms equality comparison of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c, ...]
where c = 1 when a == b, and 0 otherwise.
neqPerforms inequality comparison of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c, ...]
where c = 1 when a != b, and 0 otherwise.
eqzChecks if an unsigned 128-bit integer equals zero.

Stack transition: [a0..a3, ...] -> [c, ...]
where c = 1 when a == 0, and 0 otherwise.
ltPerforms less-than comparison of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c, ...]
where c = 1 when a < b, and 0 otherwise.
gtPerforms greater-than comparison of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c, ...]
where c = 1 when a > b, and 0 otherwise.
ltePerforms less-than-or-equal comparison of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c, ...]
where c = 1 when a <= b, and 0 otherwise.
gtePerforms greater-than-or-equal comparison of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c, ...]
where c = 1 when a >= b, and 0 otherwise.
minComputes the minimum of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, ...]
where c = min(a, b).
maxComputes the maximum of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, ...]
where c = max(a, b).

Bitwise operations

ProcedureDescription
andPerforms bitwise AND of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, ...]
where c = a AND b
orPerforms bitwise OR of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, ...]
where c = a OR b
xorPerforms bitwise XOR of two unsigned 128-bit integers.

Stack transition: [b0..b3, a0..a3, ...] -> [c0..c3, ...]
where c = a XOR b
notPerforms bitwise NOT of an unsigned 128-bit integer.

Stack transition: [a0..a3, ...] -> [c0..c3, ...]
where c = NOT(a)
shlPerforms left shift of one unsigned 128-bit integer. The shift amount n must be in the range [0, 128), otherwise it will result in an error.

Stack transition: [n, a0..a3, ...] -> [c0..c3, ...]
where c = (a << n) mod 2^128
shrPerforms right shift of one unsigned 128-bit integer. The shift amount n must be in the range [0, 128), otherwise it will result in an error.

Stack transition: [n, a0..a3, ...] -> [c0..c3, ...]
where c = a >> n
rotlPerforms left rotation of one unsigned 128-bit integer. The rotation amount n must be in the range [0, 128), otherwise it will result in an error.

Stack transition: [n, a0..a3, ...] -> [c0..c3, ...]
where c = a rotated left by n bits.
rotrPerforms right rotation of one unsigned 128-bit integer. The rotation amount n must be in the range [0, 128), otherwise it will result in an error.

Stack transition: [n, a0..a3, ...] -> [c0..c3, ...]
where c = a rotated right by n bits.
clzCounts the number of leading zeros of an unsigned 128-bit integer.

Stack transition: [a0..a3, ...] -> [count, ...]
where count is the number of leading zero bits in a (0..=128).
ctzCounts the number of trailing zeros of an unsigned 128-bit integer.

Stack transition: [a0..a3, ...] -> [count, ...]
where count is the number of trailing zero bits in a (0..=128).
cloCounts the number of leading ones of an unsigned 128-bit integer.

Stack transition: [a0..a3, ...] -> [count, ...]
where count is the number of leading one bits in a (0..=128).
ctoCounts the number of trailing ones of an unsigned 128-bit integer.

Stack transition: [a0..a3, ...] -> [count, ...]
where count is the number of trailing one bits in a (0..=128).