Skip to content

feat: add post-quantum ML-DSA-44 signer, verifier and varsig algorithm#37

Draft
Peeja wants to merge 1 commit into
mainfrom
claude/ucantone-pr-rollout-hdbgac
Draft

feat: add post-quantum ML-DSA-44 signer, verifier and varsig algorithm#37
Peeja wants to merge 1 commit into
mainfrom
claude/ucantone-pr-rollout-hdbgac

Conversation

@Peeja

@Peeja Peeja commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Ports the post-quantum ML-DSA-44 (FIPS 204) signer, verifier, and varsig algorithm onto the current multikey layout.

Why this supersedes #32

This is the same feature as #32 (by @alanshaw), but #32 was written against the pre-#30 principal/* layout and never merged. PR #30 ("Attested Signatures + UCAN Principal Clarification") then restructured principal/*multikey/* and reworked varsig/, leaving #32 stale/conflicting on main. This PR reimplements #32's reviewed logic in the new layout so it can land. Closes/supersedes #32.

What's here

  • multikey/mldsa44/{signer,signer_test}.go and multikey/mldsa44/verifier/{verifier,verifier_test}.go — mirrors multikey/{ed25519,secp256k1} exactly. GenerateIssuer() (multikey.Issuer, error) matches the sibling constructors; the verifier package self-registers via multikey.Register(Code, Decode) in init().
  • varsig/algorithm/mldsa/{mldsa,mldsa_test}.go — ML-DSA as its own self-registering single-segment algorithm (modeled on varsig/algorithm/nonstandard, since ML-DSA has no curve/hash sub-codes like ECDSA/EdDSA do). Exported as mldsa.MLDSA44, paralleling eddsa.Ed25519 / ecdsa.Secp256k1. This leaves the spec-defined varsig/algorithms.go registry untouched.
  • go.mod/go.sum — adds filippo.io/mldsa v0.0.0-20260215214346-43d0283efc3e (the exact version feat: add post-quantum ML-DSA-44 signer, verifier and varsig algorithm #32 used; a stdlib-copy pending Go 1.27's ML-DSA).

Wire compatibility

All code values are preserved from #32, so did:key and varsig encodings are unchanged:

  • private-key multicodec 0x131a (mldsa44-priv), public-key multicodec 0x1210 (mldsa44-pub), varsig algorithm discriminant 0x1210. (Spelled as multicodec.Code(0x…) since go-multicodec has no ML-DSA constants yet.)

Signing is deterministic (SignDeterministic), matching #32 and the other signers. Tests cover generate→sign→verify and did:keymultikey.Parse → verify round-trips, plus a determinism assertion.

Verified: GOWORK=off go build ./... && go vet ./... && go test ./... — all green (multikey/mldsa44, multikey/mldsa44/verifier, varsig/algorithm/mldsa all ok).

Opened as a draft for review.

🤖 Generated with Claude Code

https://claude.ai/code/session_014dZyvL474aA43c1C7E6ZpV


Generated by Claude Code

Ports the unmerged PR #32 (ML-DSA-44 post-quantum signatures, by Alan Shaw)
onto the post-#30 `multikey` layout.

PR #32 was built on the old `principal/*` package layout and the old varsig
API. PR #30 then merged and restructured `principal/*` into `multikey/*` and
reworked `varsig/` (the old API now lives under `varsig/prev`), leaving #32
stale. This reimplements the same feature — reusing Alan's reviewed crypto
logic and deterministic signing via `filippo.io/mldsa` — against the current
layout:

- `multikey/mldsa44` — the signer, mirroring `multikey/secp256k1` and
  `multikey/ed25519` (Generate/GenerateIssuer/Parse/Format/Decode/Encode/
  FromRaw + the `multikey.Signer` methods). Private-key multicodec 0x131a.
- `multikey/mldsa44/verifier` — the verifier, self-registering its Decoder
  with the multikey registry via `init`. Public-key multicodec 0x1210.
- `varsig/algorithm/mldsa` — the ML-DSA-44 varsig algorithm. ML-DSA is neither
  ECDSA nor EdDSA, so like `nonstandard` it is a single-segment,
  self-registering algorithm package exposing `MLDSA44` (paralleling
  `eddsa.Ed25519` / `ecdsa.Secp256k1`). Varsig discriminant 0x1210, preserved
  from #32 so wire encoding stays compatible.

Multicodec and varsig code values are unchanged from #32, so `did:key`
encodings and signatures interoperate. Tests cover generate/sign/verify,
encode/decode and did:key round-trips.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014dZyvL474aA43c1C7E6ZpV
Peeja pushed a commit to fil-forge/bench-http-header-ucan-size that referenced this pull request Jul 2, 2026
The earlier attested-signatures migration had to drop the mldsa44 (post-quantum
ML-DSA-44) key branch because that key type did not exist on ucantone main after
the principal/* -> multikey/* refactor. It has now been reinstated on the new
layout in fil-forge/ucantone#37, so this restores the mldsa44 case using
multikey/mldsa44.GenerateIssuer() and re-pins ucantone at that commit.

Because ucantone#37 is not yet merged, this points at that unmerged commit (the
new multikey/mldsa44 branch) rather than the old unmerged principal/mldsa44
commit it referenced before. Re-pin to a merged ucantone once #37 lands.

See fil-forge/ucantone#30

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014dZyvL474aA43c1C7E6ZpV

@alanshaw alanshaw left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks I have been meaning to do this.

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