The solver kit.
One dependency-free ES module and a node CLI. It derives each rung's instance exactly as the hook will, writes the lattice basis for fplll or G6K, turns your shortest vector into the payload the hook checks, and runs that check locally before you spend gas. The same module powers the payload builder on the Solve page.
- instance
- h from rootSeed and the hook address, NTT-domain sampling, inverse NTT
- basis
- 2n x 2n fplll matrix (about 10 MB at n = 1024)
- pack
- canonical box, k and t, minimal widths, payload, vectorHash, commit hash
- verify
- the hook's own arithmetic: biased Horner at s mod 2255 - 19
- reading
- normSq, root Hermite factor, model blocksize, the 2% rule
Until the hook is armed there is no live instance: every command needs rootSeed from the hook's Armed event, or --demo for a practice seed that is labelled as one. Lattice reduction itself runs in fplll or G6K on your own machine; the kit's JS LLL is enough for n = 64.
Against the workspace's reference script and against compiled verifiers on hardhat (cancun), per rung n = 64 to 1024: 100 prototype-contract payloads and 100 spec-harness payloads, each agreeing with the library, normSq included; 600 keccak vectors. Last full run 2026-11-01: 76 + 42 + 210 checks passed, 0 failed M.
The harness contracts are test fixtures, not the production verifier. Byte layouts the spec leaves open (hash preimages, keccak(f, g), the 16-bit chunk order) are fixed in the kit and must match the hook when it is compiled.
The test scripts read the reference script, the prototype build and hardhat from the author's workspace, so they run there, not from the zip alone. The CLI's R and phi lines still print the spec's earlier table (labelled DEFAULT); the current reward model is the table on the Rules page.
# 1. the instance for rung 128, from the Armed event's rootSeed and the hook address $ node bin/sieve.mjs instance --n 128 --root 0x<rootSeed> --hook 0x<hook> --chainid 1 --out work # 2. reduce on your own machine (fplll shown; G6K reads the same matrix) $ fplll -a bkz -b 40 work/basis_128.txt > reduced_128.txt # 3. pack the shortest usable row into a payload and a commit hash $ node bin/sieve.mjs pack --n 128 --vec reduced_128.txt --instance work/instance_128.json --recipient 0x<payee> # prints normSq, root Hermite factor, model blocksize, the 2% rule against --record, # widths, vectorHash and the commit hash; draws a random salt unless --salt is given. Keep it. # 4. check it exactly as the hook will (exit 0 accept, 2 reject with the reason) $ node bin/sieve.mjs verify payload_128.hex --instance work/instance_128.json --recipient 0x<payee> --salt 0x<salt>
Then commit c inside a buy on the Buy page, and reveal from the next block on the Solve page through a private RPC. Finalize at reveal block + 300.