Skip to content

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

Merged
alanshaw merged 4 commits into
mainfrom
claude/ucantone-pr-rollout-hdbgac
Aug 24, 2026
Merged

feat: add post-quantum ML-DSA-44 signer, verifier and varsig algorithm#37
alanshaw merged 4 commits 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.

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

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.

@alanshaw
alanshaw force-pushed the claude/ucantone-pr-rollout-hdbgac branch from 1273248 to b51b494 Compare August 24, 2026 10:34
@alanshaw
alanshaw marked this pull request as ready for review August 24, 2026 10:34
claude and others added 2 commits August 24, 2026 13:05
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
@alanshaw
alanshaw force-pushed the claude/ucantone-pr-rollout-hdbgac branch from b51b494 to 360f968 Compare August 24, 2026 12:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds ML-DSA-44 post-quantum signing, verification, DID-key support, and Varsig integration, plus regenerated DAG-JSON code.

Changes:

  • Adds ML-DSA-44 signer, verifier, constructors, and tests.
  • Adds self-registering ML-DSA Varsig support.
  • Updates Go/tooling versions and generated serializers.

Open issues remain: the verifier package must register the ML-DSA Varsig algorithm for verifier-only imports (moderate), and the Go-version/dependency claim needs reconciliation (nit).

Reviewed changes

Copilot reviewed 7 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Change
varsig/algorithm/mldsa/mldsa.go ML-DSA Varsig algorithm
varsig/algorithm/mldsa/mldsa_test.go Varsig tests
validator/internal/fixtures/datamodel/dag_json_gen.go Regenerated serializer
ucan/receipt/datamodel/dag_json_gen.go Regenerated serializer
ucan/invocation/datamodel/dag_json_gen.maps.go Regenerated map serializer
ucan/delegation/policy/selector/internal/fixtures/datamodel/dag_json_gen.go Regenerated serializer
ucan/delegation/policy/selector/datamodel/dag_json_gen.go Regenerated serializer
ucan/delegation/policy/internal/fixtures/datamodel/dag_json_gen.go Regenerated serializer
ucan/delegation/datamodel/dag_json_gen.maps.go Regenerated map serializer
result/datamodel/dag_json_gen.go Regenerated serializer
multikey/mldsa44/verifier/verifier.go ML-DSA-44 verifier
multikey/mldsa44/verifier/verifier_test.go Verifier tests
multikey/mldsa44/signer.go ML-DSA-44 signer
multikey/mldsa44/signer_test.go Signer tests
go.sum Checksum updates
go.mod Go and generator version updates
errors/datamodel/dag_json_gen.go Regenerated serializer
did/plc/json_gen.go Regenerated serializer
Files not reviewed (10)
  • did/plc/json_gen.go: Generated file
  • errors/datamodel/dag_json_gen.go: Generated file
  • result/datamodel/dag_json_gen.go: Generated file
  • ucan/delegation/datamodel/dag_json_gen.maps.go: Generated file
  • ucan/delegation/policy/internal/fixtures/datamodel/dag_json_gen.go: Generated file
  • ucan/delegation/policy/selector/datamodel/dag_json_gen.go: Generated file
  • ucan/delegation/policy/selector/internal/fixtures/datamodel/dag_json_gen.go: Generated file
  • ucan/invocation/datamodel/dag_json_gen.maps.go: Generated file
  • ucan/receipt/datamodel/dag_json_gen.go: Generated file
  • validator/internal/fixtures/datamodel/dag_json_gen.go: Generated file
Suppressed comments (1)

varsig/algorithm/mldsa/mldsa.go:27

  • Because this registration only runs when this add-on package is imported, a verifier-only consumer that imports multikey/mldsa44/verifier does not load the ML-DSA Varsig decoder: that package does not import varsig/algorithm/mldsa. Decoding an incoming delegation or invocation therefore reaches varsig.Decode and fails with an unknown scheme before the key verifier is used. Import the paired algorithm from the verifier/default registration path (or centralize add-on registration), and cover this with a verifier-only end-to-end decode test.
	varsig.RegisterAlgorithmScheme(varsig.AlgorithmSchemeDef{
		Code:    Code,
		Name:    "ML-DSA-44",
		Decoder: Decode,
	})

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread go.mod
Comment thread multikey/mldsa44/verifier/verifier.go
@alanshaw
alanshaw merged commit 6ad0099 into main Aug 24, 2026
6 checks passed
@alanshaw
alanshaw deleted the claude/ucantone-pr-rollout-hdbgac branch August 24, 2026 15:01
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.

4 participants