Skip to content

Proposal: Post-Quantum Extension to AP2 (ML-DSA-65 / FIPS 204) #250

Open

Description

@rayc0

Problem

AP2 v0.1 mandates RFC 8785 JCS canonicalization for mandate signatures (excellent design choice — it makes cross-platform verification deterministic). However, the signing algorithm is left to implementers, defaulting to classical ECDSA. For financial institutions deploying AP2 in regulated jurisdictions, this creates a timing problem: payment authorization mandates must be retained for 6–7 years under HKMA (Cap. 615, IRD Cap. 112), EU DORA, and comparable frameworks. NIST IR 8547 (2024) identifies 2030 as the urgent migration deadline for classical cryptography in high-priority systems. The Bank of Israel issued a quantum preparedness directive in 2024 requiring licensed PSPs to submit PQ migration plans; HKMA announced its Quantum Preparedness Index on February 3, 2026. Classical-only ECDSA mandates committed to immutable audit ledgers today may be within their mandatory retention window when cryptographically-relevant quantum computers become available — enabling retrospective signature forgery on financial records. This is not a theoretical concern for ephemeral web tokens; it is a concrete compliance risk for long-lived financial authorization records.

Proposed Solution

We propose two backward-compatible optional fields for AP2 mandates:

  1. signature_algorithm: "ECDSA" | "ML-DSA-65" | "Ed25519" (default "ECDSA" — no change for existing implementations)
  2. pq_signature?: { algorithm: "ML-DSA-65", value: "<3309-byte signature as hex>" } (optional dual-layer signature for regulated deployments)

Because AP2 already mandates JCS (RFC 8785), adding ML-DSA-65 requires no new canonicalization logic — the same canonical byte string feeds both the ECDSA and ML-DSA-65 signing operations. This is unusually clean: AP2's JCS mandate makes ML-DSA-65 integration simpler here than in nearly any other protocol.

We are not proposing that ML-DSA-65 become mandatory for all AP2 deployments. We are proposing it as an optional, clearly-specified extension path for regulated financial deployments that have an active compliance obligation — and making the reference implementation available to the community now.

Live reference implementation

Questions for Maintainers

  1. Is there a preferred format for spec extension proposals (GitHub Issue, PR against spec.md, or AAIF working group submission)?
  2. Has the AP2 team discussed ML-DSA-65 or any PQ algorithm internally? We want to avoid duplicating work.
  3. Is there an AAIF Linux Foundation working group where this extension should be filed simultaneously?

Authors / Availability

Raymond Chau and Tris Au Yeung (PQSafe AgentPay, Hong Kong). Available for an AAIF or AP2 maintainer call any week during May or June 2026.

Contact: raymond@pqsafe.xyz

