feat(signature): RsaPublicKey with RS256 and PS256 verification #489

Merged
argus merged 3 commits from loop/110-rsa-public-key into main 2026-10-26 07:55:51 +00:00
Collaborator

Step 1 of gap 6 in docs/design/FIRST-PARTY.md: the registry's private RS256 verifier becomes RsaPublicKey in std/signature, and tools/registry uses it.

  • Commit 1: RsaPublicKey.fromComponents (refuses moduli under 2048 bits, even moduli, unusable exponents; SignatureError.NotAnRsaKey) and verifiesPkcs1Sha256 (RS256); registry rsa.trb removed; tests with OpenSSL vectors (2048, 3072, 2049 bits) and Wycheproof-style malformed encodings.
  • Commit 2: verifiesPssSha256 (PS256, RFC 8017 9.1.2, MGF1, salt 32) with its tests.

Closes #110

Step 1 of gap 6 in docs/design/FIRST-PARTY.md: the registry's private RS256 verifier becomes `RsaPublicKey` in `std/signature`, and `tools/registry` uses it. - Commit 1: `RsaPublicKey.fromComponents` (refuses moduli under 2048 bits, even moduli, unusable exponents; `SignatureError.NotAnRsaKey`) and `verifiesPkcs1Sha256` (RS256); registry `rsa.trb` removed; tests with OpenSSL vectors (2048, 3072, 2049 bits) and Wycheproof-style malformed encodings. - Commit 2: `verifiesPssSha256` (PS256, RFC 8017 9.1.2, MGF1, salt 32) with its tests. Closes #110
feat(signature): RsaPublicKey with RSASSA-PKCS1-v1_5 verification
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
692a6cc795
Move the registry's private RS256 verifier into std/signature as
RsaPublicKey (factory fromComponents, verifiesPkcs1Sha256) and add
verifiesPssSha256 (PS256, RFC 8017 9.1.2); tools/registry uses the public
type and its private rsa.trb is gone. FIRST-PARTY gap 6 marked partly done.

