fix: bind RSA public exponent to fixed values [LA-E]#366
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Addresses LA-E by preventing RSA signature verification from using an attacker-chosen exponent witness that isn’t cryptographically bound to the authenticated certificate/key material.
Changes:
- Introduces an RSA exponent allowlist and enforces it across RSA verification paths.
- Binds
(n, e)together in the CSC→DSC path via a Poseidon2 commitment (compute_key_ne_hash) checked against a public input. - Binds DSC exponent to authenticated TBS bytes in the DSC→SOD path by byte-comparing exponent bytes at a prover-supplied offset.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| noir-examples/noir-passport/utils/sig-check/rsa/src/lib.nr | Adds exponent allowlist enforcement, introduces (n||e) Poseidon2 hash (compute_key_ne_hash), and tests for exponent allowlist. |
| noir-examples/noir-passport/utils/sig-check/rsa/Nargo.toml | Adds Poseidon dependency for the new key hash. |
| noir-examples/noir-passport/utils/sig-check/fragmented-rsa/src/lib.nr | Enforces allowed RSA exponent in fragmented RSA verification. |
| noir-examples/noir-passport/utils/sig-check/fragmented-rsa/Nargo.toml | Adds dependency on common for exponent allowlist. |
| noir-examples/noir-passport/utils/sig-check/common/src/lib.nr | Introduces assert_allowed_rsa_exponent allowlist helper. |
| noir-examples/noir-passport/utils/data-check/tbs-pubkey/src/lib.nr | Extends TBS pubkey check to include exponent value-byte comparison at an offset; adds unit tests. |
| noir-examples/noir-passport/utils/data-check/tbs-pubkey/Nargo.toml | Renames package and adds common dependency. |
| noir-examples/noir-passport/merkle_age_check/t_add_id_data_720/src/main.nr | Adds exponent + offset inputs and verifies exponent bytes are present in authenticated TBS. |
| noir-examples/noir-passport/merkle_age_check/t_add_id_data_1300/src/main.nr | Same as 720 variant for the 1300-byte TBS circuit. |
| noir-examples/noir-passport/merkle_age_check/t_add_dsc_720/src/main.nr | Adds csc_key_ne_hash public input and checks it against Poseidon hash of (n,e). |
| noir-examples/noir-passport/merkle_age_check/t_add_dsc_verify_1300/src/main.nr | Same CSC key (n,e) hash assertion for the 1300-byte fragmented flow. |
| noir-examples/noir-passport/merkle_age_check/t_add_dsc_verify_1300/Nargo.toml | Adds dependency on sig_check_rsa for compute_key_ne_hash. |
| noir-examples/noir-passport/merkle_age_check/benchmark-inputs/tbs_720/t_add_id_data_720.toml | Adds exponent and exponent offset inputs to match circuit ABI changes. |
| noir-examples/noir-passport/merkle_age_check/benchmark-inputs/tbs_720/t_add_dsc_720.toml | Adds csc_key_ne_hash to benchmark inputs. |
| noir-examples/noir-passport/merkle_age_check/benchmark-inputs/tbs_1300/t_add_id_data_1300.toml | Adds exponent and exponent offset inputs to match circuit ABI changes. |
| noir-examples/noir-passport/merkle_age_check/benchmark-inputs/tbs_1300/t_add_dsc_verify_1300.toml | Adds csc_key_ne_hash to benchmark inputs and reorders inputs accordingly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
51fb2d4 to
f308e93
Compare
dcbuild3r
pushed a commit
that referenced
this pull request
May 16, 2026
fix: bind RSA public exponent to fixed values [LA-E]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes LA-E: Unbound RSA Exponent Witness Enables Forged Passport Signature Verification.
A malicious prover could supply
exponent = 1(or any arbitrary value) as afree witness. With
e = 1, RSA verification degenerates tosig^1 mod n = sig,so a prover can forge a valid PKCS#1 v1.5 message without knowledge of any
private key.
Changes
DSC → SOD path (
t_add_id_data_720,t_add_id_data_1300)verify_rsa_pubkey_in_tbsnow acceptsexponentandexponent_offset_in_dsc_certas inputs and byte-compares the claimed exponent value against the authenticated
TBS certificate bytes at the given offset, mirroring the existing modulus check.
the prover cannot alter its bytes.
CSC → DSC path (
t_add_dsc_720,t_add_dsc_verify_1300)compute_key_ne_hash, which produces aPoseidon2 hash over
(modulus || exponent)asserted against the public inputcsc_key_ne_hash. The prover cannot substitute an alternative exponent withoutinvalidating this commitment.
Exponent allowlist (
assert_allowed_rsa_exponent)verify_rsa_pubkey_in_tbsandcompute_key_ne_hash, blockinge = 1,e = 2, and all values outside the set of known ICAO-compliantexponents
{3, 38129, 56611, 65537, 107903, 109729, 122125, 130689}.