Skip to content

fix: bind RSA public exponent to fixed values [LA-E]#366

Merged
ashpect merged 1 commit into
v1from
us/fix-unbound-rsa-exponent
Mar 27, 2026
Merged

fix: bind RSA public exponent to fixed values [LA-E]#366
ashpect merged 1 commit into
v1from
us/fix-unbound-rsa-exponent

Conversation

@x-senpai-x
Copy link
Copy Markdown
Collaborator

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 a
free witness. With e = 1, RSA verification degenerates to sig^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_tbs now accepts exponent and exponent_offset_in_dsc_cert
    as inputs and byte-compares the claimed exponent value against the authenticated
    TBS certificate bytes at the given offset, mirroring the existing modulus check.
  • The TBS certificate is authenticated by the preceding CSCA signature step, so
    the prover cannot alter its bytes.

CSC → DSC path (t_add_dsc_720, t_add_dsc_verify_1300)

  • The CSCA exponent is now included in compute_key_ne_hash, which produces a
    Poseidon2 hash over (modulus || exponent) asserted against the public input
    csc_key_ne_hash. The prover cannot substitute an alternative exponent without
    invalidating this commitment.

Exponent allowlist (assert_allowed_rsa_exponent)

  • Added to both verify_rsa_pubkey_in_tbs and compute_key_ne_hash, blocking
    e = 1, e = 2, and all values outside the set of known ICAO-compliant
    exponents {3, 38129, 56611, 65537, 107903, 109729, 122125, 130689}.

Copilot AI review requested due to automatic review settings March 22, 2026 08:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread noir-examples/noir-passport/utils/data-check/tbs-pubkey/src/lib.nr
Comment thread noir-examples/noir-passport/utils/sig-check/rsa/src/lib.nr Outdated
Comment thread noir-examples/noir-passport/utils/sig-check/rsa/src/lib.nr
@x-senpai-x x-senpai-x force-pushed the us/fix-unbound-rsa-exponent branch from 51fb2d4 to f308e93 Compare March 27, 2026 06:02
@ashpect ashpect merged commit 05f2f21 into v1 Mar 27, 2026
1 of 3 checks passed
dcbuild3r pushed a commit that referenced this pull request May 16, 2026
fix: bind RSA public exponent to fixed values [LA-E]
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.

3 participants