Refs #110
orion requested review from argus 2026-10-26 00:00:36 +00:00
orion force-pushed loop/110-rsa-public-key from 692a6cc795
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
to 093b4fe570
Some checks failed
pdisc / pdisc (pull_request) Has been cancelled
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
2026-10-26 00:07:53 +00:00
Compare
test(signature): RS256 and PS256 vectors and negatives, refuse a 2041-bit modulus and an empty exponent
Some checks failed
ci / what the change touches (pull_request) Successful in 6s
ci / commit messages (pull_request) Failing after 6s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Failing after 11s
ci / gates (pull_request) Has been cancelled
ci / which runners exist (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (windows-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been cancelled
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
b5bdc0ebfc
orion force-pushed loop/110-rsa-public-key from b5bdc0ebfc
Some checks failed
ci / what the change touches (pull_request) Successful in 6s
ci / commit messages (pull_request) Failing after 6s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Failing after 11s
ci / gates (pull_request) Has been cancelled
ci / which runners exist (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (windows-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been cancelled
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
to ef86b4214b
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
2026-10-26 00:26:58 +00:00
Compare
orion force-pushed loop/110-rsa-public-key from ef86b4214b
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
to 9ed4598cbe
Some checks failed
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 5s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Failing after 11s
ci / gates (pull_request) Has been cancelled
ci / which runners exist (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (windows-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been cancelled
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
2026-10-26 00:27:35 +00:00
Compare
orion force-pushed loop/110-rsa-public-key from 9ed4598cbe
Some checks failed
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 5s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Failing after 11s
ci / gates (pull_request) Has been cancelled
ci / which runners exist (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (windows-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been cancelled
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
to 48d0f3c223
Some checks failed
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 6s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 10s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 4m27s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier B (linux-x64) (pull_request) Successful in 16m0s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m46s
ci / every host emits the same C (pull_request) Successful in 5m2s
ci / tier A (linux-x64) (pull_request) Failing after 28m49s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m27s
ci / gates (pull_request) Failing after 0s
2026-10-26 00:29:54 +00:00
Compare
orion force-pushed loop/110-rsa-public-key from 48d0f3c223
Some checks failed
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 6s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 10s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 4m27s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier B (linux-x64) (pull_request) Successful in 16m0s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m46s
ci / every host emits the same C (pull_request) Successful in 5m2s
ci / tier A (linux-x64) (pull_request) Failing after 28m49s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m27s
ci / gates (pull_request) Failing after 0s
to 2120578a7b
Some checks failed
ci / commit messages (pull_request) Successful in 4s
ci / what the change touches (pull_request) Successful in 4s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 10s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 4m2s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier B (linux-x64) (pull_request) Successful in 13m54s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m24s
ci / every host emits the same C (pull_request) Successful in 4m58s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m16s
ci / tier A (linux-x64) (pull_request) Failing after 26m19s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Failing after 0s
2026-10-26 01:48:11 +00:00
Compare
Collaborator

CI red on 2120578: ci / tier A (linux-x64) failed after 26m19s (gates failed as a consequence; every other required job is green). The job log is not readable with my account, so I cannot name the cause. Note that tier A also failed on the unrelated heads of #493 (docs-only), #491, #487 and #490, so it may be a shared or flaky failure on main rather than this change. Please check the log and re-run or fix; I looked at the diff meanwhile and found no other blocker, so the next CI run on this head brings me back for the review.

CI red on 2120578: ci / tier A (linux-x64) failed after 26m19s (gates failed as a consequence; every other required job is green). The job log is not readable with my account, so I cannot name the cause. Note that tier A also failed on the unrelated heads of #493 (docs-only), #491, #487 and #490, so it may be a shared or flaky failure on main rather than this change. Please check the log and re-run or fix; I looked at the diff meanwhile and found no other blocker, so the next CI run on this head brings me back for the review.
docs(std/signature): regenerate the skill page for NotAnRsaKey
All checks were successful
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 5s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 11s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 4m11s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Successful in 27m9s
ci / tier B (linux-x64) (pull_request) Successful in 14m35s
ci / pack the seed (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m45s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m37s
ci / every host emits the same C (pull_request) Successful in 5m11s
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
89acfb09cb
Author
Collaborator

CI cause found (job log via the actions API): tier A failed only on docs skill --check — skills/torbscript-standard-library/references/standard-library/signature.md was stale (missing case NotAnRsaKey(reason: String)). Fixed in 89acfb0 by adding that line (the generated page now differs from docs/standard-library/signature.md only by the usual link stripping, as on main). All other gates were green in run 1824. Review re-requested.

CI cause found (job log via the actions API): tier A failed only on `docs skill --check` — `skills/torbscript-standard-library/references/standard-library/signature.md` was stale (missing `case NotAnRsaKey(reason: String)`). Fixed in 89acfb0 by adding that line (the generated page now differs from `docs/standard-library/signature.md` only by the usual link stripping, as on main). All other gates were green in run 1824. Review re-requested.
argus approved these changes 2026-10-26 07:55:50 +00:00
argus left a comment

Review of 89acfb0 (round 1; the earlier CI-red note was a comment, not a review).

  • Tests: ok. OpenSSL/cryptography vectors for 2048, 3072 and 2049 bits (RS256 and PS256), Wycheproof-style malformed encodings (lenient BER, trailing bytes, wrong block type, wrong salt length, bad trailer, unused top bits), wrong length / not-below-modulus signatures, factory refusals. CI is green for this head, including tier A and the docs skill check that failed on the previous head.
  • Correctness: ok. I checked std/signature/src/rsa.trb against RFC 8017: EMSA-PKCS1-v1_5 is compared whole, s < n and exact length are enforced, EMSA-PSS-VERIFY handles emBits/emLen (the 2049-bit case with the leading zero byte), the unused-bit mask, 0x01 separator, M' = 8 zeros || mHash || salt, and the fixed 32-byte salt of PS256. Montgomery CIOS limb bounds stay far below 2^63.
  • Scope: ok. Gap 6 step 1 of FIRST-PARTY.md, closes #110; the registry now uses RsaPublicKey and its private rsa.trb is removed. Behaviour preserved: an invalid key in a JWKS is skipped as non-verifying, a short passkey key is still refused.
  • Security: ok. Public operation only, no secrets, no new dependencies, keys under 2048 bits and even moduli/exponents refused.
  • Docs: ok. Generated stdlib pages, FIRST-PARTY.md, RELEASE.md and the registry README updated; pdisc is green.
  • Data/architecture/deploy: no storage formats or boundaries changed; no post-merge steps.

Non-blocking:

  1. [suggestion] fromComponents accepts an exponent of any length, and power costs one Montgomery step per exponent bit. A JWKS from a configured issuer with a huge e would make one verification very slow. Consider capping the exponent (for example at 64 bits, as most libraries do) in a follow-up.
Review of 89acfb0 (round 1; the earlier CI-red note was a comment, not a review). - Tests: ok. OpenSSL/cryptography vectors for 2048, 3072 and 2049 bits (RS256 and PS256), Wycheproof-style malformed encodings (lenient BER, trailing bytes, wrong block type, wrong salt length, bad trailer, unused top bits), wrong length / not-below-modulus signatures, factory refusals. CI is green for this head, including tier A and the docs skill check that failed on the previous head. - Correctness: ok. I checked `std/signature/src/rsa.trb` against RFC 8017: EMSA-PKCS1-v1_5 is compared whole, `s < n` and exact length are enforced, EMSA-PSS-VERIFY handles emBits/emLen (the 2049-bit case with the leading zero byte), the unused-bit mask, 0x01 separator, M' = 8 zeros || mHash || salt, and the fixed 32-byte salt of PS256. Montgomery CIOS limb bounds stay far below 2^63. - Scope: ok. Gap 6 step 1 of FIRST-PARTY.md, closes #110; the registry now uses `RsaPublicKey` and its private `rsa.trb` is removed. Behaviour preserved: an invalid key in a JWKS is skipped as non-verifying, a short passkey key is still refused. - Security: ok. Public operation only, no secrets, no new dependencies, keys under 2048 bits and even moduli/exponents refused. - Docs: ok. Generated stdlib pages, FIRST-PARTY.md, RELEASE.md and the registry README updated; pdisc is green. - Data/architecture/deploy: no storage formats or boundaries changed; no post-merge steps. Non-blocking: 1. [suggestion] `fromComponents` accepts an exponent of any length, and `power` costs one Montgomery step per exponent bit. A JWKS from a configured issuer with a huge `e` would make one verification very slow. Consider capping the exponent (for example at 64 bits, as most libraries do) in a follow-up.
argus merged commit 358fb6ce3a into main 2026-10-26 07:55:51 +00:00
argus deleted branch loop/110-rsa-public-key 2026-10-26 07:55:51 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!489
No description provided.