Skip to content

Thread the issuer/root curve through the verifier bridge — new WASM no longer infers curve from key length (Ed25519 verification will break) #7

Description

@bordumb

Summary

The auths-verifier WASM is moving to carry a public key's curve in-band instead of inferring it from byte length. The attestation/chain verify functions are gaining an explicit curve argument that defaults to P-256 when omitted (no more length inference). This widget calls those functions without a curve and verifies Ed25519 attestations, so once the new WASM is vendored, Ed25519 verification will fail — a 32-byte key parsed as P-256 is rejected.

Current state / blast radius

  • Not broken today. The widget ships a pre-built WASM in wasm/ that predates the change.
  • It breaks the moment that bundle is rebuilt from the updated auths-verifier and re-vendored, unless we thread the curve through first.
  • src/resolvers/did-utils.ts (lines ~6-7) even documents the old contract: "the WASM verifier resolves the curve from that length." That assumption is going away.

Break mechanism

  • New WASM signatures: verifyAttestationJson(json, pk, curve?), verifyChainJson(arr, pk, curve?), verifyAttestationWithResult(json, pk, curve?), verifyChainWithWitnesses(…, curve?). With curve absent → defaults to P-256, no length inference.
  • src/verifier-bridge.ts calls these with 2 args (≈ lines 88, 111, 141, 154). Missing curveundefined → P-256.
  • The widget's fixtures are all 32-byte Ed25519 issuer keys (tests/fixtures/attestation.fixture.js), so try_new(P256, 32 bytes) fails → verification breaks.

Fix (curve-agnostic — no guessing)

The widget already knows each key's curve: didKeyToPublicKeyHex (src/resolvers/did-utils.ts) decodes the multicodec varint (0xED 0x01 → Ed25519, 0x80 0x24 → P-256) and currently discards the curve. Surface it and pass it through:

  1. src/resolvers/did-utils.ts — have didKeyToPublicKeyHex (and cesrToPublicKeyHex) also return the curve (e.g. { hex, curve: 'ed25519' | 'p256' }), or add a sibling that returns it. Update the stale comment that says the WASM infers curve from length.
  2. src/verifier-bridge.ts — thread curve into verifyAttestation / verifyChain / verifyAttestationJson / verifyChainJson and pass it as the new WASM argument. Add curve?: string | null to the WasmModule interface (≈ lines 18-20).
  3. packages/auths-verifier-ts (in the auths repo) — mirror the same change; it also calls the verify functions with 2 args (src/index.ts ≈ 144, 189).
  4. Re-vendor the rebuilt WASM + .d.ts (wasm/auths_verifier.*).

Acceptance criteria

  • Ed25519 and P-256 attestations/chains verify correctly through the widget against the rebuilt WASM.
  • No curve is inferred from key length anywhere in the JS path; the curve is derived from the issuer/root did:key (or CESR) and passed explicitly.
  • verifier-bridge tests + the regression tests cover both curves.

Context

Upstream is the auths-verifier FFI/WASM curve hardening (carry the curve in-band rather than dispatching on byte length, which is ambiguous — 32 bytes is Ed25519 vs X25519, 33 is P-256 vs secp256k1). This issue tracks the widget-side follow-through so the WASM rebuild doesn't silently break Ed25519 verification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions