docs/decisions.md states an x25519 cost the lint cannot check, and it disagrees with the README
- Dominant language
- C
- Stars
- 2
- Forks
- 0
- Avg merge
- 1h 20m
- Merged PRs (30d)
- 74
Description
Two documents give the cost of one x25519 scalar multiplication on the same reference target, and they disagree by 37%. Neither names the flag that explains the difference, and `make lint-bench-numbers` cannot see one of them.
## The disagreement
`docs/decisions.md:43-45`:
> **x25519 in 16-bit limbs (the TweetNaCl scheme).** Cost: about 57 ms per scalar multiplication on the mips32r2 reference target
`README.md:235-237`:
> Every handshake runs two x25519 for forward secrecy, whichever mode it is in, so about 156 ms is the recurring floor and 86% of the pinned handshake's crypto.
156 ms for two is 78 ms each, not 57 ms.
Both are right about a build, and neither says which. 57 ms is 28,675,222 instructions at 500 MHz — the `native_insns` column of `bench/results-insn.csv`, the `CH_NATIVE_WIDEMUL` figure. 78 ms is 38,934,802 — the `insns` column, the 16x16 decomposition the default build ships. `docs/decisions.md` quotes the faster column while arguing for the decomposition that costs the slower one, which reads as understating the price of its own decision.
## Why the lint does not catch it
`tools/bench-numbers.py` regenerates the README's figures from `bench/results-insn.csv` and fails when they drift. But `check_restated` reads only two files:
```python
return rc | check_restated("README.md", text, want) \
| check_restated("docs/porting.md", prose(open("docs/porting.md").read()), want)
```
`docs/decisions.md` is not in that list, so `make lint-bench-numbers` passes with the unlabeled 57 ms in the tree. Every other bench figure in the repository is machine-checked against the CSV; this one is not.
## Fix
1. State the column in `docs/decisions.md`: either quote 78 ms, the default build's cost, or keep 57 ms and name `CH_NATIVE_WIDEMUL` beside it. The second is more informative, because the entry is arguing a provability-over-speed trade and the reader should see both numbers.
2. Add `docs/decisions.md` to `check_restated`'s file list so the figure cannot drift again.
## Related, same area
`README.md:222-224` states the flash side of the `PIN=ecdsa` trade and not the speed side. On mips32r2 a P-256 verify is 46,029,602 instructions against RSA-3072-PSS's 11,625,119 — **3.96x**, and 3.17x on Cortex-M3, 3.22x on rv32imac. An integrator choosing `PIN=ecdsa` for its smaller key material is also choosing a verify that costs four times as much, and the README does not say so.
Found while evaluating public-key acceleration for https://github.com/c4milo/chapulin/issues/25.
Contributor guide
Research direction
Read docs/decisions.md:43-45 and README.md:235-237, then inspect tools/bench-numbers.py and its check_restated file list. Run make lint-bench-numbers before and after the documentation and checker changes. Done means the decision text identifies the relevant cost or build mode and the lint checks docs/decisions.md against bench/results-insn.csv.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, python
- Domain
- documentation, tooling
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- Half a day
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100