Add sha256, the crypto family's intersection operator - #9
Conversation
The crypto family's intersection half. VM.md section 4 gains the 0x0b row and the family prose (variadic, atom arguments only, digest of the concatenation, zero arguments hash the empty string), the error taxonomy covers sha256 under arg_not_atom, and the D3 row no longer lists sha256 among the consensus-known opcodes BitLisp classes as unknown. COSTS.md gains the crypto family section (base 87, 134 per argument, 2 per byte, flat 320 malloc on the 32-byte digest) and the concat-shaped interleaving bullet. Both status headers now defer to the implemented-family list at the head of VM.md section 4 instead of repeating it. Every claim is probe-backed against chia-rs 0.46.0 flags 0: totals for zero through five arguments including nil and redundantly encoded atoms, the inclusive budget boundary at 724/723 on the worked example, a pair in the first argument reported at a budget of 41 where the base cost alone would burst it, and a pair in the second argument reported only once the first argument's charge fits (266/265).
The concat-shaped loop from the spec: the base cost 87 accrues without a budget check and rides on the first argument's charge, each argument's atom check precedes its own charge of 134 plus 2 per byte, and the 32-byte digest's malloc is one final charge after the loop. Hashing consumes each argument atom's actual bytes, redundant encoding bytes included, exactly the bytes the per-byte cost counts. Cross-checked against chia-rs 0.46.0 flags 0 on the full probe battery: totals for zero through five arguments including nil, redundantly encoded, and 5120-byte atoms, inclusive budget boundaries at 408/407, 566/565, and 724/723, and the pair-versus-cost_exceeded interleaving at budgets 40/41 and 265/266. Zero disagreements.
vectors/vm/crypto.json pins the sha256 rows of VM.md section 4 and COSTS.md section 8: the worked example at 724, zero arguments hashing the empty string, a nil argument reaching the same digest at a different cost, redundant versus minimal encodings hashing to distinct digests, inclusive budget boundaries (724/723, 408/407), and the interleaving boundaries where a pair argument beats or loses to cost_exceeded (41/40 and 266/265). Expected results and costs were produced by chia-rs 0.46.0 flags 0, not by bitlisp, so the file cannot self-confirm. The diff harness generator now emits 0x0b as a variadic operator, and both oracle error tables classify the sha256 pair-argument messages (chia-rs "sha256 used on list", clvm "sha256 on list") as arg_not_atom. Without the chia-rs fragment the message fell through to the bare InvalidOperatorArg catch-all and misclassified as arg_too_long, which the first fresh-seed run surfaced as ten mismatches. Two 10k runs, seeds 728281 and 314159, now pass with zero failures.
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
|
Review evidence, following the post-implementation cross-check practice from PRs 7 and 8. Five independent review passes (CLAUDE.md compliance, shallow bug scan, git history, prior-PR guidance, code-comment contracts) found no issues. Empirical checks run during review, beyond the PR's own verification:
Upstream source cross-check (reading disclosure per the reference-material policy, behavior was established by binary probes first): clvm_rs more_ops.rs op_sha256 uses the same constants (87 base, 134 per argument, 2 per byte), accrues the base cost unchecked, runs each argument's atom check before that argument's checked charge, and charges malloc on the finalized 32-byte digest. This matches the COSTS.md section 8 formula and the op_sha256 loop shape line for line. |
What changed
The sha256 operator (0x0b) lands as the intersection half of the crypto family: spec rows in VM.md and COSTS.md, the operator implementation, pinning vectors, and diff-harness coverage. The divergent half, secp_verify (D2), follows in its own PR.
Spec sections
Reading order
88b30ceSpec: operator table row, family prose, cost formula, D3 update. Every claim is probe-backed against chia-rs 0.46.0 flags 0 (probe details in the commit message).5ee7f2aImplementation: op_sha256 as a concat-shaped loop, constants in costs.py.51f58b8Vectors and harness: crypto.json (expectations produced by the oracle, not by bitlisp), generator emits 0x0b, and a harness classifier fix. The first fresh-seed run misclassified the oracle's "sha256 used on list" message through the bare InvalidOperatorArg catch-all as arg_too_long. The fix adds the sha256 fragments to both oracle tables.Verify independently
Two 10k harness runs (seeds 728281 and 314159) pass with zero failures. The vector suite is 416 cases across 9 files, 18 of them new in crypto.json.