Skip to content

research(nightly): the real cost of Ed25519 witness signing on the rvf-wasm Cognitum tile - #1226

Draft
ruvnet wants to merge 5 commits into
mainfrom
claude/focused-darwin-d8vons
Draft

ruvnet wants to merge 5 commits into
mainfrom
claude/focused-darwin-d8vons

Conversation

@ruvnet

@ruvnet ruvnet commented Oct 17, 2026

Copy link
Copy Markdown
Owner

Hypothesis

Three prior nightly runs (ADR-340, ADR-343, and the 2026-09-16
witness-signer-agent-memory run) flagged the same open question without
closing it: what does WASM binary size and signing/verification latency
actually cost for the Ed25519 witness-signing primitive
(rvf_types::ed25519) that ruvector-retrieval-receipt and
ruvector-agent-memory both depend on? None measured it against a real
compiled WASM artifact.

This run adds an opt-in, default-off witness-signing feature to
rvf-wasm (the actual Cognitum-tile WASM microkernel, which already
depends on the signing crates but ships with signing compiled out) and
measures it for real: wasm-opt -Oz binary size, and wasmtime-hosted
(Cranelift) latency vs. native.

Architecture

  • crates/rvf/rvf-wasm/src/witness.rs (new): rvf_witness_ed25519_sign /
    rvf_witness_ed25519_verify, reusing the tile's existing 2048-byte
    Message I/O buffer — no growth of the 8 KB DATA_MEMORY layout.
  • crates/rvf/rvf-wasm/Cargo.toml: witness-signing = ["rvf-types/ed25519"],
    default off.
  • crates/rvf/benches/benches/witness_wasm_bench.rs (new): loads the
    compiled .wasm via wasmtime, asserts native↔wasm cross-compatibility,
    then benchmarks sign/verify natively vs. in-wasm.
  • docs/adr/ADR-361-rvf-wasm-witness-signing-feature.md +
    docs/research/nightly/2026-10-17-wasm-witness-signing-cost/ (README +
    gist): full methodology, raw results, limitations, next research.

Files Changed

  • crates/rvf/rvf-wasm/{Cargo.toml,src/lib.rs,src/witness.rs}
  • crates/rvf/benches/{Cargo.toml,benches/witness_wasm_bench.rs}
  • crates/rvf/Cargo.lock
  • docs/adr/ADR-361-rvf-wasm-witness-signing-feature.md
  • docs/research/nightly/2026-10-17-wasm-witness-signing-cost/{README.md,gist.md}

Benchmark Command

cd crates/rvf
cargo build -p rvf-wasm --release --target wasm32-unknown-unknown
cargo build -p rvf-wasm --release --target wasm32-unknown-unknown --features witness-signing
wasm-opt -Oz <artifact> -o <out>.opt.wasm   # run on both artifacts
cargo test -p rvf-wasm --lib -- --test-threads=1
cargo test -p rvf-wasm --lib --features witness-signing -- --test-threads=1
cargo bench -p rvf-benches --bench witness_wasm_bench

Real Benchmark Results

Binary size (wasm-opt -Oz): baseline 39,087 B → witness-signing
103,793 B → delta 64,706 B (threshold: ≤60,000 B → FAIL).
Baseline re-verified byte-identical to unmodified main via git stash.

Latency (criterion median, wasmtime/Cranelift vs. native):

  • Sign: 32.64 µs → 286.66 µs = 8.78x (threshold: ≤5x → FAIL)
  • Verify: 45.24 µs → 162.92 µs = 3.60x (threshold: ≤5x → PASS)

Correctness: rvf-wasm lib tests 6/6 (feature off, unchanged) and
8/8 (feature on, 2 new). Native↔wasm cross-compatibility assertion:
PASS (signatures byte-identical both directions, tamper correctly
rejected).

Acceptance Result

ACCEPT  — correctness / wire-compatibility / default-build regression gate
REJECT  — binary-size budget (64,706 B > 60,000 B)
REJECT  — signing-latency budget (8.78x > 5x)
ACCEPT  — verification-latency budget (3.60x <= 5x)

Reported as a genuinely mixed result — thresholds were fixed before
benchmarking and were not relaxed afterward. The new code is correct and
safe to merge as an opt-in, off-by-default feature; its measured cost does
not clear the budget this run pre-committed to, and that is the headline
finding, not a footnote.

A side-finding unrelated to this change: the pre-existing baseline tile
(feature off) measures ~39 KB after wasm-opt -Oz, not the "<8 KB" its own
module doc claims — flagged, not root-caused, in the ADR's Open Questions.

Darwin / Flywheel

No live Darwin evolutionary search this run (this is infrastructure
measurement, not a population search). No in-repo Flywheel/witness-chain
tool for nightly-research provenance exists (consistent with every prior
run's identical finding); this PR's documents and raw benchmark output are
the retained evidence.

Security Review

No new attack surface: the new exports operate on caller-controlled,
fixed-offset buffers in the tile's existing linear memory, matching every
other export's convention. The feature is additive and off by default; no
existing export's signature or behavior changes. Full detail in ADR-361's
Security section.

Main Limitations

Steady-state call latency only (no cold-start/instantiation cost measured
in the loop); wasmtime/Cranelift on x86_64 is a real WASM runtime but not
literal Cognitum hardware or a browser wasm-bindgen path; one fixed
96-byte message size; the sign-vs-verify latency asymmetry is not
root-caused. Full list in the nightly README's Limitations section.

Production Recommendation

Ship as an opt-in feature (already the case in this PR) so a deployment
can decide deliberately whether the ~65 KB / up to ~8.8x latency cost is
worth tamper-evident signing for its specific tile. Do not enable by
default. Next step before wider adoption: evaluate a smaller no_std
Ed25519 implementation against this PR's exact benchmark harness (Next
Research item 2 in the nightly report).


🤖 Generated with claude-flow

https://claude.ai/code/session_01TtFC4EMG4oAHkoC17vZnsK


Generated by Claude Code

claude and others added 5 commits October 17, 2026 07:35
Adds a default-off `witness-signing` feature exposing
rvf_witness_ed25519_sign/verify exports, reusing the existing Message
I/O buffer so the default Cognitum tile build is unaffected. Closes
the gap flagged by three prior nightly runs (ADR-340, ADR-343, and the
2026-09-16 witness-signer-agent-memory run): no real WASM artifact had
ever measured this primitive's cost at the edge.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01TtFC4EMG4oAHkoC17vZnsK
Loads the compiled rvf-wasm witness-signing artifact via wasmtime
(Cranelift) and measures real sign/verify latency against the same
rvf_types::ed25519 primitive called natively, plus a startup
cross-compatibility assertion (native<->wasm signature interop).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01TtFC4EMG4oAHkoC17vZnsK
Records the measured, mixed result: default build and native<->wasm
wire compatibility are unaffected (ACCEPT), but both the 60 KB
binary-size budget and the 5x signing-latency budget are exceeded
(REJECT) while verification-latency (3.60x) holds. Also documents a
pre-existing, unrelated discrepancy: the baseline tile already
measures ~39 KB after wasm-opt -Oz, not the <8 KB its own module doc
claims.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01TtFC4EMG4oAHkoC17vZnsK
…8/0349)

The Security audit / cargo-audit checks on this PR failed on four
rustls advisories published 2026-10-14, unrelated to this PR's
rvf-wasm witness-signing change: rustls is a transitive dependency at
the root workspace level (crates/rvf has its own separate Cargo.lock,
untouched by this fix), and main's own most recent scheduled
supply-chain run (2026-10-13, run 38377957804) already fails the
identical way. Same validated fix already landed on a sibling nightly
branch (claude/focused-darwin-rkdqv7, commit 60e1c69); ported here
rather than re-derived. Verified with `cargo check -p ruvector-core`.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01TtFC4EMG4oAHkoC17vZnsK

ruvnet commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

CI: Security audit / cargo-audit — investigated, partially fixed, rest is pre-existing

Both Security audit and cargo audit (RustSec advisories) failed on 97fc6e5 with 13 RustSec findings. None involve this PR's actual change (wasmtime, cranelift, ed25519-dalek — the new deps this PR adds — appear nowhere in the findings), and this PR never touched the root Cargo.lock the audit scans (crates/rvf is excluded from the root workspace and has its own separate lockfile, which is the only lockfile this PR modified before this comment).

Fixed and pushed (b39b946): 4 of the 13 findings were rustls 0.23.45 (RUSTSEC-2026-0346/0347/0348/0349, published 2026-10-14, transitive via reqwest -> hyper-rustls). A validated fix for this exact issue already exists on sibling nightly branch claude/focused-darwin-rkdqv7 (commit 60e1c6979), which notes the identical advisories would fail an audit of main's lockfile too — confirmed here independently: main's own most recent scheduled supply-chain run (2026-10-13, run 38377957804) already fails this same way. I ported that fix (2-line Cargo.lock bump to 0.23.46, verified with cargo check -p ruvector-core) rather than re-deriving it.

Not fixed — pre-existing, out of this PR's scope: the remaining 9 findings are all zip (3 different major versions pinned simultaneously — 1.1.4, 2.4.2, 7.2.0 — each carrying RUSTSEC-2026-0367/0368/0369), plus 2 pre-existing warnings (rustls-pemfile 2.2.0 unmaintained, lru unsound) that don't block the audit. Traced with cargo tree -i zip@<version>: zip 2.4.2 comes via ndarray-npy -> ruvector-cli; zip 7.2.0 comes via candle-core/candle-nn/candle-transformers -> ruvllm, ruvector-py, mcp-brain-server, ruvllm-cli, ruvector-typesafe-train. All fixes require >=9.0.0, a major bump that would mean upgrading the candle ML stack and/or ndarray-npy across several unrelated crates — a substantial, separate effort with real risk of breaking those crates, well outside what a rvf-wasm witness-signing research PR should carry. Re-running the two checks would still fail on these 9 findings, so I'm not spending the one re-run here; both checks will stay red on this PR until that separate dependency-upgrade work lands (tracked as pre-existing workspace debt, not introduced by this PR).


Generated by Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants