]> git.codecow.com Git - nano25519.git/commitdiff
Update agent file.
authorChris Duncan <chris@zoso.dev>
Wed, 26 Aug 2026 08:40:19 +0000 (01:40 -0700)
committerChris Duncan <chris@zoso.dev>
Wed, 26 Aug 2026 08:40:19 +0000 (01:40 -0700)
AGENTS.md

index 6dc9825f51f4d53dc91d3f1820dd947b5d3a0d2f..301726049f134c41191d7583ba3438675f1cb997 100644 (file)
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -20,8 +20,9 @@ verify_blocks(pub, blocks)  // { hash, signature }[], up to 256 -> boolean[]
 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
 
@@ -64,7 +65,12 @@ length once at module load and re-exports them.
 | `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
@@ -87,9 +93,10 @@ ordinary AssemblyScript:
   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
@@ -158,8 +165,9 @@ never show up on the clock; only the point arithmetic does.
 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