Inputs are `Uint8Array` or hex strings, and the output type follows the input
type. `derive` and `sign` take an optional preallocated output buffer as a
trailing argument. `verify_blocks` is the Nano account-chain case — many block
-hashes against one public key — and is under active construction; check the
-living context document before relying on it.
+hashes against one public key. It is correct across the full range as of
+`914c83c`, but not yet any faster than N sequential `verify()` calls — the
+per-key work is still redone per block.
## Commands
| `MESSAGE_BUFFER` | 32 KiB. A message for `sign`/`verify`, or packed 96-byte `hash \|\| signature` records for `verify_blocks` |
| `PRV_BUFFER`, `PUB_BUFFER` | 32 bytes each |
| `SIGNATURE_BUFFER` | one signature for single `verify` |
-| `OUTPUT_BUFFER` | public key, signature, or one result byte per verified block |
+| `OUTPUT_BUFFER` | 256 B. A public key, a signature, or one result byte per verified block |
+
+`verify_blocks` writes one result byte per block, so its cap **is**
+`OUTPUT_BUFFER_BYTELENGTH` — both the wasm guard and the host guard derive from
+it rather than hardcoding 256, and they cannot drift when the buffer is resized.
+Preserve that coupling, and note it only holds while one byte per block does.
Exported byte-length globals (`KEY_BYTELENGTH`, `MESSAGE_BUFFER_BYTELENGTH`, …)
are the single source of truth for these sizes — read them rather than
cannot be exported. Only compile-time constants survive as exported globals.
- **`enable: ["simd"]`** — field elements are 12 `i32` limbs, not 10. The two
trailing limbs are padding; respect the stride.
-- **`initialMemory: 4`** — pins the module at 4 pages. Without it the stub
- allocator doubles on growth (1→2→4→8). Re-derive this value when buffer
- sizes change rather than leaving it stale.
+- **`initialMemory: 2`** — pins the module at 2 pages. Without it the stub
+ allocator doubles on growth (1→2→4→8), so page counts are always powers of
+ two. Re-derive this whenever a buffer is resized rather than leaving it
+ stale; it has been wrong in both directions already.
Memory growth *during* a call would detach every `Uint8Array` view the host
holds, so keeping call paths allocation-free is a correctness requirement, not
failing**, and that one failure is expected.
`verify_blocks` has **no vector coverage yet** — a green suite says nothing
-about it. Exercise it directly, and at batch sizes past 64 and past 256, where
-the interesting boundaries are.
+about it. Exercise it directly, and across the whole range rather than at one
+size: its bugs have twice been invisible below a boundary (64, then 256) and
+only appeared past it.
The failing case is `PROBLEM_VECTOR`: a live cemented Nano block from a
small-order account (`nano_11a11…`, public key `0100…00`) that network