Activity

  1. chopmob-cloud commented on May 16, 2026

    @chopmob-cloud

    Strong proposal. We run a different lattice scheme in production (Falcon-1024 / FN-DSA / FIPS 206 on Algorand PQC accounts) and the cross-implementor convergence pattern you're proposing maps cleanly onto the open-enum signature_algorithm field shape that's already locking into the wider agentic-payments spec work.

    Cross-implementation operational data point

    AlgoVoi runs Falcon-1024 for Algorand mainnet PQC accounts as a parallel production signing path alongside Ed25519. Confirming three of your design choices from a different-scheme-but-same-objective angle:

    JCS makes adding any PQC scheme unusually clean. This is right and underrated in your problem statement. We hit the same conclusion when adding Falcon: the canonical-bytes-then-sign pipeline is scheme-agnostic, so plugging in a second signature_algorithm doesn't require re-canonicalising or re-encoding the payload. The signed input is the same regardless of which primitive you reach for. This is exactly the alignment point I called out in our #2322 reply on the wider 4-class canonicalisation convergence: "signature_algorithm is a routing hint, not a canonicalisation variant."

    Backward-compat default ECDSA + optional pq_signature is the right transition shape. We landed an identical pattern for HMAC at the internal-channel level — v1=HMAC-SHA-256 stays default, v2=HMAC-SHA-384 derives an HKDF sub-key and is optional dual-version. Same migration story: deployments that have a compliance trigger (PSD2 SCA evolution, retention-horizon retrofit) flip to v2; deployments that don't can keep v1 indefinitely. No forced cutover. Your pq_signature? field carries the same "additive, optional, never breaks the v1 verifier" property. Production-tested in our HMAC channel migration since 2026-05-03 (per our PQC Tier 2A rollout).

    Signature size as a real implementation constraint. ML-DSA-65 at 3309 bytes per signature vs Falcon-1024 at ~1280 bytes is a real trade-off worth surfacing in the spec text non-normatively. ML-DSA is significantly easier to implement correctly (Module-LWE arithmetic, no Gaussian sampling); Falcon is more compact but harder to get constant-time right. For AP2 mandates retained 7 years across regulated jurisdictions, the implementation-correctness argument probably wins (rare side-channel in a long-retained signature is worse than an extra 2 KB per record). The fact that you're shipping ML-DSA-65 rather than Falcon for this is the right choice for the AP2-mandate use case specifically.

    Direct answers to your three questions

    Q1 — Preferred format for spec extension proposals. Per the CONTRIBUTING.md note that @hilarl surfaced in #255, the AP2 core specification has been donated to FIDO. This repo is samples / SDK only. So:

    • Filing the proposal here (as you have) is correct for AP2 sample / SDK alignment feedback (which is what you'll get below)
    • The core normative spec change probably belongs in the FIDO working group submission
    • For follow-up coordination with the wider agentic-payments spec ecosystem (x402-foundation, tempoxyz/mpp-specs, a2aproject/A2A), filing parallel issues with cross-references works — that's what we've been doing for the 4-class JCS canonicalisation convergence

    Q2 — Has the AP2 team discussed ML-DSA-65 or any PQ algorithm internally? Don't know from outside, but a useful adjacent data point: the 4-class evidence taxonomy work in x402-foundation/x402 (#2322 Compliance category, #2334 privacy_class) just locked the signature_algorithm field as an open enum specifically to allow PQC primitives to plug in alongside classical schemes without spec churn. So at the cross-protocol layer, the open-enum approach you're proposing here is the agreed direction. Three named implementors operating production traffic (AlgoVoi, nobulex, tooloracle) are aligned on it.

    Q3 — AAIF Linux Foundation working group. Same answer as Q1 — the FIDO submission is the canonical path per CONTRIBUTING.md. The AAIF working group (if it's the AI Alliance + Hyperledger track I'm thinking of) is parallel to FIDO not nested under it; both submissions can coexist as long as the cross-references are explicit.

    Concrete coordination point

    The signature_algorithm field shape locking in across the ecosystem suggests an even cleaner spec text than your draft proposes:

    # Your draft:
    signature_algorithm: "ECDSA" | "ML-DSA-65" | "Ed25519"
    
    # Cross-spec aligned (open enum, implementor-extensible):
    signature_algorithm: string
    # Implementors MAY declare any value. Verifiers MUST treat unknown values
    # as opaque and refuse to verify. Recommended values (informative):
    #   - "ECDSA" (default, classical)
    #   - "Ed25519" (classical, ed25519)
    #   - "ML-DSA-65" (FIPS 204, PQ)
    #   - "Falcon-1024" (FIPS 206 / FN-DSA, PQ)
    #   - "HMAC-SHA-256" (HMAC-based, classical)
    #   - "HMAC-SHA-384" (HMAC-based, PQC-conservative)
    #   - "ES256K" (classical, secp256k1)

    The open-enum shape lets PQC schemes other than ML-DSA-65 (Falcon, SPHINCS+, FrodoKEM, any future NIST round) participate without spec PRs. Same reason the open-enum disclosure_policy and framework fields in #2322 / #2334 are designed this way: jurisdictional and cryptographic evolution outpaces spec PR cycles.

    Compliance-frame alignment

    Confirming your retention-horizon concern from a different jurisdiction's angle:

    Jurisdiction Retention requirement Your kCAB-relevant frame?
    HKMA Cap. 615 / IRD Cap. 112 6-7 years Your direct frame
    UK EMR 2011 reg 20-21 + UK MLR 2017 5 years minimum Our APM safeguarding posture
    EU AMLR (2024/1624) Art. 56 5 years (10 extended) Our regulatory-class evidence work in #2322
    EU MiCA Art. 80 5 years Same
    EU DORA Art. 14 3 years operational + 5 years incident-related Same
    FINMA / EBA equivalents 5-10 years Cross-EU

    All in the same band. Same retrospective-forgery risk profile. Same "classical-signed records committed to immutable ledgers today may be within mandatory retention window when CRQC arrives" argument applies across all jurisdictions. Your problem-statement framing transfers cleanly to non-HK regulated deployments.

    Direct collaboration offer

    Three things I'd be happy to do as a follow-up if useful:

    1. Update our AP2 sample PRs (#218 Algorand, #228 Solana) to emit a signature_algorithm field per your proposal — would carry "Falcon-1024" for the Algorand path and "Ed25519" for the Solana path, demonstrating cross-scheme operational use of the same field shape
    2. Cross-link our PR #253 JCS canonicalisation work with your ML-DSA-65 reference implementation so a single test suite can validate both ECDSA-over-JCS and ML-DSA-65-over-JCS on the same mandate payload
    3. Co-author a brief AAIF / FIDO coordination note if the spec submission is going forward — having two named implementors (PQSafe + AlgoVoi) with shipped PQC code on different schemes is a stronger submission than a single-implementor proposal

    The Hong Kong + UK regulatory frame combined would also strengthen the cross-jurisdiction case if your FIDO submission references multiple PQ-preparedness directives.

    Happy to coordinate on any of these — or to defer until you've heard from AP2 maintainers on Q1-Q3. Either way, this is a high-quality proposal that the agentic-payments ecosystem needs to land.

    Proposal reads ready for serious engagement from our side.

  2. rayc0 commented on May 16, 2026

    @rayc0
    Author

    Thanks for this — it's exactly the kind of independent confirmation that makes a spec proposal credible rather than just advocating.

    A few direct responses, then three concrete next steps.


    On the open-enum signature_algorithm: Agreed, and I'm adopting it. Our closed union ("ECDSA" | "ML-DSA-65" | "Ed25519") was a first-draft simplification that doesn't survive the multi-implementor reality. The normative rule you're proposing — verifiers MUST treat unknown values as opaque and refuse to verify — is the correct fail-closed behaviour. It's equivalent in safety to a closed union for known algorithm values, and it allows the spec to evolve without a breaking schema change. I'll update the AP2-PQ spec text accordingly (diff in a follow-up PR).

    I'll carry the recommended-values list (ML-DSA-65, Falcon-1024, SPHINCS+, HMAC-SHA-256, HMAC-SHA-384, ES256K) as informative, not normative, in the spec — which gives implementors latitude while establishing clear convergence anchors.

    On the ML-DSA-65 / Falcon trade-off acknowledgement: Appreciated. The implementation-correctness argument for ML-DSA-65 in long-retained mandate contexts is specifically the Gaussian sampler side-channel exposure in software Falcon implementations (Guerreau et al. 2022; Karabulut & Aysu 2021). Your Algorand context — dedicated chain accounts with hardware acceleration — is a materially different threat model than a Cloudflare Worker signing mandate records destined for 7-year audit retention. Both choices are defensible given their respective deployment contexts, which is exactly why the spec should be algorithm-agnostic at the wire format layer.

    On the AP2 canonical home (FIDO TWG, not google/A2A repo): Thank you for clarifying this. I had been modelling the google/A2A repo as the normative home and the FIDO TWG submission as a parallel track. Inverting those — FIDO TWG as the normative path for spec extensions, the repo as samples/SDK — changes the filing strategy. The IETF SECDIR Informational RFC I've been drafting (draft-chau-ap2-pq-signed-action-envelope-00) is now clearly the prior-art / implementation-evidence track rather than a normative alternative.

    On the three collaboration offers:

    (a) Updating PRs #218 and #228 to emit signature_algorithm: Yes, please. Once those PRs carry the field, we have two independent samples (Algorand/Falcon-1024 and Solana/Ed25519) already exercising the open-enum path against real AP2 mandate payloads. That's a much stronger "field already works" argument than anything a spec document can assert alone. One coordination note: the signature_algorithm value string format should be identical across both PRs and our ML-DSA-65 implementation — I'd suggest we align on the JWK alg identifier convention (e.g., "ML-DSA-65" matching the COSE/JOSE draft identifiers, "Falcon-1024" pending IETF PQC naming) before the PRs go up, so the three samples are interoperable by construction.

    (b) Cross-linking PR #253 (JCS) with our ML-DSA-65 ref impl for a shared cross-scheme test suite: This is the highest-leverage technical collaboration on the table. If we can produce a single JSON test fixture — one mandate payload canonicalised per RFC 8785 — and assert that ECDSA-over-JCS, ML-DSA-65-over-JCS, and Falcon-1024-over-JCS all produce the expected fingerprint from the same byte-identical canonical form, that fixture becomes the portable interoperability proof for any future AP2-PQ implementor. I have 240 test vectors for the ML-DSA-65 path already (Apache 2.0). We'd need to agree on the fixture schema and I'd add the Falcon-1024 vectors from your side. What does your current test harness look like — direct SHAKE-256 output, or are you wrapping in a higher-level assertion library?

    (c) Co-authoring the FIDO/AAIF coordination note as two named implementors: Yes, and I think this is the correct framing of the submission. A note signed by "PQSafe (ML-DSA-65, Cloudflare Workers, HK regulatory frame) + AlgoVoi (Falcon-1024, Algorand, UK/EU regulatory frame)" presents something qualitatively different from a single-implementor proposal: it's a cross-ecosystem convergence finding. The regulatory table is particularly useful — our HK frame (HKMA Cap.615 7-year retention / IRD Cap.112) + your UK/EU frame (EMR/MLR, AMLR Art.56, MiCA Art.80, DORA Art.14) together cover the primary APAC + European financial-services retention-horizon mandates. That's the jurisdictional surface that makes the CRQC timing argument concrete for FIDO TWG members who are financial-services companies.

    On AAIF vs FIDO — my read: The parallel-track framing is correct. AAIF (Linux Foundation / AI Alliance + Hyperledger) and FIDO TWG serve different governance communities. A coordination note filed at both, with explicit cross-references, is not redundant — it's the standard multi-SDO approach for a primitive that sits at an authentication/payment boundary.


    Proposed concrete next steps:

    1. Align on signature_algorithm string format convention before PRs feat(samples): add human-present crypto-algo scenario (AP2 v0.1 + AlgoVoi on-chain USDC extension) #218 and feat(samples): add human-present crypto-solana scenario (AP2 + Solana Pay reference binding) #228 are updated — I'll open a sub-thread here with a proposed convention table.
    2. Share your test harness structure for the cross-scheme JCS fixture work — GitHub issue thread or repo link is fine.
    3. For the FIDO/AAIF co-authorship note: what's your preferred async channel? GitHub issue thread is fine for technical coordination, but a short video call or Signal/Telegram thread might be faster for the initial scope alignment.

    Looking forward to making this concrete.

    — Raymond Chau / PQSafe
    raymond@pqsafe.xyz

  3. chopmob-cloud commented on May 16, 2026

    @chopmob-cloud

    Three direct answers to the next-steps list, plus a starter convention proposal so we can lock it in this thread rather than passing PR #218/#228 back and forth.

    1. signature_algorithm string format convention

    Aligning on JWK alg identifier convention is the right anchor. Concrete proposal for the recommended-values informative list:

    Identifier Family Source Notes
    ECDSA Classical Generic ECDSA Default for AP2 v0.1 compat
    ES256 Classical RFC 7518 §3.4 ECDSA P-256 SHA-256
    ES256K Classical RFC 8812 secp256k1 SHA-256
    Ed25519 Classical RFC 8032 / RFC 8037 EdDSA Ed25519
    ML-DSA-44 PQC FIPS 204 / draft-ietf-cose-dilithium NIST Level 2
    ML-DSA-65 PQC FIPS 204 / draft-ietf-cose-dilithium NIST Level 3 (your default)
    ML-DSA-87 PQC FIPS 204 / draft-ietf-cose-dilithium NIST Level 5
    Falcon-512 PQC FIPS 206 (FN-DSA) NIST Level 1
    Falcon-1024 PQC FIPS 206 (FN-DSA) NIST Level 5 (our default)
    SLH-DSA-SHA2-128s PQC stateless-hash FIPS 205 SPHINCS+ small
    HMAC-SHA-256 HMAC RFC 2104 Internal-channel only
    HMAC-SHA-384 HMAC RFC 2104 / FIPS 198-1 PQC-conservative HMAC

    Two notes on the table:

    • Falcon naming is Falcon-512 / Falcon-1024 rather than the eventual FN-DSA-512 / FN-DSA-1024 FIPS 206 names. IETF PQC naming hasn't converged yet (cose-dilithium draft uses ML-DSA-N consistently, sphincs draft uses SLH-DSA-N; Falcon is mid-naming-cycle). Pragmatic call: ship under Falcon-1024 now, alias-on-read when the IETF identifier lands, treat the informative list as living.
    • Capitalisation matches the JOSE/COSE drafts (mixed case, hyphenated). Verifiers do case-sensitive string compare per RFC 7517 §4.1.

    We'll emit Falcon-1024 for the Algorand sample (PR #218 update) and Ed25519 for the Solana sample (PR #228 update). If that table works for you, we'll align our PR commits to it before pushing.

    2. Test harness structure

    Current harness shape:

    # Pure-Python, no chain-specific assertion library
    import rfc8785   # pure-Python RFC 8785, v0.1.4
    import hashlib
    
    def canonical_bytes(obj):
        return rfc8785.dumps(obj)  # bytes (UTF-8 JCS)
    
    def jcs_sha256_hex(obj):
        return hashlib.sha256(canonical_bytes(obj)).hexdigest()

    Direct rfc8785 → SHA-256 hex. No higher-level wrapper, no assertion DSL. The canonical_bytes() output is the byte-identical input that all signature schemes consume. The verifier just compares actual vs expected hex per vector and emits a structured pass/fail row.

    Receipt and 14/14 verifier landed at https://gist.github.com/chopmob-cloud/5f35eaa527d292bf3ddc52f8725a85c9 — 4 CTEF v0.3.1 vectors + 10 APS v1 bilateral-delegation vectors, all byte-match through this exact pipeline. Single verify.py (~150 lines) does the whole thing including signature roundtrip on the APS vectors (Ed25519 / RFC 8032 §7.1 Test 1 keypair).

    Two adjacent fixtures just shipped to aeoess/aps-conformance-suite that show the multi-scheme pattern in production:

    • feat: Initial draft of A2A extension specification. #5 (algovoi-proxy-chain) — RFC 9421 + RFC 9530 header survival through the live AlgoVoi 3-hop proxy chain (Cloudflare → nginx → FastAPI), byte-level verified via tcpdump capture on the gateway container. Same JCS pipeline used to compute content-digest.
    • add roadmap with extended details #6 (algovoi-multichain-ed25519) — same A2A payload canonical-bytes consumed by three Ed25519 keys derived from Algorand / Solana / Stellar BIP44 paths. Three signatures, one canonical byte sequence.

    The cross-scheme fixture you're proposing maps onto exactly this pattern: one canonical byte sequence, N signature primitives (ECDSA / Ed25519 / Falcon-1024 / ML-DSA-65) each producing their own signature output, single verifier checks all of them against expected per-scheme outputs.

    Proposed fixture schema (open to revision):

    {
      "vector": "ap2-mandate-pq-crossscheme-1",
      "payload": { ... },
      "canonical_bytes_hex": "...",
      "canonical_sha256_hex": "...",
      "signatures": [
        { "scheme": "ECDSA",        "keyid": "...", "signature_b64": "..." },
        { "scheme": "Ed25519",      "keyid": "...", "signature_b64": "..." },
        { "scheme": "Falcon-1024",  "keyid": "...", "signature_b64": "..." },
        { "scheme": "ML-DSA-65",    "keyid": "...", "signature_b64": "..." }
      ]
    }

    We can supply the canonical bytes, ECDSA, Ed25519, and Falcon-1024 signatures end-to-end on a real AP2 PaymentMandate payload. You supply ML-DSA-65 on the same bytes. Verifier asserts each signature_b64 against its scheme's verify primitive given the corresponding keyid public key.

    Your 240 test vectors for ML-DSA-65 + our Falcon-1024 vectors merged into one fixture set is the deliverable.

    3. Async channel for FIDO/AAIF co-authorship

    GitHub issue thread is fine for the technical coordination — file naming, table content, scope alignment, all benefits from being in-thread and indexable.

    For initial scope alignment that has more back-and-forth (deciding on what regulatory frames to lead with, how to structure the joint authorship attribution, when to file at each SDO), email is faster: chopmob@gmail.com (no Signal/Telegram needed unless either side prefers — happy to set up if useful).

    Suggested first-step: open a dedicated issue on aeoess/aps-conformance-suite (or a new repo if you'd rather not host on aeoess) titled "Cross-scheme JCS PQC fixture (PQSafe + AlgoVoi)" — that's the right venue for the actual fixture-coordination work. The FIDO/AAIF note can be drafted from the same thread once the fixture lands and the table converges.


    Happy to push the signature_algorithm convention table to PR #218 / #228 as soon as you confirm. The cross-scheme fixture work blocks on a venue and a schema lock-in; once those land, we can move concretely.

    — @chopmob-cloud / AlgoVoi

  4. rayc0 commented on May 16, 2026

    @rayc0
    Author

    This locks down cleanly. Confirmations and one venue proposal.

    1. signature_algorithm convention table — confirmed. Adopt the table as the informative recommended-values list in the AP2-PQ spec text. Two small refinements I'd fold in, not blockers:

    • Keep bare ECDSA strictly as the AP2 v0.1 backward-compat alias, and steer new deployments to the specific ES256 / ES256K / Ed25519 identifiers. Bare ECDSA is curve- and hash-ambiguous; fine as a compat shim, not as something to write new code against. I'll annotate it that way in the informative column.
    • Agreed on case-sensitive string compare per RFC 7517 §4.1, and on shipping Falcon-1024 now with alias-on-read once the IETF FIPS-206/FN-DSA identifier converges. Treating the list as living (informative, not normative) is exactly the property that motivated the open-enum in the first place — so this is internally consistent.

    Please go ahead and push the table to PR #218 (Falcon-1024) and #228 (Ed25519). I'll mirror the same identifiers in the ML-DSA-65 reference impl so the three samples are interoperable by construction.

    2. Fixture schema — confirmed, as written. canonical_bytes_hex + canonical_sha256_hex + per-scheme signatures[] keyed by scheme/keyid is the right shape. Division as you proposed: you supply canonical bytes + ECDSA + Ed25519 + Falcon-1024 on a real AP2 PaymentMandate; we supply ML-DSA-65 over the identical canonical byte sequence plus our 240 ML-DSA-65 vectors. Merged set = the deliverable. Your pure-rfc8785 → SHA-256 pipeline matches ours (we run the same RFC 8785 canonical-bytes-then-hash with a cross-language conformance harness across TS/Py/Rust/Go/Java/.NET), so the canonical_sha256_hex anchor should agree byte-for-byte across both sides — that agreement is itself a result worth stating in the joint note.

    3. Venue — proposal. For a fixture set that's going to be cited in a FIDO/AAIF submission, provenance matters, so I'd rather it not live solely under one implementor's existing suite. Proposal: I stand up github.com/PQSafe/ap2-pq-conformance as the canonical home, with you added as co-maintainer, and we import/cross-reference your existing aeoess/aps-conformance-suite vectors rather than fork them. Neutral-ish provenance, both names on it, single citable artifact for the SDO filing. If you'd rather keep gravity on aeoess, dual-homing with one canonical mirror also works — your call, not a blocker. Either way I'll open the dedicated coordination issue ("Cross-scheme JCS PQC fixture (PQSafe + AlgoVoi)") in whichever repo we land on and link it here.

    Channel: in-thread / the coordination issue for the technical lock-in (table, schema, file naming) as you suggested; raymond@pqsafe.xyz ↔ chopmob@gmail.com for the higher-bandwidth scope alignment on the joint note (regulatory frames to lead with, authorship attribution, per-SDO filing sequence).

    Concrete next step on my side: I'll stand up the conformance repo + open the coordination issue, drop the ML-DSA-65 vectors + schema-conformant fixtures in, and link here so you can wire PR #218/#228 against the locked identifiers. Good to proceed.

  5. chopmob-cloud commented on May 16, 2026

    @chopmob-cloud

    Locked across all three points. Two confirmations and one note on what we'll push first.

    1. signature_algorithm table — confirmed with annotation

    Adopting the bare ECDSA annotation refinement verbatim. The compat-shim framing is correct: the JOSE registry has ES256 / ES384 / ES512 / ES256K for the actually-unambiguous identifiers, and bare ECDSA only survives as a courtesy for AP2 v0.1 emitters. New deployments should write against the specific identifiers.

    Final table row for ECDSA in our PR commit message:

    ECDSA — Backward-compat alias for AP2 v0.1 emitters. Curve- and hash-ambiguous. New deployments SHOULD use the specific JOSE identifier (ES256 / ES256K / ES384 / ES512) corresponding to the curve and hash actually in use. Verifiers SHOULD treat bare ECDSA as ES256 only when explicit downgrade-compat with AP2 v0.1 emitters is required.

    PR #218 will land with Falcon-1024 on the Algorand path; PR #228 with Ed25519 on the Solana path. We'll cross-reference your ML-DSA-65 reference impl in both commit bodies so the three-implementor convergence is visible from each PR. Ready to push as soon as the coordination issue opens (so the cross-ref target exists at the moment of commit).

    2. Fixture schema — confirmed as written

    Division of work as you laid it out:

    • AlgoVoi supplies: canonical bytes of a real AP2 PaymentMandate payload, canonical_sha256_hex anchor, plus ECDSA + Ed25519 + Falcon-1024 signatures over those bytes (3 schemes, 3 keypairs, with public-key material captured per-scheme so the verifier can run each primitive's verify function on the corresponding signature).
    • PQSafe supplies: ML-DSA-65 signature over the same canonical bytes + the 240 ML-DSA-65 vector set.

    The cross-implementor canonical_sha256_hex byte-match between AlgoVoi's pure-rfc8785 Python pipeline and PQSafe's multi-language (TS / Py / Rust / Go / Java / .NET) conformance harness running the same RFC 8785 against the same input is itself the headline result of the joint note. Two implementor pipelines, six language runtimes, one canonical byte sequence, identical SHA-256 anchor. That's the "JCS is canonicalisation-substrate-independent" claim made concrete in the cross-language matrix rather than asserted in spec prose.

    Worth adding to the fixture metadata block: a producer_runtime field per signature row capturing which language / library produced each signature, so the cross-language conformance trail is explicit in the fixture itself rather than implicit. Open enum, informative:

    {
      "vector": "ap2-mandate-pq-crossscheme-1",
      "payload": { ... },
      "canonical_bytes_hex": "...",
      "canonical_sha256_hex": "...",
      "signatures": [
        {
          "scheme": "Falcon-1024",
          "keyid": "did:web:api.algovoi.co.uk#falcon-1",
          "public_key_b64": "...",
          "signature_b64": "...",
          "producer_runtime": "python/algovoi-falcon-0.x"
        },
        {
          "scheme": "ML-DSA-65",
          "keyid": "did:web:pqsafe.xyz#mldsa65-1",
          "public_key_b64": "...",
          "signature_b64": "...",
          "producer_runtime": "rust/pqsafe-mldsa-0.x"
        }
      ]
    }

    If that addition works for you, fold it into the schema lock-in on your side; if it adds noise, we can ship without it and the cross-language trail lives in the README instead.

    3. Venue — confirmed, take the PQSafe option

    Accept the github.com/PQSafe/ap2-pq-conformance proposal with co-maintainer access for the AlgoVoi GitHub identity (@chopmob-cloud). Reasoning explicit so it's on record:

    • Neutral-ish provenance for SDO filing. A repo under one implementor with both names on it as co-maintainers carries cleaner citation surface for FIDO TWG / AAIF than a single-implementor repo with a referenced upstream. Reviewers don't have to walk a cross-repo chain to confirm joint authorship.
    • Single canonical artifact for citation. A dual-homed setup invites long-tail drift between the two copies; a single canonical home (with our existing aeoess/aps-conformance-suite vectors imported by cross-reference, not forked) keeps the citable surface unambiguous.
    • PQSafe-led is the right framing for the technical surface. The fixture set's lead claim is "cross-scheme JCS preserves canonicalisation across classical + multiple PQ schemes" — that's an ML-DSA-65-implementor's lead, with AlgoVoi as the Falcon-1024 side-implementor confirming the property. Joint authorship, not co-equal lead.

    Practical asks once the repo is up:

    • Co-maintainer invite to @chopmob-cloud
    • We'll PR the canonical bytes + ECDSA + Ed25519 + Falcon-1024 fixtures against your schema scaffold
    • Cross-reference target in our aps-conformance-suite README pointing into PQSafe/ap2-pq-conformance so anyone walking the AlgoVoi audit trail finds the joint fixture, and vice versa from your README
    • The coordination issue you open as the canonical thread (we'll link from here so future readers find it)

    4. Channel split — confirmed

    • Technical lock-in: in-thread on the coordination issue, indexable, version-stable
    • Scope alignment for the joint note: raymond@pqsafe.xyz ↔ chopmob@gmail.com for the higher-bandwidth pieces — regulatory frame to lead with (HK regulatory + UK/EU regulatory as the named-jurisdiction header), authorship attribution shape ("PQSafe + AlgoVoi" in alphabetical order vs lead-implementor-first), per-SDO filing sequence (FIDO TWG ahead of AAIF, or parallel-filed at both with cross-references in the bodies?), submission window timing relative to the v0.3.2 layering-figure publish window on the agentgraph side.

    Will hold the bare-ECDSA annotation, the producer_runtime field addition, and the AlgoVoi-side PR #218 / #228 work in queue pending your "repo up + coordination issue open" signal. Good to proceed.

    — @chopmob-cloud / AlgoVoi

  6. chopmob-cloud commented on May 21, 2026

    @chopmob-cloud

    @rayc0 — AlgoVoi-side fixture is up. Three signatures over a single AP2 PaymentMandate canonical byte sequence, ready for your ML-DSA-65 side to land against the same bytes.

    https://gist.github.com/chopmob-cloud/c7d2f788ff92593a636e642c8a81bbe1

    Contents:

    • ap2-pqc-v0-algovoi-side.json — mandate body + JCS canonical bytes (501 bytes, sha256:cc8315f7696c65b2a07eb278de0e45c3149319526c8d443c7e38a17de04c28e0) + ES256 + Ed25519 + Falcon-1024 signatures with public keys
    • verify.py — single-file standalone verifier; runs pip install rfc8785 cryptography pqcrypto && python verify.py …
    • README.md — the agreed informative algorithm-identifier table baked in, plus reproduction recipe

    Locks in everything we agreed on 2026-05-16:

    • Open-enum signature_algorithm with the agreed identifier table (informative recommended-values; verifiers MUST fail-closed on unknown values)
    • Fixture schema as written — single canonical byte sequence, per-scheme signatures[] keyed by algorithm, public keys emitted alongside signatures so any reader can reproduce the verification from the published material
    • AlgoVoi side: ES256 + Ed25519 + Falcon-1024 — your ML-DSA-65 over the identical canonical bytes makes the four-signature-scheme cross-implementor convergence visible by construction

    When you push the ML-DSA-65 side, the expected_canonical_sha256 digest should match byte-for-byte — that's the integration point.

    Two follow-ups from my side ready to ship as soon as the coordination issue (or your ML-DSA-65 gist) opens, so the cross-references resolve at commit time:

    1. PR feat(samples): add human-present crypto-algo scenario (AP2 v0.1 + AlgoVoi on-chain USDC extension) #218 commit landing the identifier-table addition on the Algorand crypto-algo scenario
    2. PR feat(samples): add human-present crypto-solana scenario (AP2 + Solana Pay reference binding) #228 commit landing the same table on the Solana crypto-solana scenario

    Happy to mirror the fixture pattern into either PR's sample data, or keep the conformance set scoped to this gist + your ML-DSA-65 gist. Whichever surface you'd prefer.

    — AlgoVoi (chopmob-cloud)

  7. chopmob-cloud commented on May 25, 2026

    @chopmob-cloud

    @rayc0 — following up on the 2026-05-16 coordination locked across comments 3-5 of this thread.

    What was agreed (verbatim from the public record)

    Three substantive lock-ins from your reply at 2026-05-16T19:07:53Z (comment 4):

    1. signature_algorithm identifier table — "confirmed. Adopt the table as the informative recommended-values list in the AP2-PQ spec text."
    2. Cross-scheme fixture schema — "confirmed, as written."
    3. Joint canonical home with co-maintainer access — "I stand up github.com/PQSafe/ap2-pq-conformance as the canonical home, with you added as co-maintainer."

    Confirmed back from AlgoVoi at 2026-05-16T19:09:44Z (comment 5):

    "Accept the github.com/PQSafe/ap2-pq-conformance proposal with co-maintainer access for the AlgoVoi GitHub identity (@chopmob-cloud)."

    Mutual agreement is on the public record.

    AlgoVoi side — shipped as agreed (2026-05-21)

    Per comment 6, AlgoVoi-side fixture is published:

    • Gist: chopmob-cloud/c7d2f788ff92593a636e642c8a81bbe1 — AP2 PaymentMandate canonical bytes (501 bytes, sha256:cc8315f7696c65b2a07eb278de0e45c3149319526c8d443c7e38a17de04c28e0) + ES256 + Ed25519 + Falcon-1024 signatures with public keys, plus standalone verify.py reproducer.

    Ready for the ML-DSA-65 side to land against the identical canonical byte sequence — the four-scheme cross-implementor convergence is the joint deliverable from comment 4.

    PQSafe side — observed state (2026-05-25, nine days after the lock-in)

    • github.com/PQSafe/ap2-pq-conformance — the joint canonical home agreed in comment 4 — does not appear in the PQSafe org public repository list.
    • PQSafe/ap2-pq-test-vectors — exists but predates the coordination (created 2026-05-02T03:23:14Z, last pushed 2026-05-02T13:52:16Z — before the AlgoVoi engagement on this thread). README is sole-PQSafe-authored: "Produced by PQSafe AgentPay as a contribution to the FIDO Alliance Payments Technical Working Group." It uses the same canonical-bytes-then-hash pipeline shape and the JOSE-aligned identifier convention, but it is not the joint canonical home specified in comment 4.
    • Coordination issue — proposed in comment 4 to be opened on the joint repo for technical lock-in — has not been opened.
    • ML-DSA-65 signature over the identical canonical byte sequence — the integration point named in comment 6 — has not been published.

    What's the next step

    One straightforward question and a contingency:

    1. When will PQSafe/ap2-pq-conformance open with @chopmob-cloud co-maintainer access, and the joint fixture set (AlgoVoi-side gist + PQSafe ML-DSA-65 vectors) landed together as agreed in comments 4-5?
    2. If PQSafe's filing strategy has changed since 2026-05-16 — e.g., ap2-pq-test-vectors became the canonical home for a sole-PQSafe FIDO TWG submission rather than the joint repo from comment 4 — naming that explicitly is the cleanest resolution. AlgoVoi can host the joint canonical repo at chopmob-cloud/ap2-pq-conformance with PQSafe as co-maintainer instead — symmetric to your original offer — so the joint deliverable lands somewhere regardless of whose org hosts it.

    No accusation in this comment. The 2026-05-16 lock-in is a public-record agreement; the AlgoVoi-side work shipped on 2026-05-21 was published in good faith. The path forward needs PQSafe to either land the agreed joint deliverable, or name what has changed.

    -- AlgoVoi

  8. chopmob-cloud commented on May 25, 2026

    @chopmob-cloud

    Status update on the AP2#250 joint deliverable.

    Per the symmetric contingency offered in the 2026-05-25 follow-up, AlgoVoi has stood up the joint canonical repo:

    chopmob-cloud/ap2-pq-conformance — public, Apache-2.0, ready for PQSafe co-maintainer onboarding.

    What's in the repo as of initial commit

    • algovoi-side/ — the AlgoVoi-side fixture shipped 2026-05-21 (ES256 + Ed25519 + Falcon-1024 signatures over AP2 PaymentMandate canonical bytes; canonical_sha256_hex = cc8315f7696c65b2a07eb278de0e45c3149319526c8d443c7e38a17de04c28e0; standalone verify.py runnable against pip install rfc8785 cryptography pqcrypto)
    • pqsafe-side/ — reserved slot for the PQSafe ML-DSA-65 contribution per the AP2#250 comment 4 lock-in
    • algorithm-identifier-table.md — the 12-row signature_algorithm informative recommended-values table convention from AP2#250 comments 3-5 (verifiers MUST treat unknown values as opaque and refuse to verify; case-sensitive string compare per RFC 7517 §4.1)
    • README.md — full history + fixture schema lock-in from AP2#250 + co-maintainer policy

    For PQSafe

    The original AP2#250 comment 4 proposal was to land the joint deliverable at github.com/PQSafe/ap2-pq-conformance with @chopmob-cloud as co-maintainer. That proposal remains the cleanest path; this AlgoVoi-hosted contingency exists so the joint deliverable has a public home regardless. Two outcomes from here, either of which closes the AP2#250 deliverable:

    1. PQSafe still wants to host: stand up PQSafe/ap2-pq-conformance with @chopmob-cloud as co-maintainer per comment 4. The AlgoVoi-side fixture mirrors over via PR; this repo becomes a redundant copy that we can archive.
    2. PQSafe lands ML-DSA-65 here: open a PR to pqsafe-side/ with ML-DSA-65 signatures over the identical canonical bytes + the 240-vector ML-DSA-65 set; receive co-maintainer access on merge. Joint deliverable lands without needing a new repo.

    Either path closes the joint-deliverable scope from AP2#250 comments 4-6 cleanly. The third option — silence — leaves the AlgoVoi-side fixture as the standalone reference and the joint deliverable open.

    For other implementors

    The repository is open to any contributor landing a signature scheme over the identical canonical byte sequence. Co-maintainer access is reserved on the same terms: ship a verifiable signature against canonical_sha256_hex = cc8315f7... and become a co-maintainer of the contribution.

    The 12-row identifier table in algorithm-identifier-table.md is informative — implementors MAY declare any value; verifiers MUST fail-closed on unknown values. SLH-DSA, NTRU, classical ECDSA variants, etc. all welcome under the open-enum convention.

    -- AlgoVoi

  9. rayc0 commented on May 26, 2026

    @rayc0
    Author

    @chopmob-cloud — thanks for the AlgoVoi-side fixture (2026-05-21) and the symmetric-contingency repo. Apologies for the gap on my side over the past week.

    Taking option 2 from your latest comment: I've opened a PR landing the PQSafe-side ML-DSA-65 (FIPS 204) signature over the identical canonical bytes —

    chopmob-cloud/ap2-pq-conformance#1

    It signs the same 501-byte JCS canonical (expected_canonical_sha256 = sha256:cc8315f7696c65b2a07eb278de0e45c3149319526c8d443c7e38a17de04c28e0) with ML-DSA-65, and ships a standalone verify.py:

    canonical sha256 OK: sha256:cc8315f7...e0
    ML-DSA-65 verify: OK  (pk=1952B sig=3309B)
    PASS — ML-DSA-65 signature verifies over the identical AP2 #250 canonical bytes.
    

    That closes the four-scheme cross-implementor convergence (ES256 + Ed25519 + Falcon-1024 + ML-DSA-65) over one canonical payload — the JCS+SHA-256 substrate determinism we locked in on 2026-05-16, independent of signature scheme. The 240-vector ML-DSA-65 set lives in PQSafe/ap2-pq-test-vectors on the same pipeline; happy to mirror a curated subset into the joint repo if you'd prefer it co-located.

  10. chopmob-cloud commented on May 26, 2026

    @chopmob-cloud

    AP2 #250 joint deliverable — closed.

    PR landed: chopmob-cloud/ap2-pq-conformance#1 (merged 2026-05-26 04:38 UTC, merge commit 250ab18).

    @rayc0 — thanks for landing this. Co-maintainer invitation sent per the published policy.

    Independent verification on a fresh clone:

    canonical sha256 OK: sha256:cc8315f7696c65b2a07eb278de0e45c3149319526c8d443c7e38a17de04c28e0
    ML-DSA-65 verify: OK  (pk=1952B sig=3309B)
    PASS — ML-DSA-65 signature verifies over the identical AP2 #250 canonical bytes.
    

    Cross-implementor convergence locked in: ES256 + Ed25519 + Falcon-1024 (AlgoVoi-side) + ML-DSA-65 (PQSafe-side) all signing the same 501-byte JCS canonical of one AP2 PaymentMandate. Four signature schemes, one canonical payload, byte-identical SHA-256 across both sides — the JCS+SHA-256 substrate determinism is independent of signature scheme, as locked in on this thread 2026-05-16.

    The repo is open for additional contributors landing signatures over the identical canonical bytes (SLH-DSA, NTRU, classical ECDSA variants, etc.) per the open-enum convention captured in algorithm-identifier-table.md. Co-maintainer access is reserved on the same terms — ship a verifiable signature against canonical_sha256_hex = cc8315f7...e0, become a co-maintainer.

    Closing this for the joint-deliverable scope. Happy to keep this thread open if reviewers want to track downstream signature_algorithm registry additions or coordinate with future AP2 mandate-schema changes.

    -- AlgoVoi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions