Skip to content

keys: VerifyingKey.precompute() works for keys built from bytes, PEM or DER - #382

Open
fametrano wants to merge 1 commit into
tlsfuzzer:masterfrom
fametrano:precompute-after-from-string
Open

fametrano wants to merge 1 commit into
tlsfuzzer:masterfrom
fametrano:precompute-after-from-string

Conversation

@fametrano

@fametrano fametrano commented Sep 7, 2026 •

Copy link
Copy Markdown

On the Weierstrass curves, VerifyingKey.precompute() raises AssertionError for every key built with from_string, from_pem or from_der. On 0.19.2:

built with precompute()
SigningKey.from_secret_exponent(...).verifying_key works
VerifyingKey.from_string(raw) / from_string(compressed) AssertionError
VerifyingKey.from_pem(...) / from_der(...) AssertionError

Cause: from_string calls PointJacobi.from_bytes without order, so point.order() is None; precompute() then hits assert order in _maybe_precompute. from_pem and from_der go through from_string. Keys from a SigningKey or from signature recovery carry the order and are not affected; EdDSA keys take a separate branch.

Fix: pass order=curve.order (one line). Test: precompute() then verify() after each of the four constructions; it fails on master and passes with the fix. Full suite: 2040 passed.

The docstring says to call precompute() when verifying hundreds of signatures under one key. A caller in that case usually has the key as bytes, PEM or DER, which is where precompute() fails. Measured on secp256k1, a verification drops from about 1057 µs to 501 µs with the table.

Written with LLM, a computer and the Internet; the mistakes, as usual, are all mine.

VerifyingKey.from_string built the public point without the curve
order, so on the Weierstrass curves precompute() failed with
AssertionError for every key built from bytes, PEM or DER, the
last two going through from_string. A verifying key obtained from
a SigningKey, or from signature recovery, carries the order and
could be precomputed.

Pass the order to PointJacobi.from_bytes and test precompute()
after each of the four constructions.
@fametrano

Copy link
Copy Markdown
Author

@tomato42 the two workflow runs on this PR (GitHub CI and CodeQL) have been waiting for approval since I opened it, so CI has not run here yet — it is my first PR to this repo. Could you approve them?

Re-checked today on the current tip 02c9cb7, which is up to date with master: the full suite gives 2040 passed, 5 skipped.

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.

1 participant