Skip to content

Open question: add P-256/ES256 as a second signing curve? #78

Description

@LKSNDRTMLKV

Open question, deliberately not scheduled. Recorded so the answer is found rather than re-derived, and so nobody adds a second curve by accident while writing a mapper.

Recorded in an internal architecture decision record, 2026-07-31.

Where this stands

We sign with Ed25519/EdDSA only. is_allowed_alg is a one-element allowlist by design (crates/dpp-crypto/src/jws/algorithm.rs), which makes JWS algorithm confusion impossible by construction.

Checked against primary sources on 2026-07-31, nothing we are building requires P-256:

Source Requirement
UNTP Verifiable Credentials profile MUST use enveloping VC-JOSE-COSE with JOSE; MUST implement did:web. No algorithm named
draft-ietf-oauth-sd-jwt-vc-17 No algorithm mandated. ES256 appears in examples only
W3C Data Integrity eddsa-jcs-2022 / eddsa-rdfc-2022 are the Ed25519 cryptosuites. The embedded form does not force P-256
OpenID4VC HAIP MUST support P-256/ES256 — but scoped to wallet-based issuance and presentation flows
EUDI Wallet ARF ES256/384/512 — same wallet ecosystem

Every hard ES256 requirement sits in the wallet ecosystem. Nothing in the doors we are building does.

The trigger that reopens this

We commit to the EUDI wallet / OpenID4VC ecosystem — issuing into a wallet over OpenID4VCI, or accepting OpenID4VP presentations. That is a product decision about which ecosystem we sell into, not a cryptographic one.

Weaker secondary trigger: an integrator presents a verifier that is ES256-only and will not change. That is a data point, not a mandate — the response might be a hosted verification endpoint rather than a second curve.

The one risk not retired

🔶 We never measured how many real VC verifiers accept EdDSA. "Much of the ecosystem is ES256" is asserted in two planning docs and neither cites anything. EdDSA is RFC 8037 and mainstream JOSE libraries implement it, so the expectation is that this is fine — but it is an expectation, not a measurement, and it is the single thing that could make that record wrong.

Cheap way to retire it: the UNTP plan's merge gate already requires verifying our credential with an off-the-shelf JOSE library, not our own verifier. Do that check on day one of that work rather than at the end. One afternoon, and it either confirms the decision or fires the trigger before anything is built on top of it.

What must be true before this is picked up

The algorithm-agile key shape (the key-shape work) has to land first, and it is breaking:

  • KeyEntry (crates/dpp-crypto/src/keystore/entry.rs) is a pub struct of concrete ed25519_dalek types
  • PublicKeyInfo (crates/dpp-crypto/src/keystore/store.rs) carries no algorithm, so dpp-vc's DID builder cannot know which JWK shape to emit

The persisted format is already agile — KeyRecord::algorithm exists with a serde default for pre-agility stores — so the keystore data migration is not a concern. Once the shape lands, adding a curve is genuinely additive and this issue becomes a normal feature.

What it will cost when the trigger fires

  • Algorithm confusion becomes reachable. Mitigated by binding alg to KeyRecord::algorithm, never the JWS header — which is part of the shape work, not this
  • Signature length stops discriminating — a P-256 JOSE signature is also 64 bytes (r‖s), same as Ed25519, so the [u8; 64] check silently stops being a type check
  • No verify_strict analogue — Ed25519's RFC 8032 §8 strictness has no P-256 equivalent; ECDSA needs low-s normalisation instead, separately written and tested
  • Cross-curve rotation is undefined, and did:web documents would carry mixed-curve verification methods
  • A p256 dependency on the crate a recent crate-boundary decision just made a zero-workspace-dependency leaf

Out of scope in any case: dpp-rules's JwsVerify::verify_eddsa. Plugin-bundle signing is a separate trust domain and can stay Ed25519-only indefinitely; generalising it needs its own reason.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions