Carry-Save Step Definition #
One iteration of carry-save shift-and-add multiplication. Models PicoRV32 pcpi_mul with CARRY_CHAIN=0 (pure carry-save).
Equations
- One or more equations did not get rendered due to their size.
Instances For
N iterations of carry-save shift-and-add.
Equations
Instances For
Core Lemma: Carry-Save Addition Identity #
For any three bitvectors a, b, c: (a ^^^ b ^^^ c) + (((a &&& b) ||| (a &&& c) ||| (b &&& c)) <<< 1) = a + b + c
This is the fundamental property of carry-save adders: XOR computes the sum bits, majority computes the carry bits, and shifting the carry left by 1 propagates it to the next bit position.
Concrete Correctness Verification #
We verify the carry-save algorithm produces correct results for specific test vectors using native_decide. These cover all MUL variants used by the MulOracle and serve as regression tests.
7 * 6 = 42
100 * 100 = 10000
12345 * 6789 = 83810205
0 * x = 0
x * 0 = 0
1 * 1 = 1
Factorial: 362880 * 10 = 3628800
Large: 0xFFFF * 0xFFFF = 0xFFFE0001
Power of 2: 256 * 256 = 65536
Asymmetric: 1 * 0xFFFFFFFF
Large product: 0xFFFFFFFF * 2
Parametric Proof: Carry-Save Addition = True Addition #
The carry-save identity holds for all bit widths. We prove it parametrically using the fact that for each bit position i: xor(a[i], b[i], c[i]) = (a[i] + b[i] + c[i]) mod 2 majority(a[i], b[i], c[i]) = (a[i] + b[i] + c[i]) / 2
The carry propagation via left-shift gives us a ripple-add.
Full adder identity at the bit level: For single bits, xor is sum and majority is carry.
Loop Invariant and Main Theorem #
The main correctness theorem states that after n steps of carry-save shift-and-add starting from (0, 0, rs1, rs2):
rd + rdx = (lower n bits of rs1) * rs2
We prove this by induction, using carrySave_add_eq at each step.
After one step: rd' + rdx' = rd + rdx + partial_product. This holds because carry-save addition preserves the sum.
Small-width carry-save equals multiplication (4-bit, 2 steps). Proves the full equivalence for small inputs via bv_decide.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Oracle correctness: for 32-bit unsigned multiply, carrySaveN 32 matches direct multiplication. Verified by concrete examples; parametric proof depends on carrySave_add_eq_64 + induction (WIP).