c4milo / c4milo/chapulin

docs/decisions.md states an x25519 cost the lint cannot check, and it disagrees with the README

Open Beginner friendly
#165 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.