Add ECSM accelerator markdown spec#667
Conversation
Codex Code ReviewFinding
No other concrete issues found in the PR diff. |
| factor = 1 | ||
| while isinstance(typ, list) and len(typ) == 2 and isinstance(typ[1], int): | ||
| factor *= typ[1] | ||
| typ = typ[0] |
There was a problem hiding this comment.
Low — silent fallback for unknown types produces wrong bus sizes
When a type label is not found in config["variables"]["types"], the function returns factor (which is 1 by default) without any warning. This can silently produce incorrect bus sizes in the signatures table.
| typ = typ[0] | |
| for type_cfg in config.get("variables", {}).get("types", []): | |
| if type_cfg.get("label") == typ: | |
| return factor * len(type_cfg.get("subtypes", [])) | |
| # Unknown primitive types (Bit, Byte, Half, etc.) have size 1 | |
| return factor |
Consider at minimum logging a warning if the type resolves to nothing, so spec authors know when a new type is missing from config.
| | Tag | Range | Description | Multiplicity | | ||
| |-----|-------|-------------|--------------| | ||
| | `ECSM-C5.i` | i ∈ [0, 31] | μ ⇒ `IS_BYTE<x2[i]>` | | | ||
| | `ECSM-C6.i` | i ∈ [0, 31] | μ ⇒ `IS_BYTE<q0[i]>` | | |
There was a problem hiding this comment.
Medium — xG is not range-checked to [0, p)
The spec notes that xG is range-checked because it is read from memory (each byte is in [0, 255]), but that only guarantees xG ∈ [0, 2^256). There is no constraint that xG < p.
By contrast, xR is explicitly range-checked in ECSM-C28–C30 using the subtraction-overflow trick.
If a caller provides xG ≥ p, the polynomial constraints for yG will be satisfied for (xG mod p, yG) (since all arithmetic is mod p). The accelerator would silently compute k × (xG mod p, yG) instead of rejecting the input.
For secp256k1, p = 2^256 − 2^32 − 977, so inputs with xG ∈ [p, 2^256) are only ~2^32 values — a small but non-trivial set.
Recommend adding an assumption or a range-check constraint analogous to ECSM-C28–C30 for xG, or explicitly documenting this as a trusted-input assumption (analogous to the existing addr alignment assumptions).
| | `xR` | `U256BL` | $(`k` times `G`)_x$ | | ||
|
|
||
| ### Auxiliary | ||
|
|
There was a problem hiding this comment.
Low — empty placeholders throughout generated markdown
Several lines read like:
"The chip is comprised of variables that are expressed using columns and leverages interaction(s):"
The #nr_variables, #nr_columns, and #nr_interactions values are computed at Typst-render time and are not available in the TOML-to-Markdown conversion, so they appear as empty strings. This happens here and in the ECDAS and EC_SCALAR sections as well.
If this spec document is meant to be human-readable as committed markdown, consider either:
- Computing and injecting these numbers in
typst_to_md.py, or - Removing these sentences from the markdown output (they add more noise than value when empty).
| The purpose of this accelerator is to speed up the scalar multiplication $k times G$ for scalar $k in [1, N)$ and point $G in E(0, b, p) without {#inf}$ with $p in [2^248, 2^256)$. | ||
| In particular, the accelerator supports the curve $#`secp256k1` = E(0, 7, 2^256-2^32 - 977)$. | ||
| This accelerator leverages _double-and-add_, executing the multiplication in $O(log(k))$ doublings and $O(w_H (k)) = O(log(k))$ additions, where $w_H (dot)$ denotes the hamming-weight of a bitstring. | ||
|
|
There was a problem hiding this comment.
Typo: "remaing" → "remaining" (also appears in the generated docs/spec/ecsm.md and docs/spec/spec_full.md).
| q_2 &= #`r` + p^(-1) dot (lambda (x_A - x_R) - y_A - y_R)\ | ||
| $ | ||
| from which we can conclude that $q'_0, q_2 in (#`r`-p, #`r`+p)$ and $q'_1 in (#`r`, #`r` + p)$. | ||
| When doubling, only the formulae for $lambda$ and $x_R$ are different: |
Review SummaryThis PR adds the ECSM (Elliptic Curve Scalar Multiply) accelerator specification — covering the ECSM, ECDAS, and EC_SCALAR chips — along with TOML/Typst sources, regenerated Markdown outputs, and two rendering bug fixes. Fixes (correct)Nested-subtraction parenthesisation — both the Python fix (
Signatures rendering — the new Issues found
Spec correctness notes
|
Summary
docs/spec/ecsm.mdanddocs/spec/spec_full.mdround - (1 - next_op)keep their parenthesesNotes
The nested-subtraction fix corrects the generated ECDAS send interaction from the misleading
round - 1 - next_oprendering toround - (1 - next_op), matching the TOML expression semantics and the prover implementation.Validation
python3 scripts/typst_to_md.py --output-dir docs/spec