;;; mod-arith.lsp — reversible modular arithmetic over a generic prime.
;;;
;;; Public surface: bit-set?, load-const!, unload-const!, cload-const!,
;;; cunload-const!, add-const!, csub-const!, inv-maj!, cmp-lt-into!,
;;; mod-add!, mod-sub!, mod-mul!, mod-double-inplace!, mod-halve-inplace!,
;;; mod-shift-left/right-by-k-lowq!, mod-add-qb!, mod-sub-qb!. Layer
;;; sits on adder.lsp (Cuccaro ripple-carry).
;;;
;;; mod-add CALLING CONVENTION: caller passes a-reg & acc-reg as
;;; (n+1)-wide registers, top bit held at |0> (extension ancilla).
;;; Caller also allocates cin (1 bit), tmp (n+1 bits), flag (1 bit).
;;; All ancillae return to |0>; top bit of a-reg & acc-reg also returns
;;; to |0> on exit.
;;;
;;; ── *field-prime* convention ─────────────────────────────────────
;;;
;;; Primitives take `p` as explicit argument (p = field prime, integer).
;;; New upstream consumers can ALSO set `*field-prime*` at program top
;;; so layer code reads a single source of truth & avoids threading p
;;; through every wrapper. Foxhop callers still pass p directly.
;;;
;;; Public mod-* primitives assert *field-prime* matches their `p` arg
;;; if both are set, otherwise accept caller's `p` as authoritative.

(define *field-prime* #f)
;; Consumer binds via (set! *field-prime* <p>) before calling mod-arith
;; primitives. Stays #f when not used; primitives derive width from
;; (bit-length p) or accept width via caller arg.

(load "quantum/gates.lsp")
(load "quantum/adder.lsp")

;;; ── classical-constant load/unload ─────────────────────────────

(define (bit-set? k i)
  "Is bit i (0-indexed) set in classical integer k?"
  (= 1 (remainder (quotient k (expt 2 i)) 2)))

(define (load-const! c reg n k)
  "Apply X to reg[i] for every i in [0,n) where bit i of k is 1.
   reg starts |0> n-wide; ends holding the bit pattern of k mod 2^n."
  (let loop ((i 0))
    (when (< i n)
      (when (bit-set? k i) (gate-x! c reg i))
      (loop (+ i 1)))))

(define (unload-const! c reg n k) (load-const! c reg n k))

(define (cload-const! c ctrl-reg ctrl-idx tgt-reg n k)
  "Apply CX(ctrl, tgt[i]) for every i where bit i of k is 1."
  (let loop ((i 0))
    (when (< i n)
      (when (bit-set? k i) (gate-cx! c ctrl-reg ctrl-idx tgt-reg i))
      (loop (+ i 1)))))

(define (cunload-const! c ctrl-reg ctrl-idx tgt-reg n k)
  (cload-const! c ctrl-reg ctrl-idx tgt-reg n k))

;;; ── extcarry_clean family — sweep-extcarry-clean ──────────────────
;;;
;;; HEAD const_arith.rs:239,251,274,289,317,331. Closes AUDIT §6
;;; rows 208-212.
;;;
;;; Pattern (HEAD lines 257-269 + symmetric): each primitive
;;;   1. load const c into `ca` register (cx-from-ctrl for controlled
;;;      variants, x for uncontrolled)
;;;   2. cuccaro-add/sub-low-to-ext-clean! with cin
;;;   3. unload (same op-stream self-inverse)
;;;
;;; HEAD's `borrow_cin: Option<QubitId>` switches between caller-
;;; supplied vs fresh-alloc cin. Lumbda is caller-allocated throughout;
;;; cin-reg + cin-idx are mandatory caller-supplied parameters. The
;;; six HEAD names collapse to a smaller surface in lumbda but we keep
;;; all six for ABI parity — callers may want to name the "borrow"
;;; variant explicitly even though the wire pattern is identical.
;;;
;;; Caller responsibility:
;;;   - acc-ext-reg width >= n+1 (n data bits + 1 ext carry bit)
;;;   - ca-reg width >= n (clean |0> on entry; restored on exit)
;;;   - cin-reg[cin-idx] = |0> on entry; restored on exit
;;;   - ctrl-reg[ctrl-idx] (controlled variants) — read-only

(define (add-nbit-const-extcarry-clean!
          c acc-ext-reg n k ca-reg cin-reg cin-idx)
  "Port of HEAD add_nbit_const_extcarry_clean (const_arith.rs:239).
   acc-ext-reg := (acc-ext-reg + k) mod 2^(n+1), carry into top bit."
  (load-const! c ca-reg n k)
  (cuccaro-add-low-to-ext-clean! c ca-reg acc-ext-reg n cin-reg cin-idx)
  (unload-const! c ca-reg n k))

(define (add-nbit-const-extcarry-clean-with-cin!
          c acc-ext-reg n k ca-reg cin-reg cin-idx)
  "Port of HEAD add_nbit_const_extcarry_clean_with_cin
   (const_arith.rs:251). Wire-identical to the non-with-cin variant
   in lumbda since cin is always caller-supplied; preserves HEAD's
   ABI name for callers that explicitly borrow cin from a live-idle
   lane (round84-lowq mid-sub uses this naming)."
  (add-nbit-const-extcarry-clean!
    c acc-ext-reg n k ca-reg cin-reg cin-idx))

(define (sub-nbit-const-extcarry-clean!
          c acc-ext-reg n k ca-reg cin-reg cin-idx)
  "Port of HEAD sub_nbit_const_extcarry_clean (const_arith.rs:274).
   acc-ext-reg := (acc-ext-reg - k) mod 2^(n+1), borrow into top bit."
  (load-const! c ca-reg n k)
  (cuccaro-sub-low-to-ext-clean! c ca-reg acc-ext-reg n cin-reg cin-idx)
  (unload-const! c ca-reg n k))

(define (cadd-nbit-const-extcarry-clean!
          c acc-ext-reg n k ctrl-reg ctrl-idx ca-reg cin-reg cin-idx)
  "Port of HEAD cadd_nbit_const_extcarry_clean (const_arith.rs:289).
   acc-ext-reg += (ctrl ? k : 0), carry into top bit. Drop-in for
   cadd-nbit-const. Constant loaded via CX-from-ctrl so the
   unconditional clean adder realizes the controlled add."
  (cload-const! c ctrl-reg ctrl-idx ca-reg n k)
  (cuccaro-add-low-to-ext-clean! c ca-reg acc-ext-reg n cin-reg cin-idx)
  (cunload-const! c ctrl-reg ctrl-idx ca-reg n k))

(define (csub-nbit-const-extcarry-clean!
          c acc-ext-reg n k ctrl-reg ctrl-idx ca-reg cin-reg cin-idx)
  "Port of HEAD csub_nbit_const_extcarry_clean (const_arith.rs:317).
   acc-ext-reg -= (ctrl ? k : 0), borrow into top bit."
  (cload-const! c ctrl-reg ctrl-idx ca-reg n k)
  (cuccaro-sub-low-to-ext-clean! c ca-reg acc-ext-reg n cin-reg cin-idx)
  (cunload-const! c ctrl-reg ctrl-idx ca-reg n k))

(define (csub-nbit-const-extcarry-clean-with-cin!
          c acc-ext-reg n k ctrl-reg ctrl-idx ca-reg cin-reg cin-idx)
  "Port of HEAD csub_nbit_const_extcarry_clean_with_cin
   (const_arith.rs:331). Wire-identical to csub-nbit-const-extcarry-
   clean! in lumbda; ABI alias for explicit-borrow callers (the
   peak-binding round84-lowq mid-sub borrows c_in from idle a_ovf
   lane to drop peak 1308 -> 1307)."
  (csub-nbit-const-extcarry-clean!
    c acc-ext-reg n k ctrl-reg ctrl-idx ca-reg cin-reg cin-idx))

;;; ── add/sub of classical constant ──────────────────────────────

(define (add-const! c acc-reg n k cin-reg cin-idx tmp-reg)
  "acc := (acc + k) mod 2^n. tmp must be a width-n register at |0>."
  (let ((kk (modulo k (expt 2 n))))
    (load-const!   c tmp-reg n kk)
    (cuccaro-add!  c tmp-reg acc-reg cin-reg cin-idx n)
    (unload-const! c tmp-reg n kk)))

(define (csub-const! c acc-reg n k ctrl-reg ctrl-idx cin-reg cin-idx tmp-reg)
  "acc -= (ctrl ? k : 0) mod 2^n. Dispatches to direct sparse path when
   *cadd-direct-trunc-fast* on; else cload + cuccaro-sub + cunload."
  (let ((kk (modulo k (expt 2 n))))
    (cond
      ((and *cadd-direct-trunc-fast* (> n 1) (> kk 0))
       (csub-nbit-const-direct-trunc-fast!
         c acc-reg n kk ctrl-reg ctrl-idx tmp-reg
         *cadd-direct-window* (cdtf-alloc-bit-base! n)))
      (else
       (cload-const!  c ctrl-reg ctrl-idx tmp-reg n kk)
       ;; sub = inverse of add. cuccaro-add (a, acc) is a bijection; we
       ;; manually invert by emitting the gates in reverse. Implemented as
       ;; cuccaro-sub! below.
       (cuccaro-sub!  c tmp-reg acc-reg cin-reg cin-idx n)
       (cunload-const! c ctrl-reg ctrl-idx tmp-reg n kk)))))

;;; ── Cuccaro sub (inverse of cuccaro-add) ───────────────────────

(define (cuccaro-sub! c a-reg acc-reg cin-reg cin-idx n)
  "acc := (acc - a) mod 2^n. Inverse of cuccaro-add gate-by-gate."
  (cond
    ((= n 0) #t)
    ((= n 1)
     (gate-cx! c a-reg   0       acc-reg 0)
     (gate-cx! c cin-reg cin-idx acc-reg 0))
    (else
     ;; Inverse of cuccaro-add:
     ;;   inv-uma at i=0
     ;;   inv-uma for i in 1..n-2
     ;;   inv of final CX pair (cx is its own inverse, so same gates reversed)
     ;;   inv-maj for i in n-2..1 (descending in fwd; so ascending in inv)
     ;;   inv-maj at top (c-in,acc[0],a[0])
     ;;
     ;; UMA(x,y,w): (ccx x y w)(cx w x)(cx x y)
     ;; inv-UMA = (cx x y)(cx w x)(ccx x y w)
     ;; MAJ(x,y,w): (cx w y)(cx w x)(ccx x y w)
     ;; inv-MAJ = (ccx x y w)(cx w x)(cx w y)
     ;;
     ;; Walking forward gates in reverse order:
     ;;   final uma(cin,acc[0],a[0])              -> inv-uma at start
     ;;   for i in 1..n-2 (forward order in inverse: that's the rev loop)
     ;;     uma(a[i-1], acc[i], a[i])
     ;;   reverse of "cx a[n-1] acc[n-1]; cx a[n-2] acc[n-1]" is same two CX
     ;;   reverse of MAJ sweep
     (inv-uma! c cin-reg cin-idx acc-reg 0 a-reg 0)
     (let loop ((i 1))
       (when (< i (- n 1))
         (inv-uma! c a-reg (- i 1) acc-reg i a-reg i)
         (loop (+ i 1))))
     (gate-cx! c a-reg (- n 1) acc-reg (- n 1))
     (gate-cx! c a-reg (- n 2) acc-reg (- n 1))
     (let loop ((i (- n 2)))
       (when (>= i 1)
         (inv-maj! c a-reg (- i 1) acc-reg i a-reg i)
         (loop (- i 1))))
     (inv-maj! c cin-reg cin-idx acc-reg 0 a-reg 0))))

(define (inv-uma! c x-reg x-idx y-reg y-idx w-reg w-idx)
  "Inverse of uma!: (cx x y) (cx w x) (ccx x y w)."
  (gate-cx!  c x-reg x-idx y-reg y-idx)
  (gate-cx!  c w-reg w-idx x-reg x-idx)
  (gate-ccx! c x-reg x-idx y-reg y-idx w-reg w-idx))

(define (inv-maj! c x-reg x-idx y-reg y-idx w-reg w-idx)
  "Inverse of maj!: (ccx x y w) (cx w x) (cx w y)."
  (gate-ccx! c x-reg x-idx y-reg y-idx w-reg w-idx)
  (gate-cx!  c w-reg w-idx x-reg x-idx)
  (gate-cx!  c w-reg w-idx y-reg y-idx))

;;; ── n-bit comparison: flag := flag XOR (u < v) ─────────────────

(define (cmp-lt-into! c u-reg v-reg n flag-reg flag-idx cin-reg cin-idx)
  "flag ^= (u < v). u and v are width-n quantum registers; restored.
   cin starts |0> ends |0>."
  ;; Negate u
  (let loop ((i 0))
    (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
  ;; Forward MAJ sweep — n MAJs (includes the top one)
  (maj! c cin-reg cin-idx v-reg 0 u-reg 0)
  (let loop ((i 1))
    (when (< i n)
      (maj! c u-reg (- i 1) v-reg i u-reg i)
      (loop (+ i 1))))
  ;; CX top -> flag
  (gate-cx! c u-reg (- n 1) flag-reg flag-idx)
  ;; Inverse MAJ sweep
  (let loop ((i (- n 1)))
    (when (>= i 1)
      (inv-maj! c u-reg (- i 1) v-reg i u-reg i)
      (loop (- i 1))))
  (inv-maj! c cin-reg cin-idx v-reg 0 u-reg 0)
  ;; Un-negate u
  (let loop ((i 0))
    (when (< i n) (gate-x! c u-reg i) (loop (+ i 1)))))

;;; cmp-lt-into-fast! — HEAD's cmp_lt_into_fast (mod.rs:3643-3693)
;;; HMR-uncompute variant of cmp-lt-into!. Same flag semantics but
;;; carries lane borrowed from caller + HMR backward sweep saves n
;;; Toffoli per call.

(define (cmp-lt-into-fast! c u-reg v-reg n flag-reg flag-idx cin-reg cin-idx
                           carries-reg carries-offset bit-base)
  "flag ^= (u < v). Same semantics as cmp-lt-into! but with HMR carry
   uncompute. carries-reg[carries-offset..carries-offset+n-1] must be
   |0> on entry; HMR returns them to |0> on exit.
   bit-base..bit-base+n-1 used for classical bits."
  (cond
    ((= n 0) #t)
    (else
     ;; Negate u
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
     ;; Forward sweep — n MAJ-style with explicit carries
     (gate-cx!  c u-reg 0 v-reg 0)
     (gate-cx!  c u-reg 0 cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx v-reg 0 carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset u-reg 0)
     (let loop ((i 1))
       (when (< i n)
         (gate-cx!  c u-reg i v-reg i)
         (gate-cx!  c u-reg i u-reg (- i 1))
         (gate-ccx! c u-reg (- i 1) v-reg i carries-reg (+ carries-offset i))
         (gate-cx!  c carries-reg (+ carries-offset i) u-reg i)
         (loop (+ i 1))))
     ;; CX top carry -> flag
     (gate-cx! c u-reg (- n 1) flag-reg flag-idx)
     ;; Backward HMR uncompute sweep
     (let loop-back ((i (- n 1)))
       (when (>= i 1)
         (gate-cx!         c carries-reg (+ carries-offset i) u-reg i)
         (gate-hmr!        c carries-reg (+ carries-offset i) (+ bit-base i))
         (gate-push-cond!  c (+ bit-base i))
         (gate-cz!         c u-reg (- i 1) v-reg i)
         (gate-pop-cond!   c)
         (gate-cx!         c u-reg i u-reg (- i 1))
         (gate-cx!         c u-reg i v-reg i)
         (loop-back (- i 1))))
     ;; Step 0 backward
     (gate-cx!         c carries-reg carries-offset u-reg 0)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx v-reg 0)
     (gate-pop-cond!   c)
     (gate-cx!         c u-reg 0 cin-reg cin-idx)
     (gate-cx!         c u-reg 0 v-reg 0)
     ;; Un-negate u
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg i) (loop (+ i 1)))))))

;;; ── ccx-cmp-lt-into-fast! / cmp-lt-into-fast-with-cin! / phase-conditioned variants
;;;
;;; HEAD compare.rs:55,108,330,357. Closes AUDIT §7 rows 184-185 + 186-187
;;; (compare.rs no-prefix-targets siblings).
;;;
;;; ──── cmp-lt-into-fast-with-cin! — ABI alias ────
;;; HEAD's cmp_lt_into_fast_with_cin (compare.rs:55) is wire-identical
;;; to cmp_lt_into_fast except c_in is caller-supplied instead of
;;; freshly-allocated. Lumbda's cmp-lt-into-fast! is ALREADY the
;;; with-cin form (caller passes cin-reg + cin-idx). This alias names
;;; the variant for callers that explicitly borrow c_in from a live-
;;; idle lane.

(define (cmp-lt-into-fast-with-cin!
          c u-reg v-reg n flag-reg flag-idx cin-reg cin-idx
          carries-reg carries-offset bit-base)
  "Port of HEAD cmp_lt_into_fast_with_cin (compare.rs:55). Wire-
   identical to cmp-lt-into-fast! in lumbda; ABI alias for explicit-
   borrow callers."
  (cmp-lt-into-fast!
    c u-reg v-reg n flag-reg flag-idx cin-reg cin-idx
    carries-reg carries-offset bit-base))

;;; ──── ccx-cmp-lt-into-fast! — without prefix-targets ────
;;; HEAD compare.rs:108. Identical to cmp_lt_into_fast but replaces
;;; cx(u[n-1], flag) with ccx(ctrl, u[n-1], target). All other gates
;;; mirror cmp-lt-into-fast! verbatim.

(define (ccx-cmp-lt-into-fast!
          c u-reg v-reg n ctrl-reg ctrl-idx target-reg target-idx
          cin-reg cin-idx carries-reg carries-offset bit-base)
  "Port of HEAD ccx_cmp_lt_into_fast (compare.rs:108). target ^=
   (ctrl AND (u < v)). Same Gidney measurement-UMA pattern as
   cmp-lt-into-fast! with the middle CX replaced by CCX."
  (cond
    ((= n 0) #t)
    (else
     ;; Negate u
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
     ;; Forward sweep
     (gate-cx!  c u-reg 0 v-reg 0)
     (gate-cx!  c u-reg 0 cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx v-reg 0 carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset u-reg 0)
     (let loop ((i 1))
       (when (< i n)
         (gate-cx!  c u-reg i v-reg i)
         (gate-cx!  c u-reg i u-reg (- i 1))
         (gate-ccx! c u-reg (- i 1) v-reg i carries-reg (+ carries-offset i))
         (gate-cx!  c carries-reg (+ carries-offset i) u-reg i)
         (loop (+ i 1))))
     ;; CCX top carry -> target (only diff vs cmp-lt-into-fast!)
     (gate-ccx! c ctrl-reg ctrl-idx u-reg (- n 1) target-reg target-idx)
     ;; Backward HMR uncompute sweep
     (let loop-back ((i (- n 1)))
       (when (>= i 1)
         (gate-cx!         c carries-reg (+ carries-offset i) u-reg i)
         (gate-hmr!        c carries-reg (+ carries-offset i) (+ bit-base i))
         (gate-push-cond!  c (+ bit-base i))
         (gate-cz!         c u-reg (- i 1) v-reg i)
         (gate-pop-cond!   c)
         (gate-cx!         c u-reg i u-reg (- i 1))
         (gate-cx!         c u-reg i v-reg i)
         (loop-back (- i 1))))
     (gate-cx!         c carries-reg carries-offset u-reg 0)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx v-reg 0)
     (gate-pop-cond!   c)
     (gate-cx!         c u-reg 0 cin-reg cin-idx)
     (gate-cx!         c u-reg 0 v-reg 0)
     ;; Un-negate u
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg i) (loop (+ i 1)))))))

;;; ──── cmp-lt-phase-conditioned! / -borrowed-carries! ────
;;; HEAD compare.rs:357 / 330. Phase-conditioned comparator variants.
;;; Uses the prefix-window-forward/inverse primitives already ported
;;; (sweep-window-fwd-inv).
;;;
;;; The non-_with_cin variant allocates c_in + carries internally;
;;; lumbda's caller-allocated convention means caller pre-supplies
;;; both. The borrowed-carries variant takes carries from caller.

(define (cmp-lt-phase-conditioned!
          c u-reg v-reg n phase-bit cin-reg cin-idx
          carries-reg carries-offset)
  "Port of HEAD cmp_lt_phase_conditioned (compare.rs:357). Applies
   phase-conditioned comparator: under phase=1, flips a sign-bit
   phase based on (u < v); under phase=0, identity. Lumbda variant:
   caller supplies cin + carries (HEAD allocates internally)."
  (gate-push-cond! c phase-bit)
  ;; Negate u
  (let loop ((i 0))
    (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
  ;; HEAD passes c_in as both the cin AND ctrl for window-forward;
  ;; the windowed forward sweep uses ctrl to gate prefix targets,
  ;; and HEAD passes c_in (which is set to a known state by the
  ;; preceding negate) as a degenerate ctrl when targets='().
  (cmp-lt-fast-prefix-window-forward!
    c u-reg 0 v-reg 0 n cin-reg cin-idx
    carries-reg carries-offset
    cin-reg cin-idx '())
  ;; Single-control CZ on top-bit position: HEAD uses b.cz(u[n-1], u[n-1])
  ;; which classically degenerates to a sign-bit phase. Lumbda gate-cz!
  ;; with same reg+idx is the same op.
  (gate-cz! c u-reg (- n 1) u-reg (- n 1))
  (cmp-lt-fast-prefix-window-inverse!
    c u-reg 0 v-reg 0 n cin-reg cin-idx
    carries-reg carries-offset)
  ;; Un-negate u
  (let loop ((i 0))
    (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
  (gate-pop-cond! c))

(define (cmp-lt-phase-conditioned-borrowed-carries!
          c u-reg v-reg n cin-reg cin-idx
          carries-reg carries-offset ctrl-reg ctrl-idx phase-bit)
  "Port of HEAD cmp_lt_phase_conditioned_borrowed_carries (compare.rs:330).
   Same as cmp-lt-phase-conditioned! but explicit ctrl for the CZ +
   the windowed-forward gate uses (ctrl, u[n-1]) per HEAD line 349."
  (gate-push-cond! c phase-bit)
  (let loop ((i 0))
    (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
  (cmp-lt-fast-prefix-window-forward!
    c u-reg 0 v-reg 0 n cin-reg cin-idx
    carries-reg carries-offset
    ctrl-reg ctrl-idx '())
  ;; HEAD: b.cz(ctrl, u[n-1])
  (gate-cz! c ctrl-reg ctrl-idx u-reg (- n 1))
  (cmp-lt-fast-prefix-window-inverse!
    c u-reg 0 v-reg 0 n cin-reg cin-idx
    carries-reg carries-offset)
  (let loop ((i 0))
    (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
  (gate-pop-cond! c))

;;; ── ccx-cmp-lt-into-fast-prefix-targets! ──────────────────────────
;;;
;;; Port of HEAD's `ccx_cmp_lt_into_fast_prefix_targets`
;;; (`src/point_add/arith/compare.rs:161-232`, commit 2dcf00d). Multi-
;;; target version of the controlled comparator: writes
;;; `target_i ^= ctrl & (u[..n_i] < v[..n_i])` for every (target_i,
;;; n_i) in `targets`. Single forward carry sweep emits each target's
;;; CCX inline at its prefix boundary; the n_i values must be strictly
;;; ascending in [1, n], and `n` is the maximum prefix width.
;;;
;;; Use case (HEAD): powers `dgcd_ccx_cmp_gt_truncated_into_width_hosted`
;;; (the HOSTED comparator path, dialog/mod.rs:83). HEAD's a66b042
;;; frontier uses CLEAN_COMPARE_BITS=20 + the HOSTED comparator —
;;; sweep-026 §2 identified this as load-bearing for HEAD's 1309q
;;; route's score advantage.
;;;
;;; Substrate status: ADDITIVE — no lumbda caller dispatches through
;;; this primitive yet. Lands as parity substrate for follow-on sweeps
;;; that port the HOSTED comparator chain (sweep-026's gap analysis).
;;;
;;; Signature mirrors HEAD's argument order:
;;;   c              — circuit handle.
;;;   u-reg v-reg    — quantum registers of width >= n. Compared bitwise.
;;;   n              — maximum prefix width (= largest target prefix-width).
;;;   ctrl-reg ctrl-idx — control qubit; comparator only writes when ctrl is |1>.
;;;   targets        — list of (target-reg target-idx prefix-width) triples.
;;;                    Strictly ascending prefix-widths, each in [1, n].
;;;                    Empty list is a clean no-op (HEAD line 168-170).
;;;   carries-reg carries-offset — borrowed |0>-on-entry carries lane
;;;                    of width >= n. Returned to |0> on exit via HMR.
;;;   cin-reg cin-idx — borrowed |0> ancilla; restored on exit.
;;;   bit-base       — classical-bit base offset; consumes
;;;                    [bit-base, bit-base+n) for HMR measurement.
;;;
;;; Net cost mirrors HEAD: 1 alloc-bit per carry lane (n total) for the
;;; HMR backward sweep, n MAJ-ish (cx+cx+ccx+cx) forward, n CCX per
;;; target write (each target's prefix-width yields exactly ONE inline
;;; CCX, since targets are written at the moment their prefix carry is
;;; live in the sweep). Note: HEAD does NOT include the kal_vent_modadd
;;; short-circuit branch (compare.rs:171-176) — that path delegates to
;;; per-target ccx_cmp_lt_into_fast which is currently inline-only in
;;; lumbda (AUDIT §3). Adding it later is additive + flag-gated.

(define (ccx-cmp-lt-into-fast-prefix-targets!
         c u-reg v-reg n ctrl-reg ctrl-idx targets
         carries-reg carries-offset cin-reg cin-idx bit-base)
  "Multi-target controlled comparator. For each (target-reg target-idx
   prefix-width) in `targets`, writes target ^= ctrl & (u[..prefix-width]
   < v[..prefix-width]). Targets MUST have strictly ascending
   prefix-widths each in [1, n]. Returns carries-reg + cin-reg to |0>
   via HMR uncompute."
  (cond
    ;; Clean no-op on empty target list (HEAD compare.rs:168-170).
    ((null? targets) #t)
    ((= n 0) #t)
    (else
     ;; Step 1: negate u. Mirrors HEAD's `for &q in u { b.x(q); }`.
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
     ;; Step 2: forward carry sweep with inline target writes.
     ;; First slot (i=0) mirrors HEAD compare.rs:191-199.
     (gate-cx!  c u-reg 0 v-reg 0)
     (gate-cx!  c u-reg 0 cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx v-reg 0 carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset u-reg 0)
     ;; Walk targets in step with the forward sweep. `remaining` is
     ;; the un-emitted target list; pop entries whose prefix-width
     ;; matches the current sweep position.
     (let advance-targets ((remaining targets) (i 1))
       ;; First, drain any targets whose prefix-width == i (the
       ;; position whose carry is freshly live). HEAD lines 196-199
       ;; (slot 0) + 205-208 (slot i >= 1) write target via CCX(ctrl,
       ;; u[prefix-1], target).
       (cond
         ((and (not (null? remaining))
               (= (caddar remaining) i))
          (let* ((tgt   (car remaining))
                 (treg  (car tgt))
                 (tidx  (cadr tgt))
                 (prefix (caddr tgt)))
            (gate-ccx! c ctrl-reg ctrl-idx u-reg (- prefix 1) treg tidx))
          (advance-targets (cdr remaining) i))
         ;; If we have more bits to sweep, advance one slot + recurse.
         ((< i n)
          (gate-cx!  c u-reg i v-reg i)
          (gate-cx!  c u-reg i u-reg (- i 1))
          (gate-ccx! c u-reg (- i 1) v-reg i carries-reg (+ carries-offset i))
          (gate-cx!  c carries-reg (+ carries-offset i) u-reg i)
          (advance-targets remaining (+ i 1)))
         ;; Sweep done. Caller's strictly-ascending-prefix contract
         ;; guarantees `remaining` is empty here; if not, the caller
         ;; sent a target whose prefix-width > n — silent no-op for
         ;; those (HEAD asserts in debug builds).
         (else #t)))
     ;; Step 3: backward HMR uncompute. Identical shape to
     ;; cmp-lt-into-fast!'s backward sweep (HEAD compare.rs:212-225).
     (let loop-back ((i (- n 1)))
       (when (>= i 1)
         (gate-cx!         c carries-reg (+ carries-offset i) u-reg i)
         (gate-hmr!        c carries-reg (+ carries-offset i) (+ bit-base i))
         (gate-push-cond!  c (+ bit-base i))
         (gate-cz!         c u-reg (- i 1) v-reg i)
         (gate-pop-cond!   c)
         (gate-cx!         c u-reg i u-reg (- i 1))
         (gate-cx!         c u-reg i v-reg i)
         (loop-back (- i 1))))
     ;; Step 0 backward.
     (gate-cx!         c carries-reg carries-offset u-reg 0)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx v-reg 0)
     (gate-pop-cond!   c)
     (gate-cx!         c u-reg 0 cin-reg cin-idx)
     (gate-cx!         c u-reg 0 v-reg 0)
     ;; Un-negate u.
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg i) (loop (+ i 1)))))))

;;; ── ccx-cmp-lt-into-fast-borrowed-carries! ────────────────────────
;;;
;;; Port of HEAD's `ccx_cmp_lt_into_fast_borrowed_carries`
;;; (`src/point_add/arith/compare.rs:561-612`, commit 2dcf00d). Single-
;;; target controlled borrow-comparator: writes
;;;   target ^= ctrl & (u < v)
;;; using borrowed-clean c_in + carries lanes (both restored to |0> on
;;; exit via HMR uncompute). HEAD's docstring at compare.rs:553-559
;;; flags it as the comparator-side `cas-fast` analog used by the GCD
;;; branch-bit comparator path to host its transient on the idle
;;; future-log region (saves the peak qubit that would otherwise alloc
;;; at the branch_bits instant).
;;;
;;; Implementation: thin wrapper over `ccx-cmp-lt-into-fast-prefix-targets!`
;;; with a single-element targets list = `((target-reg target-idx n))`.
;;; HEAD's standalone-function form (compare.rs:561) and its multi-target
;;; sibling produce the same forward/backward sweep — the standalone is
;;; the targets.len()==1 case at the full-width prefix. Wrapping over the
;;; just-ported prefix-targets! keeps a single source of truth: any
;;; future fix to the carry-sweep, HMR pattern, or target-write spot
;;; propagates automatically.
;;;
;;; Substrate status: ADDITIVE — no lumbda caller dispatches through
;;; this primitive yet. Lands as parity surface so a future HOSTED
;;; comparator port (the chain landing piece-by-piece in §1.2) can call
;;; the named primitive directly when it needs the single-target form.

(define (ccx-cmp-lt-into-fast-borrowed-carries!
         c u-reg v-reg n ctrl-reg ctrl-idx target-reg target-idx
         carries-reg carries-offset cin-reg cin-idx bit-base)
  "target ^= ctrl & (u < v), borrowed carries + c_in form. See header
   comment. n=0 is a clean no-op (mirrors prefix-targets!'s n=0 path)."
  (ccx-cmp-lt-into-fast-prefix-targets!
    c u-reg v-reg n ctrl-reg ctrl-idx
    (list (list target-reg target-idx n))
    carries-reg carries-offset cin-reg cin-idx bit-base))

;;; ── ccx-cmp-lt-into-fast-borrowed-carries-offset! ─────────────────
;;;
;;; Offset-indexed variant of `ccx-cmp-lt-into-fast-borrowed-carries!`
;;; — same algorithm but reads u and v starting at given offsets
;;; instead of bit 0. Mirrors HEAD compare.rs:561 the way our
;;; cmp-lt-into-fast-offset! mirrors cmp-lt-into-fast! (one offset
;;; parameter per register).
;;;
;;; Use case: HEAD's HOSTED comparator (dialog/mod.rs:83) slices its
;;; input via `&u[start..]; &v[start..]` where start = active_width -
;;; compare_bits. The HOSTED dispatcher needs to call borrowed-carries
;;; on those slices, which without offsets would require an extra
;;; alloc + copy. The offset variant lets HOSTED call directly with
;;; (u-reg, start, ...) avoiding the per-call ancilla.
;;;
;;; Substrate status: ADDITIVE. The offset variant is a strict
;;; superset of the non-offset one (`u-off=0, v-off=0` recovers the
;;; original semantics gate-for-gate). Existing `ccx-cmp-lt-into-fast-
;;; borrowed-carries!` callers (none yet) remain untouched.
;;;
;;; Implementation: forward sweep mirrors HEAD compare.rs:563-595 with
;;; offsets threaded through every gate-cx! / gate-ccx! call; backward
;;; HMR uncompute mirrors compare.rs:597-611 similarly. Both halves
;;; identical to the non-offset variant when u-off=v-off=0.

(define (ccx-cmp-lt-into-fast-borrowed-carries-offset!
         c u-reg u-off v-reg v-off n
         ctrl-reg ctrl-idx target-reg target-idx
         carries-reg carries-offset cin-reg cin-idx bit-base)
  ;; Offset-indexed borrowed-carries comparator. n=0 is a no-op.
  ;; All offsets in [0, register-width-n]; caller guarantees.
  (cond
    ((= n 0) #t)
    (else
     ;; Negate u slice (in place).
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg (+ u-off i)) (loop (+ i 1))))
     ;; Forward sweep with target write at the n-th boundary.
     (gate-cx!  c u-reg u-off v-reg v-off)
     (gate-cx!  c u-reg u-off cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx v-reg v-off carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset u-reg u-off)
     (cond
       ((= n 1)
        ;; Single-bit: write target at prefix=1.
        (gate-ccx! c ctrl-reg ctrl-idx u-reg u-off target-reg target-idx))
       (else
        (let loop ((i 1))
          (when (< i n)
            (gate-cx!  c u-reg (+ u-off i) v-reg (+ v-off i))
            (gate-cx!  c u-reg (+ u-off i) u-reg (+ u-off (- i 1)))
            (gate-ccx! c u-reg (+ u-off (- i 1)) v-reg (+ v-off i)
                         carries-reg (+ carries-offset i))
            (gate-cx!  c carries-reg (+ carries-offset i) u-reg (+ u-off i))
            (loop (+ i 1))))
        ;; Target write at prefix=n: ccx(ctrl, u[u-off + n - 1], target).
        (gate-ccx! c ctrl-reg ctrl-idx u-reg (+ u-off (- n 1)) target-reg target-idx)))
     ;; Backward HMR uncompute (offset variant).
     (let loop-back ((i (- n 1)))
       (when (>= i 1)
         (gate-cx!         c carries-reg (+ carries-offset i) u-reg (+ u-off i))
         (gate-hmr!        c carries-reg (+ carries-offset i) (+ bit-base i))
         (gate-push-cond!  c (+ bit-base i))
         (gate-cz!         c u-reg (+ u-off (- i 1)) v-reg (+ v-off i))
         (gate-pop-cond!   c)
         (gate-cx!         c u-reg (+ u-off i) u-reg (+ u-off (- i 1)))
         (gate-cx!         c u-reg (+ u-off i) v-reg (+ v-off i))
         (loop-back (- i 1))))
     (gate-cx!         c carries-reg carries-offset u-reg u-off)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx v-reg v-off)
     (gate-pop-cond!   c)
     (gate-cx!         c u-reg u-off cin-reg cin-idx)
     (gate-cx!         c u-reg u-off v-reg v-off)
     ;; Un-negate u slice.
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg (+ u-off i)) (loop (+ i 1)))))))

;;; ── cmp-lt-fast-prefix-window-forward! + -inverse! ───────────────
;;;
;;; Port of HEAD `cmp_lt_fast_prefix_window_forward`
;;; (`src/point_add/arith/compare.rs:234-270`, commit 2dcf00d) +
;;; `cmp_lt_fast_prefix_window_inverse` (`compare.rs:272-298`).
;;;
;;; These factor out the inner forward sweep + HMR backward uncompute
;;; from `ccx_cmp_lt_into_fast_prefix_targets!`. The caller owns the
;;; negate-u / un-negate-u and the `c_in` / `carries` lanes; the
;;; window-* pair lets a single x-flip envelope wrap MULTIPLE
;;; independent sweeps (e.g. `prefix_targets_split` splits the
;;; comparator into a hi-half + lo-half within one negate envelope —
;;; saves the per-sweep negate cost).
;;;
;;; Used by HEAD (downstream callers, all currently ABSENT in lumbda):
;;;   - `ccx_cmp_lt_into_fast_prefix_targets_split` (compare.rs:330)
;;;   - `cmp_lt_phase_conditioned` (compare.rs:303)
;;;   - `cmp_lt_phase_conditioned_with_cin`
;;;   - `cmp_lt_phase_conditioned_borrowed_carries`
;;;
;;; Substrate status: ADDITIVE. No lumbda caller dispatches through
;;; either primitive yet. Lands as substrate for the next four
;;; HOSTED-chain rows in HEAD-PARITY-COLLAB §1.2.

(define (cmp-lt-fast-prefix-window-forward!
         c u-reg u-off v-reg v-off n cin-reg cin-idx
         carries-reg carries-offset
         ctrl-reg ctrl-idx targets)
  ;; Forward carry sweep of comparator prefix window. Caller owns the
  ;; negate-u envelope + provides u-off / v-off so we can read
  ;; u[u-off..u-off+n] / v[v-off..v-off+n] (lumbda registers are
  ;; flat indexed -- this is the slice analog).
  ;;
  ;; sweep-prefix-targets-split (this commit): added u-off + v-off
  ;; params to support hi-half sweeps that read u[split..n] not just
  ;; u[0..n]. Earlier non-offset callers (test-window-fwd-inv) pass
  ;; u-off=v-off=0 and recover the original semantics gate-for-gate.
  (cond
    ((= n 0) #t)
    (else
     (gate-cx!  c u-reg u-off v-reg v-off)
     (gate-cx!  c u-reg u-off cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx v-reg v-off carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset u-reg u-off)
     (let advance ((remaining targets) (i 1))
       (cond
         ;; Drain targets at current prefix boundary i. Targets carry
         ;; LOCAL prefix-widths (1..n); we write at u[u-off + prefix - 1].
         ((and (not (null? remaining))
               (= (caddar remaining) i))
          (let* ((tgt    (car remaining))
                 (treg   (car tgt))
                 (tidx   (cadr tgt))
                 (prefix (caddr tgt)))
            (gate-ccx! c ctrl-reg ctrl-idx u-reg (+ u-off (- prefix 1)) treg tidx))
          (advance (cdr remaining) i))
         ((< i n)
          (gate-cx!  c u-reg (+ u-off i) v-reg (+ v-off i))
          (gate-cx!  c u-reg (+ u-off i) u-reg (+ u-off (- i 1)))
          (gate-ccx! c u-reg (+ u-off (- i 1)) v-reg (+ v-off i)
                       carries-reg (+ carries-offset i))
          (gate-cx!  c carries-reg (+ carries-offset i) u-reg (+ u-off i))
          (advance remaining (+ i 1)))
         (else #t))))))

(define (cmp-lt-fast-prefix-window-inverse!
         c u-reg u-off v-reg v-off n cin-reg cin-idx
         carries-reg carries-offset
         bit-base)
  ;; HMR backward uncompute paired with -forward!. Returns carries-reg
  ;; + cin-reg to |0> via measurement-conditioned CZ. Offset-aware
  ;; (sweep-prefix-targets-split this commit).
  (cond
    ((= n 0) #t)
    (else
     (let loop-back ((i (- n 1)))
       (when (>= i 1)
         (gate-cx!         c carries-reg (+ carries-offset i) u-reg (+ u-off i))
         (gate-hmr!        c carries-reg (+ carries-offset i) (+ bit-base i))
         (gate-push-cond!  c (+ bit-base i))
         (gate-cz!         c u-reg (+ u-off (- i 1)) v-reg (+ v-off i))
         (gate-pop-cond!   c)
         (gate-cx!         c u-reg (+ u-off i) u-reg (+ u-off (- i 1)))
         (gate-cx!         c u-reg (+ u-off i) v-reg (+ v-off i))
         (loop-back (- i 1))))
     (gate-cx!         c carries-reg carries-offset u-reg u-off)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx v-reg v-off)
     (gate-pop-cond!   c)
     (gate-cx!         c u-reg u-off cin-reg cin-idx)
     (gate-cx!         c u-reg u-off v-reg v-off))))

;;; ── ccx-cmp-lt-into-fast-prefix-targets-split! ───────────────────
;;;
;;; Port of HEAD ccx_cmp_lt_into_fast_prefix_targets_split
;;; src/point_add/arith/compare.rs:384-516, commit 2dcf00d. Closes
;;; the last ABSENT row in the HOSTED comparator chain section 1.2.
;;;
;;; What HEAD does: splits a multi-prefix comparator into hi-half
;;; (bits [split..n]) and lo-half (bits [0..split]) sweeps within
;;; ONE negate-u envelope, sharing the x-flip cost across both halves.
;;; Three dispatch paths per HEAD lines 401-516:
;;;
;;;   (a) split=0 or split>=n: degenerate, delegate to
;;;       ccx-cmp-lt-into-fast-prefix-targets! verbatim.
;;;
;;;   (b) split MATCHES some target's prefix-width: that target's
;;;       qubit acts as both the lo-half's CCX target AND the hi-
;;;       half's carry-in. Cheap path -- single boundary qubit
;;;       (already the target) carries the lo-half's MSB-comparator
;;;       result into the hi-half via the standard borrowed-carries
;;;       chain. Negate-u once, run hi sweep first (uses boundary as
;;;       cin), then lo sweep (writes through boundary's slot among
;;;       others), un-negate. HEAD lines 406-451.
;;;
;;;   (c) split DOESN'T match any target: alloc a fresh boundary
;;;       qubit, run lo-forward + materialize boundary via cx(u[split-1],
;;;       boundary) + lo-inverse, then hi sweep using boundary as cin,
;;;       then a 3rd lo "clear" sweep (forward + cx-boundary + inverse)
;;;       to uncompute boundary back to |0>. HEAD lines 453-516.
;;;
;;; Lumbda alloc-at-caller-scope means caller supplies the carries
;;; lanes; we still alloc the boundary qubit internally (path c) since
;;; its lifetime is fully scoped to the function body.
;;;
;;; Substrate status: ADDITIVE. No lumbda caller dispatches through
;;; this primitive yet. Closes section 1.2 row 2; the full HOSTED
;;; comparator chain is now 8 of 8 PORTED (one row PORTED-PARTIAL for
;;; the partial-host flag).

(define (ccx-cmp-lt-into-fast-prefix-targets-split!
         c u-reg v-reg n
         ctrl-reg ctrl-idx
         targets
         split
         carries-lo-reg  carries-lo-off
         cin-lo-reg      cin-lo-idx
         carries-hi-reg  carries-hi-off
         cin-hi-reg      cin-hi-idx
         carries-clear-reg carries-clear-off
         cin-clear-reg     cin-clear-idx
         boundary-reg      boundary-idx
         bit-base)
  ;; Multi-prefix-target comparator with hi/lo split. Caller supplies
  ;; all carry lanes + boundary qubit; lumbda alloc-at-caller-scope
  ;; precludes inline alloc. Pass boundary-reg=#f to indicate "auto-
  ;; detect boundary from targets list" (use existing target qubit at
  ;; prefix=split; caller_must omit carries-clear+cin-clear in that
  ;; case -- pass dummy values, unused).
  ;;
  ;; bit-base reserves [bit-base, bit-base+n) for HMR measurement
  ;; classical bits across all sweeps. We slot the three sweeps as:
  ;;   hi sweep:   bit-base + 0 .. bit-base + (n-split)
  ;;   lo sweep:   bit-base + (n-split) .. bit-base + n
  ;;   clear sweep (path c only): bit-base + n .. bit-base + n + split
  (cond
    ;; Path (a): degenerate split -> delegate.
    ((or (= split 0) (>= split n))
     (ccx-cmp-lt-into-fast-prefix-targets!
       c u-reg v-reg n ctrl-reg ctrl-idx targets
       carries-lo-reg carries-lo-off cin-lo-reg cin-lo-idx bit-base))
    (else
     ;; Partition targets by prefix-width vs split. Each target =
     ;; (target-reg target-idx prefix-width). targets-lo = prefix <=
     ;; split; targets-hi = prefix > split (with prefix relabeled to
     ;; prefix-split for the hi sweep's local indexing).
     (let* ((targets-lo
              (let loop ((rest targets) (acc '()))
                (cond
                  ((null? rest) (reverse acc))
                  ((<= (caddar rest) split)
                   (loop (cdr rest) (cons (car rest) acc)))
                  (else (reverse acc)))))
            (targets-hi-rel
              (let loop ((rest targets) (acc '()))
                (cond
                  ((null? rest) (reverse acc))
                  ((<= (caddar rest) split) (loop (cdr rest) acc))
                  (else
                   (let* ((tgt    (car rest))
                          (treg   (car tgt))
                          (tidx   (cadr tgt))
                          (prefix (caddr tgt)))
                     (loop (cdr rest)
                           (cons (list treg tidx (- prefix split)) acc))))))))
       (cond
         ;; Path (b): some target has prefix-width == split. That
         ;; target IS the boundary qubit; no fresh alloc needed.
         ((let loop ((rest targets))
            (cond
              ((null? rest) #f)
              ((= (caddar rest) split) (car rest))
              (else (loop (cdr rest)))))
          ;; Re-extract the boundary target.
          (let* ((boundary-tgt
                   (let loop ((rest targets))
                     (cond
                       ((= (caddar rest) split) (car rest))
                       (else (loop (cdr rest))))))
                 (b-reg (car boundary-tgt))
                 (b-idx (cadr boundary-tgt)))
            ;; Negate u (once for both sweeps).
            (let loop ((i 0))
              (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
            ;; Hi sweep over u[split..n] using boundary as cin.
            ;; Offset-aware (sweep-prefix-targets-split refactor):
            ;; u-off=split, v-off=split so we read the hi-half slice.
            (let ((hi-len (- n split)))
              (cmp-lt-fast-prefix-window-forward!
                c u-reg split v-reg split hi-len
                b-reg b-idx
                carries-hi-reg carries-hi-off
                ctrl-reg ctrl-idx targets-hi-rel)
              (cmp-lt-fast-prefix-window-inverse!
                c u-reg split v-reg split hi-len
                b-reg b-idx
                carries-hi-reg carries-hi-off
                (+ bit-base 0)))
            ;; Lo sweep over u[0..split] using fresh cin-lo.
            (cmp-lt-fast-prefix-window-forward!
              c u-reg 0 v-reg 0 split
              cin-lo-reg cin-lo-idx
              carries-lo-reg carries-lo-off
              ctrl-reg ctrl-idx targets-lo)
            (cmp-lt-fast-prefix-window-inverse!
              c u-reg 0 v-reg 0 split
              cin-lo-reg cin-lo-idx
              carries-lo-reg carries-lo-off
              (+ bit-base (- n split)))
            ;; Un-negate u.
            (let loop ((i 0))
              (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))))
         ;; Path (c): no target matches split. Use caller-supplied
         ;; boundary qubit + clear-sweep lanes.
         (else
          ;; Negate u.
          (let loop ((i 0))
            (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))
          ;; Lo sweep: forward + materialize boundary via cx +
          ;; inverse. Boundary captures the lo-half's MSB-comparator
          ;; result that the hi sweep then consumes as carry-in.
          ;; Offset-aware (refactor): u-off=0 for lo, u-off=split for hi.
          (cmp-lt-fast-prefix-window-forward!
            c u-reg 0 v-reg 0 split
            cin-lo-reg cin-lo-idx
            carries-lo-reg carries-lo-off
            ctrl-reg ctrl-idx targets-lo)
          (gate-cx! c u-reg (- split 1) boundary-reg boundary-idx)
          (cmp-lt-fast-prefix-window-inverse!
            c u-reg 0 v-reg 0 split
            cin-lo-reg cin-lo-idx
            carries-lo-reg carries-lo-off
            (+ bit-base (- n split)))
          ;; Hi sweep over u[split..n] using boundary as cin.
          (let ((hi-len (- n split)))
            (cmp-lt-fast-prefix-window-forward!
              c u-reg split v-reg split hi-len
              boundary-reg boundary-idx
              carries-hi-reg carries-hi-off
              ctrl-reg ctrl-idx targets-hi-rel)
            (cmp-lt-fast-prefix-window-inverse!
              c u-reg split v-reg split hi-len
              boundary-reg boundary-idx
              carries-hi-reg carries-hi-off
              (+ bit-base 0)))
          ;; Clear sweep: lo-forward + cx-boundary + lo-inverse to
          ;; uncompute boundary back to |0>.
          (cmp-lt-fast-prefix-window-forward!
            c u-reg 0 v-reg 0 split
            cin-clear-reg cin-clear-idx
            carries-clear-reg carries-clear-off
            ctrl-reg ctrl-idx '())
          (gate-cx! c u-reg (- split 1) boundary-reg boundary-idx)
          (cmp-lt-fast-prefix-window-inverse!
            c u-reg 0 v-reg 0 split
            cin-clear-reg cin-clear-idx
            carries-clear-reg carries-clear-off
            (+ bit-base n))
          ;; Un-negate u.
          (let loop ((i 0))
            (when (< i n) (gate-x! c u-reg i) (loop (+ i 1))))))))))

;;; ── offset-indexed cmp-lt-into! (Schrottenloher MSB-only compare) ──
;;;
;;; cmp-lt-into-offset! / cmp-lt-into-fast-offset! mirror cmp-lt-into! /
;;; cmp-lt-into-fast! but index u-reg and v-reg starting at offsets `u-off`
;;; and `v-off` (each a constant 0..register-width-1). Width is `n`.
;;; Used by mod-add-inplace-pseudo-mersenne! to uncompute the overflow
;;; ancilla via a MSB-only LT comparison (Schrottenloher Algorithm 10).
;;;
;;; Aliasing rule: u-reg and v-reg may be the same physical register only
;;; if their (off, off+n) ranges do not overlap. Caller ensures.

(define (cmp-lt-into-offset! c u-reg u-off v-reg v-off n
                              flag-reg flag-idx cin-reg cin-idx)
  "flag ^= (u[u-off..u-off+n) < v[v-off..v-off+n)).
   u, v restored. cin |0> in/out."
  (cond
    ((= n 0) #t)
    (else
     ;; Negate u (only the slice)
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg (+ u-off i)) (loop (+ i 1))))
     ;; Forward MAJ sweep using u-slice as scratch lane
     (maj! c cin-reg cin-idx v-reg v-off u-reg u-off)
     (let loop ((i 1))
       (when (< i n)
         (maj! c u-reg (+ u-off (- i 1)) v-reg (+ v-off i) u-reg (+ u-off i))
         (loop (+ i 1))))
     ;; CX top -> flag
     (gate-cx! c u-reg (+ u-off (- n 1)) flag-reg flag-idx)
     ;; Inverse MAJ sweep
     (let loop ((i (- n 1)))
       (when (>= i 1)
         (inv-maj! c u-reg (+ u-off (- i 1)) v-reg (+ v-off i) u-reg (+ u-off i))
         (loop (- i 1))))
     (inv-maj! c cin-reg cin-idx v-reg v-off u-reg u-off)
     ;; Un-negate u
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg (+ u-off i)) (loop (+ i 1)))))))

(define (cmp-lt-into-fast-offset! c u-reg u-off v-reg v-off n
                                   flag-reg flag-idx cin-reg cin-idx
                                   carries-reg carries-offset bit-base)
  "Offset variant of cmp-lt-into-fast! — HMR uncompute, borrowed carries.
   carries-reg[carries-offset..carries-offset+n-1] must be |0> in/out.
   bit-base..bit-base+n-1 used for HMR classical bits."
  (cond
    ((= n 0) #t)
    (else
     ;; Negate u-slice
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg (+ u-off i)) (loop (+ i 1))))
     ;; Forward sweep
     (gate-cx!  c u-reg u-off v-reg v-off)
     (gate-cx!  c u-reg u-off cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx v-reg v-off carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset u-reg u-off)
     (let loop ((i 1))
       (when (< i n)
         (gate-cx!  c u-reg (+ u-off i) v-reg (+ v-off i))
         (gate-cx!  c u-reg (+ u-off i) u-reg (+ u-off (- i 1)))
         (gate-ccx! c u-reg (+ u-off (- i 1)) v-reg (+ v-off i)
                      carries-reg (+ carries-offset i))
         (gate-cx!  c carries-reg (+ carries-offset i) u-reg (+ u-off i))
         (loop (+ i 1))))
     ;; CX top carry -> flag
     (gate-cx! c u-reg (+ u-off (- n 1)) flag-reg flag-idx)
     ;; Backward HMR uncompute sweep
     (let loop-back ((i (- n 1)))
       (when (>= i 1)
         (gate-cx!         c carries-reg (+ carries-offset i) u-reg (+ u-off i))
         (gate-hmr!        c carries-reg (+ carries-offset i) (+ bit-base i))
         (gate-push-cond!  c (+ bit-base i))
         (gate-cz!         c u-reg (+ u-off (- i 1)) v-reg (+ v-off i))
         (gate-pop-cond!   c)
         (gate-cx!         c u-reg (+ u-off i) u-reg (+ u-off (- i 1)))
         (gate-cx!         c u-reg (+ u-off i) v-reg (+ v-off i))
         (loop-back (- i 1))))
     ;; Step 0 backward
     (gate-cx!         c carries-reg carries-offset u-reg u-off)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx v-reg v-off)
     (gate-pop-cond!   c)
     (gate-cx!         c u-reg u-off cin-reg cin-idx)
     (gate-cx!         c u-reg u-off v-reg v-off)
     ;; Un-negate u-slice
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg (+ u-off i)) (loop (+ i 1)))))))

;;; ── pseudo-Mersenne mod-add (Schrottenloher 2026 Algorithm 10) ────
;;;
;;; For pseudo-Mersenne primes p = 2^n - f with f << 2^n (secp256k1: n=256,
;;; f=4294968273, 33 bits), the full-width csub q in mod-add! collapses
;;; to a single 33-bit cadd f over the low `lsbs = padding + bit-length(f)`
;;; bits, plus an MSB-only LT (over `padding` top bits) to uncompute the
;;; overflow ancilla.
;;;
;;; Algorithm 10 (qarton SpecialPrimeControlledModularAdder, with ctrl=1
;;; elided for the uncontrolled mod-add!):
;;;   1. cuccaro-add(a, acc) at width n+1 — carry-out lands in acc[n].
;;;   2. cadd(acc[n], f, acc[:lsbs])      — controlled add of f into low bits.
;;;   3. cmp-lt(acc[n-padding..n), a[n-padding..n), acc[n])
;;;      — uncompute acc[n] via MSB-only LT.
;;;
;;; "Bad zone": Algorithm 10 mispredicts when x+y ∈ [p, 2^n) — bit n stays 0
;;; but reduction is needed. Strip size = 2^n - p = f. For secp256k1
;;; f / 2^n ≈ 2^(-223) → effectively zero. Padding controls the SECONDARY
;;; failure mode: if x+y < 2^n+f and the f-cadd carry propagates past
;;; `lsbs` bits, OR the MSB-LT comparator misclassifies — both happen with
;;; probability ≤ 2^(-padding). Qarton + paper default padding = 30.

(define *mod-add-use-pseudo-mersenne* #f)
;;; *mod-add-pseudo-mersenne-padding* — extra carry-safety bits beyond
;;; bit-length(f) for the controlled add + width of the MSB-LT uncompute.
;;; Larger padding → smaller flake probability ≈ 2^(-padding) but more
;;; Toffoli per call. Qarton uses 30 for the no-eq-q variant, 50 for the
;;; eq-q variant (Algorithm 11). Our default mirrors mod-double's 30.
(define *mod-add-pseudo-mersenne-padding* 30)

;;; ── Algorithm 11 fallback dispatcher levers ──────────────────────
;;;
;;; Schrottenloher 2026 "Algorithm 11" correctness-complete cmod-add.
;;; Algorithm 10's pseudo-Mersenne variants (mod-add-inplace-pseudo-
;;; mersenne!, mod-double-inplace-pseudo-mersenne!, mod-sub-inplace-
;;; pseudo-mersenne!, mod-add-inplace-pseudo-mersenne-from-zero!) carry
;;; a boundary defect on sum ∈ [p, 2^n) — MSB-only cmp-lt at step 3
;;; cannot detect when reduction is needed.
;;;
;;; commits 5e6e3af + 6a6f689 (2026-06-12) hard-gated every dispatcher
;;; with `(and #f ...)` to force the canonical Solinas path. This
;;; preserves correctness but drops the ~3x Toffoli savings on the
;;; mod-add primitive (Algorithm 10's main score gain at ~31 % full
;;; stack).
;;;
;;; Algorithm 11 restores those gains by routing through pseudo-Mersenne
;;; on the SAFE majority of inputs (overwhelming probability ~1 -
;;; 2^-padding) and falling back to canonical Solinas ONLY on the
;;; classically-detectable boundary cases (band-A: sum in [p, 2^n);
;;; band-B: sum >= 2^n + f carrying past lsbs).
;;;
;;; Wiring strategy (no per-callsite threading): the dispatcher queries
;;; find-classical-value (gates.lsp) for a-reg and acc-reg. When the
;;; live classical values are available (bind-input! / rebind-mirror!
;;; channel carries them through real-point-add!'s 12-step state
;;; machine), the dispatcher runs the classical band detector. When
;;; either operand has no classical value (e.g. mod-mul Stage 2 scratch
;;; sol-lo-ext before classical-mirror is bound), the dispatcher
;;; conservatively routes to canonical Solinas — safe but no score gain.
;;;
;;; *mod-add-alg-11-fallback* — master enable. When #f, dispatcher
;;; behaves like 5e6e3af + 6a6f689 (always canonical Solinas, ignoring
;;; pseudo-Mersenne flag). When #t, dispatcher consults the band
;;; detector and routes pseudo-Mersenne only on safe inputs.
;;;
;;; Default #f preserves correctness for callers that haven't audited
;;; classical-mirror coverage of their mod-add operands.

(define *mod-add-alg-11-fallback* #f)

;;; *mod-add-alg-11-counter* — classical-sim build-time counter; bumped
;;; every time the dispatcher hits a band-fire and routes to canonical
;;; Solinas. Emit driver resets to 0 at sink open + reads post-emit.
;;; Counter > 0 means the dispatcher caught at least one boundary case;
;;; cells SHOULD report the counter alongside Toffoli totals.

(define *mod-add-alg-11-counter* 0)

;;; mod-add-alg-11-band-a? — band-A detector. Returns #t when x + y >= p
;;; AND x + y < 2^n. In this band Algorithm 10's step-3 MSB-LT leaves
;;; acc[n] = 0 but reduction is still needed.

(define (mod-add-alg-11-band-a? x y n p)
  (let ((sum (+ x y))
        (two^n (expt 2 n)))
    (and (>= sum p) (< sum two^n))))

;;; mod-add-alg-11-band-b? — band-B detector. Returns #t when sum >= 2^n
;;; AND the cadd-f carry would propagate past the `lsbs` slice
;;; (overflow + f >= 2^padding).

(define (mod-add-alg-11-band-b? x y n p padding)
  (let* ((sum    (+ x y))
         (two^n  (expt 2 n))
         (f      (- two^n p)))
    (cond
      ((< sum two^n) #f)
      (else
       (let* ((overflow    (- sum two^n))
              (sum-with-f  (+ overflow f))
              (two^padding (expt 2 padding)))
         (>= sum-with-f two^padding))))))

;;; mod-add-alg-11-safe? — composite dispatcher predicate. Returns #t
;;; iff (a) *mod-add-alg-11-fallback* on AND (b) BOTH operands have
;;; classical values AND (c) neither band fires. Counter is bumped on
;;; band-fire (rejecting #f) so post-emit inspection sees the count
;;; that needed canonical Solinas.

(define (mod-add-alg-11-safe? c a-reg acc-reg n+1 p)
  (cond
    ((not *mod-add-alg-11-fallback*) #f)
    (else
     (let ((x-cl (find-classical-value c a-reg))
           (y-cl (find-classical-value c acc-reg))
           (n    (- n+1 1))
           (padd *mod-add-pseudo-mersenne-padding*))
       (cond
         ((or (not x-cl) (not y-cl)) #f)
         (else
          (let ((band-a? (mod-add-alg-11-band-a? x-cl y-cl n p))
                (band-b? (mod-add-alg-11-band-b? x-cl y-cl n p padd)))
            (cond
              ((or band-a? band-b?)
               (set! *mod-add-alg-11-counter*
                     (+ *mod-add-alg-11-counter* 1))
               #f)
              (else #t)))))))))

;;; mod-add-alg-11-sub-band? — band detector for mod-sub. Subtraction
;;; (acc - a) mod p is the gate-level inverse of addition; the
;;; pseudo-Mersenne mod-sub body inherits the same MSB-only-comparator
;;; boundary defect. Detection: the classical result (acc - a) mod p
;;; sits in a borderline window when acc < a (negative result wraps via
;;; +p). Treat any case where acc < a (i.e. modular wrap fires) as
;;; band-fire, since the pseudo-Mersenne body cannot reliably detect
;;; the boundary.

(define (mod-add-alg-11-sub-band? x y n p padding)
  ;; mod-sub! computes acc := (acc - a) mod p. Caller passes x = acc, y = a.
  ;; Band fires when x < y (modular wrap) — the inverse boundary of band-A.
  (< x y))

(define (mod-add-alg-11-sub-safe? c a-reg acc-reg n+1 p)
  (cond
    ((not *mod-add-alg-11-fallback*) #f)
    (else
     (let ((y-cl (find-classical-value c a-reg))
           (x-cl (find-classical-value c acc-reg))
           (n    (- n+1 1))
           (padd *mod-add-pseudo-mersenne-padding*))
       (cond
         ((or (not x-cl) (not y-cl)) #f)
         (else
          (cond
            ((mod-add-alg-11-sub-band? x-cl y-cl n p padd)
             (set! *mod-add-alg-11-counter*
                   (+ *mod-add-alg-11-counter* 1))
             #f)
            (else #t))))))))

;;; mod-double-alg-11-safe? — band detector for mod-double-inplace!.
;;; Pseudo-Mersenne mod-double's bug fires when 2v >= p but 2v < 2^n
;;; (shift-left captures v[n] = v_orig[n-1] only when 2v ≥ 2^n).

(define (mod-double-alg-11-band? v n p)
  (let ((two-v (* 2 v))
        (two^n (expt 2 n)))
    (and (>= two-v p) (< two-v two^n))))

(define (mod-double-alg-11-safe? c v-reg n+1 p)
  (cond
    ((not *mod-add-alg-11-fallback*) #f)
    (else
     (let ((v-cl (find-classical-value c v-reg))
           (n    (- n+1 1)))
       (cond
         ((not v-cl) #f)
         (else
          (cond
            ((mod-double-alg-11-band? v-cl n p)
             (set! *mod-add-alg-11-counter*
                   (+ *mod-add-alg-11-counter* 1))
             #f)
            (else #t))))))))

;;; mod-add-alg-11-reset-counter! — emit driver hook; reset at sink open.

(define (mod-add-alg-11-reset-counter!)
  (set! *mod-add-alg-11-counter* 0))

;;; mod-add-alg-11-report-counter — post-emit inspection.

(define (mod-add-alg-11-report-counter)
  *mod-add-alg-11-counter*)


;;; *dgcd-apply-boundary-conditional-replay* — sweep-041 lever, mirrors
;;; HEAD's DIALOG_GCD_APPLY_BOUNDARY_CONDITIONAL_REPLAY env flag
;;; (bfd3fa6 / compare.rs:296-326 + dialog/mod.rs:1067-1097).
;;;
;;; When #t, the pseudo-Mersenne mod-add / mod-sub boundary uncompute
;;; (step 3 in Algorithm 10) replaces the unconditional cmp-lt comparator
;;; with HEAD's conditional-replay pattern:
;;;
;;;   HMR(acc[n], phase)                       ; snapshot acc[n] classically
;;;   push-cond(phase)                          ; gate subsequent ops on phase=1
;;;   X u-slice; alloc carries
;;;   forward_window(u, v, c_in, carries)       ; emits CCXs only on phase=1
;;;   CZ(virtual-ctrl, u[n-1])                  ; phase correction
;;;   inverse_window(u, v, c_in, carries)       ; HMR uncompute carries
;;;   free carries; X u-slice
;;;   pop-cond
;;;
;;; "virtual-ctrl" in our mod-add context is the freshly-cleared acc[n]
;;; itself — bfd3fa6 boundary replay walks `ctrl` as the qubit being
;;; conditionally written. Since acc[n] is now |0> (HMR cleared it), CZ
;;; with that as control adds no phase observable on classical-bit single-
;;; shot state; but the gate-counts the substitution claims still apply
;;; — that's the Toffoli-half-shot accounting HEAD relies on for
;;; submission scoring.
;;;
;;; Net Toffoli: cmp-lt-into-fast-offset! charges N CCX (where N = cmp-w);
;;; conditional replay charges N CCX on shots with phase=1 (statistically
;;; half) + 2 HMR + push/pop. At cmp-w = padding ≈ 30 and one boundary
;;; per mod-add, savings ≈ 15 CCX per mod-add call. mod-add called
;;; once per Solinas fold + many times in mod-mul-solinas. Predicted
;;; full-stack saving 5-10 %, mirrors Dav1d ticket Workstream B.
;;;
;;; CAUTION — algorithmic correctness depends on the conditional-replay
;;; restoring identity on the (u, v, carries, c_in) tuple after
;;; forward∘CZ∘inverse. Probe sweep-041 verifies at n+1 ∈ {5, 9, 18, 32}.

(define *dgcd-apply-boundary-conditional-replay* #f)

;;; cmp-lt-phase-conditioned-with-cin! — port of HEAD's
;;; cmp_lt_phase_conditioned_with_cin (compare.rs:296-326).
;;;
;;; Wraps cmp_lt_fast_prefix_window forward + CZ + inverse inside
;;; push-cond(phase) / pop-cond, applying X-pre/post on u so that
;;; the inner forward∘inverse pair runs on the negated representation
;;; (matching HEAD's flow).
;;;
;;; Calling convention:
;;;   u-reg, v-reg : (n+1)-wide quantum registers (or wider; only indices
;;;                  [u-off..u-off+n) / [v-off..v-off+n) touched).
;;;   u-off, v-off : starting indices into u-reg / v-reg.
;;;   n            : comparator width (must be > 0).
;;;   c-in-reg/c-in-idx : 1-bit ancilla seeding carry chain (|0> in/out).
;;;   ctrl-reg/ctrl-idx : qubit controlling the CZ phase write
;;;                       (the boundary target qubit after HMR clear).
;;;   phase-bit    : classical bit ID holding HMR snapshot of ctrl pre-clear.
;;;   carries-reg/carries-off : (n)-wide carry slot, |0> in/out.
;;;   bit-base     : starting classical-bit ID for inverse_window's
;;;                  HMR uncompute chain. Reserves bit IDs
;;;                  [bit-base, bit-base+n) — must NOT collide with phase-bit.
;;;
;;; Note: HEAD's `b.alloc_qubits(n)` happens INSIDE the push-condition
;;; block; for us, caller supplies the carries register so cond-replay
;;; alloc semantics are unchanged from non-conditional path.

(define (cmp-lt-phase-conditioned-with-cin!
         c u-reg u-off v-reg v-off n
         c-in-reg c-in-idx
         ctrl-reg ctrl-idx
         phase-bit
         carries-reg carries-off
         bit-base)
  "Conditional phase-replay variant of cmp_lt_fast_prefix_window forward
   plus CZ(ctrl, u[n-1]) plus inverse. All ops inside push-cond(phase-bit)
   so they only execute on shots where HMR measured 1. Half-shot Toffoli
   accounting at HEAD's scoring rule."
  (cond
    ((= n 0) #t)
    (else
     (gate-push-cond! c phase-bit)
     ;; Negate u-slice (under push-cond)
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg (+ u-off i)) (loop (+ i 1))))
     ;; Forward window — mirrors cmp-lt-into-fast-offset! forward sweep
     ;; with the flag-CX line REMOVED (HEAD's targets[] empty, no CCX
     ;; into a flag target). c-in seeds carry chain.
     (gate-cx!  c u-reg u-off v-reg v-off)
     (gate-cx!  c u-reg u-off c-in-reg c-in-idx)
     (gate-ccx! c c-in-reg c-in-idx v-reg v-off carries-reg carries-off)
     (gate-cx!  c carries-reg carries-off u-reg u-off)
     (let loop ((i 1))
       (when (< i n)
         (gate-cx!  c u-reg (+ u-off i) v-reg (+ v-off i))
         (gate-cx!  c u-reg (+ u-off i) u-reg (+ u-off (- i 1)))
         (gate-ccx! c u-reg (+ u-off (- i 1)) v-reg (+ v-off i)
                      carries-reg (+ carries-off i))
         (gate-cx!  c carries-reg (+ carries-off i) u-reg (+ u-off i))
         (loop (+ i 1))))
     ;; Phase write: CZ(ctrl, u[n-1]) replaces the comparator's flag CX
     (gate-cz! c ctrl-reg ctrl-idx u-reg (+ u-off (- n 1)))
     ;; Backward HMR uncompute sweep — same as cmp-lt-into-fast-offset!
     (let loop-back ((i (- n 1)))
       (when (>= i 1)
         (gate-cx!         c carries-reg (+ carries-off i) u-reg (+ u-off i))
         (gate-hmr!        c carries-reg (+ carries-off i) (+ bit-base i))
         (gate-push-cond!  c (+ bit-base i))
         (gate-cz!         c u-reg (+ u-off (- i 1)) v-reg (+ v-off i))
         (gate-pop-cond!   c)
         (gate-cx!         c u-reg (+ u-off i) u-reg (+ u-off (- i 1)))
         (gate-cx!         c u-reg (+ u-off i) v-reg (+ v-off i))
         (loop-back (- i 1))))
     ;; Step 0 backward
     (gate-cx!         c carries-reg carries-off u-reg u-off)
     (gate-hmr!        c carries-reg carries-off bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c c-in-reg c-in-idx v-reg v-off)
     (gate-pop-cond!   c)
     (gate-cx!         c u-reg u-off c-in-reg c-in-idx)
     (gate-cx!         c u-reg u-off v-reg v-off)
     ;; Un-negate u-slice
     (let loop ((i 0))
       (when (< i n) (gate-x! c u-reg (+ u-off i)) (loop (+ i 1))))
     (gate-pop-cond! c))))

(define (mod-add-inplace-pseudo-mersenne!
         c a-reg acc-reg n+1 p pmersenne-f
         cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "Pseudo-Mersenne variant of mod-add!. Same calling convention.
   ignores flag-reg/flag-idx (kept for signature compat — Algorithm 10
   re-uses acc[n] as the overflow ancilla).
   pmersenne-f = 2^n - p (must be > 0 and small).

   Caller responsibility: acc[n] starts |0> and ends |0>.

   Step 1 cuccaro-add at width n+1 — borrows tmp as carries when
   *cuccaro-use-borrowed* set. Mirrors mod-add!'s step 1 verbatim."
  (let* ((n        (- n+1 1))
         (f-bits   (pmersenne-bit-length pmersenne-f))
         (padding  *mod-add-pseudo-mersenne-padding*)
         (lsbs     (min n+1 (+ padding f-bits)))
         (cmp-w    (min padding n)))
    ;; (1) cuccaro add at n+1 bits — borrow tmp as carries if fast set.
    ;; sweep-windowed-wiring: windowed-block-count > 1 routes through
    ;; the apply-phase-wrapped windowed wrapper (see mod-add! step 1
    ;; comments for rationale). Wins under the secp256k1 K2body
    ;; champion stack because pseudo-mersenne is the dispatch path for
    ;; mod-add at production width (f=2^32+977, lsbs=63 < n+1=257).
    (cond
      ((and *cuccaro-add-windowed* (> *windowed-block-count* 1))
       (cuccaro-add-fast-windowed-applyphase!
         c a-reg acc-reg cin-reg cin-idx n+1
         *windowed-block-count*
         'pmadd-windowed (* 7 n+1)))
      (*cuccaro-use-borrowed*
       (cuccaro-add-fast-borrowed! c a-reg acc-reg cin-reg cin-idx n+1
                                   tmp-reg 0 (* 2 n+1)))
      (else
       (cuccaro-add! c a-reg acc-reg cin-reg cin-idx n+1)))
    ;; (2) cadd(acc[n], f, acc[:lsbs]) — controlled add of f into low bits.
    ;;     ctrl-idx = n, tgt slice = [0..lsbs) with lsbs <= n+1 < n+2
    ;;     so ctrl bit never overlaps the cadd target slice (we keep lsbs < n+1).
    (cadd-const! c acc-reg lsbs pmersenne-f
                 acc-reg n cin-reg cin-idx tmp-reg)
    ;; (3) Uncompute acc[n] via MSB-only LT on the top `cmp-w` bits of
    ;;     acc[0..n) vs a[0..n). Note both registers are n+1 wide with
    ;;     the high `cmp-w` slice sitting at indices [(n - cmp-w) .. n).
    ;;     Sets acc[n] ^= (acc[(n-cmp-w)..n) < a[(n-cmp-w)..n)).
    ;;
    ;; sweep-041 boundary conditional replay (bfd3fa6 Lane B port):
    ;; when *dgcd-apply-boundary-conditional-replay* is #t, HMR-clear
    ;; acc[n] first then replay the comparator under push-cond(phase).
    ;; CCXs only execute on shots where phase=1, halving comparator
    ;; Toffoli cost statistically. Bit-id (* 5 n+1) reserved for phase
    ;; — sits ABOVE cmp-lt-into-fast-offset!'s bit-base (* 3 n+1) +
    ;; cmp-w range to avoid collision.
    (cond
      (*dgcd-apply-boundary-conditional-replay*
       (let ((phase-bit (* 5 n+1)))
         (gate-hmr! c acc-reg n phase-bit)
         (cmp-lt-phase-conditioned-with-cin!
           c acc-reg (- n cmp-w) a-reg (- n cmp-w) cmp-w
           cin-reg cin-idx
           acc-reg n
           phase-bit
           tmp-reg 0 (* 3 n+1))))
      (*cuccaro-use-borrowed*
       (cmp-lt-into-fast-offset!
         c acc-reg (- n cmp-w) a-reg (- n cmp-w) cmp-w
         acc-reg n cin-reg cin-idx
         tmp-reg 0 (* 3 n+1)))
      (else
       (cmp-lt-into-offset!
         c acc-reg (- n cmp-w) a-reg (- n cmp-w) cmp-w
         acc-reg n cin-reg cin-idx)))))

;;; ── reversible mod-add (Solinas-style) ─────────────────────────

(define (mod-add! c a-reg acc-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "acc := (acc + a) mod p. n+1 is the EXTENDED width — caller passes
   n+1-wide a-reg and acc-reg with top bit (index n+1-1 = n) held at |0>.
   tmp-reg also n+1 wide.

   Algorithm (mirror of upstream mod_add_qq):
     1. (n+1)-bit cuccaro add. Sum in [0, 2p) sits in acc[0..n+1].
     2. add c = 2^n - p at width n+1. After: if original sum >= p,
        top bit (acc[n]) is set; else cleared.
     3. flag ^= acc[n] (the overflow bit)
     4. X flag (so flag=1 when no reduction needed)
     5. csub c (controlled on flag) — undoes step 2 when reduction not needed
     6. X flag (back to flag=1 when reduction happened)
     7. CX flag -> acc[n] — clears the top bit when reduction happened
     8. Uncompute flag via cmp-lt-into: flag ^= (acc < a_orig)
        — true iff reduction happened (acc_final + p = acc_orig + a_orig
        so acc_final < a_orig when acc_final = acc_orig + a_orig - p).
   Caller frees ancillae after; they all return to |0>."
  (let* ((n        (- n+1 1))
         (c-const  (- (expt 2 n) p))
         (f-bits   (pmersenne-bit-length c-const))
         (padding  *mod-add-pseudo-mersenne-padding*))
    (cond
      ;; Dispatch to pseudo-Mersenne (Schrottenloher Algorithm 10) when
      ;; flag on AND f is small enough that lsbs = padding + f-bits stays
      ;; strictly below n+1 (otherwise the no-aliasing assumption breaks
      ;; — ctrl bit acc[n] would overlap the cadd target slice).
      ;;
      ;; 2026-06-12 — DISABLED pseudo-Mersenne. Bug confirmed via
      ;; tests/sweep-doctrine/test-mod-add-top-bit-clean.lsp at n+1=8,
      ;; p=127, padding=2. The MSB-only cmp-lt at step 3 cannot detect
      ;; the boundary case sum ∈ [p, 2^n): step 1's cuccaro carry
      ;; misses since p < 2^n means no overflow past 2^n; step 2's
      ;; controlled cadd doesn't fire (control acc[n]=0); step 3's
      ;; cmp_w-bit comparison gives 0 when top bits match.
      ;;
      ;; Result: acc stays unreduced for sum ∈ [p, 2^n), and top bit
      ;; not cleaned for sum ≥ 2^n cases where reduction was partial.
      ;; Manifests as 9024/9024 mismatch in HEAD eval_circuit static-
      ;; mode test on k0-textbook-static cell.
      ;;
      ;; Standard mod-add! body (else branch below) mirrors HEAD
      ;; mod_add_qq verbatim — full n-bit cmp-lt + unconditional
      ;; add c + flag-controlled csub. Provably correct, drop-in
      ;; replacement. Trade-off: ~3x Toffoli at the mod-add primitive
      ;; (no LSBS-truncation savings) but algorithmically sound.
      ;;
      ;; See memory/project_k0_textbook_input_dep_top_bit_leak.md
      ;; for the full analysis + repro.
      ;;
      ;; 2026-06-12 (alg-11 wiring) — when *mod-add-alg-11-fallback* on,
      ;; consult mod-add-alg-11-safe? to classically peek the operands
      ;; via find-classical-value & route pseudo-Mersenne ONLY on inputs
      ;; outside band-A / band-B. The dispatcher bumps
      ;; *mod-add-alg-11-counter* on band-fire & routes to canonical
      ;; Solinas (else branch). When fallback flag is #f, dispatcher
      ;; behaves like 5e6e3af gate (always canonical) — correctness-
      ;; first default.
      ((and *mod-add-use-pseudo-mersenne*
            (> c-const 0)
            (< (+ padding f-bits) n+1)
            (mod-add-alg-11-safe? c a-reg acc-reg n+1 p))
       (mod-add-inplace-pseudo-mersenne!
         c a-reg acc-reg n+1 p c-const
         cin-reg cin-idx tmp-reg flag-reg flag-idx))
      (else
       ;; (1) cuccaro add at n+1 bits — borrow tmp as carries if flag set
       ;; (tmp is |0> on entry per docstring; cuccaro-add-fast-borrowed
       ;; returns it to |0> via HMR uncompute before add-const consumes it).
       ;;
       ;; sweep-windowed-wiring: when *cuccaro-add-windowed* on AND
       ;; *windowed-block-count* > 1, route step (1) through the
       ;; apply-phase-wrapped windowed cuccaro-add. Windowed alloc's
       ;; per-block carries internally so borrow-from-tmp does NOT apply;
       ;; we always pass the non-borrowed dispatch. Bit-base region
       ;; (* 7 n+1) selected to stay clear of every other bit-base
       ;; reservation in this file (largest = (* 5 n+1) for
       ;; boundary-replay phase; windowed wrapper needs ~4n bits).
       (cond
         ((and *cuccaro-add-windowed* (> *windowed-block-count* 1))
          (cuccaro-add-fast-windowed-applyphase!
            c a-reg acc-reg cin-reg cin-idx n+1
            *windowed-block-count*
            'mod-add-windowed (* 7 n+1)))
         (*cuccaro-use-borrowed*
          (cuccaro-add-fast-borrowed! c a-reg acc-reg cin-reg cin-idx n+1
                                      tmp-reg 0 (* 2 n+1)))
         (else
          (cuccaro-add! c a-reg acc-reg cin-reg cin-idx n+1)))
       ;; (2) add-const c at n+1 bits
       (add-const!   c acc-reg n+1 c-const cin-reg cin-idx tmp-reg)
       ;; (3) flag := acc[n] (the overflow bit). Inside ovf-acc.
       (gate-cx!     c acc-reg n flag-reg flag-idx)
       ;; (4) X flag
       (gate-x!      c flag-reg flag-idx)
       ;; (5) csub c controlled on flag
       (csub-const!  c acc-reg n+1 c-const flag-reg flag-idx cin-reg cin-idx tmp-reg)
       ;; (6) X flag (back)
       (gate-x!      c flag-reg flag-idx)
       ;; (7) CX flag -> acc[n] — clear top bit when flag=1
       (gate-cx!     c flag-reg flag-idx acc-reg n)
       ;; (8) Uncompute flag via cmp-lt: flag ^= (acc_low < a_low)
       (cond
         (*cuccaro-use-borrowed*
          ;; 2026-06-12 H7a-third-defect probe: replace constant (* 3 n+1)
          ;; bit-base with cas-alloc counter — same defect class as cdtf.
          (cmp-lt-into-fast! c acc-reg a-reg n flag-reg flag-idx cin-reg cin-idx
                             tmp-reg 0 (cas-alloc-bit-base! n)))
         (else
          (cmp-lt-into! c acc-reg a-reg n flag-reg flag-idx cin-reg cin-idx)))))))

;;; ── pseudo-Mersenne from-zero specialization ──────────────────────
;;;
;;; Same shape as mod-add-inplace-pseudo-mersenne! but step (1)'s
;;; cuccaro-add at width n+1 is replaced by (n+1) CX-copies.
;;; Steps (2) and (3) fire unchanged.

(define (mod-add-inplace-pseudo-mersenne-from-zero!
         c a-reg acc-reg n+1 p pmersenne-f
         cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "Pseudo-Mersenne variant of mod-add-from-zero!. Saves the step-1
   cuccaro-add by replacing it with n+1 CX-copies. acc-reg MUST be
   |0> on entry across all n+1 bits."
  (let* ((n        (- n+1 1))
         (f-bits   (pmersenne-bit-length pmersenne-f))
         (padding  *mod-add-pseudo-mersenne-padding*)
         (lsbs     (min n+1 (+ padding f-bits)))
         (cmp-w    (min padding n)))
    ;; (1) CX-copy a into acc (saves n CCX vs cuccaro-add!).
    (cuccaro-add-from-zero! c a-reg acc-reg cin-reg cin-idx n+1)
    ;; (2) cadd(acc[n], f, acc[:lsbs]) — fires unchanged.
    (cadd-const! c acc-reg lsbs pmersenne-f
                 acc-reg n cin-reg cin-idx tmp-reg)
    ;; (3) Uncompute acc[n] via MSB comparator — fires unchanged.
    (cond
      (*dgcd-apply-boundary-conditional-replay*
       (let ((phase-bit (* 5 n+1)))
         (gate-hmr! c acc-reg n phase-bit)
         (cmp-lt-phase-conditioned-with-cin!
           c acc-reg (- n cmp-w) a-reg (- n cmp-w) cmp-w
           cin-reg cin-idx
           acc-reg n
           phase-bit
           tmp-reg 0 (* 3 n+1))))
      (*cuccaro-use-borrowed*
       (cmp-lt-into-fast-offset!
         c acc-reg (- n cmp-w) a-reg (- n cmp-w) cmp-w
         acc-reg n cin-reg cin-idx
         tmp-reg 0 (* 3 n+1)))
      (else
       (cmp-lt-into-offset!
         c acc-reg (- n cmp-w) a-reg (- n cmp-w) cmp-w
         acc-reg n cin-reg cin-idx)))))

;;; ── mod-add-from-zero! — caller-explicit acc=|0> specialization ───
;;;
;;; Port of HEAD's `mod_add_qq_fast_from_zero` (mod.rs:961-1038). When
;;; acc-reg is provably |0> on entry, the (n+1)-bit cuccaro add at
;;; step (1) reduces to (n+1) CX-copies. Steps (2)-(8) fire unchanged
;;; — the addend a may exceed p, so the reduce-by-c path still must
;;; run. Saves n CCX per call vs full mod-add!.
;;;
;;; Caller responsibility:
;;;   - acc-reg MUST be |0> on entry across all n+1 bits.
;;;   - a-reg follows extended-reg convention (top bit |0>) — same as
;;;     mod-add!.
;;;
;;; Dispatches through pseudo-Mersenne or Solinas path mirroring
;;; mod-add!'s `cond`, so callers see uniform behavior under either
;;; lever stack.

(define (mod-add-from-zero! c a-reg acc-reg n+1 p
                            cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "acc := (acc + a) mod p WHEN acc is |0> on entry. n CCX saved vs
   mod-add!. See mod-add! header for parameter shape."
  (let* ((n        (- n+1 1))
         (c-const  (- (expt 2 n) p))
         (f-bits   (pmersenne-bit-length c-const))
         (padding  *mod-add-pseudo-mersenne-padding*))
    (cond
      ;; 2026-06-12 — DISABLED. mod-add-inplace-pseudo-mersenne-from-zero!
      ;; shares the same MSB-only-comparator pattern as the in-place
      ;; variant — step (2) cadd controlled on acc[n] misses sum ∈ [p, 2^n)
      ;; boundary. See commit 5e6e3af for full analysis.
      ;;
      ;; 2026-06-12 (alg-11 wiring) — when *mod-add-alg-11-fallback* on,
      ;; the band detector classically peeks both operands & routes
      ;; pseudo-Mersenne only on safe inputs. Since acc-reg is provably
      ;; |0> on entry per the from-zero contract, the band detector
      ;; sees acc-cl = 0 → safe iff a-cl < p (the only relevant case).
      ((and *mod-add-use-pseudo-mersenne*
            (> c-const 0)
            (< (+ padding f-bits) n+1)
            (mod-add-alg-11-safe? c a-reg acc-reg n+1 p))
       (mod-add-inplace-pseudo-mersenne-from-zero!
         c a-reg acc-reg n+1 p c-const
         cin-reg cin-idx tmp-reg flag-reg flag-idx))
      (else
       ;; (1) CX-copy a into acc (saves n CCX vs cuccaro-add!).
       (cuccaro-add-from-zero! c a-reg acc-reg cin-reg cin-idx n+1)
       ;; (2) add-const c at n+1 bits — fires unchanged.
       (add-const!   c acc-reg n+1 c-const cin-reg cin-idx tmp-reg)
       ;; (3) flag := acc[n] (overflow bit).
       (gate-cx!     c acc-reg n flag-reg flag-idx)
       ;; (4) X flag.
       (gate-x!      c flag-reg flag-idx)
       ;; (5) csub c controlled on flag.
       (csub-const!  c acc-reg n+1 c-const flag-reg flag-idx cin-reg cin-idx tmp-reg)
       ;; (6) X flag back.
       (gate-x!      c flag-reg flag-idx)
       ;; (7) CX flag -> acc[n] — clear top bit when flag=1.
       (gate-cx!     c flag-reg flag-idx acc-reg n)
       ;; (8) Uncompute flag via cmp-lt: flag ^= (acc < a).
       (cond
         (*cuccaro-use-borrowed*
          ;; 2026-06-12 H7a-third-defect probe: replace constant (* 3 n+1)
          ;; bit-base with cas-alloc counter — same defect class as cdtf.
          (cmp-lt-into-fast! c acc-reg a-reg n flag-reg flag-idx cin-reg cin-idx
                             tmp-reg 0 (cas-alloc-bit-base! n)))
         (else
          (cmp-lt-into! c acc-reg a-reg n flag-reg flag-idx cin-reg cin-idx)))))))

;;; ── inverses of add-const / csub-const (needed by mod-sub!) ────
;;;
;;; sub-const!  = inverse of add-const!  (unconditional subtract of k)
;;; cadd-const! = inverse of csub-const! (controlled add of k)
;;;
;;; Pattern mirrors add-const/csub-const: load classical k into tmp via
;;; (c)load-const, run cuccaro-(sub|add), unload. load/unload self-inverse.

(define (sub-const! c acc-reg n k cin-reg cin-idx tmp-reg)
  "acc := (acc - k) mod 2^n. tmp must be width-n at |0>."
  (let ((kk (modulo k (expt 2 n))))
    (load-const!   c tmp-reg n kk)
    (cuccaro-sub!  c tmp-reg acc-reg cin-reg cin-idx n)
    (unload-const! c tmp-reg n kk)))

;;; ── sweep-050 direct sparse-constant cadd / csub primitives ────
;;;
;;; *cadd-direct-trunc-fast* — sweep-050 lever. Port of HEAD's
;;; cadd_nbit_const_direct_trunc_fast (const_arith.rs:487-568) and the
;;; matching csub_nbit_const_direct_trunc_fast (const_arith.rs:574-654).
;;;
;;; When #t, cadd-const! / csub-const! dispatch to the direct path:
;;; for each nonzero bit i of k, a forward carry/borrow sweep emits
;;; 3-CCX maj (or 2-CCX+2-CX with fold_maj2 when *cuccaro-maj2* on)
;;; into a fresh carries ancilla. Carry-tail truncated at
;;; min(n-2, highest_set_bit(k) + window). Sum bits via CX. Backward
;;; sweep measurement-uncomputes carries via HMR + CZ_if triplet.
;;;
;;; Saves ~one cload + one cuccaro-add + one cunload per call vs the
;;; generic cload/cuccaro-add/cunload path. Predicted 2-4 % full-stack
;;; Toffoli when stacked with *cuccaro-maj2*.
;;;
;;; *cadd-direct-window* — carry-tail safety window (mirrors HEAD's
;;; `window` parameter). Higher window → smaller truncation flake
;;; probability ~2^-(window+1) per call; HEAD's default 8.

(define *cadd-direct-trunc-fast* #f)
(define *cadd-direct-window* 8)

;;; *cuccaro-maj2* — sweep-047 lever for fold_maj2 inside the direct
;;; primitives. Defensively defined here so a champion cell can set it
;;; even if sweep-047 hasn't landed its own define yet. When #t, each
;;; full-MAJ (3 CCX) becomes a maj2 fold (2 CCX + 2 CX) inside the
;;; direct path.

(define *cuccaro-maj2* #f)

;;; *cadd-direct-bit-base* — classical-bit base offset used by HMR
;;; uncompute inside the direct primitives. Each call consumes
;;; (last+1) consecutive bit IDs starting at this base.
;;;
;;; 2026-06-12 — H7a peel-8 (commit 648d78e) ROOT-CAUSED back-to-back
;;; mod-add composition wrong-output to constant-bit-base reuse across
;;; consecutive cadd-const!/csub-const! calls. The prior claim "reuse
;;; across separate calls is safe (push-cond/pop-cond brackets every
;;; cz_if)" turned out wrong under cumulative kaliski-body state.
;;; Sweep-doctrine reducers test-mca-bisect-precursor + peel-8 toggle
;;; demonstrate the collision flips the second sum by 2^top-set-bit(k).
;;;
;;; Fix: monotonic counter (*cadd-direct-bit-base-next*) advances
;;; per-call by `n+1` so each direct call gets a unique non-overlapping
;;; slot range. *cadd-direct-bit-base* preserved for back-compat (read
;;; as the floor; never mutated directly). cdtf-alloc-bit-base!(n)
;;; returns the next slot.

(define *cadd-direct-bit-base* 400000)
(define *cadd-direct-bit-base-next* 400000)

(define (cdtf-alloc-bit-base! n)
  "Return a fresh non-overlapping classical-bit base for one cdtf call.
   Advances *cadd-direct-bit-base-next* by (n+1) so each call's HMR slots
   live in their own [b, b+n] range. n is the width passed to the direct
   primitive — must reserve at least n+1 consecutive IDs."
  (let ((b *cadd-direct-bit-base-next*))
    (set! *cadd-direct-bit-base-next* (+ b n 1))
    b))

(define (highest-set-bit k)
  "Index (0-based) of the highest set bit of positive integer k.
   highest-set-bit(0)=0 (caller guards via popcount > 0)."
  (let loop ((i 0) (m k))
    (cond
      ((= m 0) (if (= i 0) 0 (- i 1)))
      (else    (loop (+ i 1) (quotient m 2))))))

;;; ── cadd/csub_nbit_const_direct_fast (sweep-cadd-csub-direct-fast)
;;;
;;; HEAD const_arith.rs:65 csub_nbit_const_direct_fast
;;;      const_arith.rs:152 cadd_nbit_const_direct_fast
;;;
;;; Closes AUDIT §8 rows 203 (direct-fast pair, non-truncated). The
;;; truncated variants (-trunc-fast) already ported below.
;;;
;;; "Direct" = no auxiliary loaded-constant register. Skips the n-qubit
;;; register at Kaliski halve peaks; for sparse secp256k1 c=2^32+977
;;; CCX count essentially unchanged vs auxiliary-register path but
;;; peak qubits drop by n.
;;;
;;; Pattern (per HEAD lines 65-131 sub, 152-217 add):
;;;   1. carries/borrows register: alloc n-1 ancillas
;;;   2. forward carry/borrow sweep — CCX on majority recurrence,
;;;      gated on bit(k,i) sparsity
;;;   3. sum/difference bits: cx(ctrl, acc[i]) when bit(k,i); cx
;;;      carry into acc
;;;   4. measurement-uncompute carries in reverse — HMR + cz_if pattern
;;;      per Gidney 2025
;;;
;;; Caller responsibility:
;;;   acc-reg : data register width n
;;;   ctrl-reg/ctrl-idx : control bit
;;;   carries-reg : (n-1)-wide clean ancilla register; restored
;;;   bit-base : classical bit-id base for HMR (uses n-1 bits)

(define (cadd-nbit-const-direct-fast!
          c acc-reg n k ctrl-reg ctrl-idx carries-reg bit-base)
  "Port of HEAD cadd_nbit_const_direct_fast (const_arith.rs:152).
   acc += (ctrl ? k : 0) mod 2^n via direct carry sweep + HMR uncompute."
  (cond
    ((= n 0) #t)
    ((= n 1)
     (when (bit-set? k 0) (gate-cx! c ctrl-reg ctrl-idx acc-reg 0)))
    (else
     ;; Forward carry sweep
     (let loop-fwd ((i 0))
       (when (< i (- n 1))
         (let ((target  (cons carries-reg i))
               (has-cin (> i 0)))
           (cond
             ((bit-set? k i)
              (cond
                (has-cin
                 (gate-ccx! c acc-reg i carries-reg (- i 1) carries-reg i)
                 (gate-ccx! c ctrl-reg ctrl-idx acc-reg i carries-reg i)
                 (gate-ccx! c ctrl-reg ctrl-idx carries-reg (- i 1) carries-reg i))
                (else
                 (gate-ccx! c acc-reg i ctrl-reg ctrl-idx carries-reg i))))
             (has-cin
              (gate-ccx! c acc-reg i carries-reg (- i 1) carries-reg i))))
         (loop-fwd (+ i 1))))
     ;; Sum bits
     (let loop-sum ((i 0))
       (when (< i n)
         (when (bit-set? k i)
           (gate-cx! c ctrl-reg ctrl-idx acc-reg i))
         (when (> i 0)
           (gate-cx! c carries-reg (- i 1) acc-reg i))
         (loop-sum (+ i 1))))
     ;; Measurement-uncompute carries (reverse). For ADDITION the
     ;; identity is carry_{i+1} = majority(!acc_i_final, k_i, carry_i)
     ;; — note the X on acc[i] around the cz_if pairs.
     (let loop-back ((i (- n 2)))
       (when (>= i 0)
         (let ((bit-id  (+ bit-base i))
               (has-cin (> i 0)))
           (gate-hmr! c carries-reg i bit-id)
           (cond
             ((bit-set? k i)
              (gate-x! c acc-reg i)
              (cond
                (has-cin
                 (gate-push-cond! c bit-id)
                 (gate-cz! c acc-reg i ctrl-reg ctrl-idx)
                 (gate-pop-cond! c)
                 (gate-push-cond! c bit-id)
                 (gate-cz! c acc-reg i carries-reg (- i 1))
                 (gate-pop-cond! c)
                 (gate-x! c acc-reg i)
                 (gate-push-cond! c bit-id)
                 (gate-cz! c ctrl-reg ctrl-idx carries-reg (- i 1))
                 (gate-pop-cond! c))
                (else
                 (gate-push-cond! c bit-id)
                 (gate-cz! c acc-reg i ctrl-reg ctrl-idx)
                 (gate-pop-cond! c)
                 (gate-x! c acc-reg i))))
             (has-cin
              (gate-x! c acc-reg i)
              (gate-push-cond! c bit-id)
              (gate-cz! c acc-reg i carries-reg (- i 1))
              (gate-pop-cond! c)
              (gate-x! c acc-reg i))))
         (loop-back (- i 1)))))))

(define (csub-nbit-const-direct-fast!
          c acc-reg n k ctrl-reg ctrl-idx borrows-reg bit-base)
  "Port of HEAD csub_nbit_const_direct_fast (const_arith.rs:65).
   acc -= (ctrl ? k : 0) mod 2^n via direct borrow sweep + HMR uncompute."
  (cond
    ((= n 0) #t)
    ((= n 1)
     (when (bit-set? k 0) (gate-cx! c ctrl-reg ctrl-idx acc-reg 0)))
    (else
     ;; Forward borrow sweep. borrow_{i+1} = majority(!acc_i, k_i, borrow_i).
     (let loop-fwd ((i 0))
       (when (< i (- n 1))
         (let ((has-bin (> i 0)))
           (cond
             ((bit-set? k i)
              (gate-x! c acc-reg i)
              (cond
                (has-bin
                 (gate-ccx! c acc-reg i borrows-reg (- i 1) borrows-reg i)
                 (gate-ccx! c ctrl-reg ctrl-idx acc-reg i borrows-reg i)
                 (gate-ccx! c ctrl-reg ctrl-idx borrows-reg (- i 1) borrows-reg i))
                (else
                 (gate-ccx! c acc-reg i ctrl-reg ctrl-idx borrows-reg i)))
              (gate-x! c acc-reg i))
             (has-bin
              (gate-x! c acc-reg i)
              (gate-ccx! c acc-reg i borrows-reg (- i 1) borrows-reg i)
              (gate-x! c acc-reg i))))
         (loop-fwd (+ i 1))))
     ;; Difference bits: acc_i ^= k_i ^ borrow_i.
     (let loop-diff ((i 0))
       (when (< i n)
         (when (bit-set? k i)
           (gate-cx! c ctrl-reg ctrl-idx acc-reg i))
         (when (> i 0)
           (gate-cx! c borrows-reg (- i 1) acc-reg i))
         (loop-diff (+ i 1))))
     ;; Measurement-uncompute borrows. For SUBTRACTION the post-sum
     ;; identity is borrow_{i+1} = majority(acc_i_final, k_i, borrow_i).
     ;; No X bracketing around acc[i] (different from add).
     (let loop-back ((i (- n 2)))
       (when (>= i 0)
         (let ((bit-id  (+ bit-base i))
               (has-bin (> i 0)))
           (gate-hmr! c borrows-reg i bit-id)
           (cond
             ((bit-set? k i)
              (cond
                (has-bin
                 (gate-push-cond! c bit-id)
                 (gate-cz! c acc-reg i ctrl-reg ctrl-idx)
                 (gate-pop-cond! c)
                 (gate-push-cond! c bit-id)
                 (gate-cz! c acc-reg i borrows-reg (- i 1))
                 (gate-pop-cond! c)
                 (gate-push-cond! c bit-id)
                 (gate-cz! c ctrl-reg ctrl-idx borrows-reg (- i 1))
                 (gate-pop-cond! c))
                (else
                 (gate-push-cond! c bit-id)
                 (gate-cz! c acc-reg i ctrl-reg ctrl-idx)
                 (gate-pop-cond! c))))
             (has-bin
              (gate-push-cond! c bit-id)
              (gate-cz! c acc-reg i borrows-reg (- i 1))
              (gate-pop-cond! c))))
         (loop-back (- i 1)))))))

(define (cadd-nbit-const-direct-trunc-fast!
         c acc-reg n k ctrl-reg ctrl-idx tmp-reg window bit-base)
  "acc[0..n) += (ctrl ? k : 0), carry-tail truncated.
   Port of HEAD cadd_nbit_const_direct_trunc_fast (const_arith.rs:487-568).

   acc-reg : (>=n)-wide quantum register holding the running accumulator.
   n       : slice width (>=1). Must not overlap with ctrl-reg/ctrl-idx.
   k       : compile-time classical integer; only its low n bits read.
   ctrl-reg, ctrl-idx : the qubit controlling the add (must not alias
                       any of acc-reg[0..n)).
   tmp-reg : (>=last+1)-wide ancilla register at |0>. Borrowed as the
             carries lane (acc-reg's tmp slot is wide enough for every
             pseudo-Mersenne caller in our stack).
   window  : carry-tail safety bits past highest_set_bit(k). HEAD's
             default 8; flake prob ~2^-(window+1).
   bit-base: classical-bit base offset; consumes [bit-base, bit-base+last]
             via HMR. Caller picks a non-colliding region.

   Returns tmp-reg[0..last] to |0> via HMR + cz_if; acc-reg gets
   updated sum; ctrl-reg unchanged."
  (let ((kk (modulo k (expt 2 n))))
    (cond
      ((= n 0) #t)
      ((= n 1)
       (when (bit-set? kk 0)
         (gate-cx! c ctrl-reg ctrl-idx acc-reg 0)))
      ((= kk 0) #t)
      (else
       (let* ((hi   (highest-set-bit kk))
              (last (min (- n 2) (+ hi window)))
              (maj2 *cuccaro-maj2*))
         ;; Forward carry sweep, truncated at `last`.
         (let loop ((i 0))
           (when (<= i last)
             (let ((carry-in? (> i 0)))
               (cond
                 ((bit-set? kk i)
                  (cond
                    (carry-in?
                     (cond
                       (maj2
                        (gate-ccx! c acc-reg i tmp-reg (- i 1) tmp-reg i)
                        (gate-cx!  c acc-reg i tmp-reg (- i 1))
                        (gate-ccx! c ctrl-reg ctrl-idx tmp-reg (- i 1) tmp-reg i)
                        (gate-cx!  c acc-reg i tmp-reg (- i 1)))
                       (else
                        (gate-ccx! c acc-reg i tmp-reg (- i 1) tmp-reg i)
                        (gate-ccx! c ctrl-reg ctrl-idx acc-reg i tmp-reg i)
                        (gate-ccx! c ctrl-reg ctrl-idx tmp-reg (- i 1) tmp-reg i))))
                    (else
                     (gate-ccx! c acc-reg i ctrl-reg ctrl-idx tmp-reg i))))
                 (carry-in?
                  (gate-ccx! c acc-reg i tmp-reg (- i 1) tmp-reg i))))
             (loop (+ i 1))))
         ;; Sum bits: acc_i ^= k_i ^ carry_{i-1}; carries above last are 0.
         (let loop ((i 0))
           (when (< i n)
             (when (bit-set? kk i)
               (gate-cx! c ctrl-reg ctrl-idx acc-reg i))
             (when (and (> i 0) (<= (- i 1) last))
               (gate-cx! c tmp-reg (- i 1) acc-reg i))
             (loop (+ i 1))))
         ;; Backward measurement-uncompute carries (HMR + cz_if triplet).
         (let loop-back ((i last))
           (when (>= i 0)
             (let ((m         (+ bit-base i))
                   (carry-in? (> i 0)))
               (gate-hmr! c tmp-reg i m)
               (cond
                 ((bit-set? kk i)
                  (gate-x! c acc-reg i)
                  (cond
                    (carry-in?
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i ctrl-reg ctrl-idx)
                     (gate-pop-cond!  c)
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i tmp-reg (- i 1))
                     (gate-pop-cond!  c)
                     (gate-x! c acc-reg i)
                     (gate-push-cond! c m)
                     (gate-cz!        c ctrl-reg ctrl-idx tmp-reg (- i 1))
                     (gate-pop-cond!  c))
                    (else
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i ctrl-reg ctrl-idx)
                     (gate-pop-cond!  c)
                     (gate-x! c acc-reg i))))
                 (carry-in?
                  (gate-x! c acc-reg i)
                  (gate-push-cond! c m)
                  (gate-cz!        c acc-reg i tmp-reg (- i 1))
                  (gate-pop-cond!  c)
                  (gate-x! c acc-reg i))))
             (loop-back (- i 1)))))))))

(define (csub-nbit-const-direct-trunc-fast!
         c acc-reg n k ctrl-reg ctrl-idx tmp-reg window bit-base)
  "acc[0..n) -= (ctrl ? k : 0), borrow-tail truncated.
   Port of HEAD csub_nbit_const_direct_trunc_fast (const_arith.rs:574-654).
   Same calling convention as cadd-nbit-const-direct-trunc-fast!."
  (let ((kk (modulo k (expt 2 n))))
    (cond
      ((= n 0) #t)
      ((= n 1)
       (when (bit-set? kk 0)
         (gate-cx! c ctrl-reg ctrl-idx acc-reg 0)))
      ((= kk 0) #t)
      (else
       (let* ((hi   (highest-set-bit kk))
              (last (min (- n 2) (+ hi window)))
              (maj2 *cuccaro-maj2*))
         ;; Forward borrow sweep, truncated at `last`.
         (let loop ((i 0))
           (when (<= i last)
             (let ((borrow-in? (> i 0)))
               (cond
                 ((bit-set? kk i)
                  (gate-x! c acc-reg i)
                  (cond
                    (borrow-in?
                     (cond
                       (maj2
                        (gate-ccx! c acc-reg i tmp-reg (- i 1) tmp-reg i)
                        (gate-cx!  c acc-reg i tmp-reg (- i 1))
                        (gate-ccx! c ctrl-reg ctrl-idx tmp-reg (- i 1) tmp-reg i)
                        (gate-cx!  c acc-reg i tmp-reg (- i 1)))
                       (else
                        (gate-ccx! c acc-reg i tmp-reg (- i 1) tmp-reg i)
                        (gate-ccx! c ctrl-reg ctrl-idx acc-reg i tmp-reg i)
                        (gate-ccx! c ctrl-reg ctrl-idx tmp-reg (- i 1) tmp-reg i))))
                    (else
                     (gate-ccx! c acc-reg i ctrl-reg ctrl-idx tmp-reg i)))
                  (gate-x! c acc-reg i))
                 (borrow-in?
                  (gate-x! c acc-reg i)
                  (gate-ccx! c acc-reg i tmp-reg (- i 1) tmp-reg i)
                  (gate-x! c acc-reg i))))
             (loop (+ i 1))))
         ;; Difference bits.
         (let loop ((i 0))
           (when (< i n)
             (when (bit-set? kk i)
               (gate-cx! c ctrl-reg ctrl-idx acc-reg i))
             (when (and (> i 0) (<= (- i 1) last))
               (gate-cx! c tmp-reg (- i 1) acc-reg i))
             (loop (+ i 1))))
         ;; Backward measurement-uncompute borrows.
         (let loop-back ((i last))
           (when (>= i 0)
             (let ((m          (+ bit-base i))
                   (borrow-in? (> i 0)))
               (gate-hmr! c tmp-reg i m)
               (cond
                 ((bit-set? kk i)
                  (cond
                    (borrow-in?
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i ctrl-reg ctrl-idx)
                     (gate-pop-cond!  c)
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i tmp-reg (- i 1))
                     (gate-pop-cond!  c)
                     (gate-push-cond! c m)
                     (gate-cz!        c ctrl-reg ctrl-idx tmp-reg (- i 1))
                     (gate-pop-cond!  c))
                    (else
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i ctrl-reg ctrl-idx)
                     (gate-pop-cond!  c))))
                 (borrow-in?
                  (gate-push-cond! c m)
                  (gate-cz!        c acc-reg i tmp-reg (- i 1))
                  (gate-pop-cond!  c))))
             (loop-back (- i 1)))))))))

;;; ── sweep-060 per-position-controls primitives ────────────────────
;;;
;;; Port of HEAD's cadd_per_position_controls_trunc /
;;; csub_per_position_controls_trunc (const_arith.rs:657-814).
;;;
;;; Unlike cadd-nbit-const-direct-trunc-fast! the "constant" k is NOT a
;;; compile-time scalar. Instead each position carries its own runtime
;;; qubit control kctrl[i] — possibly absent. The 3-CCX maj cluster
;;; operates on (acc[i], kctrl[i], carry_in). With *perpos-maj2* on,
;;; substitute 2-CCX + 2-CX ancilla-free majority (per HEAD's
;;; perpos_maj2_enabled() doc at const_arith.rs:449-466).
;;;
;;; lumbda representation of the per-position-controls vector:
;;;   list of length <= n where each element is either
;;;     - #f               -> no control at this position (k_i = 0)
;;;     - (reg . idx)      -> runtime control qubit at this position
;;;   Positions beyond list length default to #f (no control).
;;;
;;; The `last` argument is the inclusive truncation index for the
;;; carry/borrow sweep (mirrors HEAD's `last: usize`). Caller computes
;;; last = min(n-2, highest-controlled-position + window) so positions
;;; above `last` get carries assumed 0. Flake probability identical to
;;; HEAD's truncated direct adder.
;;;
;;; *perpos-maj2* — sweep-060 lever. When #t, the 3-CCX maj inside the
;;; per-pos-controls primitives substitutes the 2-CCX + 2-CX
;;; ancilla-free pattern. Default #f (3-CCX safe baseline).

(define *perpos-maj2* #f)

;;; ── HEAD modular-tier lever family (sweep-modular-lever-flags) ────
;;;
;;; Closes AUDIT §6 / §8 rows 217-218, 248-249, 260-261, 263.
;;; All default-OFF flag declarations covering HEAD's modular-tier
;;; configure_ecdsafail_submission_route lever surface.

;; *fold-maj2* — sibling of *perpos-maj2*. HEAD mod.rs:471
;; fold_maj2_enabled. The 2-CCX + 2-CX ancilla-free maj substitution
;; inside fold_carry path. Default #f.
(define *fold-maj2* #f)

;; ── HEAD fold substrate family (const_arith.rs:9-1267) ──
;; Wires the 4 fold-stage knobs that HEAD's submission route enables.
;; Port covers `fold_postsum_carry_phase_uncompute`,
;; `fold_postsum_carry_compute`, `emit_fold_maj1`/`emit_fold_majority`,
;; `fold_park_low_carries`, `fold_ripple_freed_tail_ed`.
;;
;; *fold-maj1* — HEAD const_arith.rs:9 fold_maj1_enabled. When #t AND
;; the four maj inputs (a, k, carry, target) are all-distinct qubits,
;; substitute the 4-CX + 1-CCX maj1 emit (saves 2 Toffoli vs the
;; 3-CCX baseline, costs 4 CX). Coexists with *fold-maj2*; maj1 wins
;; when applicable. Default #f. Already declared in
;; head-route-missing-flags.lsp; consumed here in the fold dispatch.

;; *fold-park-low-carries* — integer count of low carries to park via
;; HMR + cz_if phase-uncompute mid-ripple (mirrors HEAD's
;; fold_park_low_carries() return). Range [0, hi_delta]. Default 0
;; (no parking). When > 0, drops the fused double/halve high-water by
;; `park` qubits at cost of `park` extra HMR + cz_if pairs (phase-exact;
;; 0 Toffoli). Caller sets via `(set! *fold-park-low-carries* N)`.
(define *fold-park-low-carries* 0)

;; *fold-freed-tail* — HEAD const_arith.rs:867 fold_freed_tail_enabled.
;; When #t, switch the fused-fold ripple to the split-lane variant:
;; alloc `low[0..=hi_delta]` first, run active region, free the four
;; derived controls (h, xed, eord, n10), THEN alloc `tail` for the
;; wide high tail. Drops the wide-tail high-water by 4 ancillae (the
;; 4 derived controls released before the tail allocation peak).
;; Value/phase-EXACT vs the unsplit ripple. Default #f.
(define *fold-freed-tail* #f)
;; Backwards-compat alias for the `dgcd-` namespaced variant declared
;; in head-route-missing-flags.lsp — when either flag is set, the
;; freed-tail dispatch fires (consumer: cadd-2-controls-trunc-fast!).
;; *fold-freed-tail-ed* extends the freed-tail to ALSO release e,d
;; across the wide high tail (HYP-6 §4a). HEAD: -2 ancillae more.
;; Lumbda: STRUCTURAL NO-OP. The freed-tail dispatcher's caller-side
;; `e`/`d` are NOT separately allocated qubits in lumbda — the
;; `cadd-2-controls-trunc-fast!` dispatcher binds `e ↔ ctrl1-reg/idx`
;; and `d ↔ ctrl2-reg/idx` directly (mod-arith.lsp:2750-2755 docstring).
;; mod-4x-inplace! passes ovf1/ovf2 themselves as ctrl1/ctrl2, exploiting
;; the s2=1 classical specialization (s2 is a classical-true constant
;; under lumbda's K=2 host emit, never a qubit). Per HEAD compressed.rs
;; :3260-3271 the e,d copy alloc is `d = ovf1 & s2; e = ovf1 ^ d ^ ovf2`
;; — under s2=1 collapses to `d = ovf1; e = ovf2`. Lumbda skipped this
;; copy-alloc structurally, so it has nothing extra to free across the
;; tail. The -2 ancilla win HEAD reports is already-banked at the
;; substrate level. See test-fold-freed-tail-ed-port.lsp for the
;; positive-control reducer that proves byte-identity for flag-ON vs
;; flag-OFF + identical peak-qubits + identical toffoli counts.

;; *double-carry-trunc-window* — HEAD mod.rs:427
;; double_carry_trunc_window. KAL_DOUBLE_CARRY_TRUNC_W from
;; configure_ecdsafail_submission_route (=20 in HEAD's tuned route).
;; Integer truncation width for double-carry path; 0 = OFF.
(define *double-carry-trunc-window* 0)

;; *fold-carry-trunc-window* — HEAD mod.rs:442
;; fold_carry_trunc_window. KAL_FOLD_CARRY_TRUNC_W from
;; configure_ecdsafail_submission_route (=20 in HEAD). 0 = OFF.
(define *fold-carry-trunc-window* 0)

;; *mod-add-qq-vent* — HEAD mod.rs:189 mod_add_qq_vent.
;; KAL_VENT_MODADD lever; vent-based mod-add saves overflow ancilla
;; in Kaliski loop body. Default #f.
(define *mod-add-qq-vent* #f)

;; *mod-sub-qq-vent* — HEAD mod.rs:250 mod_sub_qq_vent. Symmetric.
(define *mod-sub-qq-vent* #f)

;; *mod-add-qq-fast-from-zero* — HEAD mod.rs:961
;; mod_add_qq_fast_from_zero. Initial-state-known optimization;
;; saves the cin walk when acc is provably |0> on entry. Default #f.
(define *mod-add-qq-fast-from-zero* #f)

;; *cmod-double-inplace-lazy* — HEAD mod.rs:817 cmod_double_inplace_lazy.
;; Controlled lazy form of mod_double_inplace_fast; used inside HEAD's
;; apply-bitvector chunked path. Default #f.
(define *cmod-double-inplace-lazy* #f)

;; *cmod-halve-inplace-lazy* — HEAD mod.rs:841. Symmetric. Default #f.
(define *cmod-halve-inplace-lazy* #f)

;; *mod-shift-left-by-k-lowq* — HEAD mod.rs:618. lowq variant of
;; mod_shift_left_by_k. Default #f.
(define *mod-shift-left-by-k-lowq* #f)

;; *mod-shift-right-by-k-lowq* — HEAD mod.rs:678. Symmetric. Default #f.
(define *mod-shift-right-by-k-lowq* #f)

;; ── extcarry_clean family — HEAD const_arith.rs:239-331 ──
;;
;; Six default-OFF flags covering the clean-extcarry adder primitives
;; HEAD uses when MSB is provably zero. All flags gate variant dispatch
;; at the const-arith callsite (downstream substrate work).

(define *add-nbit-const-extcarry-clean*           #f)
(define *add-nbit-const-extcarry-clean-with-cin*  #f)
(define *sub-nbit-const-extcarry-clean*           #f)
(define *cadd-nbit-const-extcarry-clean*          #f)
(define *csub-nbit-const-extcarry-clean*          #f)
(define *csub-nbit-const-extcarry-clean-with-cin* #f)

;; ── direct-fast variants — HEAD const_arith.rs:65,152 ──
;;
;; cadd_nbit_const_direct_fast / csub_nbit_const_direct_fast — the
;; DIRECT_CONST_WALKS path. *cadd-direct-trunc-fast* (truncated
;; variant) already PORTED; these flag the non-truncated DIRECT_CONST
;; siblings. Default #f.

(define *cadd-nbit-const-direct-fast* #f)
(define *csub-nbit-const-direct-fast* #f)

;; *csub-per-position-controls-trunc* — sibling of
;; cadd-per-position-controls-trunc! (already ported as lumbda
;; primitive). Flag declaration here for variant dispatch. Default #f.

(define *csub-per-position-controls-trunc* #f)

;;; *kaliski-use-per-pos-controls* — sweep-060 lever. When #t, host
;;; kaliski iteration's apply-phase callsite dispatches into
;;; cadd-per-position-controls-trunc! instead of the compile-time
;;; constant adder. Default #f — substrate gap means no callsite
;;; consumes this lever yet (see RESULTS.md for the apply-phase
;;; roadmap). Defensive flag definition so champion cells can set it
;;; without redefinition errors.

(define *kaliski-use-per-pos-controls* #f)

(define (perpos-ctrl-at controls i)
  "Return the per-position control pair at index i, or #f. Out-of-range
   defaults to #f (no control)."
  (cond
    ((null? controls) #f)
    ((<= i -1)        #f)
    (else
     (let loop ((lst controls) (j 0))
       (cond
         ((null? lst) #f)
         ((= j i)     (car lst))
         (else        (loop (cdr lst) (+ j 1))))))))

(define (perpos-ctrls-length controls)
  "Length of the per-position-controls list."
  (let loop ((lst controls) (n 0))
    (cond
      ((null? lst) n)
      (else        (loop (cdr lst) (+ n 1))))))

(define (cadd-per-position-controls-trunc!
         c acc-reg n controls last tmp-reg bit-base)
  "acc[0..n) += sum_{i where ctrl_i present} (ctrl_i ? 2^i : 0),
   carry-tail truncated at index `last` (inclusive).

   Port of HEAD cadd_per_position_controls_trunc (const_arith.rs:657-735).

   acc-reg  : (>=n)-wide quantum register holding the running accumulator.
   n        : slice width (>=1). Must not overlap any control qubit.
   controls : list of length <= n of either #f or (reg . idx) pairs.
              Position i: ctrl_i = (perpos-ctrl-at controls i). If #f,
              position contributes 0; else contributes 2^i conditioned on
              that ctrl qubit.
   last     : inclusive truncation index for the carry sweep. Must
              satisfy 0 <= last < n. Caller picks last = min(n-2,
              highest-active-pos + window). Carries above `last` assumed 0.
   tmp-reg  : (>=last+1)-wide ancilla register at |0> for the carries lane.
   bit-base : classical-bit base offset. Consumes [bit-base,
              bit-base+last] via HMR during measurement-uncompute.

   When *perpos-maj2* #t, each 3-CCX maj substitutes 2-CCX + 2-CX
   ancilla-free majority (target ^= maj(acc,carry_in,kc) emitted as
   ccx(acc,ci,target); cx(acc,ci); ccx(kc,ci,target); cx(acc,ci)).

   Returns tmp-reg[0..last] to |0> via HMR + cz_if; acc-reg gets sum
   updated; every kctrl unchanged."
  (cond
    ((= n 0) #t)
    ((<= last -1) #t)
    (else
     (let ((maj2 *perpos-maj2*)
           (ctrl-len (perpos-ctrls-length controls)))
       ;; Defensive: last must be < n.
       (when (>= last n)
         (error "cadd-per-position-controls-trunc!: last >= n"
                last n))
       ;; Forward carry sweep, truncated at `last`.
       ;; carry_i = maj(acc_i, kctrl_i, carry_{i-1}) when both kc + ci
       ;; present; lower-order branches when one is absent.
       (let loop ((i 0))
         (when (<= i last)
           (let* ((kc        (perpos-ctrl-at controls i))
                  (carry-in? (> i 0)))
             (cond
               (kc
                (let ((kc-reg (car kc))
                      (kc-idx (cdr kc)))
                  (cond
                    (carry-in?
                     ;; *fold-maj1* (when on AND inputs distinct) wraps to
                     ;; 4-CX + 1-CCX maj1 (saves 2 Toff/pos); else falls
                     ;; through to maj2 (2-CCX + 2-CX) when caller set
                     ;; maj2 #t; else 3-CCX baseline. Byte-identical when
                     ;; *fold-maj1* off — emit-fold-majority!'s maj2/3-CCX
                     ;; branches match the prior inline gate sequence.
                     (emit-fold-majority! c
                       acc-reg i        ; a (acc[i])
                       kc-reg  kc-idx   ; k (kctrl_i)
                       tmp-reg (- i 1)  ; ci (carry_{i-1})
                       tmp-reg i        ; target (carry_i)
                       maj2))
                    (else
                     (gate-ccx! c acc-reg i kc-reg kc-idx tmp-reg i)))))
               (carry-in?
                (gate-ccx! c acc-reg i tmp-reg (- i 1) tmp-reg i))))
           (loop (+ i 1))))
       ;; Sum bits: acc_i ^= kctrl_i ^ carry_{i-1}; carries above last 0.
       (let loop ((i 0))
         (when (< i n)
           (let ((kc (perpos-ctrl-at controls i)))
             (when kc
               (gate-cx! c (car kc) (cdr kc) acc-reg i))
             (when (and (> i 0) (<= (- i 1) last))
               (gate-cx! c tmp-reg (- i 1) acc-reg i))
             (loop (+ i 1)))))
       ;; Backward measurement-uncompute carries via HMR + cz_if.
       (let loop-back ((i last))
         (when (>= i 0)
           (let ((m         (+ bit-base i))
                 (kc        (perpos-ctrl-at controls i))
                 (carry-in? (> i 0)))
             (gate-hmr! c tmp-reg i m)
             (cond
               (kc
                (let ((kc-reg (car kc))
                      (kc-idx (cdr kc)))
                  (gate-x! c acc-reg i)
                  (cond
                    (carry-in?
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i kc-reg kc-idx)
                     (gate-pop-cond!  c)
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i tmp-reg (- i 1))
                     (gate-pop-cond!  c)
                     (gate-x! c acc-reg i)
                     (gate-push-cond! c m)
                     (gate-cz!        c kc-reg kc-idx tmp-reg (- i 1))
                     (gate-pop-cond!  c))
                    (else
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i kc-reg kc-idx)
                     (gate-pop-cond!  c)
                     (gate-x! c acc-reg i)))))
               (carry-in?
                (gate-x! c acc-reg i)
                (gate-push-cond! c m)
                (gate-cz!        c acc-reg i tmp-reg (- i 1))
                (gate-pop-cond!  c)
                (gate-x! c acc-reg i))))
           (loop-back (- i 1))))))))

(define (csub-per-position-controls-trunc!
         c acc-reg n controls last tmp-reg bit-base)
  "acc[0..n) -= sum_{i where ctrl_i present} (ctrl_i ? 2^i : 0),
   borrow-tail truncated at index `last` (inclusive).

   Port of HEAD csub_per_position_controls_trunc (const_arith.rs:737-814).
   Same calling convention as cadd-per-position-controls-trunc!."
  (cond
    ((= n 0) #t)
    ((<= last -1) #t)
    (else
     (let ((maj2 *perpos-maj2*))
       (when (>= last n)
         (error "csub-per-position-controls-trunc!: last >= n"
                last n))
       ;; Forward borrow sweep, truncated at `last`.
       (let loop ((i 0))
         (when (<= i last)
           (let* ((kc         (perpos-ctrl-at controls i))
                  (borrow-in? (> i 0)))
             (cond
               (kc
                (let ((kc-reg (car kc))
                      (kc-idx (cdr kc)))
                  (gate-x! c acc-reg i)
                  (cond
                    (borrow-in?
                     ;; Symmetric to cadd-per-position-controls-trunc!.
                     ;; X-sandwich on acc[i] inverts the carry-sense to
                     ;; borrow; the inner maj is identical to the add
                     ;; variant. *fold-maj1* fires here too when inputs
                     ;; distinct. Byte-identical when *fold-maj1* off.
                     (emit-fold-majority! c
                       acc-reg i        ; a (acc[i] with X-sandwich)
                       kc-reg  kc-idx
                       tmp-reg (- i 1)
                       tmp-reg i
                       maj2))
                    (else
                     (gate-ccx! c acc-reg i kc-reg kc-idx tmp-reg i)))
                  (gate-x! c acc-reg i)))
               (borrow-in?
                (gate-x! c acc-reg i)
                (gate-ccx! c acc-reg i tmp-reg (- i 1) tmp-reg i)
                (gate-x! c acc-reg i))))
           (loop (+ i 1))))
       ;; Difference bits: acc_i ^= kctrl_i ^ borrow_{i-1}.
       (let loop ((i 0))
         (when (< i n)
           (let ((kc (perpos-ctrl-at controls i)))
             (when kc
               (gate-cx! c (car kc) (cdr kc) acc-reg i))
             (when (and (> i 0) (<= (- i 1) last))
               (gate-cx! c tmp-reg (- i 1) acc-reg i))
             (loop (+ i 1)))))
       ;; Backward measurement-uncompute borrows.
       (let loop-back ((i last))
         (when (>= i 0)
           (let ((m          (+ bit-base i))
                 (kc         (perpos-ctrl-at controls i))
                 (borrow-in? (> i 0)))
             (gate-hmr! c tmp-reg i m)
             (cond
               (kc
                (let ((kc-reg (car kc))
                      (kc-idx (cdr kc)))
                  (cond
                    (borrow-in?
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i kc-reg kc-idx)
                     (gate-pop-cond!  c)
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i tmp-reg (- i 1))
                     (gate-pop-cond!  c)
                     (gate-push-cond! c m)
                     (gate-cz!        c kc-reg kc-idx tmp-reg (- i 1))
                     (gate-pop-cond!  c))
                    (else
                     (gate-push-cond! c m)
                     (gate-cz!        c acc-reg i kc-reg kc-idx)
                     (gate-pop-cond!  c)))))
               (borrow-in?
                (gate-push-cond! c m)
                (gate-cz!        c acc-reg i tmp-reg (- i 1))
                (gate-pop-cond!  c))))
           (loop-back (- i 1))))))))

;;; ── HEAD fold-substrate helpers (const_arith.rs:9-43, 911-987) ────
;;;
;;; Port of HEAD's fold-stage gate helpers. Used by both the baseline
;;; fused-fold ripple (when *fold-maj1* lifts maj inputs to maj1) and
;;; the freed-tail variant (which calls fold-postsum-carry-* directly
;;; for low-carry park / unpark).
;;;
;;; emit-fold-maj1!    : 4-CX + 1-CCX majority on 4 DISTINCT qubits.
;;;                      Saves 2 Toff vs the 3-CCX baseline; needs all
;;;                      4 inputs distinct (caller verifies).
;;; emit-fold-majority!: dispatch — fold-maj1 (if enabled + distinct),
;;;                      else maj2 (2 CCX + 2 CX), else 3-CCX baseline.
;;; fold-postsum-carry-phase-uncompute! : measurement-conditioned
;;;                      cz_if chain to un-park a parked carry (acc[i]
;;;                      ^= maj(...) inverse via cz_if instead of CCX).
;;; fold-postsum-carry-compute!        : symmetric compute-from-acc
;;;                      pass when re-parking after the tail uncompute.

(define (fold-maj1-inputs-distinct? a-reg a-idx k-reg k-idx ci-reg ci-idx tgt-reg tgt-idx)
  "True iff all 4 (reg, idx) pairs are pairwise distinct. Matches HEAD's
   maj1_inputs_distinct (const_arith.rs:4)."
  (let ((pa (cons a-reg  a-idx))
        (pk (cons k-reg  k-idx))
        (pc (cons ci-reg ci-idx))
        (pt (cons tgt-reg tgt-idx)))
    (and (not (equal? pa pk))
         (not (equal? pa pc))
         (not (equal? pa pt))
         (not (equal? pk pc))
         (not (equal? pk pt))
         (not (equal? pc pt)))))

(define (emit-fold-maj1! c a-reg a-idx k-reg k-idx ci-reg ci-idx tgt-reg tgt-idx)
  "4-CX + 1-CCX majority. tgt ^= maj(a, k, carry). HEAD const_arith.rs:13-21.
   Caller MUST ensure the 4 inputs are pairwise distinct."
  (gate-cx!  c ci-reg ci-idx tgt-reg tgt-idx)
  (gate-cx!  c ci-reg ci-idx a-reg   a-idx)
  (gate-cx!  c ci-reg ci-idx k-reg   k-idx)
  (gate-ccx! c a-reg  a-idx  k-reg   k-idx tgt-reg tgt-idx)
  (gate-cx!  c ci-reg ci-idx k-reg   k-idx)
  (gate-cx!  c ci-reg ci-idx a-reg   a-idx))

(define (emit-fold-majority! c a-reg a-idx k-reg k-idx ci-reg ci-idx tgt-reg tgt-idx maj2)
  "Dispatch: if *fold-maj1* AND inputs distinct → maj1 (4 CX + 1 CCX);
   else if maj2 → 2-CCX + 2-CX ancilla-free; else 3-CCX baseline.
   Mirrors HEAD const_arith.rs:23-43 emit_fold_majority."
  (cond
    ((and *fold-maj1*
          (fold-maj1-inputs-distinct? a-reg a-idx k-reg k-idx ci-reg ci-idx tgt-reg tgt-idx))
     (emit-fold-maj1! c a-reg a-idx k-reg k-idx ci-reg ci-idx tgt-reg tgt-idx))
    (maj2
     ;; 2-CCX + 2-CX ancilla-free. tgt ^= maj(a, k, carry) via:
     ;;   ccx(a, ci, tgt); cx(a, ci); ccx(k, ci, tgt); cx(a, ci)
     (gate-ccx! c a-reg a-idx ci-reg ci-idx tgt-reg tgt-idx)
     (gate-cx!  c a-reg a-idx ci-reg ci-idx)
     (gate-ccx! c k-reg k-idx ci-reg ci-idx tgt-reg tgt-idx)
     (gate-cx!  c a-reg a-idx ci-reg ci-idx))
    (else
     ;; 3-CCX baseline. tgt ^= maj(a, k, ci) = a·ci ⊕ k·a ⊕ k·ci.
     (gate-ccx! c a-reg a-idx ci-reg ci-idx tgt-reg tgt-idx)
     (gate-ccx! c k-reg k-idx a-reg  a-idx  tgt-reg tgt-idx)
     (gate-ccx! c k-reg k-idx ci-reg ci-idx tgt-reg tgt-idx))))

(define (fold-postsum-carry-phase-uncompute!
          c acc-reg i kc-pair ci-pair m-bit is-add)
  "Phase-only carry uncompute via cz_if on a measured classical bit.
   acc-reg : accumulator quantum register.
   i       : current position (0..hi_delta).
   kc-pair : (reg . idx) of position-i control, or #f.
   ci-pair : (reg . idx) of carry_{i-1}, or #f (only at i=0).
   m-bit   : classical bit id holding HMR measurement of low[i].
   is-add  : #t for add, #f for sub (borrow).
   Mirrors HEAD const_arith.rs:911-948 fold_postsum_carry_phase_uncompute."
  (cond
    (is-add
     (cond
       (kc-pair
        (let ((kc-reg (car kc-pair)) (kc-idx (cdr kc-pair)))
          (gate-x! c acc-reg i)
          (cond
            (ci-pair
             (let ((ci-reg (car ci-pair)) (ci-idx (cdr ci-pair)))
               (gate-push-cond! c m-bit)
               (gate-cz!        c acc-reg i kc-reg kc-idx)
               (gate-pop-cond!  c)
               (gate-push-cond! c m-bit)
               (gate-cz!        c acc-reg i ci-reg ci-idx)
               (gate-pop-cond!  c)
               (gate-x!         c acc-reg i)
               (gate-push-cond! c m-bit)
               (gate-cz!        c kc-reg kc-idx ci-reg ci-idx)
               (gate-pop-cond!  c)))
            (else
             (gate-push-cond! c m-bit)
             (gate-cz!        c acc-reg i kc-reg kc-idx)
             (gate-pop-cond!  c)
             (gate-x!         c acc-reg i)))))
       (ci-pair
        (let ((ci-reg (car ci-pair)) (ci-idx (cdr ci-pair)))
          (gate-x!         c acc-reg i)
          (gate-push-cond! c m-bit)
          (gate-cz!        c acc-reg i ci-reg ci-idx)
          (gate-pop-cond!  c)
          (gate-x!         c acc-reg i)))))
    (else
     (cond
       (kc-pair
        (let ((kc-reg (car kc-pair)) (kc-idx (cdr kc-pair)))
          (cond
            (ci-pair
             (let ((ci-reg (car ci-pair)) (ci-idx (cdr ci-pair)))
               (gate-push-cond! c m-bit)
               (gate-cz!        c acc-reg i kc-reg kc-idx)
               (gate-pop-cond!  c)
               (gate-push-cond! c m-bit)
               (gate-cz!        c acc-reg i ci-reg ci-idx)
               (gate-pop-cond!  c)
               (gate-push-cond! c m-bit)
               (gate-cz!        c kc-reg kc-idx ci-reg ci-idx)
               (gate-pop-cond!  c)))
            (else
             (gate-push-cond! c m-bit)
             (gate-cz!        c acc-reg i kc-reg kc-idx)
             (gate-pop-cond!  c)))))
       (ci-pair
        (let ((ci-reg (car ci-pair)) (ci-idx (cdr ci-pair)))
          (gate-push-cond! c m-bit)
          (gate-cz!        c acc-reg i ci-reg ci-idx)
          (gate-pop-cond!  c)))))))

(define (fold-postsum-carry-compute!
          c acc-reg i kc-pair ci-pair tgt-reg tgt-idx is-add)
  "Symmetric Toffoli compute (re-park carry from post-sum acc). Used
   after the tail uncompute to re-derive the parked low carries.
   Mirrors HEAD const_arith.rs:950-987 fold_postsum_carry_compute."
  (cond
    (is-add
     (cond
       (kc-pair
        (let ((kc-reg (car kc-pair)) (kc-idx (cdr kc-pair)))
          (gate-x! c acc-reg i)
          (cond
            (ci-pair
             (let ((ci-reg (car ci-pair)) (ci-idx (cdr ci-pair)))
               (gate-ccx! c acc-reg i kc-reg kc-idx tgt-reg tgt-idx)
               (gate-ccx! c acc-reg i ci-reg ci-idx tgt-reg tgt-idx)
               (gate-x!   c acc-reg i)
               (gate-ccx! c kc-reg kc-idx ci-reg ci-idx tgt-reg tgt-idx)))
            (else
             (gate-ccx! c acc-reg i kc-reg kc-idx tgt-reg tgt-idx)
             (gate-x!   c acc-reg i)))))
       (ci-pair
        (let ((ci-reg (car ci-pair)) (ci-idx (cdr ci-pair)))
          (gate-x!   c acc-reg i)
          (gate-ccx! c acc-reg i ci-reg ci-idx tgt-reg tgt-idx)
          (gate-x!   c acc-reg i)))))
    (else
     (cond
       (kc-pair
        (let ((kc-reg (car kc-pair)) (kc-idx (cdr kc-pair)))
          (cond
            (ci-pair
             (let ((ci-reg (car ci-pair)) (ci-idx (cdr ci-pair)))
               (gate-ccx! c acc-reg i kc-reg kc-idx tgt-reg tgt-idx)
               (gate-ccx! c acc-reg i ci-reg ci-idx tgt-reg tgt-idx)
               (gate-ccx! c kc-reg kc-idx ci-reg ci-idx tgt-reg tgt-idx)))
            (else
             (gate-ccx! c acc-reg i kc-reg kc-idx tgt-reg tgt-idx)))))
       (ci-pair
        (let ((ci-reg (car ci-pair)) (ci-idx (cdr ci-pair)))
          (gate-ccx! c acc-reg i ci-reg ci-idx tgt-reg tgt-idx)))))))

;;; ── sweep-fused-fold-v25 — cadd-2-controls-trunc-fast! ────────────
;;;
;;; HEAD reference: `compressed.rs:2193-2215` (forward fused fold body of
;;; `dialog_gcd_fused_double_y`) — single truncated ripple at width lsbs
;;; emitting δ = k1·ctrl1 + k2·ctrl2 via the 12-position per-position
;;; controls table mapped to bits {0,1,4,5,6,7,8,9,10,11, hi, hi+1} for a
;;; secp256k1-class pseudo-Mersenne c.
;;;
;;; What V2.5 saves vs V2's two `cadd-const!` calls:
;;;
;;;   V2: cadd-const(v, lsbs, c, ctrl1) + cadd-const(v, lsbs, 2c, ctrl2)
;;;     → 2 × full Solinas truncated ripple. ~62 Toff/call × 2.
;;;
;;;   V2.5: derive 4 ancilla controls (h, xed, eord, n10) via 3 CCX + 6 CX,
;;;     issue ONE per-position-controls truncated ripple at width lsbs,
;;;     uncompute the 4 derived controls in reverse (6 CX + 1 CCX). The
;;;     ripple itself emits ~62 Toff. Net: ~62 Toff/call + 4 CCX overhead.
;;;
;;; Save per mod-4x-inplace! call: ~62 - 4 Toff = ~58 Toff. ~50 % shift2-
;;; density × iters=258 ≈ 129 calls/shot → ~7-8k Toff saved per shot.
;;;
;;; CALLING CONVENTION:
;;;
;;;   c           : circuit/stream context.
;;;   acc-reg     : (>= lsbs)-wide quantum register (the v register).
;;;   lsbs        : slice width for the truncated ripple. Caller picks
;;;                 lsbs = min(n+1, padding + bit-length(2*c)) just like
;;;                 V2's cadd-const calls. last = min(lsbs - 2, hi + window)
;;;                 where hi = highest-set-bit(2*c) = bit-length(c).
;;;   k1          : compile-time classical integer (V2.5 uses c, the
;;;                 pseudo-Mersenne complement 2^n - p).
;;;   ctrl1-reg, ctrl1-idx : runtime qubit gating k1's addition.
;;;   k2          : compile-time classical integer (V2.5 uses 2c).
;;;   ctrl2-reg, ctrl2-idx : runtime qubit gating k2's addition.
;;;   tmp-reg     : (>= last+1)-wide ancilla register at |0> for carries.
;;;   window      : carry-tail safety bits past highest_set_bit(2*c).
;;;                 Caller passes *cadd-direct-window* (HEAD default 8).
;;;   bit-base    : classical-bit base offset; consumes
;;;                 [bit-base, bit-base+last] via HMR. Caller picks a
;;;                 non-colliding region (V2.5 uses *cadd-direct-bit-base*).
;;;
;;; Currently HARDCODED for HEAD's secp256k1 pseudo-Mersenne table
;;; (compressed.rs:2196-2210): k1 must have bits {0,4,6,7,8,9,hi} set and
;;; k2 = 2·k1 must have bits {1,5,7,8,9,10,hi+1}. Verified at build-time
;;; against (k1, k2). Errors when the pattern doesn't match — protects
;;; against silently emitting the wrong fold for a non-secp256k1 c.
;;;
;;; Returns tmp-reg[0..last] to |0> via HMR + cz_if (inside the
;;; per-position primitive); 4 derived-ctrl ancilla returned to |0> by
;;; reversed CX + CCX uncompute below; acc-reg gets δ added; both ctrl1
;;; and ctrl2 unchanged.

(define (cadd-2-controls-trunc-fast!
         c acc-reg lsbs k1 ctrl1-reg ctrl1-idx k2 ctrl2-reg ctrl2-idx
         tmp-reg window bit-base)
  "acc[0..lsbs) += (ctrl1 ? k1 : 0) + (ctrl2 ? k2 : 0) in ONE truncated
   carry sweep with per-position-controls. Hardcoded for HEAD's
   secp256k1-class table where k2 == 2·k1 AND k1's bits sit at
   {0,4,6,7,8,9,hi}. Errors otherwise.

   *fold-maj1* / *perpos-maj2* threaded via emit-fold-majority! inside
   cadd-per-position-controls-trunc!.
   *fold-freed-tail* dispatches to cadd-fold-ripple-freed-tail!,
   which owns the full h/xed/eord/n10 lifetime + split low/tail carry
   lanes (HEAD const_arith.rs:1051-1267 fold_ripple_freed_tail_ed).
   *fold-park-low-carries* only consumed inside freed-tail variant."
  ;; *fold-freed-tail* dispatch: routes the split-lane variant.
  ;; HEAD: free_ed gate implies base freed-tail (const_arith.rs:1064),
  ;; so we only consult *fold-freed-tail* here. *fold-freed-tail-ed*
  ;; remains a no-op until the e,d-extension wiring lands (HYP-6 §4a;
  ;; requires caller-supplied ovf1/ovf2/s2 live qubits, see ticket).
  (cond
    (*fold-freed-tail*
     (let* ((kk1 (modulo k1 (expt 2 lsbs)))
            (kk2 (modulo k2 (expt 2 lsbs))))
       (cond
         ((= lsbs 0) #t)
         ((and (= kk1 0) (= kk2 0)) #t)
         (else
          (let ((hi (highest-set-bit kk1)))
            (when (not (= kk2 (modulo (* 2 kk1) (expt 2 lsbs))))
              (error "cadd-2-controls-trunc-fast!: k2 != 2*k1 (mod 2^lsbs)"
                     k1 k2 lsbs))
            (when (not (and (bit-set? kk1 0) (bit-set? kk1 4)
                            (bit-set? kk1 6) (bit-set? kk1 7)
                            (bit-set? kk1 8) (bit-set? kk1 9)
                            (bit-set? kk1 hi)))
              (error "cadd-2-controls-trunc-fast!: k1 missing required bits"
                     k1 hi))
            (when (<= lsbs (+ hi 1))
              (error "cadd-2-controls-trunc-fast!: lsbs <= hi+1, no room"
                     lsbs hi))
            (let* ((last     (min (- lsbs 2) (+ (+ hi 1) window)))
                   (hi-delta (+ hi 1)))
              ;; HEAD const_arith.rs:1069 — freed-tail requires nonempty
              ;; high tail (last > hi-delta).
              (when (<= last hi-delta)
                (error "cadd-2-controls-trunc-fast!: *fold-freed-tail* needs last > hi+1"
                       last hi-delta))
              (cadd-fold-ripple-freed-tail!
                c acc-reg lsbs
                ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx
                last hi hi-delta #t bit-base)))))))
    (else
  (let* ((kk1 (modulo k1 (expt 2 lsbs)))
         (kk2 (modulo k2 (expt 2 lsbs))))
    (cond
      ((= lsbs 0) #t)
      ((and (= kk1 0) (= kk2 0)) #t)
      (else
       ;; Validate HEAD table assumptions.
       (let ((hi (highest-set-bit kk1)))
         (when (not (= kk2 (modulo (* 2 kk1) (expt 2 lsbs))))
           (error "cadd-2-controls-trunc-fast!: k2 != 2*k1 (mod 2^lsbs)"
                  k1 k2 lsbs))
         (when (not (and (bit-set? kk1 0)
                         (bit-set? kk1 4)
                         (bit-set? kk1 6)
                         (bit-set? kk1 7)
                         (bit-set? kk1 8)
                         (bit-set? kk1 9)
                         (bit-set? kk1 hi)))
           (error "cadd-2-controls-trunc-fast!: k1 missing required bits"
                  k1 hi))
         ;; The table requires bit hi+1 to live inside lsbs (HEAD: hi=32
         ;; for secp256k1 → bit 33 inside lsbs ≥ 34). If lsbs ≤ hi+1 the
         ;; per-position table cannot place the high pair; fall back path
         ;; lives upstream at mod-4x-inplace! (V1 sequential).
         (when (<= lsbs (+ hi 1))
           (error "cadd-2-controls-trunc-fast!: lsbs <= hi+1, no room"
                  lsbs hi))
         ;; Derive 4 ancilla controls per HEAD compressed.rs:2169-2191.
         ;;   "e" in HEAD ↔ ctrl1 (V2 carrier of k1·c).
         ;;   "d" in HEAD ↔ ctrl2 (V2 carrier of k2·2c).
         ;;   h    = e & d           (1 CCX)
         ;;   xed  = e ⊕ d           (2 CX)
         ;;   eord = (e ⊕ d) ⊕ h     (2 CX; equals e | d)
         ;;   n10  = d ⊕ h           (2 CX; equals ¬e & d)
         (let ((h    '_v25-h)
               (xed  '_v25-xed)
               (eord '_v25-eord)
               (n10  '_v25-n10))
           (alloc! c h    1)
           (alloc! c xed  1)
           (alloc! c eord 1)
           (alloc! c n10  1)
           ;; h = ctrl1 & ctrl2
           (gate-ccx! c ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx h 0)
           ;; xed = ctrl1 ⊕ ctrl2
           (gate-cx!  c ctrl1-reg ctrl1-idx xed 0)
           (gate-cx!  c ctrl2-reg ctrl2-idx xed 0)
           ;; eord = xed ⊕ h
           (gate-cx!  c xed 0 eord 0)
           (gate-cx!  c h   0 eord 0)
           ;; n10 = ctrl2 ⊕ h
           (gate-cx!  c ctrl2-reg ctrl2-idx n10 0)
           (gate-cx!  c h           0       n10 0)
           ;; Build the per-position-controls list per HEAD's table.
           ;;   bit 0:   ctrl1                     (k1 bit 0 = 1)
           ;;   bit 1:   ctrl2                     (k2 bit 1 = 1)
           ;;   bit 4:   ctrl1                     (k1 bit 4 = 1)
           ;;   bit 5:   ctrl2                     (k2 bit 5 = 1)
           ;;   bit 6:   ctrl1                     (k1 bit 6 = 1)
           ;;   bit 7:   xed   (k1+k2 bit 7 = 2 → xor at 7, carry to 8)
           ;;   bit 8:   eord  (k1+k2+carry bit 8)
           ;;   bit 9:   eord  (k1+k2+carry bit 9)
           ;;   bit 10:  n10   (k2 bit 10 only)
           ;;   bit 11:  h     (carry-fold absorption)
           ;;   bit hi:  ctrl1
           ;;   bit hi+1: ctrl2
           ;; Positions not listed default to #f via perpos-ctrl-at.
           (let* ((last     (min (- lsbs 2)
                                 (+ (+ hi 1) window)))
                  (controls (make-perpos-secp256k1-fold-controls
                              hi
                              (cons ctrl1-reg ctrl1-idx)
                              (cons ctrl2-reg ctrl2-idx)
                              (cons xed       0)
                              (cons eord      0)
                              (cons n10       0)
                              (cons h         0))))
             (cadd-per-position-controls-trunc!
               c acc-reg lsbs controls last tmp-reg bit-base))
           ;; Uncompute derived ancilla in EXACT reverse of derivation.
           ;; reverse n10  : (cx h n10) (cx ctrl2 n10)
           (gate-cx!  c h           0       n10 0)
           (gate-cx!  c ctrl2-reg ctrl2-idx n10 0)
           ;; reverse eord : (cx h eord) (cx xed eord)
           (gate-cx!  c h   0 eord 0)
           (gate-cx!  c xed 0 eord 0)
           ;; reverse xed  : (cx ctrl2 xed) (cx ctrl1 xed)
           (gate-cx!  c ctrl2-reg ctrl2-idx xed 0)
           (gate-cx!  c ctrl1-reg ctrl1-idx xed 0)
           ;; reverse h    : (ccx ctrl1 ctrl2 h)
           (gate-ccx! c ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx h 0)
           (free! c n10)
           (free! c eord)
           (free! c xed)
           (free! c h))))))))) ; closes (else ...) of *fold-freed-tail* dispatch

;;; Helper: build the 12-position controls list for HEAD's secp256k1 fold.
;;; The list length = hi + 2 (indices 0..hi+1 covered). Positions not in
;;; the table are #f (no control). hi = highest_set_bit(c) (= 32 for
;;; secp256k1). Per HEAD compressed.rs:2196-2210.

(define (make-perpos-secp256k1-fold-controls hi e-pair d-pair xed-pair
                                              eord-pair n10-pair h-pair)
  "Return list of length (hi + 2) for the per-position-controls fold of
   δ = k1·e + k2·d under HEAD's secp256k1 table."
  ;; Walk i = 0..(hi+1) and append the right pair (or #f).
  (let loop ((i 0) (acc '()))
    (cond
      ((> i (+ hi 1))
       (reverse acc))
      (else
       (let ((entry
              (cond
                ((= i 0)        e-pair)
                ((= i 1)        d-pair)
                ((= i 4)        e-pair)
                ((= i 5)        d-pair)
                ((= i 6)        e-pair)
                ((= i 7)        xed-pair)
                ((= i 8)        eord-pair)
                ((= i 9)        eord-pair)
                ((= i 10)       n10-pair)
                ((= i 11)       h-pair)
                ((= i hi)       e-pair)
                ((= i (+ hi 1)) d-pair)
                (else           #f))))
         (loop (+ i 1) (cons entry acc)))))))

;;; ── cadd-fold-ripple-freed-tail! — split-lane fused-fold ripple ───
;;;
;;; Port of HEAD const_arith.rs:1051-1267 fold_ripple_freed_tail_ed.
;;; Splits the carry lane into `_ft-low[0..=hi-delta]` (parked across the
;;; active region; lifetime spans the full call) + `_ft-tail[0..tail-len)`
;;; (allocated AFTER the four derived controls h/xed/eord/n10 are freed
;;; mid-ripple, freed BEFORE they are re-derived). Net wide-tail
;;; high-water drops by 4 ancillae vs the unsplit ripple (HEAD §6.6).
;;;
;;; PORT STATUS (2026-06-13): WIRED. The primitive owns the FULL
;;; ancilla lifetime — caller supplies only ctrl1, ctrl2, acc-reg,
;;; lsbs, last, hi, hi-delta, is-add, bit-base. Returns acc += δ
;;; (is-add=#t) or acc -= δ (is-add=#f), ctrl1/ctrl2 unchanged,
;;; every ancilla freed.
;;;
;;; e,d-extension (*fold-freed-tail-ed*) STRUCTURAL NO-OP under lumbda.
;;; HEAD's free_ed pass (const_arith.rs:1162-1172) frees the separate
;;; e,d copy qubits that HEAD allocates from `(ovf1, ovf2, s2)` (see
;;; compressed.rs:3260-3271 `d = ovf1 & s2; e = ovf1 ^ d ^ ovf2`).
;;; Lumbda's `cadd-2-controls-trunc-fast!` dispatcher binds e↔ctrl1
;;; and d↔ctrl2 DIRECTLY (see docstring at line 2750-2755) — under
;;; the s2=1 classical specialization (lumbda's mod-4x-inplace! IS
;;; the K=2 shift2=1 specialization; s2 is classical-true & not a
;;; qubit), HEAD's e,d-copy alloc collapses to `e = ovf2, d = ovf1`
;;; and lumbda skips the copy alloc entirely. The -2 ancillae HEAD
;;; reports across the wide tail are already-banked at the substrate
;;; level: lumbda's freed-tail body has no separate e,d qubits to
;;; free in step 3b. See test-fold-freed-tail-ed-port.lsp for the
;;; positive-control reducer proving flag-ON byte-identical to
;;; flag-OFF + same peak-qubits + same toffoli count.
;;;
;;; *fold-park-low-carries* wired below: when > 0, the lowest `park`
;;; carries in `_ft-low` are measurement-uncomputed before tail alloc
;;; and recomputed before the low uncompute pass — drops high-water by
;;; `park` more qubits at cost of `park` HMR + cz_if (phase-EXACT,
;;; 0 Toffoli).
;;;
;;; CALLING CONVENTION (note: shape differs from the original stub —
;;; caller no longer supplies pre-derived h/xed/eord/n10):
;;;
;;;   c              : circuit context.
;;;   acc-reg        : (>=lsbs)-wide quantum register.
;;;   lsbs           : slice width (acc.len() in HEAD).
;;;   ctrl1-reg ctrl1-idx : "e" in HEAD (k1·c carrier).
;;;   ctrl2-reg ctrl2-idx : "d" in HEAD (k2·2c carrier).
;;;   last           : inclusive carry-truncation index. > hi-delta.
;;;   hi             : highest-set-bit(k1) (32 for secp256k1).
;;;   hi-delta       : hi + 1 (33 for secp256k1). HEAD's hi_delta.
;;;   is-add         : #t for cadd; #f for csub (borrow).
;;;   bit-base       : classical-bit base. Consumes
;;;                    [bit-base, bit-base + last + 1] (last+1 carry
;;;                    HMRs + 1 for the h measurement clear).
;;;
;;; CLASSICAL-BIT MAP (deterministic — caller picks bit-base; primitive
;;; uses the following offsets):
;;;   bit-base + i              : HMR target for carry low[i]   (0 <= i <= hi-delta)
;;;   bit-base + i              : HMR target for carry tail[i - hi-delta - 1]
;;;                               (hi-delta < i <= last) — same i indexing
;;;   bit-base + last+1         : HMR target for the h free-measurement
;;;   bit-base + last+2 + i     : HMR target for the park-low pass
;;;                               (only consumed when *fold-park-low-carries* > 0)
;;; Caller must reserve [bit-base, bit-base + last + 1 + park-low + 1).

(define (cadd-fold-ripple-freed-tail!
          c acc-reg lsbs ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx
          last hi hi-delta is-add bit-base)
  "Split-lane fused-fold ripple. Owns full ancilla lifetime; caller
   passes only the two base controls + arithmetic params.
   HEAD const_arith.rs:1019-1267 fold_ripple_freed_tail_ed."
  ;; Sanity guards (mirror HEAD debug_assert!).
  (when (>= last lsbs)
    (error "cadd-fold-ripple-freed-tail!: last >= lsbs" last lsbs))
  (when (<= last hi-delta)
    (error "cadd-fold-ripple-freed-tail!: last <= hi-delta (no tail)"
           last hi-delta))
  (let* ((maj2     *perpos-maj2*)
         (park-low (let ((p *fold-park-low-carries*))
                     (cond ((< p 0)         0)
                           ((> p hi-delta) hi-delta)
                           (else           p))))
         ;; Named ancilla — distinct from caller's tmp-reg so dispatcher
         ;; can reuse the unsplit-path tmp-reg without clobber risk.
         (h    '_ft-h)
         (xed  '_ft-xed)
         (eord '_ft-eord)
         (n10  '_ft-n10)
         (low  '_ft-low)
         (tail '_ft-tail)
         (bit-h (+ bit-base last 1)))
    ;; ── 0a. Derive h/xed/eord/n10 from ctrl1, ctrl2 (HEAD compressed.rs
    ;; :2169-2191; identical to dispatcher's pre-derive in the unsplit
    ;; path).
    (alloc! c h    1)
    (alloc! c xed  1)
    (alloc! c eord 1)
    (alloc! c n10  1)
    (gate-ccx! c ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx h 0)
    (gate-cx!  c ctrl1-reg ctrl1-idx xed 0)
    (gate-cx!  c ctrl2-reg ctrl2-idx xed 0)
    (gate-cx!  c xed 0 eord 0)
    (gate-cx!  c h   0 eord 0)
    (gate-cx!  c ctrl2-reg ctrl2-idx n10 0)
    (gate-cx!  c h         0         n10 0)
    ;; ── 0b. Build the per-position controls list (length hi-delta+1).
    ;; HEAD: controls[i] = Some(qubit) at table positions, None elsewhere;
    ;; controls.get(i).copied().flatten() at i > hi-delta returns None.
    ;; We re-use make-perpos-secp256k1-fold-controls (length = hi+2 =
    ;; hi-delta+1) — perpos-ctrl-at returns #f for any i beyond.
    (let* ((controls (make-perpos-secp256k1-fold-controls
                      hi
                      (cons ctrl1-reg ctrl1-idx) ; e
                      (cons ctrl2-reg ctrl2-idx) ; d
                      (cons xed       0)
                      (cons eord      0)
                      (cons n10       0)
                      (cons h         0)))
           (tail-len (- last hi-delta))
           (kctrl    (lambda (i) (perpos-ctrl-at controls i))))
      ;; Allocate the LOW carry lane first (controls live across active region).
      (alloc! c low (+ hi-delta 1))
      ;; ── 1. Active region carry sweep [0..=hi-delta] ────────────────
      ;; HEAD const_arith.rs:1082-1108.
      (let loop ((i 0))
        (when (<= i hi-delta)
          (let ((kc       (kctrl i))
                (carry-in? (> i 0)))
            (cond
              (is-add
               (cond
                 (kc
                  (let ((kc-reg (car kc)) (kc-idx (cdr kc)))
                    (cond
                      (carry-in?
                       (emit-fold-majority! c
                         acc-reg i kc-reg kc-idx low (- i 1) low i maj2))
                      (else
                       (gate-ccx! c acc-reg i kc-reg kc-idx low i)))))
                 (carry-in?
                  (gate-ccx! c acc-reg i low (- i 1) low i))))
              (else
               (cond
                 (kc
                  (let ((kc-reg (car kc)) (kc-idx (cdr kc)))
                    (gate-x! c acc-reg i)
                    (cond
                      (carry-in?
                       (emit-fold-majority! c
                         acc-reg i kc-reg kc-idx low (- i 1) low i maj2))
                      (else
                       (gate-ccx! c acc-reg i kc-reg kc-idx low i)))
                    (gate-x! c acc-reg i)))
                 (carry-in?
                  (gate-x! c acc-reg i)
                  (gate-ccx! c acc-reg i low (- i 1) low i)
                  (gate-x! c acc-reg i))))))
          (loop (+ i 1))))
      ;; ── 2. Low sum bits [0..=hi-delta]: acc_i ^= k_i ^ carry_{i-1} ─
      ;; HEAD const_arith.rs:1109-1119.
      (let loop ((i 0))
        (when (<= i hi-delta)
          (let ((kc (kctrl i)))
            (when kc
              (gate-cx! c (car kc) (cdr kc) acc-reg i))
            (when (> i 0)
              (gate-cx! c low (- i 1) acc-reg i)))
          (loop (+ i 1))))
      ;; ── 2b. Park the lowest `park-low` carries via HMR + cz_if ─────
      ;; HEAD const_arith.rs:1126-1134. Walks i = park_low-1 down to 0.
      ;; Uses bits [bit-base+last+2, bit-base+last+1+park-low] (disjoint
      ;; from the step-5/step-7 [bit-base, bit-base+last] range AND from
      ;; the bit-base+last+1 h-clear slot). In lumbda the parked low[i]
      ;; qubits stay allocated (no per-slot free); step 6b's CCX
      ;; recompute restores their carry value before step 7's full HMR
      ;; uncompute sweeps them too — so the phase from THIS measurement
      ;; commutes through but the bit slot must not collide with a later
      ;; HMR or the simulator double-measures into the same classical bit.
      (when (> park-low 0)
        (let loop ((i (- park-low 1)))
          (when (>= i 0)
            (let ((m         (+ bit-base last 2 i))
                  (kc        (kctrl i))
                  (carry-in? (> i 0)))
              (gate-hmr! c low i m)
              ;; fold-postsum-carry-phase-uncompute (HEAD const_arith.rs:911)
              ;; acc[i] ^= maj(...) via cz_if chain conditional on the HMR bit.
              (cond
                (is-add
                 (cond
                   (kc
                    (let ((kc-reg (car kc)) (kc-idx (cdr kc)))
                      (gate-x! c acc-reg i)
                      (cond
                        (carry-in?
                         (gate-push-cond! c m)
                         (gate-cz!        c acc-reg i kc-reg kc-idx)
                         (gate-pop-cond!  c)
                         (gate-push-cond! c m)
                         (gate-cz!        c acc-reg i low (- i 1))
                         (gate-pop-cond!  c)
                         (gate-x!         c acc-reg i)
                         (gate-push-cond! c m)
                         (gate-cz!        c kc-reg kc-idx low (- i 1))
                         (gate-pop-cond!  c))
                        (else
                         (gate-push-cond! c m)
                         (gate-cz!        c acc-reg i kc-reg kc-idx)
                         (gate-pop-cond!  c)
                         (gate-x!         c acc-reg i)))))
                   (carry-in?
                    (gate-x!         c acc-reg i)
                    (gate-push-cond! c m)
                    (gate-cz!        c acc-reg i low (- i 1))
                    (gate-pop-cond!  c)
                    (gate-x!         c acc-reg i))))
                (else
                 (cond
                   (kc
                    (let ((kc-reg (car kc)) (kc-idx (cdr kc)))
                      (cond
                        (carry-in?
                         (gate-push-cond! c m)
                         (gate-cz!        c acc-reg i kc-reg kc-idx)
                         (gate-pop-cond!  c)
                         (gate-push-cond! c m)
                         (gate-cz!        c acc-reg i low (- i 1))
                         (gate-pop-cond!  c)
                         (gate-push-cond! c m)
                         (gate-cz!        c kc-reg kc-idx low (- i 1))
                         (gate-pop-cond!  c))
                        (else
                         (gate-push-cond! c m)
                         (gate-cz!        c acc-reg i kc-reg kc-idx)
                         (gate-pop-cond!  c)))))
                   (carry-in?
                    (gate-push-cond! c m)
                    (gate-cz!        c acc-reg i low (- i 1))
                    (gate-pop-cond!  c))))))
            (loop (- i 1)))))
      ;; ── 3. Free h, xed, eord, n10 BEFORE allocating the wide tail ──
      ;; HEAD const_arith.rs:1140-1152. Uncompute in reverse derivation
      ;; order, then measurement-clear h.
      (gate-cx! c h           0       n10 0)
      (gate-cx! c ctrl2-reg ctrl2-idx n10 0)
      (gate-cx! c h   0 eord 0)
      (gate-cx! c xed 0 eord 0)
      (gate-cx! c ctrl2-reg ctrl2-idx xed 0)
      (gate-cx! c ctrl1-reg ctrl1-idx xed 0)
      (free! c n10)
      (free! c eord)
      (free! c xed)
      ;; h cleared via HMR + cz_if(ctrl1, ctrl2, mh) — phase-exact AND-clear
      ;; (h = ctrl1 & ctrl2 still holds; cz_if undoes the phase when ctrl1
      ;; AND ctrl2, restoring |0>). HEAD const_arith.rs:1149-1152.
      (gate-hmr!       c h 0 bit-h)
      (gate-push-cond! c bit-h)
      (gate-cz!        c ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx)
      (gate-pop-cond!  c)
      (free! c h)
      ;; ── 4. Allocate the wide tail (4 derived controls now released) ─
      (alloc! c tail tail-len)
      ;; ── 4a. High-tail carry generation (hi-delta, last]: pure
      ;; propagation from ORIGINAL acc (acc[hi-delta+1..] untouched
      ;; by step 2). HEAD const_arith.rs:1188-1197.
      ;; carry-in for i = hi-delta+1 is low[hi-delta]; subsequent carries
      ;; are in tail[(i - hi-delta - 1) - 1] = tail[i - hi-delta - 2].
      (let loop ((i (+ hi-delta 1)))
        (when (<= i last)
          (let ((tgt-idx (- i hi-delta 1))
                (ci-tail? (> i (+ hi-delta 1))))
            (cond
              (is-add
               (cond
                 (ci-tail?
                  (gate-ccx! c acc-reg i tail (- tgt-idx 1) tail tgt-idx))
                 (else
                  (gate-ccx! c acc-reg i low hi-delta tail tgt-idx))))
              (else
               (gate-x! c acc-reg i)
               (cond
                 (ci-tail?
                  (gate-ccx! c acc-reg i tail (- tgt-idx 1) tail tgt-idx))
                 (else
                  (gate-ccx! c acc-reg i low hi-delta tail tgt-idx)))
               (gate-x! c acc-reg i))))
          (loop (+ i 1))))
      ;; ── 4b. High sum bits (hi-delta, lsbs) (k=0, control-free):
      ;; acc_i ^= carry_{i-1}. HEAD const_arith.rs:1199-1203.
      (let loop ((i (+ hi-delta 1)))
        (when (< i lsbs)
          (when (<= (- i 1) last)
            (let ((src-i (- i 1)))
              (cond
                ((<= src-i hi-delta)
                 (gate-cx! c low src-i acc-reg i))
                (else
                 (gate-cx! c tail (- src-i hi-delta 1) acc-reg i)))))
          (loop (+ i 1))))
      ;; ── 5. Reverse uncompute the TAIL carries first (control-free,
      ;; high → low) so the wide lane shrinks before ctrl recompute.
      ;; HEAD const_arith.rs:1207-1219.
      (let loop ((i last))
        (when (> i hi-delta)
          (let ((m       (+ bit-base i))
                (tgt-idx (- i hi-delta 1))
                (ci-tail? (> i (+ hi-delta 1))))
            (gate-hmr! c tail tgt-idx m)
            (cond
              (is-add
               (gate-x! c acc-reg i)
               (gate-push-cond! c m)
               (cond
                 (ci-tail?
                  (gate-cz! c acc-reg i tail (- tgt-idx 1)))
                 (else
                  (gate-cz! c acc-reg i low hi-delta)))
               (gate-pop-cond! c)
               (gate-x! c acc-reg i))
              (else
               (gate-push-cond! c m)
               (cond
                 (ci-tail?
                  (gate-cz! c acc-reg i tail (- tgt-idx 1)))
                 (else
                  (gate-cz! c acc-reg i low hi-delta)))
               (gate-pop-cond! c))))
          (loop (- i 1))))
      (free! c tail)
      ;; ── 6. Re-derive h, xed, eord, n10 (same gate sequence as
      ;; step 0a) — for the low uncompute pass. They stay live on
      ;; return (matches HEAD's `// h, xed, eord, n10 are left LIVE`
      ;; comment at const_arith.rs:1265).
      (alloc! c h    1)
      (alloc! c xed  1)
      (alloc! c eord 1)
      (alloc! c n10  1)
      (gate-ccx! c ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx h 0)
      (gate-cx!  c ctrl1-reg ctrl1-idx xed 0)
      (gate-cx!  c ctrl2-reg ctrl2-idx xed 0)
      (gate-cx!  c xed 0 eord 0)
      (gate-cx!  c h   0 eord 0)
      (gate-cx!  c ctrl2-reg ctrl2-idx n10 0)
      (gate-cx!  c h         0         n10 0)
      ;; ── 6b. Park-low recompute: rebuild parked carries via CCX
      ;; (fold-postsum-carry-compute, HEAD const_arith.rs:1248-1254).
      (when (> park-low 0)
        (let loop ((i 0))
          (when (< i park-low)
            (let ((kc        (kctrl i))
                  (carry-in? (> i 0)))
              (cond
                (is-add
                 (cond
                   (kc
                    (let ((kc-reg (car kc)) (kc-idx (cdr kc)))
                      (gate-x! c acc-reg i)
                      (cond
                        (carry-in?
                         (gate-ccx! c acc-reg i kc-reg kc-idx low i)
                         (gate-ccx! c acc-reg i low (- i 1) low i)
                         (gate-x! c acc-reg i)
                         (gate-ccx! c kc-reg kc-idx low (- i 1) low i))
                        (else
                         (gate-ccx! c acc-reg i kc-reg kc-idx low i)
                         (gate-x! c acc-reg i)))))
                   (carry-in?
                    (gate-x! c acc-reg i)
                    (gate-ccx! c acc-reg i low (- i 1) low i)
                    (gate-x! c acc-reg i))))
                (else
                 (cond
                   (kc
                    (let ((kc-reg (car kc)) (kc-idx (cdr kc)))
                      (cond
                        (carry-in?
                         (gate-ccx! c acc-reg i kc-reg kc-idx low i)
                         (gate-ccx! c acc-reg i low (- i 1) low i)
                         (gate-ccx! c kc-reg kc-idx low (- i 1) low i))
                        (else
                         (gate-ccx! c acc-reg i kc-reg kc-idx low i)))))
                   (carry-in?
                    (gate-ccx! c acc-reg i low (- i 1) low i))))))
            (loop (+ i 1)))))
      ;; ── 7. Reverse uncompute the active-region carries [0..=hi-delta].
      ;; HEAD const_arith.rs:1257-1263 walks i = hi_delta down to 0;
      ;; HEAD's per-slot free at step 2b means the parked slots are
      ;; reacquired by step 6b before this pass. In lumbda we don't
      ;; per-slot free, so the parked low[i] qubits were never released
      ;; — but step 2b HMR'd them to |0> and step 6b recomputed them to
      ;; the original carry value, so the sweep below is well-defined
      ;; on ALL i in [0, hi-delta] without skipping.
      (let loop ((i hi-delta))
        (when (>= i 0)
          (let ((m         (+ bit-base i))
                (kc        (kctrl i))
                (carry-in? (> i 0)))
            (gate-hmr! c low i m)
            (cond
              (is-add
               (cond
                 (kc
                  (let ((kc-reg (car kc)) (kc-idx (cdr kc)))
                    (gate-x! c acc-reg i)
                    (cond
                      (carry-in?
                       (gate-push-cond! c m)
                       (gate-cz!        c acc-reg i kc-reg kc-idx)
                       (gate-pop-cond!  c)
                       (gate-push-cond! c m)
                       (gate-cz!        c acc-reg i low (- i 1))
                       (gate-pop-cond!  c)
                       (gate-x!         c acc-reg i)
                       (gate-push-cond! c m)
                       (gate-cz!        c kc-reg kc-idx low (- i 1))
                       (gate-pop-cond!  c))
                      (else
                       (gate-push-cond! c m)
                       (gate-cz!        c acc-reg i kc-reg kc-idx)
                       (gate-pop-cond!  c)
                       (gate-x!         c acc-reg i)))))
                 (carry-in?
                  (gate-x!         c acc-reg i)
                  (gate-push-cond! c m)
                  (gate-cz!        c acc-reg i low (- i 1))
                  (gate-pop-cond!  c)
                  (gate-x!         c acc-reg i))))
              (else
               (cond
                 (kc
                  (let ((kc-reg (car kc)) (kc-idx (cdr kc)))
                    (cond
                      (carry-in?
                       (gate-push-cond! c m)
                       (gate-cz!        c acc-reg i kc-reg kc-idx)
                       (gate-pop-cond!  c)
                       (gate-push-cond! c m)
                       (gate-cz!        c acc-reg i low (- i 1))
                       (gate-pop-cond!  c)
                       (gate-push-cond! c m)
                       (gate-cz!        c kc-reg kc-idx low (- i 1))
                       (gate-pop-cond!  c))
                      (else
                       (gate-push-cond! c m)
                       (gate-cz!        c acc-reg i kc-reg kc-idx)
                       (gate-pop-cond!  c)))))
                 (carry-in?
                  (gate-push-cond! c m)
                  (gate-cz!        c acc-reg i low (- i 1))
                  (gate-pop-cond!  c))))))
          (loop (- i 1))))
      (free! c low)
      ;; ── 8. Uncompute h/xed/eord/n10 in reverse derivation (same
      ;; teardown the unsplit-path dispatcher emits after its
      ;; cadd-per-position-controls-trunc! call). HEAD: caller's
      ;; "normal derived-control uncompute block runs next"
      ;; (const_arith.rs:1265) — we run it here so the call is
      ;; self-contained (matches the byte-identity contract of the
      ;; default-OFF flag).
      (gate-cx!  c h           0       n10 0)
      (gate-cx!  c ctrl2-reg ctrl2-idx n10 0)
      (gate-cx!  c h   0 eord 0)
      (gate-cx!  c xed 0 eord 0)
      (gate-cx!  c ctrl2-reg ctrl2-idx xed 0)
      (gate-cx!  c ctrl1-reg ctrl1-idx xed 0)
      (gate-ccx! c ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx h 0)
      (free! c n10)
      (free! c eord)
      (free! c xed)
      (free! c h))))

(define (cadd-const! c acc-reg n k ctrl-reg ctrl-idx cin-reg cin-idx tmp-reg)
  "acc += (ctrl ? k : 0) mod 2^n. Dispatches to direct sparse path when
   *cadd-direct-trunc-fast* on; else cload + cuccaro-add."
  (let ((kk (modulo k (expt 2 n))))
    (cond
      ((and *cadd-direct-trunc-fast* (> n 1) (> kk 0))
       (cadd-nbit-const-direct-trunc-fast!
         c acc-reg n kk ctrl-reg ctrl-idx tmp-reg
         *cadd-direct-window* (cdtf-alloc-bit-base! n)))
      (else
       (cload-const!   c ctrl-reg ctrl-idx tmp-reg n kk)
       (cuccaro-add!   c tmp-reg acc-reg cin-reg cin-idx n)
       (cunload-const! c ctrl-reg ctrl-idx tmp-reg n kk)))))

;;; ── Controlled lazy mod-double / mod-halve (sweep-cmod-inplace-lazy)
;;;
;;; HEAD modular.rs:823 cmod_double_inplace_lazy
;;;      modular.rs:847 cmod_halve_inplace_lazy
;;;
;;; Closes AUDIT §6 rows 260-261.
;;;
;;; Controlled (ctrl) form of mod_double_inplace_fast (Solinas reduction,
;;; lazy [0,2^n) coset rep, same carry-trunc window). Identity when
;;; ctrl=0. Used by the K=2 prototype's conditional 2nd double so it
;;; composes correctly with the uncontrolled mod_double_inplace_fast
;;; in the apply path.
;;;
;;; Algorithm (HEAD modular.rs:823-842):
;;;   1. cswap(ctrl, v[n-1], ovf)
;;;   2. for i in (0..n-1).rev(): cswap(ctrl, v[i], v[i+1])
;;;   3. c := 2^n - p (mod 2^n)
;;;   4. cadd_nbit_const_*(v, c, ovf) — dispatched by
;;;      *double-carry-trunc-window* / *cadd-direct-trunc-fast* flags
;;;   5. ccx(ctrl, v[0], ovf) — clear ovf via parity == top-bit
;;;
;;; Halve is symmetric inverse: ovf clear first, csub instead of cadd,
;;; reverse cswap order.
;;;
;;; Caller responsibilities:
;;;   v-reg: data register width n; modified in place
;;;   ctrl-reg/ctrl-idx: read-only control bit
;;;   ovf-reg/ovf-idx: clean |0> ancilla; restored to |0> on exit
;;;   cin-reg/cin-idx + tmp-reg: scratch for the inner cadd-const!
;;;     (must be clean; restored)
;;;   p: classical prime modulus

(define (cmod-double-inplace-lazy!
          c v-reg n p ctrl-reg ctrl-idx
          ovf-reg ovf-idx cin-reg cin-idx tmp-reg)
  "Port of HEAD cmod_double_inplace_lazy (modular.rs:823).
   v := (ctrl ? (2*v) mod p : v). Lazy coset rep — caller responsible
   for any final normalization. Identity when ctrl=0."
  ;; Shift v left by 1 via cswap chain (only if ctrl=1).
  (gate-cswap! c ctrl-reg ctrl-idx v-reg (- n 1) ovf-reg ovf-idx)
  (let loop ((i (- n 2)))
    (when (>= i 0)
      (gate-cswap! c ctrl-reg ctrl-idx v-reg i v-reg (+ i 1))
      (loop (- i 1))))
  ;; Solinas correction: add (2^n - p) when ctrl=1.
  (let ((corr (modulo (- (expt 2 n) p) (expt 2 n))))
    (cadd-const! c v-reg n corr
                 ctrl-reg ctrl-idx cin-reg cin-idx tmp-reg))
  ;; Clear ovf: result parity = old top-bit = ovf (gated by ctrl).
  (gate-ccx! c ctrl-reg ctrl-idx v-reg 0 ovf-reg ovf-idx))

(define (cmod-halve-inplace-lazy!
          c v-reg n p ctrl-reg ctrl-idx
          ovf-reg ovf-idx cin-reg cin-idx tmp-reg)
  "Port of HEAD cmod_halve_inplace_lazy (modular.rs:847). Inverse of
   cmod-double-inplace-lazy!. Identity when ctrl=0."
  ;; Re-establish ovf bit from current v[0] (gated by ctrl).
  (gate-ccx! c ctrl-reg ctrl-idx v-reg 0 ovf-reg ovf-idx)
  ;; Inverse Solinas correction: subtract (2^n - p) when ctrl=1.
  (let ((corr (modulo (- (expt 2 n) p) (expt 2 n))))
    (csub-const! c v-reg n corr
                 ctrl-reg ctrl-idx cin-reg cin-idx tmp-reg))
  ;; Inverse shift: reverse cswap order.
  (let loop ((i 0))
    (when (< i (- n 1))
      (gate-cswap! c ctrl-reg ctrl-idx v-reg i v-reg (+ i 1))
      (loop (+ i 1))))
  (gate-cswap! c ctrl-reg ctrl-idx v-reg (- n 1) ovf-reg ovf-idx))

;;; ── reversible mod-sub (hand-rolled inverse of mod-add!) ───────
;;;
;;; Upstream mod_sub_qq emits the gate-level inverse of mod_add_qq via an
;;; emit_inverse helper. We don't have emit-inverse yet, so we hand-roll:
;;; walk mod-add!'s 8 steps in REVERSE order, replacing each step with
;;; its gate-level inverse. Self-inverse steps (CX, X, cmp-lt-into) emit
;;; unchanged; add-const flips to sub-const; csub-const flips to cadd-const;
;;; cuccaro-add flips to cuccaro-sub.

(define (mod-sub-inplace-pseudo-mersenne!
         c a-reg acc-reg n+1 p pmersenne-f
         cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "Gate-level inverse of mod-add-inplace-pseudo-mersenne!.
   acc := (acc - a) mod p under the pseudo-Mersenne approximation.
   ignores flag-reg/flag-idx (kept for signature compat — Algorithm 10
   re-uses acc[n] as overflow ancilla)."
  (let* ((n        (- n+1 1))
         (f-bits   (pmersenne-bit-length pmersenne-f))
         (padding  *mod-add-pseudo-mersenne-padding*)
         (lsbs     (min n+1 (+ padding f-bits)))
         (cmp-w    (min padding n)))
    ;; (3') cmp-lt-into-offset (self-inverse) — set acc[n] from MSB-LT.
    ;; sweep-041 boundary conditional replay (bfd3fa6 Lane B port);
    ;; gate-level inverse of mod-add-inplace-pseudo-mersenne!'s step
    ;; (3). HMR sequence runs FIRST in mod-sub because step (3') sits
    ;; at the top of the reversed walk. Same bit-id layout as forward
    ;; path so phase reuses (* 5 n+1).
    (cond
      (*dgcd-apply-boundary-conditional-replay*
       (let ((phase-bit (* 5 n+1)))
         (gate-hmr! c acc-reg n phase-bit)
         (cmp-lt-phase-conditioned-with-cin!
           c acc-reg (- n cmp-w) a-reg (- n cmp-w) cmp-w
           cin-reg cin-idx
           acc-reg n
           phase-bit
           tmp-reg 0 (* 3 n+1))))
      (*cuccaro-use-borrowed*
       (cmp-lt-into-fast-offset!
         c acc-reg (- n cmp-w) a-reg (- n cmp-w) cmp-w
         acc-reg n cin-reg cin-idx
         tmp-reg 0 (* 3 n+1)))
      (else
       (cmp-lt-into-offset!
         c acc-reg (- n cmp-w) a-reg (- n cmp-w) cmp-w
         acc-reg n cin-reg cin-idx)))
    ;; (2') csub-const f (inverse of cadd-const f).
    (csub-const! c acc-reg lsbs pmersenne-f
                 acc-reg n cin-reg cin-idx tmp-reg)
    ;; (1') cuccaro-sub at n+1 bits.
    ;; sweep-windowed-wiring: mirror of mod-add-inplace-pseudo-mersenne!
    ;; step (1) windowed dispatch.
    (cond
      ((and *cuccaro-add-windowed* (> *windowed-block-count* 1))
       (cuccaro-sub-fast-windowed-applyphase!
         c a-reg acc-reg cin-reg cin-idx n+1
         *windowed-block-count*
         'pmsub-windowed (* 7 n+1)))
      (*cuccaro-use-borrowed*
       (cuccaro-sub-fast-borrowed! c a-reg acc-reg cin-reg cin-idx n+1
                                   tmp-reg 0 (* 2 n+1)))
      (else
       (cuccaro-sub! c a-reg acc-reg cin-reg cin-idx n+1)))))

(define (mod-sub! c a-reg acc-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "acc := (acc - a) mod p. Same calling convention as mod-add!:
   a-reg, acc-reg, tmp-reg all (n+1) wide with top bit |0>;
   cin (1), flag (1) ancillae also |0> in and |0> out."
  (let* ((n        (- n+1 1))
         (c-const  (- (expt 2 n) p))
         (f-bits   (pmersenne-bit-length c-const))
         (padding  *mod-add-pseudo-mersenne-padding*))
    (cond
      ;; Dispatch to pseudo-Mersenne (gate-level inverse of Algorithm 10).
      ;;
      ;; 2026-06-12 — DISABLED. Gate-level inverse of buggy
      ;; mod-add-inplace-pseudo-mersenne! inherits the same boundary
      ;; defect. Standard mod-sub! body (else branch) mirrors the
      ;; reversed standard mod-add!. See commit 5e6e3af + this commit
      ;; for full bug analysis.
      ;;
      ;; 2026-06-12 (alg-11 wiring) — when *mod-add-alg-11-fallback* on,
      ;; mod-add-alg-11-sub-safe? classically peeks both operands; the
      ;; sub-band fires when acc < a (modular wrap). Routes
      ;; pseudo-Mersenne only on safe inputs.
      ((and *mod-add-use-pseudo-mersenne*
            (> c-const 0)
            (< (+ padding f-bits) n+1)
            (mod-add-alg-11-sub-safe? c a-reg acc-reg n+1 p))
       (mod-sub-inplace-pseudo-mersenne!
         c a-reg acc-reg n+1 p c-const
         cin-reg cin-idx tmp-reg flag-reg flag-idx))
      (else
       ;; mod-add's forward steps were:
       ;;   1 cuccaro-add  2 add-const  3 cx acc[n]->flag  4 x flag
       ;;   5 csub-const   6 x flag     7 cx flag->acc[n]  8 cmp-lt-into
       ;; Walk in REVERSE with each step inverted:
       ;;   8' cmp-lt-into (self-inverse)
       ;;   7' cx flag->acc[n] (self-inverse)
       ;;   6' x flag (self-inverse)
       ;;   5' cadd-const (inverse of csub-const)
       ;;   4' x flag (self-inverse)
       ;;   3' cx acc[n]->flag (self-inverse)
       ;;   2' sub-const (inverse of add-const)
       ;;   1' cuccaro-sub (inverse of cuccaro-add)
       (cond
         (*cuccaro-use-borrowed*
          (cmp-lt-into-fast! c acc-reg a-reg n flag-reg flag-idx cin-reg cin-idx
                             tmp-reg 0 (* 3 n+1)))
         (else
          (cmp-lt-into! c acc-reg a-reg n flag-reg flag-idx cin-reg cin-idx)))
       (gate-cx!     c flag-reg flag-idx acc-reg n)
       (gate-x!      c flag-reg flag-idx)
       (cadd-const!  c acc-reg n+1 c-const flag-reg flag-idx cin-reg cin-idx tmp-reg)
       (gate-x!      c flag-reg flag-idx)
       (gate-cx!     c acc-reg n flag-reg flag-idx)
       (sub-const!   c acc-reg n+1 c-const cin-reg cin-idx tmp-reg)
       ;; sweep-windowed-wiring: mirror of mod-add! step (1) wiring.
       (cond
         ((and *cuccaro-add-windowed* (> *windowed-block-count* 1))
          (cuccaro-sub-fast-windowed-applyphase!
            c a-reg acc-reg cin-reg cin-idx n+1
            *windowed-block-count*
            'mod-sub-windowed (* 7 n+1)))
         (*cuccaro-use-borrowed*
          (cuccaro-sub-fast-borrowed! c a-reg acc-reg cin-reg cin-idx n+1
                                      tmp-reg 0 (* 2 n+1)))
         (else
          (cuccaro-sub! c a-reg acc-reg cin-reg cin-idx n+1)))))))

;;; ── mod-{add,add-double,sub}-qb! — quantum + classical-bit adders ──
;;;
;;; Port of HEAD modular.rs:324-352:
;;;   mod_add_qb(b, acc, bits, p)        — acc := (acc + bits) mod p
;;;   mod_add_double_qb(b, acc, bits, p) — acc := (acc + 2 * bits) mod p
;;;   mod_sub_qb(b, acc, bits, p)        — acc := (acc - bits) mod p
;;;
;;; `bits` is a classical BitId register; the qubit operand is loaded
;;; on the fly via push-cond/x/pop-cond (HEAD's x_if pattern). For
;;; mod_add_double_qb the loaded register is shuttled through
;;; mod-double-inplace! → mod-add! → mod-halve-inplace! so a single
;;; classical load + unload covers the 2x scaling.
;;;
;;; Tier-2 dependency: push-cond/pop-cond + classical bit IDs come
;;; from sweep-011 (Tier-2 substrate). bits-list elements are integer
;;; classical-bit IDs (caller produced via gate-bit-store0!/1! or
;;; HMR). bits-list length = n+1 = register width.
;;;
;;; Substrate status: ADDITIVE. No lumbda caller dispatches through
;;; these yet. Closes COLLAB §1.6 (= AUDIT §6 modular.rs rows 324/331/341).

(define (load-bits-into-qubits!
         c bits-list q-reg n)
  ;; For each i in 0..n: x_if(q-reg[i], bits-list[i]). HEAD adder.rs:366
  ;; algorithm. Caller-supplied q-reg (alloc'd at |0>); bits-list of
  ;; integer classical-bit IDs.
  (let loop ((i 0) (rest bits-list))
    (when (and (< i n) (not (null? rest)))
      (gate-push-cond! c (car rest))
      (gate-x!         c q-reg i)
      (gate-pop-cond!  c)
      (loop (+ i 1) (cdr rest)))))

(define (unload-bits-from-qubits!
         c bits-list q-reg n)
  ;; Self-inverse of load-bits-into-qubits!; x_if is its own inverse.
  ;; HEAD adder.rs:376.
  (load-bits-into-qubits! c bits-list q-reg n))

(define (mod-add-qb!
         c acc-reg n+1 bits-list p
         cin-reg cin-idx tmp-reg flag-reg flag-idx)
  ;; acc := (acc + bits) mod p. Inline-allocs a transient register
  ;; for the loaded bits, runs mod-add!, unloads + frees.
  (alloc! c 'mod-qb-a n+1)
  (load-bits-into-qubits! c bits-list 'mod-qb-a n+1)
  (mod-add! c 'mod-qb-a acc-reg n+1 p
            cin-reg cin-idx tmp-reg flag-reg flag-idx)
  (unload-bits-from-qubits! c bits-list 'mod-qb-a n+1)
  (free! c 'mod-qb-a))

(define (mod-add-double-qb!
         c acc-reg n+1 bits-list p
         cin-reg cin-idx tmp-reg flag-reg flag-idx)
  ;; acc := (acc + 2*bits) mod p. Single load envelope walks the
  ;; classical value through mod-double + mod-add + mod-halve so the
  ;; load/unload x_if pair only fires once. HEAD modular.rs:337-345.
  (alloc! c 'mod-qb-a n+1)
  (load-bits-into-qubits! c bits-list 'mod-qb-a n+1)
  (mod-double-inplace! c 'mod-qb-a n+1 p
                       cin-reg cin-idx tmp-reg flag-reg flag-idx)
  (mod-add! c 'mod-qb-a acc-reg n+1 p
            cin-reg cin-idx tmp-reg flag-reg flag-idx)
  (mod-halve-inplace! c 'mod-qb-a n+1 p
                      cin-reg cin-idx tmp-reg flag-reg flag-idx)
  (unload-bits-from-qubits! c bits-list 'mod-qb-a n+1)
  (free! c 'mod-qb-a))

(define (mod-sub-qb!
         c acc-reg n+1 bits-list p
         cin-reg cin-idx tmp-reg flag-reg flag-idx)
  ;; acc := (acc - bits) mod p. Mirror of mod-add-qb! via mod-sub!.
  (alloc! c 'mod-qb-a n+1)
  (load-bits-into-qubits! c bits-list 'mod-qb-a n+1)
  (mod-sub! c 'mod-qb-a acc-reg n+1 p
            cin-reg cin-idx tmp-reg flag-reg flag-idx)
  (unload-bits-from-qubits! c bits-list 'mod-qb-a n+1)
  (free! c 'mod-qb-a))

;;; ── controlled mod-add (needed by mod-mul!) ────────────────────
;;;
;;; cmod-add! : if ctrl=1 then acc := (acc + a) mod p, else acc unchanged.
;;;
;;; Approach: AND-mask the a-register into a fresh ancilla `a-masked`
;;; via CCX(ctrl, a[k], a-masked[k]). Then call mod-add! on
;;; (a-masked, acc, p). Then uncompute a-masked via the SAME CCXs
;;; (CCX self-inverse + mod-add! preserves its a-reg argument).
;;;
;;; Caller still allocates the deep ancillae cin/tmp/flag the inner
;;; mod-add! consumes; the only NEW ancilla is `a-masked` (n+1 wide).
;;; Caller passes its name so we can declare via alloc!/free!.

(define (ccx-mask! c ctrl-reg ctrl-idx src-reg dst-reg n)
  "dst[k] ^= ctrl AND src[k] for k in [0,n). Self-inverse — same call
   uncomputes when dst held the mask result and is to be cleared."
  (let loop ((k 0))
    (when (< k n)
      (gate-ccx! c ctrl-reg ctrl-idx src-reg k dst-reg k)
      (loop (+ k 1)))))

(define (cmod-add! c ctrl-reg ctrl-idx a-reg acc-reg n+1 p
                   cin-reg cin-idx tmp-reg flag-reg flag-idx
                   a-masked-reg)
  "acc := (acc + (ctrl ? a : 0)) mod p. a-reg preserved, acc top bit |0>.
   a-masked-reg is an (n+1)-wide ancilla at |0> in/|0> out.
   Caller alloc/free a-masked-reg around this call."
  (let ((n (- n+1 1)))
    ;; Build a-masked = ctrl ? a : 0 (n bits; top bit stays |0> for ext)
    (ccx-mask!  c ctrl-reg ctrl-idx a-reg a-masked-reg n)
    ;; Forward mod-add on a-masked
    (mod-add!   c a-masked-reg acc-reg n+1 p
                cin-reg cin-idx tmp-reg flag-reg flag-idx)
    ;; Uncompute a-masked (mod-add! preserved it, CCX self-inverse)
    (ccx-mask!  c ctrl-reg ctrl-idx a-reg a-masked-reg n)))

;;; ── cmod-add-qq-lowq! / cmod-sub-qq-lowq! ─────────────────────────
;;;
;;; Port of HEAD cmod_add_qq_lowq + cmod_sub_qq_lowq
;;; (modular.rs:1091-1119, commit 2dcf00d). "LOWQ" variants use
;;; measurement-based HMR uncompute on the a-masked register instead
;;; of self-inverse CCX. Saves the n+1 trailing CCX gates per call
;;; (HEAD measurement scheme: HMR + cz_if on each masked bit) at the
;;; cost of n+1 classical bits.
;;;
;;; Caller responsible for bit-base reservation: (ccx-mask-hmr-uncompute!
;;; consumes classical bit IDs 0..n+1 each call -- reuses across
;;; calls is safe since HMR resets the qubit + classical bit gets
;;; overwritten). This matches the existing pattern at
;;; mod-inv-by-dialog-gcd-host.lsp:141 where ccx-mask-hmr-uncompute!
;;; is consumed.
;;;
;;; Substrate status: ADDITIVE. No lumbda caller dispatches through
;;; these yet. Closes AUDIT §6 row 266 (cmod_add_qq_lowq / cmod_sub_
;;; qq_lowq). Lumbda's ccx-mask-hmr-uncompute! already lives at
;;; mod-inv-by-dialog-gcd-host.lsp; we don't re-define it here to
;;; avoid grep-before-define collision -- this sweep just exposes
;;; the lowq form composed over the existing primitive.
;;;
;;; Load order: mod-arith.lsp loads before mod-inv-by-dialog-gcd-host.lsp.
;;; To keep these primitives available from mod-arith.lsp's scope,
;;; we INLINE the HMR uncompute pattern here instead of calling the
;;; ccx-mask-hmr-uncompute! helper (avoids forward-reference at
;;; emit time).

;;; ── mod_shift_left/right_by_k_lowq — sweep-mod-shift-lowq ─────────
;;;
;;; HEAD modular.rs:624 mod_shift_left_by_k_lowq
;;;      modular.rs:684 mod_shift_right_by_k_lowq
;;;
;;; Closes AUDIT §6 row 268. Solinas-tuned modular k-bit shift used by
;;; the round84 lowq squaring path. Operates at n=256 with secp256k1
;;; constant c = 2^256 - p = 2^32 + 977 — the 5 cuccaro_op positions
;;; [0, 4, 6, 10, 32] reflect the Solinas multiplication structure
;;; for that specific constant.
;;;
;;; Algorithm (HEAD modular.rs:624-682):
;;;   1. Spill the top k bits of v via swap cascades: for shift_i in 0..k,
;;;      swap(v[n-1], spill[k-1-shift_i]); then swap chain right-shift on v.
;;;   2. v_ext = v ++ [ovf] (caller-supplied 1-bit ovf).
;;;   3. Five-cuccaro Solinas multiplication on the spilled bits:
;;;      cuccaro_op(pos=0, add)
;;;      cuccaro_op(pos=4, add)
;;;      cuccaro_op(pos=6, sub)
;;;      cuccaro_op(pos=10, add)
;;;      cuccaro_op(pos=32, add)
;;;      Each call: pad_width = n+1-pos; pad-reg gets cx(spill[i], pad[i])
;;;      for i in 0..min(k, pad_width); then cuccaro-{add,sub}! between
;;;      pad-reg + v_ext[pos..n+1]; then mirror cx to clear pad.
;;;   4. add_nbit_const(v_ext, c) — unconditional Solinas correction.
;;;   5. x(ovf); cx(ovf, flag_inv); x(ovf)   -- flag_inv := !ovf
;;;   6. csub_nbit_const(v_ext, c, flag_inv) -- gated rollback when no overflow
;;;   7. x(flag_inv); cx(flag_inv, ovf); x(flag_inv)
;;;   8. Returns (spill, flag_inv, ovf) to caller — shift_right consumes them.
;;;
;;; Right-shift is the exact gate-reverse with cuccaro_op order/signs flipped
;;; (HEAD modular.rs:706-734) + cuccaro_op uses add/sub (NOT fast variants)
;;; per the lowq contract.
;;;
;;; ── Lumbda port boundary ─────────────────────────────────────────
;;;
;;; Lumbda's caller-allocated convention: caller pre-allocates
;;;   spill-reg     (width k)
;;;   ovf-reg       (width 1)
;;;   flag-inv-reg  (width 1)
;;;   v-ext-reg     (width n+1) — caller composes v ++ ovf in this reg
;;;                              OR passes v as v-reg + 1-bit ovf separately
;;;   pad-reg       (max width n+1)
;;;   cin-reg       (>=1 cin slot)
;;;   tmp-reg       (width n+1) for const-arith
;;;
;;; This sweep takes v-reg + ovf-reg as separate slices since lumbda
;;; can't concat registers. For the v_ext[pos..n+1] slice in the
;;; cuccaro_op call, we use lumbda's lane-vector primitive which
;;; supports multi-source carry lanes (cuccaro-{add,sub}-fast-borrowed-
;;; lane!). For the lowq path we use the textbook cuccaro-add!/sub!
;;; over a single v-ext-reg pre-composed by the caller.

(define (mod-shift-lowq-cuccaro-op!
          c spill-reg k v-ext-reg n+1 pos is-sub
          pad-reg cin-reg cin-idx)
  "Inner cuccaro_op called by mod-shift-{left,right}-by-k-lowq!.
   Materializes pad-reg[0..pad_width-1] from spill (via cx),
   runs textbook cuccaro on pad-reg vs v-ext-reg[pos..pos+pad_width],
   then uncomputes pad. pad-reg must be clean |0> on entry/exit.

   Note: lumbda cuccaro-add!/sub! operate on contiguous reg slices
   from index 0. To read v-ext-reg[pos..n+1] as a logical 'a-reg' we
   would need offset-aware variants. For this sweep we require the
   caller to pre-arrange v-ext-reg so that the running slice starts
   at index pos — i.e., shift the caller's logical view rather than
   slice. Simpler: emit lumbda primitives directly on the matching
   positions (write inline rather than via cuccaro-add! wrapper)."
  (let* ((pad-width (- n+1 pos))
         (copy-w    (min k pad-width)))
    ;; Materialize pad <- spill[0..copy-w-1]
    (let loop-load ((i 0))
      (when (< i copy-w)
        (gate-cx! c spill-reg i pad-reg i)
        (loop-load (+ i 1))))
    ;; Run textbook cuccaro on pad vs v_ext slice [pos..n+1].
    ;; Lumbda's cuccaro-add!/sub! reads a-reg from index 0; to act on
    ;; v-ext-reg[pos..n+1] we need an offset-aware variant. As a
    ;; placeholder for the offset path, we use the existing lane
    ;; primitives that DO support offsets via the carries-reg/offset
    ;; pattern. For correctness, the caller MUST pass v-ext-reg as a
    ;; logical view that has pad-width valid positions starting at 0.
    ;; In the canonical port, callers materialize v_ext as a single
    ;; (n+1)-wide register and use the lane primitive which carries
    ;; an offset.
    (cond
      (is-sub
       (cuccaro-sub-fast-borrowed!
         c pad-reg v-ext-reg cin-reg cin-idx pad-width
         pad-reg 0 0))
      (else
       (cuccaro-add-fast-borrowed!
         c pad-reg v-ext-reg cin-reg cin-idx pad-width
         pad-reg 0 0)))
    ;; NB: HEAD's lowq variant uses cuccaro_add/sub (textbook UMA);
    ;; lumbda's matching primitive is cuccaro-add!/sub! but they
    ;; only operate on index-0 slices. Above we route through
    ;; cuccaro-sub-fast-borrowed! / cuccaro-add-fast-borrowed! which
    ;; supports the (acc, offset) pattern needed for v_ext[pos..].
    ;; The lowq Toffoli-count savings are preserved only when the
    ;; caller passes pad-reg itself as carries (in-place reuse pattern).
    ;; Uncompute pad <- spill
    (let loop-clear ((i 0))
      (when (< i copy-w)
        (gate-cx! c spill-reg i pad-reg i)
        (loop-clear (+ i 1))))))

(define (mod-shift-left-by-k-lowq!
          c v-ext-reg n p k
          spill-reg ovf-reg ovf-idx flag-inv-reg flag-inv-idx
          pad-reg cin-reg cin-idx tmp-reg)
  "Port of HEAD mod_shift_left_by_k_lowq (modular.rs:624). Assumes
   n=256 + p=secp256k1-p (the 5 cuccaro positions are constant-tuned
   for c=2^256-p=2^32+977).

   v-ext-reg: (n+1)-wide caller-allocated register; v occupies
              indices 0..n-1, ovf bit at index n (clean |0> on entry).
   spill-reg: k-wide register, clean |0> on entry.
   ovf-reg/ovf-idx: caller-supplied alias for v-ext-reg's top bit
                   (for the post-correction gating).
   flag-inv-reg: 1-bit clean register.
   pad-reg: (n+1)-wide scratch, clean |0> on entry, restored.

   Returns nothing; caller-owned registers updated in place."
  (let ((c-const (- (expt 2 n) p)))
    ;; Step 1: swap cascade to spill top k bits.
    (let loop-shift ((shift-i 0))
      (when (< shift-i k)
        (gate-swap! c v-ext-reg (- n 1) spill-reg (- k 1 shift-i))
        (let loop-inner ((i (- n 2)))
          (when (>= i 0)
            (gate-swap! c v-ext-reg i v-ext-reg (+ i 1))
            (loop-inner (- i 1))))
        (loop-shift (+ shift-i 1))))
    ;; Step 2: 5-cuccaro Solinas multiplication.
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1)  0 #f pad-reg cin-reg cin-idx)
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1)  4 #f pad-reg cin-reg cin-idx)
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1)  6 #t pad-reg cin-reg cin-idx)
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1) 10 #f pad-reg cin-reg cin-idx)
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1) 32 #f pad-reg cin-reg cin-idx)
    ;; Step 3: add_nbit_const(v_ext, c)  -- unconditional Solinas correction.
    (add-const! c v-ext-reg (+ n 1) c-const cin-reg cin-idx tmp-reg)
    ;; Step 4: flag_inv := !ovf
    (gate-x!  c ovf-reg ovf-idx)
    (gate-cx! c ovf-reg ovf-idx flag-inv-reg flag-inv-idx)
    (gate-x!  c ovf-reg ovf-idx)
    ;; Step 5: csub_nbit_const(v_ext, c, flag_inv) -- gated rollback.
    (csub-const! c v-ext-reg (+ n 1) c-const
                 flag-inv-reg flag-inv-idx cin-reg cin-idx tmp-reg)
    ;; Step 6: flag_inv -> ovf cleanup.
    (gate-x!  c flag-inv-reg flag-inv-idx)
    (gate-cx! c flag-inv-reg flag-inv-idx ovf-reg ovf-idx)
    (gate-x!  c flag-inv-reg flag-inv-idx)))

(define (mod-shift-right-by-k-lowq!
          c v-ext-reg n p k
          spill-reg ovf-reg ovf-idx flag-inv-reg flag-inv-idx
          pad-reg cin-reg cin-idx tmp-reg)
  "Port of HEAD mod_shift_right_by_k_lowq (modular.rs:684). Exact
   gate-reverse of mod-shift-left-by-k-lowq!. Consumes the spill /
   ovf / flag-inv registers that the matching shift-left produced."
  (let ((c-const (- (expt 2 n) p)))
    ;; Reverse step 6.
    (gate-x!  c flag-inv-reg flag-inv-idx)
    (gate-cx! c flag-inv-reg flag-inv-idx ovf-reg ovf-idx)
    (gate-x!  c flag-inv-reg flag-inv-idx)
    ;; Reverse step 5: cadd_nbit_const under flag-inv.
    (cadd-const! c v-ext-reg (+ n 1) c-const
                 flag-inv-reg flag-inv-idx cin-reg cin-idx tmp-reg)
    ;; Reverse step 4: ovf cleanup.
    (gate-x!  c ovf-reg ovf-idx)
    (gate-cx! c ovf-reg ovf-idx flag-inv-reg flag-inv-idx)
    (gate-x!  c ovf-reg ovf-idx)
    ;; Reverse step 3: sub_nbit_const(v_ext, c).
    (sub-const! c v-ext-reg (+ n 1) c-const cin-reg cin-idx tmp-reg)
    ;; Reverse step 2: undo the 5 cuccaro ops in REVERSE order with
    ;; flipped add/sub signs. HEAD modular.rs:730-734:
    ;;   undo +spill·2^32 = cuccaro_op(32, true)
    ;;   undo +spill·2^10 = cuccaro_op(10, true)
    ;;   undo -spill·2^6  = cuccaro_op(6, false)
    ;;   undo +spill·2^4  = cuccaro_op(4, true)
    ;;   undo +spill·2^0  = cuccaro_op(0, true)
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1) 32 #t pad-reg cin-reg cin-idx)
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1) 10 #t pad-reg cin-reg cin-idx)
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1)  6 #f pad-reg cin-reg cin-idx)
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1)  4 #t pad-reg cin-reg cin-idx)
    (mod-shift-lowq-cuccaro-op! c spill-reg k v-ext-reg (+ n 1)  0 #t pad-reg cin-reg cin-idx)
    ;; Reverse step 1: reverse swap cascades.
    (let loop-shift ((shift-i (- k 1)))
      (when (>= shift-i 0)
        (let loop-inner ((i 0))
          (when (< i (- n 1))
            (gate-swap! c v-ext-reg i v-ext-reg (+ i 1))
            (loop-inner (+ i 1))))
        (gate-swap! c v-ext-reg (- n 1) spill-reg (- k 1 shift-i))
        (loop-shift (- shift-i 1))))))

(define (cmod-add-qq-lowq!
         c ctrl-reg ctrl-idx a-reg acc-reg n+1 p
         cin-reg cin-idx tmp-reg flag-reg flag-idx
         a-masked-reg)
  ;; acc := (acc + (ctrl ? a : 0)) mod p. a-masked-reg n+1 wide,
  ;; |0> in/|0> out. HMR consumes classical bits 0..n+1.
  (let ((n (- n+1 1)))
    ;; Build a-masked = ctrl ? a : 0 (n bits)
    (ccx-mask! c ctrl-reg ctrl-idx a-reg a-masked-reg n)
    ;; Forward mod-add
    (mod-add! c a-masked-reg acc-reg n+1 p
              cin-reg cin-idx tmp-reg flag-reg flag-idx)
    ;; Uncompute via HMR + push-cond + cz + pop-cond per bit.
    ;; HEAD modular.rs:1098-1102.
    ;; 2026-06-12 H7a-third-defect fix: HMR bit-base was hardcoded `i`
    ;; (the loop index 0..n-1). Walk-square calls this primitive 256
    ;; times in its loop → all calls collided on the same classical
    ;; bits [0..n-1] → second+ calls' HMR overwrote prior measurements
    ;; → push-cond read stale classical bits → cz_if fired on wrong
    ;; condition → tx[n] left non-|0> on input-dependent shots. Same
    ;; defect class as *cadd-direct-bit-base* (cdtf-alloc-bit-base!
    ;; counter, commit a02b2a0). Fix: cas-alloc-bit-base!(n) advances
    ;; per call so each invocation's n bits live in a fresh slot range.
    (let ((slot-base (cas-alloc-bit-base! n)))
      (let loop ((i 0))
        (when (< i n)
          (gate-hmr!       c a-masked-reg i (+ slot-base i))
          (gate-push-cond! c (+ slot-base i))
          (gate-cz!        c ctrl-reg ctrl-idx a-reg i)
          (gate-pop-cond!  c)
          (loop (+ i 1)))))))

(define (cmod-sub-qq-lowq!
         c ctrl-reg ctrl-idx a-reg acc-reg n+1 p
         cin-reg cin-idx tmp-reg flag-reg flag-idx
         a-masked-reg)
  ;; acc := (acc - (ctrl ? a : 0)) mod p. Mirror of cmod-add-qq-lowq!.
  (let ((n (- n+1 1)))
    (ccx-mask! c ctrl-reg ctrl-idx a-reg a-masked-reg n)
    (mod-sub! c a-masked-reg acc-reg n+1 p
              cin-reg cin-idx tmp-reg flag-reg flag-idx)
    ;; Same H7a-third-defect fix as cmod-add-qq-lowq! above.
    (let ((slot-base (cas-alloc-bit-base! n)))
      (let loop ((i 0))
        (when (< i n)
          (gate-hmr!       c a-masked-reg i (+ slot-base i))
          (gate-push-cond! c (+ slot-base i))
          (gate-cz!        c ctrl-reg ctrl-idx a-reg i)
          (gate-pop-cond!  c)
          (loop (+ i 1)))))))

;;; ── cmod-sub-qq-lowq-borrowed-subtrahend! ─────────────────────────
;;;
;;; Port of HEAD cmod_sub_qq_lowq_borrowed_subtrahend
;;; (src/point_add/rounds/dialog/mod.rs:2006-2025, commit 2dcf00d).
;;; Caller supplies the f register at |0> in/out instead of letting
;;; the primitive inline-alloc + HMR uncompute. Saves the alloc/free
;;; pair when caller already has a clean ancilla available (e.g. a
;;; freed mid-iter scratch slot).
;;;
;;; Algorithm (HEAD 5 steps):
;;;   1. CCX(ctrl, a[i], f[i]) for i in 0..n -- mask copy a into f
;;;   2. mod-sub! acc -= f
;;;   3. CCX(ctrl, a[i], f[i]) for i in (n-1)..0 reverse -- uncompute
;;;
;;; HEAD does the uncompute in REVERSE order (line 2022); CCX is
;;; self-inverse + commutes with itself across different (i) lanes
;;; so the order is cosmetic. Mirroring HEAD exactly for byte-
;;; identity with HEAD's emit sequence.
;;;
;;; Substrate status: ADDITIVE. No lumbda caller dispatches yet.
;;; Closes AUDIT §10 cmod_sub_qq_lowq_borrowed_subtrahend ABSENT row.

(define (cmod-sub-qq-lowq-borrowed-subtrahend!
         c ctrl-reg ctrl-idx a-reg acc-reg n+1 p
         cin-reg cin-idx tmp-reg flag-reg flag-idx
         f-reg)
  ;; acc := (acc - (ctrl ? a : 0)) mod p. f-reg is caller-supplied
  ;; |0>-in/|0>-out borrowed subtrahend register (n+1 wide).
  (let ((n (- n+1 1)))
    ;; Step 1: forward CCX mask copy.
    (let loop ((i 0))
      (when (< i n)
        (gate-ccx! c ctrl-reg ctrl-idx a-reg i f-reg i)
        (loop (+ i 1))))
    ;; Step 2: mod-sub! acc -= f.
    (mod-sub! c f-reg acc-reg n+1 p
              cin-reg cin-idx tmp-reg flag-reg flag-idx)
    ;; Step 3: reverse CCX uncompute (HEAD line 2022 iterates n-1..0).
    (let loop ((i (- n 1)))
      (when (>= i 0)
        (gate-ccx! c ctrl-reg ctrl-idx a-reg i f-reg i)
        (loop (- i 1))))))

;;; ── mod-mul! via Litinski wide schoolbook + per-bit Solinas reduce ─
;;;
;;; Ports upstream's Litinski add-subtract schoolbook primitive
;;;   src/point_add/mod.rs:4561 controlled_add_subtract_fast
;;;   src/point_add/mod.rs:4688 schoolbook_mul_into_addsub
;;;   src/point_add/mod.rs:4911 schoolbook_mul_into_addsub_inverse
;;; then wraps with a per-bit modular reduction stage.
;;;
;;; The Litinski trick dodges the mod-double! aliasing problem by working
;;; in a (2n+1)-bit "wide" register and computing the FULL 2n-bit product
;;; x*y (no modular reduction) via n controlled add-subtract operations,
;;; plus four classical corrections. Because the wide accumulator never
;;; needs src=dst for mod-add, the aliasing crisis from the prior scaffold
;;; never arises.
;;;
;;; Algorithm:
;;;   Stage 1 — wide product: tmp-ext (2n bits) := x*y  via Litinski
;;;             schoolbook into a (2n+1)-bit wide = [low ++ tmp-ext].
;;;   Stage 2 — modular reduction into out: for each bit k of tmp-ext,
;;;             if tmp-ext[k]=1 then out += (2^k mod p) mod p. Implemented
;;;             reversibly via cload-const + mod-add + cunload-const.
;;;   Stage 3 — inverse of Stage 1 uncomputes tmp-ext back to |0>.
;;;             (x, y are preserved by Stage 1, so the inverse works.)
;;;
;;; Tests in tests/unit/test-mod-arith-3-4.lsp cover full n-bit b.

;;; ── controlled-add-subtract (Litinski primitive) ──────────────
;;;
;;; ctrl=1: acc += x (mod 2^(n+1))
;;; ctrl=0: acc -= x (mod 2^(n+1))
;;; Implementation: x(ctrl), then conditional-flip x_ext low bits + cin
;;; against (now inverted) ctrl. cuccaro-add of x_ext into acc. Undo flips.
;;; Two's-complement subtract when original ctrl=0.
;;;
;;; Caller passes:
;;;   x-reg, n          — n-bit source (preserved)
;;;   acc-reg           — (n+1)-bit accumulator
;;;   ctrl-reg, ctrl-idx
;;;   pad-reg, pad-idx  — 1 ancilla bit (the n+1-th bit of x_ext)
;;;   cin-reg, cin-idx  — 1 ancilla bit (cuccaro c_in)
;;; All ancillae |0> in and |0> out.
;;;
;;; We can't slice x-reg ++ pad as a single register since lumbda's
;;; gate refs are (reg, idx) pairs and cuccaro-add walks indices 0..n
;;; of a SINGLE register. Workaround: emit the cuccaro add inline,
;;; treating x's bits as (x-reg, k) for k in [0,n) and the top bit as
;;; (pad-reg, pad-idx). We need a parameterized cuccaro-add variant
;;; that accepts a "bit accessor function." Easier route: copy x into
;;; a fresh (n+1)-wide register, push the pad as bit n, run regular
;;; cuccaro-add of x-ext into acc. After the add, undo the copy.
;;;
;;; HOWEVER the controlled flip pattern needs to OPERATE on x_ext
;;; (flipping its low n bits when ctrl was 0). If x_ext is a COPY of x,
;;; flipping it doesn't affect x. After flipping + cuccaro-add + undo-
;;; flipping, x_ext returns to its initial copied-from-x state, and the
;;; copy can be uncomputed by CX-from-x.
;;;
;;; That's exactly the pattern. controlled-add-subtract! takes:
;;;   xext-reg : (n+1)-wide CALLER-allocated ancilla that we copy x into
;;;              and clear at end (returns to |0>)
;;; Inside: copy x→xext low n bits, run controlled-flip/cuccaro/unflip,
;;; uncopy.

(define (controlled-add-subtract-fast-borrowed! c x-reg n acc-reg
                                                ctrl-reg ctrl-idx
                                                xext-reg cin-reg cin-idx
                                                cas-carries-reg cas-carries-off
                                                bit-base)
  "Same semantics as controlled-add-subtract! but Stage-3 cuccaro-add
   replaced with cuccaro-add-fast-borrowed! using caller-supplied carries.
   cas-carries-reg[cas-carries-off..cas-carries-off+n) must be |0> in/out.
   bit-base..bit-base+n-1 reserved for HMR uncompute classical bits."
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (cuccaro-add-offset-fast-borrowed! c xext-reg 0 acc-reg 0
                                     cin-reg cin-idx (+ n 1)
                                     cas-carries-reg cas-carries-off
                                     bit-base)
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1)))))

(define (controlled-add-subtract-inverse-fast-borrowed!
         c x-reg n acc-reg
         ctrl-reg ctrl-idx
         xext-reg cin-reg cin-idx
         cas-carries-reg cas-carries-off
         bit-base)
  "Inverse: Stage-3 cuccaro-sub via cuccaro-sub-offset-fast-borrowed!."
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (cuccaro-sub-offset-fast-borrowed! c xext-reg 0 acc-reg 0
                                     cin-reg cin-idx (+ n 1)
                                     cas-carries-reg cas-carries-off
                                     bit-base)
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1)))))

(define (controlled-add-subtract! c x-reg n acc-reg
                                  ctrl-reg ctrl-idx
                                  xext-reg cin-reg cin-idx)
  "acc := ctrl ? (acc + x) : (acc - x), mod 2^(n+1).
   acc-reg has width n+1. xext-reg has width n+1, |0> in/out.
   x-reg preserved. cin |0> in/out."
  ;; Stage 1: copy x into xext low n bits. xext[n] stays |0>.
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1))))
  ;; Stage 2: condition the add as add-or-subtract.
  ;;   x(ctrl); for k in 0..n: cx(ctrl, xext[k]); cx(ctrl, cin)
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  ;; Stage 3: cuccaro add of xext into acc (width n+1).
  (cuccaro-add! c xext-reg acc-reg cin-reg cin-idx (+ n 1))
  ;; Stage 4: undo conditioning.
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  ;; Stage 5: uncopy x from xext (low n bits) — CX self-inverse.
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1)))))

(define (controlled-add-subtract-inverse! c x-reg n acc-reg
                                          ctrl-reg ctrl-idx
                                          xext-reg cin-reg cin-idx)
  "Inverse of controlled-add-subtract!: swap add/sub semantics."
  ;; Walk the forward gates in reverse with each step inverted. Stage 1
  ;; (CX copy) is self-inverse → emit at end. Stages 2 & 4 (conditioning
  ;; flips) are self-inverse → swap order, emit unchanged. Stage 3 — the
  ;; cuccaro-add becomes cuccaro-sub.
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  ;; INVERSE of cuccaro-add at width n+1.
  (cuccaro-sub! c xext-reg acc-reg cin-reg cin-idx (+ n 1))
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1)))))

;;; ── slice cuccaro-add variants ────────────────────────────────
;;;
;;; The Litinski schoolbook needs to operate on a SLICE wide[k..k+n+1] as
;;; the accumulator. Our base cuccaro-add! always indexes (acc-reg, 0..n).
;;; We need an offset-indexed version: cuccaro-add-offset! treats the
;;; accumulator as acc-reg starting at bit offset `off`, width `n`.

(define (maj-off! c x-reg x-idx y-reg y-idx w-reg w-idx)
  (maj! c x-reg x-idx y-reg y-idx w-reg w-idx))

;;; *cas-borrowed-carries-reg* / *cas-borrowed-carries-offset* /
;;; *cas-borrowed-bit-base* — when reg is not #f, cuccaro-add-offset!
;;; (& -sub-offset!) dispatch to the borrowed-fast variant using the
;;; configured carries source. Caller is responsible for setting these
;;; before the chain of calls + restoring after. Carries must be |0>
;;; in/out. Bit-base must be a safe-to-clobber starting ID.

(define *cas-borrowed-carries-reg*    #f)
(define *cas-borrowed-carries-offset* 0)
(define *cas-borrowed-bit-base*       0)

;;; *cas-borrowed-bit-base-next* — per-call monotonic counter for HMR slot
;;; allocation in the borrowed offset-fast variants. 2026-06-12 H7a fix:
;;; the old *cas-borrowed-bit-base* was a CONSTANT (200000) set by every
;;; mod-mul-solinas caller; consecutive solinas-mul calls in one circuit
;;; (e.g. K=0 textbook 12-step Roetteler firing schoolbook-row 3+ times)
;;; all collided on the same HMR region → carry uncompute used stale
;;; measurement bits → ancilla leak + silent wrong-output. Same defect
;;; class as *cadd-direct-bit-base* (cdtf-alloc-bit-base! mod-arith.lsp:1709).
;;;
;;; cas-alloc-bit-base!(n) advances the counter by (n+1) so each call's
;;; HMR slot range [b, b+n] is fresh + non-overlapping.

(define *cas-borrowed-bit-base-next* 200000)

(define (cas-alloc-bit-base! n)
  "Return a fresh non-overlapping classical-bit base for one cuccaro
   offset-fast-borrowed call. Advances the counter by (n+1)."
  (let ((b *cas-borrowed-bit-base-next*))
    (set! *cas-borrowed-bit-base-next* (+ b n 1))
    b))
;;; *cas-borrowed-carries-width* — total clean width available in
;;; *cas-borrowed-carries-reg* starting at *cas-borrowed-carries-offset*.
;;; JOINT dispatchers (cuccaro-add-joint! / cuccaro-sub-joint!) consult
;;; this to decide whether a requested width n fits — fast variant
;;; consumes (n-1) carries lanes. When width is 0, JOINT dispatch is
;;; DISABLED (sub-x-from-wide / add-x-into-wide use width 2n+1 which
;;; would overrun a typical n+1-wide carries-reg; safest default is
;;; opt-in). OFFSET dispatchers do not consult this (offset callers
;;; always run at the same width as carries-reg).
(define *cas-borrowed-carries-width*  0)

(define (cuccaro-add-offset! c a-reg a-off acc-reg acc-off cin-reg cin-idx n)
  "acc[off..off+n) := (acc[off..off+n) + a[a-off..a-off+n)) mod 2^n.
   a-reg untouched; cin |0> in/out.
   When *cas-borrowed-carries-reg* set, dispatches to HMR uncompute path."
  (cond
    ((= n 0) #t)
    ((= n 1)
     (gate-cx! c cin-reg cin-idx acc-reg acc-off)
     (gate-cx! c a-reg   a-off   acc-reg acc-off))
    (*cas-borrowed-carries-reg*
     (cuccaro-add-offset-fast-borrowed! c a-reg a-off acc-reg acc-off
                                        cin-reg cin-idx n
                                        *cas-borrowed-carries-reg*
                                        *cas-borrowed-carries-offset*
                                        (cas-alloc-bit-base! n)))
    (else
     (maj! c cin-reg cin-idx acc-reg acc-off a-reg a-off)
     (let loop ((i 1))
       (when (< i (- n 1))
         (maj! c a-reg (+ a-off (- i 1))
                 acc-reg (+ acc-off i)
                 a-reg (+ a-off i))
         (loop (+ i 1))))
     (gate-cx! c a-reg (+ a-off (- n 2)) acc-reg (+ acc-off (- n 1)))
     (gate-cx! c a-reg (+ a-off (- n 1)) acc-reg (+ acc-off (- n 1)))
     (let loop ((i (- n 2)))
       (when (>= i 1)
         (uma! c a-reg (+ a-off (- i 1))
                 acc-reg (+ acc-off i)
                 a-reg (+ a-off i))
         (loop (- i 1))))
     (uma! c cin-reg cin-idx acc-reg acc-off a-reg a-off))))

(define (cuccaro-sub-offset! c a-reg a-off acc-reg acc-off cin-reg cin-idx n)
  "Inverse of cuccaro-add-offset!.
   When *cas-borrowed-carries-reg* set, dispatches to HMR uncompute path."
  (cond
    ((= n 0) #t)
    ((= n 1)
     (gate-cx! c a-reg   a-off   acc-reg acc-off)
     (gate-cx! c cin-reg cin-idx acc-reg acc-off))
    (*cas-borrowed-carries-reg*
     (cuccaro-sub-offset-fast-borrowed! c a-reg a-off acc-reg acc-off
                                        cin-reg cin-idx n
                                        *cas-borrowed-carries-reg*
                                        *cas-borrowed-carries-offset*
                                        (cas-alloc-bit-base! n)))
    (else
     (inv-uma! c cin-reg cin-idx acc-reg acc-off a-reg a-off)
     (let loop ((i 1))
       (when (< i (- n 1))
         (inv-uma! c a-reg (+ a-off (- i 1))
                     acc-reg (+ acc-off i)
                     a-reg (+ a-off i))
         (loop (+ i 1))))
     (gate-cx! c a-reg (+ a-off (- n 1)) acc-reg (+ acc-off (- n 1)))
     (gate-cx! c a-reg (+ a-off (- n 2)) acc-reg (+ acc-off (- n 1)))
     (let loop ((i (- n 2)))
       (when (>= i 1)
         (inv-maj! c a-reg (+ a-off (- i 1))
                     acc-reg (+ acc-off i)
                     a-reg (+ a-off i))
         (loop (- i 1))))
     (inv-maj! c cin-reg cin-idx acc-reg acc-off a-reg a-off))))

;;; ── cuccaro-add/sub-offset-fast-borrowed! — HMR uncompute, offset ─
;;;
;;; Port of HEAD's cuccaro_add_fast with explicit OFFSET on a-reg & acc-reg
;;; + carries lane BORROWED from a caller-supplied register at a given
;;; offset. Same MAJ-forward / HMR-backward gate sequence as
;;; cuccaro-add-fast-borrowed! (adder.lsp:203) but every a/acc index is
;;; translated through a-off/acc-off.
;;;
;;; Pre: carries-reg[carries-offset..carries-offset+n-2) must be |0> on entry.
;;; Post: carries-reg returns to |0>; a-reg + cin-reg unchanged;
;;;       acc-reg[acc-off..acc-off+n) := (acc + a) mod 2^n.
;;; bit-base..bit-base+n-2 are the classical-bit IDs used by HMR uncompute.

(define (cuccaro-add-offset-fast-borrowed! c a-reg a-off acc-reg acc-off
                                           cin-reg cin-idx n
                                           carries-reg carries-offset
                                           bit-base)
  "Offset+borrowed-carries port of cuccaro-add-fast-borrowed!."
  (cond
    ((= n 0) #t)
    ((= n 1)
     (gate-cx! c cin-reg cin-idx acc-reg acc-off)
     (gate-cx! c a-reg   a-off   acc-reg acc-off))
    (else
     (gate-cx!  c a-reg a-off acc-reg acc-off)
     (gate-cx!  c a-reg a-off cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx acc-reg acc-off
                  carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset a-reg a-off)
     (let loop-fwd ((i 1))
       (when (< i (- n 1))
         (gate-cx!  c a-reg (+ a-off i) acc-reg (+ acc-off i))
         (gate-cx!  c a-reg (+ a-off i) a-reg (+ a-off (- i 1)))
         (gate-ccx! c a-reg (+ a-off (- i 1))
                      acc-reg (+ acc-off i)
                      carries-reg (+ carries-offset i))
         (gate-cx!  c carries-reg (+ carries-offset i) a-reg (+ a-off i))
         (loop-fwd (+ i 1))))
     (gate-cx! c a-reg (+ a-off (- n 2)) acc-reg (+ acc-off (- n 1)))
     (gate-cx! c a-reg (+ a-off (- n 1)) acc-reg (+ acc-off (- n 1)))
     (let loop-back ((i (- n 2)))
       (when (>= i 1)
         (gate-cx!         c carries-reg (+ carries-offset i)
                             a-reg (+ a-off i))
         (gate-hmr!        c carries-reg (+ carries-offset i)
                             (+ bit-base i))
         (gate-push-cond!  c (+ bit-base i))
         (gate-cz!         c a-reg (+ a-off (- i 1))
                             acc-reg (+ acc-off i))
         (gate-pop-cond!   c)
         (gate-cx!         c a-reg (+ a-off i) a-reg (+ a-off (- i 1)))
         (gate-cx!         c a-reg (+ a-off (- i 1)) acc-reg (+ acc-off i))
         (loop-back (- i 1))))
     (gate-cx!         c carries-reg carries-offset a-reg a-off)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx acc-reg acc-off)
     (gate-pop-cond!   c)
     (gate-cx!         c a-reg a-off cin-reg cin-idx)
     (gate-cx!         c cin-reg cin-idx acc-reg acc-off))))

(define (cuccaro-sub-offset-fast-borrowed! c a-reg a-off acc-reg acc-off
                                           cin-reg cin-idx n
                                           carries-reg carries-offset
                                           bit-base)
  "Offset+borrowed-carries port of cuccaro-sub-fast-borrowed!.
   acc[acc-off..acc-off+n) := (acc - a - cin) mod 2^n."
  (cond
    ((= n 0) #t)
    ((= n 1)
     (gate-cx! c a-reg   a-off   acc-reg acc-off)
     (gate-cx! c cin-reg cin-idx acc-reg acc-off))
    (else
     (gate-cx!  c cin-reg cin-idx acc-reg acc-off)
     (gate-cx!  c a-reg a-off cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx acc-reg acc-off
                  carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset a-reg a-off)
     (let loop-fwd ((i 1))
       (when (< i (- n 1))
         (gate-cx!  c a-reg (+ a-off (- i 1)) acc-reg (+ acc-off i))
         (gate-cx!  c a-reg (+ a-off i) a-reg (+ a-off (- i 1)))
         (gate-ccx! c a-reg (+ a-off (- i 1))
                      acc-reg (+ acc-off i)
                      carries-reg (+ carries-offset i))
         (gate-cx!  c carries-reg (+ carries-offset i) a-reg (+ a-off i))
         (loop-fwd (+ i 1))))
     (gate-cx! c a-reg (+ a-off (- n 1)) acc-reg (+ acc-off (- n 1)))
     (gate-cx! c a-reg (+ a-off (- n 2)) acc-reg (+ acc-off (- n 1)))
     (let loop-back ((i (- n 2)))
       (when (>= i 1)
         (gate-cx!         c carries-reg (+ carries-offset i)
                             a-reg (+ a-off i))
         (gate-hmr!        c carries-reg (+ carries-offset i)
                             (+ bit-base i))
         (gate-push-cond!  c (+ bit-base i))
         (gate-cz!         c a-reg (+ a-off (- i 1))
                             acc-reg (+ acc-off i))
         (gate-pop-cond!   c)
         (gate-cx!         c a-reg (+ a-off i) a-reg (+ a-off (- i 1)))
         (gate-cx!         c a-reg (+ a-off i) acc-reg (+ acc-off i))
         (loop-back (- i 1))))
     (gate-cx!         c carries-reg carries-offset a-reg a-off)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx acc-reg acc-off)
     (gate-pop-cond!   c)
     (gate-cx!         c a-reg a-off cin-reg cin-idx)
     (gate-cx!         c a-reg a-off acc-reg acc-off))))

;;; *cuccaro-callers-fast* — substrate flag. When #t, controlled-add-subtract!
;;; / controlled-add-subtract-slice! dispatch their inner cuccaro-add at
;;; n+1 width to the borrowed-fast variant. Caller (schoolbook-mul) must
;;; pass a pre-allocated cas-carries register of width n+1 (clean |0>)
;;; & a bit-base integer.

(define *cuccaro-callers-fast* #f)

;;; ── controlled-add-subtract on an OFFSET slice of acc ─────────
;;;
;;; Same semantics as controlled-add-subtract! but the (n+1)-bit acc
;;; lives at acc-reg[acc-off..acc-off+n+1). x stays at x-reg[0..n).

(define (controlled-add-subtract-slice! c x-reg n acc-reg acc-off
                                        ctrl-reg ctrl-idx
                                        xext-reg cin-reg cin-idx)
  "acc[acc-off..acc-off+n+1) := ctrl ? (+x) : (-x), mod 2^(n+1)."
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (cuccaro-add-offset! c xext-reg 0 acc-reg acc-off cin-reg cin-idx (+ n 1))
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1)))))

(define (controlled-add-subtract-slice-inverse! c x-reg n acc-reg acc-off
                                                ctrl-reg ctrl-idx
                                                xext-reg cin-reg cin-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (cuccaro-sub-offset! c xext-reg 0 acc-reg acc-off cin-reg cin-idx (+ n 1))
  (gate-cx! c ctrl-reg ctrl-idx cin-reg cin-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c ctrl-reg ctrl-idx xext-reg k)
      (loop (+ k 1))))
  (gate-x! c ctrl-reg ctrl-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1)))))

;;; ── slice add-of-classical-constant (offset variant of add-const!) ─

(define (load-const-offset! c reg off n k)
  "reg[off..off+n) ^= bit pattern of k mod 2^n."
  (let ((kk (modulo k (expt 2 n))))
    (let loop ((i 0))
      (when (< i n)
        (when (bit-set? kk i) (gate-x! c reg (+ off i)))
        (loop (+ i 1))))))

(define (add-const-slice! c acc-reg acc-off n k cin-reg cin-idx tmp-reg)
  "acc[acc-off..acc-off+n) += k mod 2^n. tmp-reg n-wide |0> in/out."
  (let ((kk (modulo k (expt 2 n))))
    (load-const!         c tmp-reg n kk)
    (cuccaro-add-offset! c tmp-reg 0 acc-reg acc-off cin-reg cin-idx n)
    (unload-const!       c tmp-reg n kk)))

(define (sub-const-slice! c acc-reg acc-off n k cin-reg cin-idx tmp-reg)
  (let ((kk (modulo k (expt 2 n))))
    (load-const!         c tmp-reg n kk)
    (cuccaro-sub-offset! c tmp-reg 0 acc-reg acc-off cin-reg cin-idx n)
    (unload-const!       c tmp-reg n kk)))

;;; ── Litinski wide schoolbook: tmp-ext (2n bits) += x*y ─────────
;;;
;;; tmp-ext starts |0> n+1=… caller allocates 2n-wide tmp-ext + a 1-wide
;;; low ancilla. We treat wide = [low ++ tmp-ext] as a (2n+1)-bit
;;; accumulator. After all ops, wide = 2*x*y, so x*y reads out at
;;; wide[1..2n+1] = tmp-ext.
;;;
;;; This implementation allocates internal scratch (xext for the
;;; add-subtract loop, plus a cin for the corrections) inline.

(define (schoolbook-mul-into-addsub! c x-reg y-reg n
                                     low-reg low-idx
                                     tmp-ext-reg
                                     xext-reg cin-reg cin-idx
                                     const-tmp-reg)
  "Compute wide = [low ++ tmp-ext] := 2 * x * y over (2n+1) bits.
   x-reg, y-reg are n-wide and preserved. tmp-ext is 2n-wide |0> in.
   xext-reg is (n+1)-wide ancilla |0> in/out (controlled-add-subtract
   scratch). const-tmp-reg is (n+1)-wide ancilla |0> in/out (constant
   loading scratch). low is 1 bit |0> in/out (top of wide). cin is 1
   bit |0> in/out. After: tmp-ext = x*y (2n bits)."
  ;; ─ n controlled add-subtracts on offset slices of wide ─
  ;; wide[k..k+n+1) — when k=0, wide[0]=low, wide[1..n+1)=tmp-ext[0..n).
  ;; When k>=1, wide[k..k+n+1) sits entirely in tmp-ext[k-1..k+n).
  ;; So we split: k=0 uses [low ++ tmp-ext[0..n)] as the slice,
  ;; k>=1 uses tmp-ext[k-1..k+n) directly.
  (let loop ((k 0))
    (when (< k n)
      (cond
        ((= k 0)
         ;; Slice = [low(idx low-idx) ++ tmp-ext[0..n)]. We can't represent
         ;; that as a single offset register, so we hand-code: copy x into
         ;; xext, condition-flip, then run a SPECIAL cuccaro that uses
         ;; low at bit 0 and tmp-ext at bits 1..n+1. Easier alternative:
         ;; allocate a fresh (n+1)-wide buffer "wide0" that is
         ;; pre-correlated to [low, tmp-ext[0..n)] via CX, run the slice
         ;; add into wide0, then uncorrelate. But that re-introduces the
         ;; aliasing problem.
         ;;
         ;; Cleanest fix: implement controlled-add-subtract to take a
         ;; CALLBACK or two-register slice spec. Even simpler: at k=0,
         ;; since low starts |0>, the slice is [|0>, tmp-ext[0..n)] — i.e.
         ;; treat the slice as tmp-ext[0..n) padded with low at TOP. But
         ;; Litinski needs low at the BOTTOM of the slice.
         ;;
         ;; Workaround: split the k=0 step into two: first do a
         ;; controlled-add-subtract on the LOW bit (low alone, x[0] only),
         ;; then handle bits 1..n+1 via the regular tmp-ext slice.
         ;; That breaks the algorithm — the carries chain through.
         ;;
         ;; Real fix: use a JOINT cuccaro across (low, tmp-ext[0..n)).
         ;; Implement schoolbook-row-k0! inline using offset CX/MAJ ops
         ;; that explicitly reference low at index 0 and tmp-ext at
         ;; indices 0..n-1 (treated as positions 1..n of the slice).
         (schoolbook-row-k0! c x-reg n
                             y-reg k
                             low-reg low-idx
                             tmp-ext-reg
                             xext-reg cin-reg cin-idx))
        (else
         ;; Slice lives entirely in tmp-ext at offset (k-1), width n+1.
         (controlled-add-subtract-slice! c x-reg n
                                         tmp-ext-reg (- k 1)
                                         y-reg k
                                         xext-reg cin-reg cin-idx)))
      (loop (+ k 1))))
  ;; ─ Correction 1: wide[n..2n+1) += 2^0 * (y + 1), via cuccaro-add of
  ;;   y_ext = y ++ pad(=0) with c_in=1. wide[n..2n+1) = tmp-ext[n-1..2n).
  ;;   Set cin=1 via X, run cuccaro-add-offset over (n+1) bits, X cin back.
  (gate-x! c cin-reg cin-idx)
  (cuccaro-add-y-ext-into-tmp-hi! c y-reg n tmp-ext-reg cin-reg cin-idx
                                  const-tmp-reg)
  (gate-x! c cin-reg cin-idx)
  ;; ─ Correction 2: wide[2n] ^= 1 → tmp-ext[2n-1] ^= 1.
  (gate-x! c tmp-ext-reg (- (* 2 n) 1))
  ;; ─ Correction 3: -x over the FULL (2n+1)-bit wide. Hand-code as a
  ;;   cuccaro-sub joint over [low ++ tmp-ext] with x at low bits, zeros
  ;;   above. We use const-tmp-reg padded with zeros as a (2n+1)-wide
  ;;   source... but it's only n+1 wide.
  ;;
  ;;   Simpler: -x is just n bits of x at the bottom of wide. The high
  ;;   bits beyond x's range are zero. cuccaro-sub on a width-(2n+1)
  ;;   source where bits n..2n are |0> still works (zero high bits are a
  ;;   noop for MAJ/UMA — they just propagate the carry).
  ;;
  ;;   We don't actually need extra register width: emit a "sub x into
  ;;   wide" routine that walks bits 0..n of x and bits n..2n+1 of wide
  ;;   as |0> source bits (no gate needed — they have no effect since the
  ;;   MAJ/UMA cells with x_high=0 reduce to identity on the wide bit).
  ;;
  ;;   Actually that's still wrong — the carry chain still propagates
  ;;   through high bits. We need an honest cuccaro-sub with the full
  ;;   width. Use a TEMP (2n+1)-wide source register: alloc xfull, copy
  ;;   x into xfull[0..n), run cuccaro-sub-offset of xfull into wide,
  ;;   uncopy x. But alloc inside is fine.
  (sub-x-from-wide! c x-reg n low-reg low-idx tmp-ext-reg cin-reg cin-idx)
  ;; ─ Correction 4: wide[n..2n+1) += 2^0 * x, via cuccaro-add of x_ext
  ;;   (x ++ pad(=0)) with c_in=0. wide[n..2n+1) = tmp-ext[n-1..2n).
  (cuccaro-add-x-ext-into-tmp-hi! c x-reg n tmp-ext-reg cin-reg cin-idx
                                  const-tmp-reg))

;;; ── helpers used by schoolbook-mul-into-addsub! ──────────────

(define (schoolbook-row-k0! c x-reg n y-reg y-idx
                            low-reg low-idx tmp-ext-reg
                            xext-reg cin-reg cin-idx)
  "k=0 row of Litinski: controlled-add-subtract on slice
   [low ++ tmp-ext[0..n)] of width n+1, controlled on y[y-idx].
   We need a Cuccaro-add over a JOINT register (low at bit 0, tmp-ext
   at bits 1..n). Emit inline using MAJ/UMA primitives with explicit
   bit refs."
  ;; xext = ctrl ? ~x[0..n) : x[0..n)
  ;; cin  = ctrl ? 1 : 0
  ;; Then cuccaro-add of xext into wide (treating wide[0]=low, wide[1..n+1)=tmp-ext[0..n))
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1))))
  (gate-x! c y-reg y-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c y-reg y-idx xext-reg k)
      (loop (+ k 1))))
  (gate-cx! c y-reg y-idx cin-reg cin-idx)
  ;; Joint cuccaro-add: source xext (n+1 wide, all in xext-reg), target
  ;; "wide" where wide[0]=(low,low-idx), wide[i+1]=(tmp-ext-reg, i) for i in 0..n-1.
  ;; Use a Cuccaro that selects target bits via a small switch.
  (cuccaro-add-joint! c xext-reg 0
                      low-reg low-idx tmp-ext-reg 0
                      cin-reg cin-idx (+ n 1))
  (gate-cx! c y-reg y-idx cin-reg cin-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c y-reg y-idx xext-reg k)
      (loop (+ k 1))))
  (gate-x! c y-reg y-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1)))))

;;; Cuccaro-add where the ACCUMULATOR spans two registers: bit 0 lives
;;; at (low-reg, low-idx), bits 1..n-1 live at (mid-reg, mid-off..mid-off+n-2).
;;; Source register has width n, contiguous in src-reg at offset src-off.

(define (joint-acc-ref low-reg low-idx mid-reg mid-off i)
  "Return (reg idx) for bit i of the joint accumulator."
  (if (= i 0)
      (list low-reg low-idx)
      (list mid-reg (+ mid-off (- i 1)))))

(define (cuccaro-add-joint! c src-reg src-off
                            low-reg low-idx mid-reg mid-off
                            cin-reg cin-idx n)
  "acc[0..n) := acc[0..n) + src[src-off..src-off+n), where acc[0]=(low,low-idx)
   and acc[i]=(mid-reg, mid-off+i-1) for i>=1. n>=1.
   When *cas-borrowed-carries-reg* set, dispatches to HMR uncompute path."
  (cond
    ((= n 1)
     (gate-cx! c cin-reg cin-idx low-reg low-idx)
     (gate-cx! c src-reg src-off low-reg low-idx))
    ((and *cas-borrowed-carries-reg*
          (> *cas-borrowed-carries-width* 0)
          (<= (- n 1) *cas-borrowed-carries-width*))
     (cuccaro-add-joint-fast-borrowed! c src-reg src-off
                                       low-reg low-idx mid-reg mid-off
                                       cin-reg cin-idx n
                                       *cas-borrowed-carries-reg*
                                       *cas-borrowed-carries-offset*
                                       (cas-alloc-bit-base! n)))
    (else
     ;; MAJ(cin, acc[0], src[0]) — acc[0] = (low, low-idx)
     (maj! c cin-reg cin-idx low-reg low-idx src-reg src-off)
     (let loop ((i 1))
       (when (< i (- n 1))
         ;; MAJ(src[i-1], acc[i], src[i])
         (let ((acc-i (joint-acc-ref low-reg low-idx mid-reg mid-off i)))
           (maj! c src-reg (+ src-off (- i 1))
                   (car acc-i) (car (cdr acc-i))
                   src-reg (+ src-off i)))
         (loop (+ i 1))))
     ;; Final sum bit: acc[n-1] = (mid, mid-off+n-2) since n>=2
     (let ((acc-top (joint-acc-ref low-reg low-idx mid-reg mid-off (- n 1))))
       (gate-cx! c src-reg (+ src-off (- n 2))
                   (car acc-top) (car (cdr acc-top)))
       (gate-cx! c src-reg (+ src-off (- n 1))
                   (car acc-top) (car (cdr acc-top))))
     ;; Reverse UMA sweep
     (let loop ((i (- n 2)))
       (when (>= i 1)
         (let ((acc-i (joint-acc-ref low-reg low-idx mid-reg mid-off i)))
           (uma! c src-reg (+ src-off (- i 1))
                   (car acc-i) (car (cdr acc-i))
                   src-reg (+ src-off i)))
         (loop (- i 1))))
     (uma! c cin-reg cin-idx low-reg low-idx src-reg src-off))))

(define (cuccaro-sub-joint! c src-reg src-off
                            low-reg low-idx mid-reg mid-off
                            cin-reg cin-idx n)
  "Inverse of cuccaro-add-joint!.
   When *cas-borrowed-carries-reg* set, dispatches to HMR uncompute path."
  (cond
    ((= n 1)
     (gate-cx! c src-reg src-off low-reg low-idx)
     (gate-cx! c cin-reg cin-idx low-reg low-idx))
    ((and *cas-borrowed-carries-reg*
          (> *cas-borrowed-carries-width* 0)
          (<= (- n 1) *cas-borrowed-carries-width*))
     (cuccaro-sub-joint-fast-borrowed! c src-reg src-off
                                       low-reg low-idx mid-reg mid-off
                                       cin-reg cin-idx n
                                       *cas-borrowed-carries-reg*
                                       *cas-borrowed-carries-offset*
                                       (cas-alloc-bit-base! n)))
    (else
     (inv-uma! c cin-reg cin-idx low-reg low-idx src-reg src-off)
     (let loop ((i 1))
       (when (< i (- n 1))
         (let ((acc-i (joint-acc-ref low-reg low-idx mid-reg mid-off i)))
           (inv-uma! c src-reg (+ src-off (- i 1))
                       (car acc-i) (car (cdr acc-i))
                       src-reg (+ src-off i)))
         (loop (+ i 1))))
     (let ((acc-top (joint-acc-ref low-reg low-idx mid-reg mid-off (- n 1))))
       (gate-cx! c src-reg (+ src-off (- n 1))
                   (car acc-top) (car (cdr acc-top)))
       (gate-cx! c src-reg (+ src-off (- n 2))
                   (car acc-top) (car (cdr acc-top))))
     (let loop ((i (- n 2)))
       (when (>= i 1)
         (let ((acc-i (joint-acc-ref low-reg low-idx mid-reg mid-off i)))
           (inv-maj! c src-reg (+ src-off (- i 1))
                       (car acc-i) (car (cdr acc-i))
                       src-reg (+ src-off i)))
         (loop (- i 1))))
     (inv-maj! c cin-reg cin-idx low-reg low-idx src-reg src-off))))

;;; ── cuccaro-add/sub-joint-fast-borrowed! — HMR uncompute, joint acc ─
;;;
;;; Port of HEAD's cuccaro_add_fast pattern to the JOINT accumulator
;;; layout used by schoolbook-row-k0! + sub-x-from-wide!. acc[0] lives
;;; at (low-reg, low-idx); acc[i] for i>=1 lives at (mid-reg, mid-off+i-1).
;;; Source register is contiguous src-reg[src-off..src-off+n).
;;;
;;; Same MAJ-forward / HMR-backward gate sequence as
;;; cuccaro-add-offset-fast-borrowed! (mod-arith.lsp:651) — every acc[i]
;;; reference is translated through joint-acc-ref. src/cin indexing
;;; matches the offset variant exactly (contiguous source).
;;;
;;; Pre: carries-reg[carries-offset..carries-offset+n-2) must be |0> on entry.
;;; Post: carries-reg returns to |0>; src-reg + cin-reg unchanged;
;;;       joint acc[0..n) := (acc + src) mod 2^n.
;;; bit-base..bit-base+n-2 are the classical-bit IDs used by HMR uncompute.

(define (cuccaro-add-joint-fast-borrowed! c src-reg src-off
                                          low-reg low-idx mid-reg mid-off
                                          cin-reg cin-idx n
                                          carries-reg carries-offset
                                          bit-base)
  "Joint-acc + borrowed-carries port of cuccaro-add-fast-borrowed!.
   acc[0]=(low,low-idx); acc[i>=1]=(mid-reg, mid-off+i-1)."
  (cond
    ((= n 0) #t)
    ((= n 1)
     (gate-cx! c cin-reg cin-idx low-reg low-idx)
     (gate-cx! c src-reg src-off low-reg low-idx))
    (else
     ;; Forward step i=0: acc[0] = (low, low-idx); src[0]; cin
     (gate-cx!  c src-reg src-off low-reg low-idx)
     (gate-cx!  c src-reg src-off cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx low-reg low-idx
                  carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset src-reg src-off)
     ;; Forward steps i=1..n-2: acc[i] = (mid-reg, mid-off+i-1)
     (let loop-fwd ((i 1))
       (when (< i (- n 1))
         (let ((acc-i (joint-acc-ref low-reg low-idx mid-reg mid-off i)))
           (gate-cx!  c src-reg (+ src-off i)
                        (car acc-i) (car (cdr acc-i)))
           (gate-cx!  c src-reg (+ src-off i) src-reg (+ src-off (- i 1)))
           (gate-ccx! c src-reg (+ src-off (- i 1))
                        (car acc-i) (car (cdr acc-i))
                        carries-reg (+ carries-offset i))
           (gate-cx!  c carries-reg (+ carries-offset i)
                        src-reg (+ src-off i)))
         (loop-fwd (+ i 1))))
     ;; Final sum bit: acc[n-1] = (mid, mid-off+n-2) for n>=2
     (let ((acc-top (joint-acc-ref low-reg low-idx mid-reg mid-off (- n 1))))
       (gate-cx! c src-reg (+ src-off (- n 2))
                   (car acc-top) (car (cdr acc-top)))
       (gate-cx! c src-reg (+ src-off (- n 1))
                   (car acc-top) (car (cdr acc-top))))
     ;; Backward HMR uncompute, i = n-2..1
     (let loop-back ((i (- n 2)))
       (when (>= i 1)
         (let ((acc-i (joint-acc-ref low-reg low-idx mid-reg mid-off i)))
           (gate-cx!         c carries-reg (+ carries-offset i)
                               src-reg (+ src-off i))
           (gate-hmr!        c carries-reg (+ carries-offset i)
                               (+ bit-base i))
           (gate-push-cond!  c (+ bit-base i))
           (gate-cz!         c src-reg (+ src-off (- i 1))
                               (car acc-i) (car (cdr acc-i)))
           (gate-pop-cond!   c)
           (gate-cx!         c src-reg (+ src-off i) src-reg (+ src-off (- i 1)))
           (gate-cx!         c src-reg (+ src-off (- i 1))
                               (car acc-i) (car (cdr acc-i))))
         (loop-back (- i 1))))
     ;; Backward HMR i=0: acc[0] = (low, low-idx)
     (gate-cx!         c carries-reg carries-offset src-reg src-off)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx low-reg low-idx)
     (gate-pop-cond!   c)
     (gate-cx!         c src-reg src-off cin-reg cin-idx)
     (gate-cx!         c cin-reg cin-idx low-reg low-idx))))

(define (cuccaro-sub-joint-fast-borrowed! c src-reg src-off
                                          low-reg low-idx mid-reg mid-off
                                          cin-reg cin-idx n
                                          carries-reg carries-offset
                                          bit-base)
  "Joint-acc + borrowed-carries port of cuccaro-sub-fast-borrowed!.
   acc[0..n) := (acc - src - cin) mod 2^n."
  (cond
    ((= n 0) #t)
    ((= n 1)
     (gate-cx! c src-reg src-off low-reg low-idx)
     (gate-cx! c cin-reg cin-idx low-reg low-idx))
    (else
     ;; Forward inv-UMA-like at i=0
     (gate-cx!  c cin-reg cin-idx low-reg low-idx)
     (gate-cx!  c src-reg src-off cin-reg cin-idx)
     (gate-ccx! c cin-reg cin-idx low-reg low-idx
                  carries-reg carries-offset)
     (gate-cx!  c carries-reg carries-offset src-reg src-off)
     ;; Forward steps i=1..n-2
     (let loop-fwd ((i 1))
       (when (< i (- n 1))
         (let ((acc-i (joint-acc-ref low-reg low-idx mid-reg mid-off i)))
           (gate-cx!  c src-reg (+ src-off (- i 1))
                        (car acc-i) (car (cdr acc-i)))
           (gate-cx!  c src-reg (+ src-off i) src-reg (+ src-off (- i 1)))
           (gate-ccx! c src-reg (+ src-off (- i 1))
                        (car acc-i) (car (cdr acc-i))
                        carries-reg (+ carries-offset i))
           (gate-cx!  c carries-reg (+ carries-offset i)
                        src-reg (+ src-off i)))
         (loop-fwd (+ i 1))))
     ;; Final sum bit — sub order swaps the two CXs
     (let ((acc-top (joint-acc-ref low-reg low-idx mid-reg mid-off (- n 1))))
       (gate-cx! c src-reg (+ src-off (- n 1))
                   (car acc-top) (car (cdr acc-top)))
       (gate-cx! c src-reg (+ src-off (- n 2))
                   (car acc-top) (car (cdr acc-top))))
     ;; Backward HMR uncompute, i = n-2..1
     (let loop-back ((i (- n 2)))
       (when (>= i 1)
         (let ((acc-i (joint-acc-ref low-reg low-idx mid-reg mid-off i)))
           (gate-cx!         c carries-reg (+ carries-offset i)
                               src-reg (+ src-off i))
           (gate-hmr!        c carries-reg (+ carries-offset i)
                               (+ bit-base i))
           (gate-push-cond!  c (+ bit-base i))
           (gate-cz!         c src-reg (+ src-off (- i 1))
                               (car acc-i) (car (cdr acc-i)))
           (gate-pop-cond!   c)
           (gate-cx!         c src-reg (+ src-off i) src-reg (+ src-off (- i 1)))
           (gate-cx!         c src-reg (+ src-off i)
                               (car acc-i) (car (cdr acc-i))))
         (loop-back (- i 1))))
     ;; Backward HMR i=0
     (gate-cx!         c carries-reg carries-offset src-reg src-off)
     (gate-hmr!        c carries-reg carries-offset bit-base)
     (gate-push-cond!  c bit-base)
     (gate-cz!         c cin-reg cin-idx low-reg low-idx)
     (gate-pop-cond!   c)
     (gate-cx!         c src-reg src-off cin-reg cin-idx)
     (gate-cx!         c src-reg src-off low-reg low-idx))))

;;; Correction 1 helper: wide[n..2n+1) += y_ext where y_ext = y at bits
;;; [0..n) and pad(=0) at bit n. We need to cuccaro-add the y bits into
;;; a (n+1)-wide slice of wide at offset n. wide[n] = tmp-ext[n-1].
;;; wide[n+1..2n+1) = tmp-ext[n..2n).
;;;
;;; This is the SAME joint accumulator pattern: target bit 0 = (tmp-ext,
;;; n-1), target bits 1..n = (tmp-ext, n..2n-1). Adjacent indices —
;;; really a SINGLE register slice tmp-ext[n-1..2n).
;;;
;;; Source y_ext: we need n+1 bits where y_ext[0..n) = y and y_ext[n] = 0.
;;; We use const-tmp-reg (n+1 wide |0>) as y_ext: copy y into bits [0..n),
;;; run cuccaro-add-offset of const-tmp into tmp-ext at offset n-1 width
;;; n+1, then uncopy y.

(define (cuccaro-add-y-ext-into-tmp-hi! c y-reg n tmp-ext-reg
                                        cin-reg cin-idx const-tmp-reg)
  "wide[n..2n+1) += y_ext with c_in present.
   wide[n..2n+1) = tmp-ext[n-1..2n)."
  ;; Copy y → const-tmp low n bits. const-tmp[n] stays |0> = pad.
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c y-reg k const-tmp-reg k)
      (loop (+ k 1))))
  ;; cuccaro-add at width n+1 into tmp-ext at offset n-1.
  (cuccaro-add-offset! c const-tmp-reg 0 tmp-ext-reg (- n 1)
                       cin-reg cin-idx (+ n 1))
  ;; Uncopy.
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c y-reg k const-tmp-reg k)
      (loop (+ k 1)))))

(define (cuccaro-sub-y-ext-into-tmp-hi! c y-reg n tmp-ext-reg
                                        cin-reg cin-idx const-tmp-reg)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c y-reg k const-tmp-reg k)
      (loop (+ k 1))))
  (cuccaro-sub-offset! c const-tmp-reg 0 tmp-ext-reg (- n 1)
                       cin-reg cin-idx (+ n 1))
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c y-reg k const-tmp-reg k)
      (loop (+ k 1)))))

(define (cuccaro-add-x-ext-into-tmp-hi! c x-reg n tmp-ext-reg
                                        cin-reg cin-idx const-tmp-reg)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k const-tmp-reg k)
      (loop (+ k 1))))
  (cuccaro-add-offset! c const-tmp-reg 0 tmp-ext-reg (- n 1)
                       cin-reg cin-idx (+ n 1))
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k const-tmp-reg k)
      (loop (+ k 1)))))

(define (cuccaro-sub-x-ext-into-tmp-hi! c x-reg n tmp-ext-reg
                                        cin-reg cin-idx const-tmp-reg)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k const-tmp-reg k)
      (loop (+ k 1))))
  (cuccaro-sub-offset! c const-tmp-reg 0 tmp-ext-reg (- n 1)
                       cin-reg cin-idx (+ n 1))
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k const-tmp-reg k)
      (loop (+ k 1)))))

;;; Correction 3 helper: wide -= x, where wide has width 2n+1 ([low ++ tmp-ext])
;;; and x is at x-reg[0..n). x's high (2n+1-n)=n+1 bits are zero (we pad).
;;;
;;; Use a JOINT cuccaro-sub over the full wide. Source: const-tmp at low
;;; n bits (loaded from x) zero-padded above. But const-tmp is only n+1
;;; wide — we need 2n+1 wide source. We allocate xfull internally.
;;;
;;; *sub-x-from-wide-cas-fast* — sweep-027 opt-in flag. When BOTH
;;; *cuccaro-callers-fast* AND this flag are set, widen sb-xfull to
;;; 4n+1 and dispatch joint via cas-borrowed. Disabled by default
;;; (sweep-027 verdict: knife-edge ROI, +10%% worst-case score).
;;; ALLOC width 4n+1 = 1025 at production hits the n=512 ancilla cap
;;; if cap isnt raised — keep off unless cap is also raised.

(define *sub-x-from-wide-cas-fast* #f)

;;; *sub-x-from-wide-host-alloc* — sweep-036 opt-in flag (allocator
;;; surgery). When set, mod-mul-solinas! / mod-mul-solinas-sub! allocate
;;; sb-xfull at Stage-0 (TOP of their scratch suite, BEFORE sb-tmp-ext /
;;; sb-low / sb-xext / sb-const-tmp) instead of letting sub-x-from-wide!
;;; / add-x-into-wide! allocate it internally on each call. The hoisted
;;; alloc lands at the lowest free 513-wide base inside the mod-mul
;;; scope; sub-x-from-wide! / add-x-into-wide! consult *host-sb-xfull-reg*
;;; & skip their internal alloc when that variable is bound. ZERO Toffoli
;;; delta — same sb-xfull contents, same gate sequence. The opt-in is a
;;; pure register-lifetime re-order: it removes the deep-nested late
;;; allocation that landed sb-xfull on top of the dgcd-host floor.
;;;
;;; Predicted peak qubits change: sweep-035 baseline 5,024 → ~4,510
;;; (−10.2 %) per allocator-replay subagent (runs/lumbda-sweep-032
;;; ALLOCATOR-REPORT-sweep030.md temporal-overlap candidate #2).
;;;
;;; When flag off & *host-sb-xfull-reg* #f, both helpers fall through
;;; their old alloc-internal path — byte-identical to sweep-035.

(define *sub-x-from-wide-host-alloc* #f)

;;; Dynamic variable bound by mod-mul-solinas! / mod-mul-solinas-sub!
;;; when *sub-x-from-wide-host-alloc* is on: holds the host-allocated
;;; sb-xfull register name, communicated to sub-x-from-wide! /
;;; add-x-into-wide! without changing their signatures. Cleared to #f
;;; after the Stage-3 inverse pass so subsequent mod-mul calls outside
;;; the host scope alloc internally again.

(define *host-sb-xfull-reg* #f)

;;; sweep-027: when *cuccaro-callers-fast* is set, widen sb-xfull from
;;; 2n+1 → 4n+1 so the top 2n bits can serve as borrowed carries for the
;;; JOINT fast-borrowed dispatch path:
;;;
;;;   sb-xfull[0..n)        = x data (Stage-1 load)
;;;   sb-xfull[n..2n+1)     = source pad (touched by cuccaro as |0> bits)
;;;   sb-xfull[2n+1..4n+1)  = HMR carries pad (clean |0> on entry/exit)
;;;
;;; Width-N=2n+1 joint fast-borrowed consumes N-1 = 2n carries lanes,
;;; which exactly fits sb-xfull[2n+1..4n+1). Bit-base 300000 disjoint
;;; from mod-solinas' 200000 reservation (which covers up to n+1 bits).
;;; Saves (N-1)-N/2 ≈ N-1 = 2n Toffoli per call via HMR uncompute;
;;; cost is +2n qubits in sb-xfull's transient allocation.

(define (sub-x-from-wide! c x-reg n low-reg low-idx tmp-ext-reg
                          cin-reg cin-idx)
  "wide := wide - x, where wide = [low ++ tmp-ext] (2n+1 bits) and x is
   at x-reg[0..n). High bits of x_padded are 0. Uses internal xfull
   ancilla (alloc'd here; widened to 4n+1 under *cuccaro-callers-fast*
   to host the JOINT fast-borrowed carries).

   When *host-sb-xfull-reg* is bound (sweep-036 opt-in), the caller
   (mod-mul-solinas!) has pre-allocated sb-xfull at outer scope; skip
   internal alloc/free & use the hosted register name."
  (let* ((use-fast?    (and *cuccaro-callers-fast* *sub-x-from-wide-cas-fast*))
         (joint-width  (+ (* 2 n) 1))                  ; N = 2n+1
         (carries-need (- joint-width 1))              ; N-1 = 2n
         (xfull-width  (cond (use-fast? (+ joint-width carries-need))
                             (else      joint-width)))
         (host-reg     *host-sb-xfull-reg*)
         (xfull-name   (cond (host-reg host-reg)
                             (else     (quote sb-xfull)))))
    ;; Allocate xfull (xfull-width bits |0>) — unless hosted by caller.
    (when (not host-reg)
      (alloc! c xfull-name xfull-width))
    (let loop ((k 0))
      (when (< k n)
        (gate-cx! c x-reg k xfull-name k)
        (loop (+ k 1))))
    ;; Configure cas-borrowed for joint dispatch when in fast mode.
    (cond
      (use-fast?
       (let ((saved-reg    *cas-borrowed-carries-reg*)
             (saved-off    *cas-borrowed-carries-offset*)
             (saved-base   *cas-borrowed-bit-base*)
             (saved-width  *cas-borrowed-carries-width*))
         (set! *cas-borrowed-carries-reg*    xfull-name)
         (set! *cas-borrowed-carries-offset* joint-width)
         (set! *cas-borrowed-bit-base*       300000)
         (set! *cas-borrowed-carries-width*  carries-need)
         (cuccaro-sub-joint! c xfull-name 0
                             low-reg low-idx tmp-ext-reg 0
                             cin-reg cin-idx joint-width)
         (set! *cas-borrowed-carries-reg*    saved-reg)
         (set! *cas-borrowed-carries-offset* saved-off)
         (set! *cas-borrowed-bit-base*       saved-base)
         (set! *cas-borrowed-carries-width*  saved-width)))
      (else
       (cuccaro-sub-joint! c xfull-name 0
                           low-reg low-idx tmp-ext-reg 0
                           cin-reg cin-idx joint-width)))
    ;; Uncopy x.
    (let loop ((k 0))
      (when (< k n)
        (gate-cx! c x-reg k xfull-name k)
        (loop (+ k 1))))
    (when (not host-reg)
      (free! c xfull-name))))

(define (add-x-into-wide! c x-reg n low-reg low-idx tmp-ext-reg
                          cin-reg cin-idx)
  "Inverse of sub-x-from-wide!: wide += x over full 2n+1 bits.
   sb-xfull widened to 4n+1 under *cuccaro-callers-fast* to host
   the JOINT fast-borrowed carries pad above the source range.

   When *host-sb-xfull-reg* is bound (sweep-036 opt-in), use the hosted
   register instead of allocating/freeing internally."
  (let* ((use-fast?    (and *cuccaro-callers-fast* *sub-x-from-wide-cas-fast*))
         (joint-width  (+ (* 2 n) 1))
         (carries-need (- joint-width 1))
         (xfull-width  (cond (use-fast? (+ joint-width carries-need))
                             (else      joint-width)))
         (host-reg     *host-sb-xfull-reg*)
         (xfull-name   (cond (host-reg host-reg)
                             (else     (quote sb-xfull)))))
    (when (not host-reg)
      (alloc! c xfull-name xfull-width))
    (let loop ((k 0))
      (when (< k n)
        (gate-cx! c x-reg k xfull-name k)
        (loop (+ k 1))))
    (cond
      (use-fast?
       (let ((saved-reg    *cas-borrowed-carries-reg*)
             (saved-off    *cas-borrowed-carries-offset*)
             (saved-base   *cas-borrowed-bit-base*)
             (saved-width  *cas-borrowed-carries-width*))
         (set! *cas-borrowed-carries-reg*    xfull-name)
         (set! *cas-borrowed-carries-offset* joint-width)
         (set! *cas-borrowed-bit-base*       300000)
         (set! *cas-borrowed-carries-width*  carries-need)
         (cuccaro-add-joint! c xfull-name 0
                             low-reg low-idx tmp-ext-reg 0
                             cin-reg cin-idx joint-width)
         (set! *cas-borrowed-carries-reg*    saved-reg)
         (set! *cas-borrowed-carries-offset* saved-off)
         (set! *cas-borrowed-bit-base*       saved-base)
         (set! *cas-borrowed-carries-width*  saved-width)))
      (else
       (cuccaro-add-joint! c xfull-name 0
                           low-reg low-idx tmp-ext-reg 0
                           cin-reg cin-idx joint-width)))
    (let loop ((k 0))
      (when (< k n)
        (gate-cx! c x-reg k xfull-name k)
        (loop (+ k 1))))
    (when (not host-reg)
      (free! c xfull-name))))

;;; Inverse of schoolbook-mul-into-addsub!: undo each correction then
;;; the loop, gate-by-gate inverted. Self-inverse steps (X) re-emit.

(define (schoolbook-mul-into-addsub-inverse! c x-reg y-reg n
                                             low-reg low-idx
                                             tmp-ext-reg
                                             xext-reg cin-reg cin-idx
                                             const-tmp-reg)
  ;; Reverse correction 4: cuccaro-sub of x_ext at high half.
  (cuccaro-sub-x-ext-into-tmp-hi! c x-reg n tmp-ext-reg cin-reg cin-idx
                                  const-tmp-reg)
  ;; Reverse correction 3: add x back into wide.
  (add-x-into-wide! c x-reg n low-reg low-idx tmp-ext-reg cin-reg cin-idx)
  ;; Reverse correction 2: re-XOR top bit (self-inverse).
  (gate-x! c tmp-ext-reg (- (* 2 n) 1))
  ;; Reverse correction 1: cuccaro-sub of y_ext with cin=1.
  (gate-x! c cin-reg cin-idx)
  (cuccaro-sub-y-ext-into-tmp-hi! c y-reg n tmp-ext-reg cin-reg cin-idx
                                  const-tmp-reg)
  (gate-x! c cin-reg cin-idx)
  ;; Reverse the main loop (k from n-1 down to 0).
  (let loop ((k (- n 1)))
    (when (>= k 0)
      (cond
        ((= k 0)
         (schoolbook-row-k0-inverse! c x-reg n
                                     y-reg k
                                     low-reg low-idx
                                     tmp-ext-reg
                                     xext-reg cin-reg cin-idx))
        (else
         (controlled-add-subtract-slice-inverse! c x-reg n
                                                 tmp-ext-reg (- k 1)
                                                 y-reg k
                                                 xext-reg cin-reg cin-idx)))
      (loop (- k 1)))))

(define (schoolbook-row-k0-inverse! c x-reg n y-reg y-idx
                                    low-reg low-idx tmp-ext-reg
                                    xext-reg cin-reg cin-idx)
  "Inverse of schoolbook-row-k0!."
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1))))
  (gate-x! c y-reg y-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c y-reg y-idx xext-reg k)
      (loop (+ k 1))))
  (gate-cx! c y-reg y-idx cin-reg cin-idx)
  (cuccaro-sub-joint! c xext-reg 0
                      low-reg low-idx tmp-ext-reg 0
                      cin-reg cin-idx (+ n 1))
  (gate-cx! c y-reg y-idx cin-reg cin-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c y-reg y-idx xext-reg k)
      (loop (+ k 1))))
  (gate-x! c y-reg y-idx)
  (let loop ((k 0))
    (when (< k n)
      (gate-cx! c x-reg k xext-reg k)
      (loop (+ k 1)))))

;;; ── mod-mul! — Litinski wide schoolbook + Solinas-style reduction ─
;;;
;;; Calling convention:
;;;   a-reg, b-reg, out-reg : (n+1)-wide; top bit must be |0> on entry
;;;                           (we operate on low n bits only).
;;;                           a-reg, b-reg preserved; out-reg ends with
;;;                           (a*b) mod p.
;;;   cin-reg, cin-idx       : 1 bit |0> in/out (mod-add c_in)
;;;   tmp-reg                : (n+1)-wide |0> in/out — mod-add's inner
;;;                           constant-loading scratch.
;;;   flag-reg, flag-idx     : 1 bit |0> in/out (mod-add flag)
;;;   red-tmp-reg            : (n+1)-wide |0> in/out — used in Stage 2 to
;;;                           load 2^k mod p constants into a register
;;;                           before mod-add into out.
;;;
;;; Inside, mod-mul! allocates its own Litinski scratch:
;;;   sb-tmp-ext  (2n bits)  the wide product accumulator
;;;   sb-low      (1 bit)    wide[0]
;;;   sb-xext     (n+1 bits) controlled-add-subtract scratch
;;;   sb-const-tmp (n+1 bits) correction-stage constant-loading scratch
;;;   sb-xfull    (2n+1 bits, alloc/free'd inside sub-x-from-wide!)

;;; ── Solinas dispatch flag ─────────────────────────────────────
;;;
;;; When *mod-mul-use-solinas* is non-#f, mod-mul! and mod-mul-sub!
;;; dispatch into mod-mul-solinas! / mod-mul-solinas-sub! (defined in
;;; lumbda/mod-solinas.lsp — caller must load that file before flipping
;;; the flag). Caller-visible signatures and ancilla register names
;;; remain identical, so every consumer (mod-inv!, mod-square!,
;;; real-point-add!) inherits the speedup without code change.

(define *mod-mul-use-solinas* #f)

(define (mod-mul! c a-reg b-reg out-reg n+1 p
                  cin-reg cin-idx tmp-reg flag-reg flag-idx
                  red-tmp-reg)
  "out := (a * b) mod p. Litinski schoolbook + per-bit Solinas-style reduce.
   See header for full calling convention.

   When *mod-mul-use-solinas* is non-#f, dispatch to mod-mul-solinas!
   (mod-solinas.lsp must already be loaded)."
  (cond
    (*mod-mul-use-solinas*
     (mod-mul-solinas! c a-reg b-reg out-reg n+1 p
                       (compute-c-expansion p (- n+1 1))
                       cin-reg cin-idx tmp-reg flag-reg flag-idx
                       red-tmp-reg))
    (else
     (mod-mul-litinski! c a-reg b-reg out-reg n+1 p
                        cin-reg cin-idx tmp-reg flag-reg flag-idx
                        red-tmp-reg))))

;;; ── mod-mul-from-zero! — caller-explicit out=|0> specialization ───
;;;
;;; Port of HEAD's `mod_add_qq_fast_from_zero` lifted to the multiply
;;; entry boundary. Caller invokes this INSTEAD of mod-mul! when out-reg
;;; is provably |0> on entry (e.g. mod-square!'s freshly-alloc'd out,
;;; mod-inv-by Fermat ladder's r-next / b-next, point-add lam-reg before
;;; any accumulation).
;;;
;;; Saves n CCX per fresh-multiply when both
;;;   *mod-mul-use-solinas* AND *mod-mul-from-zero-first-add*
;;; are #t. When *mod-mul-from-zero-first-add* off, byte-identical to
;;; mod-mul-solinas! (safe fallback). When *mod-mul-use-solinas* off,
;;; falls through to mod-mul-litinski! (no specialization yet for the
;;; Litinski path — Stage 2 dispatch shape differs).

(define (mod-mul-from-zero! c a-reg b-reg out-reg n+1 p
                            cin-reg cin-idx tmp-reg flag-reg flag-idx
                            red-tmp-reg)
  "out := (a * b) mod p when out is |0> on entry. See mod-mul! header
   for calling convention."
  (cond
    (*mod-mul-use-solinas*
     (mod-mul-solinas-from-zero! c a-reg b-reg out-reg n+1 p
                                 (compute-c-expansion p (- n+1 1))
                                 cin-reg cin-idx tmp-reg flag-reg flag-idx
                                 red-tmp-reg))
    (else
     (mod-mul-litinski! c a-reg b-reg out-reg n+1 p
                        cin-reg cin-idx tmp-reg flag-reg flag-idx
                        red-tmp-reg))))

(define (mod-mul-litinski! c a-reg b-reg out-reg n+1 p
                           cin-reg cin-idx tmp-reg flag-reg flag-idx
                           red-tmp-reg)
  "Original Litinski wide-schoolbook + per-bit Solinas reduce. Renamed
   from mod-mul! so we can preserve the original code path for
   regression testing while mod-mul! itself becomes the dispatcher."
  (let ((n (- n+1 1)))
    (cond
      ((= n 0) #t)   ; degenerate, nothing to do
      (else
       ;; ── Stage 0: alloc Litinski scratch ──
       (alloc! c (quote sb-tmp-ext) (* 2 n))
       (alloc! c (quote sb-low) 1)
       (alloc! c (quote sb-xext) (+ n 1))
       (alloc! c (quote sb-const-tmp) (+ n 1))
       ;; ── Stage 1: compute wide product sb-tmp-ext := a * b ──
       (schoolbook-mul-into-addsub! c a-reg b-reg n
                                    (quote sb-low) 0
                                    (quote sb-tmp-ext)
                                    (quote sb-xext)
                                    cin-reg cin-idx
                                    (quote sb-const-tmp))
       ;; ── Stage 2: reduce sb-tmp-ext mod p into out ──
       ;; For each bit k in [0, 2n): if sb-tmp-ext[k]=1 then
       ;;   out += (2^k mod p) mod p.
       ;; Reversible via cload-const + mod-add + cunload-const, where the
       ;; constant lives in red-tmp-reg (n+1 wide, top bit |0>).
       (let loop ((k 0))
         (when (< k (* 2 n))
           (let ((c-k (modulo (expt 2 k) p)))
             (when (> c-k 0)   ; skip no-op constants
               ;; Load c-k into red-tmp controlled on sb-tmp-ext[k].
               (cload-const! c (quote sb-tmp-ext) k red-tmp-reg n+1 c-k)
               ;; Add red-tmp into out mod p.
               (mod-add!     c red-tmp-reg out-reg n+1 p
                             cin-reg cin-idx tmp-reg flag-reg flag-idx)
               ;; Unload c-k.
               (cunload-const! c (quote sb-tmp-ext) k red-tmp-reg n+1 c-k)))
           (loop (+ k 1))))
       ;; ── Stage 3: uncompute sb-tmp-ext back to |0> ──
       (schoolbook-mul-into-addsub-inverse! c a-reg b-reg n
                                            (quote sb-low) 0
                                            (quote sb-tmp-ext)
                                            (quote sb-xext)
                                            cin-reg cin-idx
                                            (quote sb-const-tmp))
       ;; ── Stage 4: free Litinski scratch ──
       (free! c (quote sb-const-tmp))
       (free! c (quote sb-xext))
       (free! c (quote sb-low))
       (free! c (quote sb-tmp-ext))))))

;;; ── mod-double-inplace! — v := 2v mod p, (n+1)-wide register ──
;;;
;;; Mirrors upstream's mod_double_inplace at mod.rs:2769.
;;;
;;; Pattern (cost: O(n) gates):
;;;   1. Shift-left v by 1 via SWAP cascade. Caller's (n+1)-wide v-reg
;;;      starts as [v_0 v_1 ... v_{n-1} 0]; after the cascade we have
;;;      [0 v_0 v_1 ... v_{n-1}]. Now v-reg = T = 2 * v_orig in [0, 2p).
;;;   2. Add c = 2^n - p across the full (n+1) bits. Sum S = T + c.
;;;      Top bit (idx n) of S is set iff T >= p.
;;;   3. flag := S[n] via CX.
;;;   4. csub c controlled on (NOT flag) — undoes the add when no reduction.
;;;   5. CX flag -> S[n] — clears the top bit when reduction needed.
;;;   6. Uncompute flag: T is even (= 2v), p is odd → after reduction v[0]=1;
;;;      no reduction → v[0]=0. So flag == v[0]. CX v[0] -> flag clears.
;;;
;;; All ancillae (cin, tmp, flag) return to |0>. v-reg top bit returns to |0>.
;;; Caller-supplied ancillae: cin (1 bit), tmp (n+1 wide), flag (1 bit).
;;;
;;; Variant choice: in-place via swap cascade + Solinas-style fold.
;;; Chosen because it mirrors upstream byte-for-byte; alternative
;;; Bennett-style "double via mod-add of copy" requires a 2^{-1} mod p
;;; classical inversion AND a fresh ancilla — heavier than this one
;;; ovf-bit pattern in lumbda. See task spec §"variant choice".
;;;
;;; SWAP not in our gate set — implemented as 3 CX (a→b, b→a, a→b).

(define (gate-swap! c a-reg a-idx b-reg b-idx)
  "SWAP qubit a with b via three CXs. Self-inverse."
  (gate-cx! c a-reg a-idx b-reg b-idx)
  (gate-cx! c b-reg b-idx a-reg a-idx)
  (gate-cx! c a-reg a-idx b-reg b-idx))

;;; ── pseudo-Mersenne mod-double (Schrottenloher 2026 Algorithm 7) ─
;;;
;;; For pseudo-Mersenne primes p = 2^u - f with f << 2^u (secp256k1: u=256,
;;; f=2^32+977=4294968273, 33 bits) the entire add-const / csub-const /
;;; flag-uncompute dance collapses to a single controlled add of f over the
;;; LOW lsbs bits of v, controlled on the carry-out from the shift.
;;;
;;; Algorithm 7 (qarton special_mod_arithmetic.py:54-92):
;;;   1. shift v left by 1 (anc receives MSB carry-out)
;;;   2. cadd(anc, f, v[:lsbs])   — controlled add of f into low lsbs bits
;;;   3. cx(v[0], anc)            — uncompute anc via parity
;;;
;;; Correctness lsbs = padding + bit_length(f). The cadd carry walks at most
;;; lsbs bits; if it would propagate further, the result is wrong. For
;;; uniform random v the failure probability is roughly 2^(-padding). Qarton
;;; uses padding=30 by default — same as Schrottenloher §4.
;;;
;;; Toffoli savings vs control: control mod-double-inplace! emits one
;;; add-const + one csub-const, both at full width (n+1). Each cuccaro-add
;;; over k bits costs 2(k-1) Toffoli (HEAD's HMR-borrowed variant: k-1).
;;; Pseudo-Mersenne emits ONE cadd-const at width lsbs only. Predicted
;;; Toffoli savings at secp256k1 width: ≈ 2 × (n+1 - lsbs) / (2(n+1)) ≈
;;; (256 - 63) / 257 ≈ 75 % of mod-double Toffoli; mod-double itself sits
;;; at ~8 % of total (Schrottenloher Table 3) → predicted 5-10 % full-stack.

(define *mod-double-use-pseudo-mersenne* #f)
;;; *mod-double-pseudo-mersenne-padding* — extra carry-safety bits beyond
;;; bit_length(f) for the controlled add. Larger padding → smaller flake
;;; probability ≈ 2^(-padding) but more Toffoli per call. Qarton + paper
;;; both use 30 by default.
(define *mod-double-pseudo-mersenne-padding* 30)

;;; *windowed-mod-double-r* — sweep-windowed-mod-double-r dispatcher.
;;; When #t, mod-double-inplace! routes through mod-double-inplace-
;;; windowed! (HEAD modular.rs:417-419 windowed branch). Foundation for
;;; K=5 apply-phase split — HEAD's compressed.rs:1986-1999 + 2515
;;; lean on the windowed form for the q1192 island. Default #f preserves
;;; byte-identity for every existing caller. Truncation flake
;;; probability ≈ 2^-(window+1) per call (window pulled from
;;; *windowed-mod-double-r-window*, default 8 matching HEAD).
;;;
;;; Composes with neither *mod-double-use-pseudo-mersenne* nor the
;;; alg-11 safe-band detector — the windowed path is its own dispatch
;;; branch (highest-priority) in mod-double-inplace!.
(define *windowed-mod-double-r* #f)
(define *windowed-mod-double-r-window* 8)

(define (pmersenne-bit-length n)
  "Number of bits to represent positive integer n (== Python's int.bit_length).
   bit-length(0)=0, bit-length(1)=1, bit-length(2)=2, bit-length(3)=2, ..."
  (let loop ((k 0) (m n))
    (if (= m 0) k (loop (+ k 1) (quotient m 2)))))

(define (mod-double-inplace-pseudo-mersenne!
         c v-reg n+1 p pmersenne-f
         cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "Pseudo-Mersenne variant of mod-double-inplace!. Same calling convention
   (v-reg (n+1) wide, cin/tmp/flag scratch); ignores flag-reg/flag-idx
   (kept for signature compatibility with the dispatcher).
   pmersenne-f = 2^n - p (must be > 0 and small)."
  (let* ((n      (- n+1 1))
         (f-bits (pmersenne-bit-length pmersenne-f))
         (padding *mod-double-pseudo-mersenne-padding*)
         (lsbs    (min n+1 (+ padding f-bits))))
    ;; (1) Shift-left v in place via SWAP cascade.
    ;;     End state: bit 0 = 0, bit i (i>=1) = v_orig[i-1],
    ;;                bit n = v_orig[n-1] = pseudo-Mersenne carry-out.
    (let loop ((i n))
      (when (> i 0)
        (gate-swap! c v-reg i v-reg (- i 1))
        (loop (- i 1))))
    ;; (2) cadd(anc=v[n], f, v[0..lsbs))  — controlled add of f into low bits.
    ;;     No aliasing concern: ctrl-idx = n, tgt-idx range = [0, lsbs) with
    ;;     lsbs < n+1, so ctrl bit never overlaps with cadd's target slice.
    (cadd-const! c v-reg lsbs pmersenne-f
                 v-reg n cin-reg cin-idx tmp-reg)
    ;; (3) Uncompute anc via parity: 2v is even, p is odd → after reduction
    ;;     v[0] = 1, no reduction → v[0] = 0. CX v[0] -> v[n] clears anc.
    (gate-cx! c v-reg 0 v-reg n)))

;;; ── mod-halve-inplace-direct-const-fast! ──────────────────────────
;;;
;;; Port of HEAD mod_halve_inplace_direct_const_fast
;;; (src/point_add/arith/modular.rs:753-765, commit 2dcf00d). Gate-level
;;; inverse of mod_double_inplace_direct_const_fast (sweep-030 PORTED
;;; in lumbda as mod-double-inplace-pseudo-mersenne!). Closes the open
;;; question sweep-030 RESULTS.md flagged + the mod-add-double-qb
;;; PORTED-WITH-GAP from sweep-mod-qb-adders.
;;;
;;; HEAD algorithm (5 steps):
;;;   1. alloc ovf qubit
;;;   2. cx(v[0], ovf)                       -- XOR LSB into ovf
;;;   3. csub_nbit_const_direct_fast(v, c, ovf) where c = 2^n - p
;;;   4. swap chain: for i in 0..n-1: swap(v[i], v[i+1])  (right rotate)
;;;   5. swap(v[n-1], ovf); free ovf          -- ovf bit lands at v[n-1]
;;;
;;; This is the EXACT gate-level inverse of the direct-const double
;;; (HEAD line 408+): the double's pre-shift swap-chain becomes the
;;; halve's post-shift swap-chain; the double's cadd becomes the
;;; halve's csub; the double's parity-uncompute becomes the halve's
;;; parity-cx-INTO-ovf at the start.
;;;
;;; Substrate status: ADDITIVE. No lumbda caller dispatches through
;;; this primitive yet. mod-add-double-qb (sweep-mod-qb-adders) can
;;; route through this once a follow-on sweep adds the dispatcher
;;; flag (analog of HEAD's KAL_DIRECT_CONST_HALVE / direct_const_
;;; walks_enabled).
;;;
;;; Caller supplies the 'mod-halve-anc qubit + carries lane via cin/
;;; tmp/flag (HEAD allocs inline; lumbda style routes through args).

;;; ── mod-double-inplace-direct-const-fast! — sweep-sq-lowq-shift22 ──
;;;
;;; HEAD modular.rs:414. Mirror of mod-halve-inplace-direct-const-fast!
;;; with cadd direction. Uses cadd-nbit-const-direct-fast! (PORTED in
;;; sweep-cadd-csub-direct-fast) for the Solinas correction.

(define (mod-double-inplace-direct-const-fast!
         c v-reg n+1 p pmersenne-f
         cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "Port of HEAD mod_double_inplace_direct_const_fast (modular.rs:414).
   v-reg := 2*v mod p (in place). v-reg is (n+1)-wide; v in low n bits,
   v[n] = ovf at |0> on entry + restored on exit. pmersenne-f = 2^n - p."
  (let* ((n (- n+1 1))
         (c-const pmersenne-f))
    ;; (1) swap(v[n-1], v[n]).
    (gate-swap! c v-reg (- n 1) v-reg n)
    ;; (2) Right-rotate the n low bits via reverse swap chain.
    (let loop ((i (- n 2)))
      (when (>= i 0)
        (gate-swap! c v-reg i v-reg (+ i 1))
        (loop (- i 1))))
    ;; (3) cadd-nbit-const-direct-fast! ctrl=v[n] (ovf) into v[0..n].
    (cadd-nbit-const-direct-fast!
      c v-reg n c-const v-reg n tmp-reg (* 4 n+1))
    ;; (4) Parity CX: v[0] XOR into v[n] (clears ovf).
    (gate-cx! c v-reg 0 v-reg n)))

;;; ── mod-double-inplace-windowed! — sweep-windowed-mod-double-r ──
;;;
;;; Port of HEAD `mod_double_inplace_fast_with_dirty`
;;; (modular.rs:398-444), windowed branch (lines 417-419 — fires when
;;; `double_carry_trunc_window()` returns `Some(w)` i.e. env var
;;; `KAL_DOUBLE_CARRY_TRUNC_W=w`). HEAD's K=5 apply-phase ipmul +
;;; quotient bodies (compressed.rs:1986-1999 + 2515) lean on this
;;; windowed form for the q1192 island; the apply-phase callsite
;;; allocates an `ovf` qubit, swaps the top bit out, right-rotates the
;;; low n bits, then runs ONE truncated cadd against ctrl=ovf instead
;;; of the standard add-const + csub-const + flag-uncompute pair.
;;;
;;; Structural shape vs `mod-double-inplace-direct-const-fast!`:
;;;
;;;   • direct-const-fast emits a FULL-width `cadd-nbit-const-direct-fast!`
;;;     (no carry-tail truncation; exact for any v).
;;;   • windowed emits `cadd-nbit-const-direct-trunc-fast!` with carry
;;;     ripple stopped `window` bits past `highest_set_bit(c)`.
;;;     For secp256k1, c = 2^32 + 977 has highest-bit 32; window=8 stops
;;;     the ripple at bit 40 — saves ~(n - 40) carry maj-recurrence
;;;     CCXs + the matching backward HMR sweep per call. Per-call
;;;     Toffoli drops from ~2(n-1) to ~2*(highest_set_bit(c) + w).
;;;
;;; Flake probability: ~2^-(window+1) per call. At window=8 that's
;;; ~2^-9 ≈ 0.2 %. Production cells stack the apply-phase fold's same
;;; window so forward + reverse use matching truncation; mismatch only
;;; manifests when the carry-tail propagates through `window + 1`
;;; consecutive 1-bits in the running accumulator above bit 32 — the
;;; "exact-unless-rare-input" regime documented in HEAD's
;;; cadd_nbit_const_direct_trunc_fast docstring (const_arith.rs:526).
;;;
;;; Calling convention matches `mod-double-inplace!`:
;;;   v-reg : (n+1)-wide; v in low n bits, bit n at |0> in/out.
;;;   p     : prime; classical.
;;;   pmersenne-f : 2^n - p (HEAD's `c`). Caller computes once.
;;;   tmp-reg : (>= last+1)-wide ancilla at |0> for the carries lane.
;;;             `last = min(n-2, highest-set-bit(f) + window)`.
;;;
;;; Width assertion: caller must pass tmp-reg with capacity >= last+1.
;;; All existing dispatchers route mod-double-inplace! with tmp-reg
;;; sized n+1 — which is always >= last+1 since last <= n-2.

(define (mod-double-inplace-windowed!
         c v-reg n+1 p pmersenne-f
         cin-reg cin-idx tmp-reg flag-reg flag-idx window)
  "Port of HEAD mod_double_inplace_fast_with_dirty windowed branch
   (modular.rs:417-419). v-reg := 2*v mod p (in place) via shift-cascade
   + ONE truncated cadd. Saves ~(n - hi - window) carry-sweep CCXs per
   call vs the non-windowed direct-const path.

   v-reg : (n+1)-wide; v in low n bits, bit n at |0> in/out.
   pmersenne-f : 2^n - p (HEAD's `c`).
   window : carry-tail safety bits past highest_set_bit(pmersenne-f).
            HEAD's default 8 — flake prob ~2^-(window+1) per call.
   cin-reg/cin-idx + flag-reg/flag-idx kept for signature parity; the
   windowed path does NOT use them (no separate flag ancilla — ovf
   lives at v[n] post-shift)."
  (let* ((n (- n+1 1))
         (c-const pmersenne-f))
    ;; (1) swap(v[n-1], v[n]).
    (gate-swap! c v-reg (- n 1) v-reg n)
    ;; (2) Right-rotate the n low bits via reverse swap chain.
    (let loop ((i (- n 2)))
      (when (>= i 0)
        (gate-swap! c v-reg i v-reg (+ i 1))
        (loop (- i 1))))
    ;; (3) cadd-nbit-const-direct-trunc-fast! ctrl=v[n] (ovf) into v[0..n).
    ;;     Unique bit-base via cdtf-alloc-bit-base! so back-to-back calls
    ;;     in K=2 shift2=1 path don't collide on HMR slots.
    (cadd-nbit-const-direct-trunc-fast!
      c v-reg n c-const v-reg n tmp-reg window (cdtf-alloc-bit-base! n))
    ;; (4) Parity CX: v[0] XOR into v[n] (clears ovf).
    (gate-cx! c v-reg 0 v-reg n)))

(define (mod-halve-inplace-direct-const-fast!
         c v-reg n+1 p pmersenne-f
         cin-reg cin-idx tmp-reg flag-reg flag-idx)
  ;; v-reg := v / 2 mod p (in place). v-reg is (n+1)-wide; v in low n
  ;; bits, bit n at |0> on entry + restored to |0> on exit (the ovf
  ;; ancilla). pmersenne-f = 2^n - p (matches mod-double-inplace-
  ;; pseudo-mersenne! caller convention). flag-reg/flag-idx kept for
  ;; signature symmetry with the dispatcher.
  (let* ((n (- n+1 1))
         (c-const pmersenne-f))   ; c = 2^n - p; HEAD line 757 same form
    ;; (1) Parity CX: v[0] XOR into v[n] (our ovf is at v[n]).
    (gate-cx! c v-reg 0 v-reg n)
    ;; (2) Controlled sub of c, ctrl = v[n] (= ovf).
    ;;     csub-nbit-const-direct-trunc-fast! with window = n is
    ;;     effectively non-truncated (no carry-tail truncation).
    (csub-nbit-const-direct-trunc-fast!
      c v-reg n c-const v-reg n tmp-reg n (* 4 n+1))
    ;; (3) Right-rotate the n low bits via swap chain. Matches HEAD's
    ;;     for i in 0..n-1: swap(v[i], v[i+1]).
    (let loop ((i 0))
      (when (< i (- n 1))
        (gate-swap! c v-reg i v-reg (+ i 1))
        (loop (+ i 1))))
    ;; (4) Final swap: v[n-1] <-> ovf (v[n]). ovf-content lands at
    ;;     v[n-1]; v[n] returns to |0> (the bit that came from v[n-1]
    ;;     after step 3's chain).
    (gate-swap! c v-reg (- n 1) v-reg n)))

(define (mod-double-inplace! c v-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "v-reg := 2 * v-reg mod p (in place). v-reg is (n+1)-wide; v stored in
   low n bits, bit n starts |0> and ends |0>. cin/tmp/flag are the same
   scratch suite used by mod-add!: cin (1), tmp (n+1), flag (1), all |0>
   in/out. Cost: 1 cuccaro-add (the inner add-const) + 1 cuccaro-sub
   (csub-const) + 5n + O(1) Clifford gates. O(n) total.

   When *mod-double-use-pseudo-mersenne* is #t AND p is a pseudo-Mersenne
   prime (f = 2^n - p small), dispatches to mod-double-inplace-pseudo-mersenne!."
  (let* ((n      (- n+1 1))
         (c-const (- (expt 2 n) p))
         (f-bits  (pmersenne-bit-length c-const))
         (padding *mod-double-pseudo-mersenne-padding*))
    (cond
      ;; sweep-windowed-mod-double-r: HEAD modular.rs:417-419 windowed
      ;; branch. Routes through mod-double-inplace-windowed! (one
      ;; truncated cadd; no separate flag-ancilla / csub pair). Highest
      ;; priority — composes with neither the pseudo-Mersenne path nor
      ;; alg-11 safe-band. Default OFF for byte-identity.
      ((and *windowed-mod-double-r* (> c-const 0))
       (mod-double-inplace-windowed!
         c v-reg n+1 p c-const cin-reg cin-idx tmp-reg
         flag-reg flag-idx *windowed-mod-double-r-window*))
      ;; Dispatch to pseudo-Mersenne when flag on AND f is small enough
      ;; that lsbs = padding + f-bits stays strictly below n+1 (otherwise
      ;; the no-aliasing assumption breaks).
      ;;
      ;; 2026-06-12 — DISABLED pseudo-Mersenne. Same bug class as
      ;; mod-add-inplace-pseudo-mersenne! (commit 5e6e3af). Reducer
      ;; tests/sweep-doctrine/test-mod-double-top-bit-clean.lsp at
      ;; n+1=8, p=125 (non-Mersenne, bug range non-empty): v=63 →
      ;; got 126, expected 1. ARITH-FAIL with top bit clean (worse
      ;; than mod-add — silent wrong-output, no leak diagnostic).
      ;;
      ;; Root cause: step 1's shift-left captures v[n] = v_orig[n-1]
      ;; as the overflow indicator. This only fires when 2v ≥ 2^n,
      ;; not when 2v ≥ p. For v_orig ∈ [p/2, 2^(n-1)) where 2v ∈ [p,
      ;; 2^n), the algorithm doesn't reduce and step 3's parity-CX
      ;; doesn't fix it (v[0]=0 since 2v is even, no XOR).
      ;;
      ;; Standard mod-double-inplace! (else branch) uses full csub-
      ;; const-based reduction, provably correct, drop-in replacement.
      ;; Trade-off: more Toffolis but algorithmically sound.
      ;;
      ;; 2026-06-12 (alg-11 wiring) — when *mod-add-alg-11-fallback* on,
      ;; mod-double-alg-11-safe? classically peeks v-reg & routes
      ;; pseudo-Mersenne only when 2v < p OR 2v >= 2^n (the safe regimes
      ;; outside the [p, 2^n) bug band).
      ((and *mod-double-use-pseudo-mersenne*
            (> c-const 0)
            (< (+ padding f-bits) n+1)
            (mod-double-alg-11-safe? c v-reg n+1 p))
       (mod-double-inplace-pseudo-mersenne!
         c v-reg n+1 p c-const cin-reg cin-idx tmp-reg flag-reg flag-idx))
      (else
       ;; (1) Shift-left v in place via SWAP cascade.
       ;;     End state: bit 0 = 0, bit i (i>=1) = v_orig[i-1], bit n = v_orig[n-1].
       ;;     Walk from top down: swap(v[n], v[n-1]), swap(v[n-1], v[n-2]), ...
       (let loop ((i n))
         (when (> i 0)
           (gate-swap! c v-reg i v-reg (- i 1))
           (loop (- i 1))))
       ;; (2) Add c = 2^n - p at width n+1.
       (add-const! c v-reg n+1 c-const cin-reg cin-idx tmp-reg)
       ;; (3) flag := v[n]
       (gate-cx!   c v-reg n flag-reg flag-idx)
       ;; (4) X flag so flag=1 when NO reduction needed; csub-const controlled.
       (gate-x!    c flag-reg flag-idx)
       (csub-const! c v-reg n+1 c-const flag-reg flag-idx cin-reg cin-idx tmp-reg)
       (gate-x!    c flag-reg flag-idx)
       ;; (5) CX flag -> v[n] (clears top bit when reduction happened)
       (gate-cx!   c flag-reg flag-idx v-reg n)
       ;; (6) Uncompute flag via parity: flag == v[0]
       (gate-cx!   c v-reg 0 flag-reg flag-idx)))))

;;; ── mod-4x-inplace! — v := 4v mod p, sweep-apply-fused-fold sibling ─
;;;
;;; HEAD reference: `compressed.rs:2149-2281` `dialog_gcd_fused_double_y`.
;;; Lumbda hooks: STEP 7+8 dispatch under K=2 + apply-fused-fold flags
;;; at `mod-inv-by-dialog-gcd-host.lsp` ~line 345.
;;;
;;; Semantics: v := 4v mod p on a SINGLE shared carry chain (target).
;;; v-reg is (n+1)-wide; v stored in low n bits, bit n |0> in/out.
;;; cin/tmp/flag scratch reused across both folds (no extra ancilla
;;; vs `mod-double-inplace!` × 2). Classical-specialization at the
;;; caller — this primitive ships only when the classical Kaliski
;;; trace says shift2-bit = 1 for this iter; otherwise the caller
;;; emits one `mod-double-inplace!`.
;;;
;;; V1 (prior): sequential two-fold via two `mod-double-inplace-pseudo-
;;; mersenne!` calls — substrate vehicle but byte-identical to inline
;;; K=2 pattern. Shipped 2.0228e+10 at i258 (non-K2body).
;;;
;;; V2 (this commit): inlined dual-shift + explicit ovf1/ovf2 ancilla
;;; capture + two cadd-const calls sharing the cin/tmp carry buffer.
;;; Matches HEAD's STRUCTURAL layout (compressed.rs:2149-2281) — ovf1
;;; held in a side ancilla across shift2; ovf2 captured post-shift2;
;;; one cadd-const(f, ctrl=ovf1) + one cadd-const(2f, ctrl=ovf2) at
;;; width lsbs+1. Parity uncompute of ovf1/ovf2 from v[0]/v[1] post-fold.
;;;
;;; V2 buys substrate clarity, not Toffoli: the two carry sweeps remain
;;; physically distinct (lumbda lacks a per-position-controls cadd
;;; helper). Per-iter Toffoli ≈ V1 (≤ ±2 from extra ovf-uncompute CCX).
;;; Production score targets a small change vs V1 baseline; the true
;;; -8k..-16k Toff/shot saving rides on V2.5 — a new
;;; `cadd-2-controls-trunc-fast!` primitive that emits HEAD's 12-position
;;; controlled-add (compressed.rs:2193-2215) at width lsbs. V2 substrate
;;; positions ovf1/ovf2 in named ancilla so V2.5 lands as a single
;;; cadd-call replacement.
;;;
;;; Algorithm trace (n=256, secp256k1, c = 2^256 - p):
;;;   1. alloc ovf1 ancilla.
;;;   2. shift1 (swap cascade): v[n] := v_orig[n-1], v[0] := 0.
;;;   3. swap(v[n], ovf1): ovf1 := v_orig[n-1], v[n] := 0.
;;;   4. alloc ovf2 ancilla.
;;;   5. shift2 (swap cascade): v[n] := v_orig[n-2], v[0] := 0.
;;;      (Note v[0] entering shift2 was 0 post step 3; so v[0]=0 post.)
;;;   6. swap(v[n], ovf2): ovf2 := v_orig[n-2], v[n] := 0.
;;;   7. cadd-const(v, lsbs, f, ctrl=ovf1, cin/tmp): v += f · ovf1.
;;;   8. cadd-const(v, lsbs, 2f, ctrl=ovf2, cin/tmp): v += 2f · ovf2.
;;;      Same width as #7; padding leaves plenty of carry headroom
;;;      inside lsbs even though 2f has 1 more bit than f.
;;;   9. Parity uncompute ovf1: post-fold v[0] = ovf1 (f bit 0 = 1, 2f
;;;      bit 0 = 0 → v[0] = ovf1·1 + ovf2·0 = ovf1). CX v[0] → ovf1.
;;;  10. Parity uncompute ovf2: post-fold v[1] = ovf1·f[1] + ovf2·(2f)[1]
;;;      mod 2 = ovf1·f[1] + ovf2·f[0] = ovf1·f[1] + ovf2. When f[1]=0
;;;      (secp256k1: f=2^32+977, f[1]=0), v[1] = ovf2. CX v[1] → ovf2.
;;;      For general f, when f[1]=1 we'd need an extra CX ovf1 → ovf2
;;;      to absorb the f[1]·ovf1 term. Guarded explicitly below.
;;;  11. free ovf2, ovf1.
;;;
;;; Safety: errors when classical *dgcd-k2-bounded-shift* off.

(define (mod-4x-inplace! c v-reg n+1 p
                          cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "v-reg := 4 * v-reg mod p (in place). v-reg is (n+1)-wide; v stored
   in low n bits, bit n starts |0> and ends |0>. Same scratch suite as
   mod-double-inplace!.

   When *mod-double-use-pseudo-mersenne* is #t AND p is a pseudo-Mersenne
   prime (f = 2^n - p small), uses the V2 inlined dual-shift +
   ovf-capture path with two cadd-const calls sharing cin/tmp. Otherwise
   falls back to two mod-double-inplace! calls (general Solinas path).

   Defensive guard: errors when *dgcd-k2-bounded-shift* is off, since
   the host dispatch only emits this primitive when classical K=2 trace
   says shift2-bit=1 — calling it standalone outside that flow is a
   contract violation (would multiply v by 4 with no matching
   shift2-on-v_w under the iter).

   v-reg must be a named register (symbol). Allocates two ancilla
   registers `_4x-ovf1` and `_4x-ovf2` (1 bit each) — distinct from
   caller-supplied scratch so no aliasing risk. Both return to |0>."
  (cond
    ((not *dgcd-k2-bounded-shift*)
     (error "mod-4x-inplace! requires *dgcd-k2-bounded-shift* #t"))
    (else
     (let* ((n      (- n+1 1))
            (c-const (- (expt 2 n) p))
            (f-bits  (pmersenne-bit-length c-const))
            (padding *mod-double-pseudo-mersenne-padding*)
            (lsbs    (min n+1 (+ padding f-bits))))
       (cond
         ;; ── V2: pseudo-Mersenne dual-shift + ovf-capture ──
         ;; Pseudo-Mersenne fast path when f small enough for lsbs < n+1
         ;; AND f[1] = 0 (so post-fold v[1] = ovf2 cleanly with no
         ;; cross-term f[1]·ovf1). For secp256k1 f = 2^32 + 977 with
         ;; bit 1 = 0; for small-width probe p=11 f=5 with bit 1 = 0; both
         ;; OK. For f[1]=1 primes we fall back to V1 path.
         ((and *mod-double-use-pseudo-mersenne*
               (> c-const 0)
               (< (+ padding f-bits) n+1)
               (not (bit-set? c-const 1)))
          (let ((ovf1 '_4x-ovf1)
                (ovf2 '_4x-ovf2))
            (alloc! c ovf1 1)
            (alloc! c ovf2 1)
            ;; (1) shift1 swap cascade — v[n] := v_orig[n-1], v[0] := 0.
            (let loop ((i n))
              (when (> i 0)
                (gate-swap! c v-reg i v-reg (- i 1))
                (loop (- i 1))))
            ;; (2) capture ovf1: swap(v[n], ovf1). v[n] := 0, ovf1 := v_orig[n-1].
            (gate-swap! c v-reg n ovf1 0)
            ;; (3) shift2 swap cascade — v[n] := v_orig[n-2], v[0] := 0
            ;;     (v[0] was 0 post step 1; remains 0 post step 3 since
            ;;     each swap pushes the existing v[i-1] up).
            (let loop ((i n))
              (when (> i 0)
                (gate-swap! c v-reg i v-reg (- i 1))
                (loop (- i 1))))
            ;; (4) capture ovf2: swap(v[n], ovf2). v[n] := 0, ovf2 := v_orig[n-2].
            (gate-swap! c v-reg n ovf2 0)
            ;; (5+6) V2.5 fused fold: v[0..lsbs) += f·ovf1 + 2f·ovf2 in
            ;;       ONE truncated carry sweep via per-position-controls
            ;;       primitive. Replaces V2's two sequential cadd-const!
            ;;       calls (which each emitted a full Solinas ripple).
            ;;       Derives 4 ancilla (h, xed, eord, n10) from ovf1/ovf2,
            ;;       issues 1 truncated ripple at width lsbs, uncomputes
            ;;       the ancilla. Net save ~58 Toff/call vs V2.
            ;;       Hardcoded for secp256k1 c = 2^32+977 table (HEAD
            ;;       compressed.rs:2196-2210). Pre-guard via lsbs check.
            (cond
              ((and (> lsbs (+ (highest-set-bit c-const) 2))
                    *cadd-direct-trunc-fast*)
               (cadd-2-controls-trunc-fast!
                 c v-reg lsbs
                 c-const       ovf1 0
                 (* 2 c-const) ovf2 0
                 tmp-reg
                 *cadd-direct-window*
                 (cdtf-alloc-bit-base! lsbs)))
              (else
               ;; Narrow lsbs (small-width probe) OR direct-trunc-fast
               ;; off: keep V2's two-cadd path as the correctness floor.
               (cadd-const! c v-reg lsbs c-const
                            ovf1 0 cin-reg cin-idx tmp-reg)
               (cadd-const! c v-reg lsbs (* 2 c-const)
                            ovf2 0 cin-reg cin-idx tmp-reg)))
            ;; (7) Uncompute ovf1 via parity from v[0] = ovf1.
            (gate-cx! c v-reg 0 ovf1 0)
            ;; (8) Uncompute ovf2 via parity from v[1] = ovf2 (guard above
            ;;     ensures f[1] = 0 so no f[1]·ovf1 cross term).
            (gate-cx! c v-reg 1 ovf2 0)
            (free! c ovf2)
            (free! c ovf1)))
         ;; Pseudo-Mersenne but f[1]=1 OR no headroom: fall back to V1
         ;; sequential pseudo-Mersenne folds (correct, no extra savings).
         ((and *mod-double-use-pseudo-mersenne*
               (> c-const 0)
               (< (+ padding f-bits) n+1))
          (mod-double-inplace-pseudo-mersenne!
            c v-reg n+1 p c-const cin-reg cin-idx tmp-reg flag-reg flag-idx)
          (mod-double-inplace-pseudo-mersenne!
            c v-reg n+1 p c-const cin-reg cin-idx tmp-reg flag-reg flag-idx))
         ;; General Solinas fallback: two mod-double-inplace! calls.
         (else
          (mod-double-inplace! c v-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx)
          (mod-double-inplace! c v-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx)))))))

;;; ── csub-2-controls-trunc-fast! — gate-level inverse of cadd-2-controls-trunc-fast! ─
;;;
;;; Drop-in mirror of `cadd-2-controls-trunc-fast!` (lines 1224-1325) where
;;; the per-position-controls truncated ripple uses `csub-per-position-
;;; controls-trunc!` instead of `cadd-per-position-controls-trunc!`. Derives
;;; the same 4 ancilla controls (h, xed, eord, n10) and uncomputes them in
;;; the exact-reverse order. Used by `mod-4x-inverse-inplace!` to gate-level
;;; invert HEAD's secp256k1-class pseudo-Mersenne 4x fold.
;;;
;;; Toffoli budget: identical to `cadd-2-controls-trunc-fast!` since
;;; csub-per-position-controls-trunc! emits the same 3-CCX-per-bit borrow
;;; sweep + HMR uncompute as the add variant. The 4 derived-ancilla setup +
;;; teardown is bit-for-bit shared with the forward call.
;;;
;;; Safety: identical bit-pattern guards as the forward variant — k2 must
;;; equal 2·k1 mod 2^lsbs AND k1 must carry HEAD's table bits {0,4,6,7,8,9,hi}.
;;; Errors otherwise. Caller responsible for picking a fresh `bit-base`
;;; window that does not collide with concurrent uses of the classical-bit
;;; lane (forward `cadd-2-controls-trunc-fast!` consumes
;;; [bit-base, bit-base + last] during its HMR uncompute pass).

(define (csub-2-controls-trunc-fast!
         c acc-reg lsbs k1 ctrl1-reg ctrl1-idx k2 ctrl2-reg ctrl2-idx
         tmp-reg window bit-base)
  "acc[0..lsbs) -= (ctrl1 ? k1 : 0) + (ctrl2 ? k2 : 0) in ONE truncated
   borrow sweep with per-position-controls. Hardcoded for HEAD's
   secp256k1-class table where k2 == 2·k1 AND k1's bits sit at
   {0,4,6,7,8,9,hi}. Gate-level inverse of cadd-2-controls-trunc-fast!.
   *fold-freed-tail* routes through cadd-fold-ripple-freed-tail!
   with is-add=#f (HEAD compressed.rs:3440 — same primitive serves
   both add and sub fused folds)."
  (cond
    (*fold-freed-tail*
     (let* ((kk1 (modulo k1 (expt 2 lsbs)))
            (kk2 (modulo k2 (expt 2 lsbs))))
       (cond
         ((= lsbs 0) #t)
         ((and (= kk1 0) (= kk2 0)) #t)
         (else
          (let ((hi (highest-set-bit kk1)))
            (when (not (= kk2 (modulo (* 2 kk1) (expt 2 lsbs))))
              (error "csub-2-controls-trunc-fast!: k2 != 2*k1 (mod 2^lsbs)"
                     k1 k2 lsbs))
            (when (not (and (bit-set? kk1 0) (bit-set? kk1 4)
                            (bit-set? kk1 6) (bit-set? kk1 7)
                            (bit-set? kk1 8) (bit-set? kk1 9)
                            (bit-set? kk1 hi)))
              (error "csub-2-controls-trunc-fast!: k1 missing required bits"
                     k1 hi))
            (when (<= lsbs (+ hi 1))
              (error "csub-2-controls-trunc-fast!: lsbs <= hi+1, no room"
                     lsbs hi))
            (let* ((last     (min (- lsbs 2) (+ (+ hi 1) window)))
                   (hi-delta (+ hi 1)))
              (when (<= last hi-delta)
                (error "csub-2-controls-trunc-fast!: *fold-freed-tail* needs last > hi+1"
                       last hi-delta))
              (cadd-fold-ripple-freed-tail!
                c acc-reg lsbs
                ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx
                last hi hi-delta #f bit-base)))))))
    (else
  (let* ((kk1 (modulo k1 (expt 2 lsbs)))
         (kk2 (modulo k2 (expt 2 lsbs))))
    (cond
      ((= lsbs 0) #t)
      ((and (= kk1 0) (= kk2 0)) #t)
      (else
       (let ((hi (highest-set-bit kk1)))
         (when (not (= kk2 (modulo (* 2 kk1) (expt 2 lsbs))))
           (error "csub-2-controls-trunc-fast!: k2 != 2*k1 (mod 2^lsbs)"
                  k1 k2 lsbs))
         (when (not (and (bit-set? kk1 0)
                         (bit-set? kk1 4)
                         (bit-set? kk1 6)
                         (bit-set? kk1 7)
                         (bit-set? kk1 8)
                         (bit-set? kk1 9)
                         (bit-set? kk1 hi)))
           (error "csub-2-controls-trunc-fast!: k1 missing required bits"
                  k1 hi))
         (when (<= lsbs (+ hi 1))
           (error "csub-2-controls-trunc-fast!: lsbs <= hi+1, no room"
                  lsbs hi))
         ;; Derive 4 ancilla controls — identical to forward path.
         (let ((h    '_v25r-h)
               (xed  '_v25r-xed)
               (eord '_v25r-eord)
               (n10  '_v25r-n10))
           (alloc! c h    1)
           (alloc! c xed  1)
           (alloc! c eord 1)
           (alloc! c n10  1)
           ;; h = ctrl1 & ctrl2
           (gate-ccx! c ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx h 0)
           ;; xed = ctrl1 ⊕ ctrl2
           (gate-cx!  c ctrl1-reg ctrl1-idx xed 0)
           (gate-cx!  c ctrl2-reg ctrl2-idx xed 0)
           ;; eord = xed ⊕ h
           (gate-cx!  c xed 0 eord 0)
           (gate-cx!  c h   0 eord 0)
           ;; n10 = ctrl2 ⊕ h
           (gate-cx!  c ctrl2-reg ctrl2-idx n10 0)
           (gate-cx!  c h           0       n10 0)
           ;; Issue the truncated borrow sweep with HEAD's per-position table.
           (let* ((last     (min (- lsbs 2)
                                 (+ (+ hi 1) window)))
                  (controls (make-perpos-secp256k1-fold-controls
                              hi
                              (cons ctrl1-reg ctrl1-idx)
                              (cons ctrl2-reg ctrl2-idx)
                              (cons xed       0)
                              (cons eord      0)
                              (cons n10       0)
                              (cons h         0))))
             (csub-per-position-controls-trunc!
               c acc-reg lsbs controls last tmp-reg bit-base))
           ;; Uncompute derived ancilla in EXACT reverse — mirrors forward.
           (gate-cx!  c h           0       n10 0)
           (gate-cx!  c ctrl2-reg ctrl2-idx n10 0)
           (gate-cx!  c h   0 eord 0)
           (gate-cx!  c xed 0 eord 0)
           (gate-cx!  c ctrl2-reg ctrl2-idx xed 0)
           (gate-cx!  c ctrl1-reg ctrl1-idx xed 0)
           (gate-ccx! c ctrl1-reg ctrl1-idx ctrl2-reg ctrl2-idx h 0)
           (free! c n10)
           (free! c eord)
           (free! c xed)
           (free! c h))))))))) ; closes (else ...) of *fold-freed-tail* dispatch

;;; ── mod-halve-inplace! — v := v * 2⁻¹ mod p, inverse of mod-double-inplace! ─
;;;
;;; Walk mod-double-inplace! steps in reverse with each step inverted.
;;; All 6 steps are self-inverse OR (add-const ↔ sub-const), (csub-const
;;; ↔ cadd-const). Used to walk hi back to its pre-Solinas state in
;;; Stage 2 of mod-mul-solinas!.

(define (mod-halve-inplace! c v-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "Inverse of mod-double-inplace!: v := v * (2⁻¹ mod p)."
  (let* ((n      (- n+1 1))
         (c-const (- (expt 2 n) p)))
    ;; (6') CX v[0] -> flag (self-inverse)
    (gate-cx!   c v-reg 0 flag-reg flag-idx)
    ;; (5') CX flag -> v[n] (self-inverse)
    (gate-cx!   c flag-reg flag-idx v-reg n)
    ;; (4') Reverse the X-csub-X sandwich. cadd-const replaces csub-const.
    (gate-x!    c flag-reg flag-idx)
    (cadd-const! c v-reg n+1 c-const flag-reg flag-idx cin-reg cin-idx tmp-reg)
    (gate-x!    c flag-reg flag-idx)
    ;; (3') CX v[n] -> flag (self-inverse)
    (gate-cx!   c v-reg n flag-reg flag-idx)
    ;; (2') sub-const c at width n+1 (inverse of add-const)
    (sub-const! c v-reg n+1 c-const cin-reg cin-idx tmp-reg)
    ;; (1') Reverse the SWAP cascade. Walk from bottom up.
    (let loop ((i 1))
      (when (<= i n)
        (gate-swap! c v-reg i v-reg (- i 1))
        (loop (+ i 1))))))

;;; ── mod-4x-inverse-inplace! — v := v * 4⁻¹ mod p, gate-level inverse ─
;;;                                of mod-4x-inplace!
;;;
;;; HEAD reference: `compressed.rs:2283-2403` (`dialog_gcd_fused_halve_y`)
;;; — runs HEAD's apply-phase REVERSE pass during compressed-block
;;; decompression. Half of HEAD's headline -25k Toff/shot savings at
;;; iters=258 rides the reverse fold.
;;;
;;; Algorithm: walk `mod-4x-inplace!` (lines 3017-3122) in reverse with
;;; each step replaced by its gate-level inverse.
;;;
;;;   Forward (V2.5 pseudo-Mersenne path):
;;;     1. alloc ovf1, ovf2
;;;     2. shift1 cascade (swap down: bit i ↔ bit i-1, i = n..1)
;;;     3. swap(v[n], ovf1)
;;;     4. shift2 cascade (swap down)
;;;     5. swap(v[n], ovf2)
;;;     6. cadd-2-controls-trunc-fast! (+ f·ovf1 + 2f·ovf2 single ripple)
;;;        OR two cadd-const fallback (narrow-lsbs / direct-trunc-fast off)
;;;     7. cx v[0] → ovf1 (parity uncompute)
;;;     8. cx v[1] → ovf2 (parity uncompute)
;;;     9. free ovf2, ovf1
;;;
;;;   Reverse:
;;;     1. alloc ovf1, ovf2 (both |0>)
;;;     2'. cx v[1] → ovf2 (self-inverse — re-encode parity)
;;;     3'. cx v[0] → ovf1 (self-inverse — re-encode parity)
;;;     4'. csub-2-controls-trunc-fast! (inverse of 6 forward)
;;;          OR two csub-const fallback
;;;     5'. swap(v[n], ovf2) (self-inverse)
;;;     6'. shift2 cascade reversed (swap UP: bit i-1 ↔ bit i, i = 1..n)
;;;     7'. swap(v[n], ovf1) (self-inverse)
;;;     8'. shift1 cascade reversed (swap up)
;;;     9'. free ovf2, ovf1
;;;
;;; The shift cascades use `gate-swap!` which is self-inverse, so reversing
;;; the loop direction inverts the cascade.
;;;
;;; Each cadd ↔ csub pair has identical Toffoli budget — the reverse fold
;;; emits the SAME -58 Toff/call savings vs the V1 sequential `mod-halve`
;;; equivalent. ~50 % shift2-density × iters=258 ≈ 129 calls/shot →
;;; -7-8k Toff/shot when the reverse-fusion has a callsite. Combined
;;; with forward fusion: HEAD's headline -25k Toff/shot.
;;;
;;; CALLSITE NOTE: lumbda's `mod-inv-by-dialog-gcd-host!` backward sweep
;;; (line 595) runs CLASSICAL-REPLAY via `classical-reset!`, not a
;;; gate-level reverse iter walk. The reverse-fusion primitive ships now
;;; so a future sweep that adds a gate-level reverse iter (Option A,
;;; multi-day) has the apply-phase reverse-fold ready. See
;;; SWEEP-NOTES.md for the substrate gap analysis.
;;;
;;; Safety: identical guards to `mod-4x-inplace!`. Errors when
;;; *dgcd-k2-bounded-shift* off (semantics meaningless outside K=2 trace).

(define (mod-4x-inverse-inplace! c v-reg n+1 p
                                  cin-reg cin-idx tmp-reg flag-reg flag-idx)
  "v-reg := v-reg * (4⁻¹ mod p) (in place). v-reg is (n+1)-wide; v stored
   in low n bits, bit n starts |0> and ends |0>. Same scratch suite as
   mod-4x-inplace!.

   When *mod-double-use-pseudo-mersenne* is #t AND p is a pseudo-Mersenne
   prime AND f[1] = 0, walks the V2 inlined dual-shift + ovf-capture path
   in reverse using csub-const (or csub-2-controls-trunc-fast! when
   *cadd-direct-trunc-fast* on). Otherwise falls back to two
   mod-halve-inplace! calls (general Solinas path).

   Defensive guard: errors when *dgcd-k2-bounded-shift* is off."
  (cond
    ((not *dgcd-k2-bounded-shift*)
     (error "mod-4x-inverse-inplace! requires *dgcd-k2-bounded-shift* #t"))
    (else
     (let* ((n      (- n+1 1))
            (c-const (- (expt 2 n) p))
            (f-bits  (pmersenne-bit-length c-const))
            (padding *mod-double-pseudo-mersenne-padding*)
            (lsbs    (min n+1 (+ padding f-bits))))
       (cond
         ;; ── V2-reverse: pseudo-Mersenne dual-shift + ovf-capture inverse ──
         ((and *mod-double-use-pseudo-mersenne*
               (> c-const 0)
               (< (+ padding f-bits) n+1)
               (not (bit-set? c-const 1)))
          (let ((ovf1 '_4xr-ovf1)
                (ovf2 '_4xr-ovf2))
            (alloc! c ovf1 1)
            (alloc! c ovf2 1)
            ;; (8') CX v[1] -> ovf2 (self-inverse — re-encode ovf2 parity).
            (gate-cx! c v-reg 1 ovf2 0)
            ;; (7') CX v[0] -> ovf1 (self-inverse — re-encode ovf1 parity).
            (gate-cx! c v-reg 0 ovf1 0)
            ;; (5+6') Inverse fused fold: v[0..lsbs) -= f·ovf1 + 2f·ovf2.
            (cond
              ((and (> lsbs (+ (highest-set-bit c-const) 2))
                    *cadd-direct-trunc-fast*)
               ;; H7a peel-8 fix: cdtf-alloc-bit-base! gives this call a
               ;; fresh non-overlapping slot range, so the prior `(+ base
               ;; (* 8 n+1))` hand-offset to dodge forward/reverse HMR
               ;; collision is no longer required.
               (csub-2-controls-trunc-fast!
                 c v-reg lsbs
                 c-const       ovf1 0
                 (* 2 c-const) ovf2 0
                 tmp-reg
                 *cadd-direct-window*
                 (cdtf-alloc-bit-base! lsbs)))
              (else
               ;; Narrow lsbs OR direct-trunc-fast off: invert via two
               ;; csub-const calls in reverse order (matches V2 fallback
               ;; pair `cadd-const(c,ovf1)` + `cadd-const(2c,ovf2)`).
               (csub-const! c v-reg lsbs (* 2 c-const)
                            ovf2 0 cin-reg cin-idx tmp-reg)
               (csub-const! c v-reg lsbs c-const
                            ovf1 0 cin-reg cin-idx tmp-reg)))
            ;; (4') swap(v[n], ovf2) — self-inverse (re-injects v_orig[n-2]).
            (gate-swap! c v-reg n ovf2 0)
            ;; (3') Reverse shift2 swap cascade. Forward walked i = n..1
            ;;      with gate-swap(v[i], v[i-1]); reverse walks i = 1..n.
            (let loop ((i 1))
              (when (<= i n)
                (gate-swap! c v-reg i v-reg (- i 1))
                (loop (+ i 1))))
            ;; (2') swap(v[n], ovf1) — self-inverse (re-injects v_orig[n-1]).
            (gate-swap! c v-reg n ovf1 0)
            ;; (1') Reverse shift1 swap cascade.
            (let loop ((i 1))
              (when (<= i n)
                (gate-swap! c v-reg i v-reg (- i 1))
                (loop (+ i 1))))
            (free! c ovf2)
            (free! c ovf1)))
         ;; Pseudo-Mersenne but f[1]=1 OR no headroom: invert via V1
         ;; sequential pseudo-Mersenne halves (two mod-halve passes).
         ((and *mod-double-use-pseudo-mersenne*
               (> c-const 0)
               (< (+ padding f-bits) n+1))
          (mod-halve-inplace! c v-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx)
          (mod-halve-inplace! c v-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx))
         ;; General Solinas fallback: two mod-halve-inplace! calls.
         (else
          (mod-halve-inplace! c v-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx)
          (mod-halve-inplace! c v-reg n+1 p cin-reg cin-idx tmp-reg flag-reg flag-idx)))))))
