Skip to content

ML-DSA signing scheme for TUF metadata#195

Open
kommendorkapten wants to merge 4 commits intotheupdateframework:masterfrom
kommendorkapten:pqc
Open

ML-DSA signing scheme for TUF metadata#195
kommendorkapten wants to merge 4 commits intotheupdateframework:masterfrom
kommendorkapten:pqc

Conversation

@kommendorkapten
Copy link
Copy Markdown
Member

Wrote up a TAP on how to encode ML-DSA keys when used within TUF and added a section on pre-auth encoding as certain targets can be fairly larger, and ML-DSA operates in pure mode, that is, no pre-hashing which is the case for RSA and ECDSA.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
@kommendorkapten kommendorkapten changed the title First draft of ml-dsa signing scheme. ML-DSA signing scheme for TUF metadata May 4, 2026
Comment thread tap21.md
limitations on message size, and potential interface constraints that
make pure mode ML-DSA unsuitable for some TUF deployments.

# Specification
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.

I was a bit confused until I got to the "TUF metadata parameters" section about where this fit with TUF. Maybe you could move that sub-section earlier

Comment thread tap21.md
```
0x74 || 0x75 || 0x66 || version || H(MSG)
```
5. Sign the pre-signing byte string using an empty context
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.

Does it make sense for us to include advice around where to do the signing? (Like do we suggest using a hardware device?) I'm not sure if this makes sense to include, but maybe we can include a link or something to guide implementers in the right direction

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think this should be out of scope for the TAP, as the decision to use an HSM vs SK vs KMS vs raw key is based on the integrating project's threat model.

Maybe as a separate TAP if this guidance doesn't exist?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think we need to sit tight here on any recommendation. I immediately see two different paths in the future:

  • Root signing like Sigstore does: HSMs, like YubiKey (assuming they release one soon that supports ML-DSA)
  • KMS for online signing of eg. targets.

So I think this TAP benefits from just defining the signing scheme.

mnm678
mnm678 previously approved these changes May 4, 2026
Copy link
Copy Markdown
Contributor

@mnm678 mnm678 left a comment

Choose a reason for hiding this comment

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

I left a few minor comments, but overall I think this is a great scheme, and addresses some of the performance concerns around ML-DSA

Copy link
Copy Markdown

@Hayden-IO Hayden-IO left a comment

Choose a reason for hiding this comment

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

This is fantastic!

Comment thread tap21.md
0x74 || 0x75 || 0x66 || <version> || H(MSG)
```

The domain separators are the ASCII codes for `tuf`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

love this :)

Comment thread tap21.md
Comment thread tap21.md
## Signature generation

1. Load the public key from TUF metadata
2. Parse the version from the public key's `scheme` and prepare the
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We could change H to SHA-512 since it's fixed? I think this was from an earlier revision when H was variable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

My thinking of keeping it is that we still have the hash decided per the version of the protocol. But you are right that for v1 only SHA-512 is allowed. For keeping the spec generic of the version I think it makes sense to keep it as is.

Comment thread tap21.md
```
0x74 || 0x75 || 0x66 || version || H(MSG)
```
5. Sign the pre-signing byte string using an empty context
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think this should be out of scope for the TAP, as the decision to use an HSM vs SK vs KMS vs raw key is based on the integrating project's threat model.

Maybe as a separate TAP if this guidance doesn't exist?

Comment thread tap21.md Outdated
* Version byte: `0x01`
* Hash algorithm: SHA-512
* Implementations MUST support
* `ML-DSA-44`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should we explicitly state the valid KEYTYPEs and SCHEMEs? All lower case to match https://theupdateframework.github.io/specification/latest/#file-formats-keys or upper case?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ah you do below...maybe that should be higher?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, @mnm678 had a few similar comments to I'll shuffle things around so more TUF details are in the beginning, I think that will make it easier to read.

Comment thread tap21.md
2. Load up the public key for verification
3. Parse `scheme` into parameter set and version
* Reject if the protocol version is not supported
* Implementations MUST NOT infer or select an ML-DSA
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should implementations verify the length of the public key and/or signature based on the ML-DSA parameter set? Maybe this is already handled by the underlying library?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That should be managed by the underlying library, and I rather not see any TUF related code try to delve into analyzing the signature/pk size. I clarify this.

Comment thread tap21.md Outdated
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
@kommendorkapten
Copy link
Copy Markdown
Member Author

Thanks for the feedback ❤️
All comments should be adressed/answered. See https://github.com/kommendorkapten/taps/blob/pqc/tap21.md for a rendered version.

Copy link
Copy Markdown

@Hayden-IO Hayden-IO left a comment

Choose a reason for hiding this comment

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

Really great work on this spec!

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