_tabs =
build_tables()
# ~1.5 s, certified exhaustively insideassert _tabs is not None, "table infeasible"
SLf, G0f, LEAF, SW, WP = _tabs
SMAX = max(max(SLf), 1)
# leaf_f indexes the leaves by the top 7 mantissa bits: the tree is full depth
assert all(depth == 7 for (depth, _p) in LEAF)
print(f"tables ok: leaves={len(LEAF)} SW={SW} WP={WP}")
⋯ 224 lines
b = Builder()
_r = declare_registers(
b, [(n, B_C) for n in ("rix", "riy", "riz", "rjx", "rjy", "rjz")] + [("k", M_K)]
)
RI = [_r["rix"], _r["riy"], _r["riz"]]
RJ = [_r["rjx"], _r["rjy"], _r["rjz"]]
KQ = _r["k"]
b.claim("ri", RI[0] + RI[1] + RI[2])
b.claim("rj", RJ[0] + RJ[1] + RJ[2])
b.claim("k", KQ)
⋯ 107 lines
_M0 = b.checkpoint() # forward-region start (everything until _MFWD mirrors)
Differences 45 Toffolis · peak 84 qubits
with b.phase("diffs/setup"):
SGN = [b.qubit() for _ in range(3)]
b.claim("sign", SGN)
for ax in range(3):
with b.phase(f"diffs/ax{ax}"):
riq = RI[ax]
rjq = RJ[ax]
sg = SGN[ax]
for q in riq:
b.x(q)
radd(riq, rjq, cout=sg)
for q in riq:
b.x(q)
for q in riq:
b.cx(sg, q)
radd(riq, [sg])
⋯ 62 lines
Squared distance 222 Toffolis · peak 123 qubits
with b.phase("squarer/a0g1"):
b.claim("n2", n2b) # all 18 wires exist once a0g1 has seeded the word
for _ax, _g, _cap in SQ_SCHED:
with b.phase(f"squarer/a{_ax}g{_g + 1}"):
emit_group(RI[_ax], SPECS[_g][
0], SPECS[_g][
1], _cap)
# ---- 3. normalize: iterative binary-search flags + staged cond. shifts ----
# z = 8*ereg[3] + 4*ereg[2] + 2*ereg[1] + ereg[0] is the left shift that
# brings the top set bit of n2 to bit 17; e = 17 - z. The shift is capped
# at 15 (= 8+4+2+1), enough for every n2 >= 4; n2 <= 3 under-shifts and is
# corrected by the tiny-n2 patch in stage 7. Each row's AND ladder
# flags that the current top s_amt bits of n2b are all zero, and one CX
# flips the row's ereg bit under the flag.
_MNORM = b.checkpoint()
Normalize 62 Toffolis · peak 105 qubits
with b.phase("normalize/setup"):
ereg = [b.qubit() for _ in range(4)]
b.claim("exp-flag", ereg)
# Shared arith.mcx would close the ladder with b.ccx(ladder, last,
# fq) — same s_amt-1 Toffoli, one fewer transient AND wire; this
# full-ladder + CX form is what the certified stream pins, and the
# extra wire is metric-free (normalize peaks at 105 of the 142 peak).
for s_amt, jz, lo, hi in NORM_ROWS:
with b.phase(f"normalize/z{s_amt}"):
flag, rec = and_ladder(b, [(n2b[17 - t], 0) for t in range(s_amt)])
b.cx(flag, ereg[jz])
and_ladder_release(b, rec)
for i in reversed(range(lo, hi)):
# operand order fixes the stream encoding (swap is
# semantically symmetric; the certified stream pins it)
b.cswap(ereg[jz], n2b[i], n2b[i + s_amt])
# ---- 4. adaptive QROM ----
_MQROM = b.checkpoint()
Line lookup 126 Toffolis · peak 129 qubits
with b.phase("qrom/setup"):
slope = [b.qubit() for _ in range(SW)]
sreg = [b.qubit() for _ in range(GLOW)]
b.claim("slope", slope)
b.claim("intercept", sreg)
addr_bits = [ereg[0]] + [n2b[16 - i] for i in range(A)]
# Early-terminating binary QROM over addr_bits = (e&1, top mantissa bits):
# each internal node costs one AND (Gidney) or one CX-pair (root); at a
# leaf, the intercept — msb stripped, it is implicit — and the slope are
# CX-copied onto sreg/slope under the path flag. Leaves sit exactly as
# shallow as build_tables' interval fitting allowed — under the R=6
# economics that is the full-depth 128-leaf tree.
# local: shared qrom.pruned_walk costs the same one AND per live
# internal node (126 on this 128-leaf tree) but roots on the bare address
# bit, clear child first; this root builds a CX-parity wire and takes
# the set-parity child first — the certified stream pins that order.
# The root parity wire is one extra transient, metric-free (qrom peaks
# below the 142 peak). The un-qrom repair walk reuses the same walker.
def walk(visit, flag, depth, prefix):
# visit(flag, depth, prefix) serves a leaf and returns True, or
# returns False to descend
if visit(flag, depth, prefix):
return
bq = addr_bits[depth]
ch = b.and_compute(flag, bq)
walk(visit, ch, depth + 1, 2 * prefix + 1)
b.cx(flag, ch)
walk(visit, ch, depth + 1, 2 * prefix)
b.cx(flag, ch)
b.and_release(ch, flag, bq)
def walk_root(visit, phase=None):
# phase names the sub-phases of the root's two children and close
b.x(ereg[0]) # address parity bit: e&1 = (17-z)&1 = NOT ereg[0]
rt = b.qubit()
b.claim("qrom-root", [rt])
b.cx(addr_bits[0], rt)
def sub(name):
return b.phase(f"{phase}/{name}") if phase else nullcontext()
with sub("parity1"):
walk(visit, rt, 1, 1)
b.x(rt)
with sub("parity0"):
walk(visit, rt, 1, 0)
b.x(rt)
with sub("close"):
b.cx(addr_bits[0], rt)
b.release_recycle("qrom-root", [rt])
b.x(ereg[0])
def load_leaf(flag, depth, prefix):
lf = LEAF.get((depth, prefix))
if lf is None:
return False
sl, g = lf
xor_word(b, flag, g - HBIT, sreg)
xor_word(b, flag, sl, slope)
return True
walk_root(load_leaf, "qrom")
# ---- 5. multiply: prod = sum_i rem_i * floor(slope*2^i/4) ----
# Row 0 lands as fresh ANDs onto the new product wires; rows 1..5 are
# in-place controlled adds (cadd). _acc tracks the maximum achievable
# running sum, proving each row's carry-out target is still zero when used.
_MMUL = b.checkpoint()
Slope product 78 Toffolis · peak 140 qubits
with b.phase("multiply/row0"):
rb0 = n2b[RL]
prod = [b.and_compute(rb0, q2) for q2 in slope[SH:]]
prod += [b.qubit() for _ in range(WP - len(prod))]
b.claim("product", prod)
_acc = (SMAX << 0) >> SH
for i in range(1, R):
with b.phase(f"multiply/row{i}"):
rb = n2b[RL + i]
sh = i - SH
if sh < 0:
avw = slope[-sh:]
pos = 0
else:
avw = slope
pos = sh
n = len(avw)
assert _acc < (1 << (pos + n)), "cout target not zero"
cout = prod[pos + n] if pos + n < WP else None
cadd(rb, avw, prod[pos : pos + n], cout)
_acc += (SMAX << i) >> SH
assert _acc < (1 << WP)
# ---- 6. gs_low -= prod (17-bit chunked complement subtract, no overall
# borrow); the chunk-borrow wire bq1 stays LIVE through the accumulate and
# the exact mirror erases it for free — an early erase would pay the
# borrow recompute twice, and lo8 pins the 142 peak either way ----
_MSUB = b.checkpoint()
Line value 16 Toffolis · peak 142 qubits
with b.phase("subtract/lo8"):
for j in range(GLOW):
b.x(sreg[j])
bq1 = b.qubit()
b.claim("borrow", [bq1])
radd(sreg[0:8], prod[0:8], cout=bq1)
with b.phase("subtract/hi9"):
radd(sreg[8:GLOW], prod[8:WP], cin=bq1)
with b.phase("subtract/restore"):
for j in range(GLOW):
b.x(sreg[j])
with b.phase("subtract/widen"):
sreg += [b.qubit() for _ in range(SREGW - GLOW - 1)]
b.claim("widen", sreg[GLOW:])
b.x(sreg[GW - 1])
# ---- 7. tiny-n2 patch (pre-shift): rewrite sreg from the deterministic
# leaf intercept G_v to Q_v. Flags are AND-allocated wires released by
# free measurement-based uncomputes. Discriminators (post-normalization,
# n2<=3 only): n2=1 -> n2b[15]=1,n2b[16]=0; n2=2 -> 0,1; n2=3 -> 1,1. ----
_MPATCH = b.checkpoint()
Small inputs 2 Toffolis · peak 142 qubits
with b.phase("patch"):
e4 = n2b[17]
b.x(e4)
t3f = b.and_compute(e4, n2b[15])
xor_word(b, t3f, XBc, sreg[:GW])
b.and_release(t3f, e4, n2b[15])
t3c = b.and_compute(e4, n2b[16])
xor_word(b, t3c, XCc, sreg[:GW])
b.and_release(t3c, e4, n2b[16])
xor_word(b, e4, XEc, sreg[:GW])
b.x(e4)
sreg.append(b.qubit())
b.claim("widen", [sreg[-1]])
assert len(sreg) == SREGW
# ---- 8. variable left shift ----
_MSHIFT = b.checkpoint()
for s_amt, jz, lim in SHIFT_ROWS:
Rescale 58 Toffolis · peak 142 qubits
with b.phase(f"shift/s{s_amt}"):
fq = ereg[jz]
for p in reversed(range(lim)):
# operands (lo, hi) — normalize's rows pass (hi, lo); the two
# stream encodings differ deliberately, the semantics do not
b.cswap(fq, sreg[p + s_amt], sreg[p])
_MFWD = b.checkpoint() # forward-region end; the accumulate is not mirrored
# ---- 9. accumulate into k (not mirrored) ----
# DELTA = round(sreg / 4): sreg[2:] is the integer part, sreg[1] enters as
# the carry-in (round-to-nearest) — this is the /4-with-round of delta_of.
# The b.x(n2b[17]) sandwich adds 2^23 exactly when the top mantissa bit is
# CLEAR, i.e. on the under-normalized tiny-n2 (n2 <= 3) branch.
Add to k 48 Toffolis · peak 142 qubits
with b.phase("accumulate"):
b.x(n2b[17])
# cin = sreg[1] is a LIVE data wire: add()'s MAJ seed carries cin's
# value (added, then UMA-restored) — that is the advertised
# round-to-nearest. The gadget docstring's |0> carry-in wording is its
# zero-ancilla corner, not a precondition here.
cdkm_add_co(b, sreg[2:25] + [n2b[17]], KQ[0:24], KQ[24], sreg[1])
b.x(n2b[17])
# ---- mirror: the conjugation F . accumulate . F^-1 ----
# Segment mirrors, one per forward stage in reverse order, emit the exact
# Bennett inverse of every forward stage EXCEPT the QROM: the un-qrom
# segment below erases the table words by X-basis demolition and repays
# the phase with one floored repair walk, so the second tree walk the
# mirror would re-bill never runs. The segmentation carries the
# ownership discipline: each set releases just before the segment whose
# frees consume its wires, so release precedes free through the whole
# teardown. Each b.phase block names one teardown step and opens before
# its releases (emits no op), so the releases and the segment's tail
# frees attribute to the un-* phase rather than to accumulate; the
# reflected sub-phase labels come from each segment's own marks.
Rescale reversed 58 Toffolis · peak 142 qubits
with b.phase("un-shift"):
b.mirror(_MSHIFT, until=_MFWD) # frees nothing
Patch reversed 2 Toffolis · peak 142 qubits
with b.phase("un-patch"):
b.release("widen", [sreg[SREGW - 1]])
b.mirror(_MPATCH, until=_MSHIFT) # frees the patch widen wire
Line value reversed 16 Toffolis · peak 142 qubits
with b.phase("un-subtract"):
b.release("widen", sreg[GLOW : SREGW - 1])
b.release("borrow", [bq1])
b.mirror(_MSUB, until=_MPATCH) # frees bq1 + widen wires
Product reversed 73 Toffolis · peak 140 qubits
with b.phase("un-multiply"):
b.release("product", prod)
b.mirror(_MMUL, until=_MSUB) # releases/frees prod
# ---- un-qrom: measurement-based unlookup + floored phase-repair walk ----
# After un-multiply the slope/intercept wires hold exactly the looked-up
# table words again — a pure function of the address bits, all still
# live. Each X-basis demolition (hmr) is free, forces its wire to |0>,
# and leaves the shot's sign multiplied by (-1)^<outcomes, word(addr)>;
# the walk below repays that mask, so clearing the words costs 17
# Toffoli instead of the mirror's second 126-AND tree walk. Frees run
# in reverse alloc order — the LIFO free-list state the later mirrors
# assert is exactly the one the mirrored unlookup would have left.
Lookup erased 17 Toffolis · peak 122 qubits
with b.phase("un-qrom/measure"):
b.release("intercept", sreg[:GLOW])
b.release("slope", slope)
m_sreg = [None] * GLOW
m_slope = [None] * SW
for j in reversed(range(GLOW)):
m_sreg[j] = b.hmr(sreg[j])
b.recycle(sreg[j])
for j in reversed(range(SW)):
m_slope[j] = b.hmr(slope[j])
b.recycle(slope[j])
# Per-flag repair coefficients in the monomial (Reed-Muller) basis.
# word(f) packs the 24 measured table bits of leaf f; W(p, S) XORs the
# words over the low-nibble subcube v <= S, so the phase to repay at
# flag p factors as sum_S <outcomes, W(p, S)> * mono_S(low bits).
# The Mobius transform runs on the classical table at build time, and
# the runtime coefficients stay plain outcome XOR chains (free OXORs;
# None = zero mask, nothing to repay). Nibble bit FL_M-1-t of v and
# of S corresponds to low[t], matching the walk's msb-first prefixes.
FL_M = 4 # low address bits served by monomials
FL_D = 7 - FL_M # repair-walk depth (high address bits)
low = addr_bits[FL_D:]
def word(f):
return (G0f[f] - HBIT) | (SLf[f] << GLOW)
def gamma(p, S):
w = 0
for v in range(1 << FL_M):
if v & ~S == 0:
w ^= word((p << FL_M) | v)
ms = [m_sreg[j] for j in range(GLOW) if (w >> j) & 1]
ms += [m_slope[j] for j in range(SW) if (w >> (GLOW + j)) & 1]
acc = None
for m2 in ms:
acc = m2 if acc is None else acc ^ m2
return acc
GAM = [[gamma(p, S) for S in range(1 << FL_M)] for p in range(1 << FL_D)]
# Monomial bank over the FL_M low address bits (m[14..11]): one AND
# wire per product of two or more bits — six pairs, four triples (a
# pair wire AND one more bit), one quad — 11 Toffoli. Singleton
# monomials are the address wires themselves and the bank floors the
# repair walk: leaves below depth FL_D are served entirely by free
# conditioned phase gates, so repair cost stops growing with leaf
# count — the economics the R=6 refit banks on.
with b.phase("un-qrom/monomials"):
def smask(ts): # subset of low-bit indices -> nibble-style mask
v = 0
for t in ts:
v |= 1 << (FL_M - 1 - t)
return v
MONO = {}
MORDER = []
for ts in (
(0, 1),
(0, 2),
(0, 3),
(1, 2),
(1, 3),
(2, 3),
(0, 1, 2),
(0, 1, 3),
(0, 2, 3),
(1, 2, 3),
(0, 1, 2, 3),
):
base = MONO[smask(ts[:-1])] if len(ts) > 2 else low[ts[0]]
w = b.and_compute(base, low[ts[-1]])
MONO[smask(ts)] = w
MORDER.append((w, base, low[ts[-1]]))
# Floored repair walk: path ANDs over the three high address bits only
# (2 + 4 = 6); at each depth-3 flag the sixteen Reed-Muller
# coefficients condition free phase gates — Z on the flag for S = 0,
# CZ against a bare low address wire or a bank monomial otherwise.
# 6 + 11 = 17 Toffoli repays the whole unlookup. The forward walker
# runs it, so the root CX-parity trick and child order match.
with b.phase("un-qrom/fix"):
def repair_leaf(flag, depth, prefix):
if depth != FL_D:
return False
g = GAM[prefix]
if g[0] is not None:
b.z(flag, cond=g[0])
for S in range(1, 1 << FL_M):
if g[S] is None:
continue
if S & (S - 1) == 0:
b.cz(flag, low[FL_M - S.bit_length()], cond=g[S])
else:
b.cz(flag, MONO[S], cond=g[S])
return True
walk_root(repair_leaf)
# Unwind the monomial bank: free measurement-based releases in exact
# reverse alloc order (bases outlive their products), restoring the
# free-list for the mirrors below.
with b.phase("un-qrom/close"):
for w, c1, c2 in reversed(MORDER):
b.and_release(w, c1, c2)
Normalize reversed 62 Toffolis · peak 105 qubits
with b.phase("un-normalize"):
b.release("exp-flag", ereg)
b.mirror(_MNORM, until=_MQROM) # frees ereg
Squares reversed 210 Toffolis · peak 123 qubits
with b.phase("un-squarer"):
b.release("n2", n2b)
b.mirror(_MSQ, until=_MNORM) # releases/frees n2
Differences reversed 45 Toffolis · peak 84 qubits
with b.phase("un-diffs"):
b.release("sign", SGN)
b.mirror(_M0, until=_MSQ) # frees the sign wires
return b, RI, RJ, KQ, n2b