Kit / node 18 or later, no install, no build step

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.

Download
Pending
Checking for the kit file.
What it does
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.

Tests the kit ships with

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.

Run it
# 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.