Repository navigation
feat(s138): deterministic CBOR and COSE_Sign1 with ML-DSA-87 - #133
Merged
Merged
Conversation
…h ML-DSA-87) Signed-off-by: Ayla Croft <aylacroft@proton.me>
…ML-DSA-87 with :error, never a crash Signed-off-by: Ayla Croft <aylacroft@proton.me>
Signed-off-by: Ayla Croft <aylacroft@proton.me>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Slice 138. Deterministic CBOR and COSE_Sign1 with ML-DSA-87, in the N6 profile, as one boundary with no dependency on the rest of Trinity. It is groundwork: nothing Trinity signs changes, and no statement uses the new format yet. Stacked on #132 (it reuses that slice's
:mldsa87_runtimetag and thefipsjob's mode-off step); retarget tomainonce #132 merges.The profile implemented is v0, draft r3, provisional. Every rule may change until a frozen v1 is published with its own vectors, and the pin (
Trinity.N6.Profile.pin/0) names the draft and the SHA-384 of its text.What it does
Trinity.N6.CBOR). An encoder that can only produce RFC 8949 section 4.2.1's deterministic encoding, for integers in [-2^63, 2^64-1], tagged byte and text strings (text valid UTF-8 in NFC), arrays, maps with keys 0..2^32-1, andfalse,true,null. A decoder that reads the input once, stops at the first defect and names it with its byte offset, then re-encodes and compares. Limits: depth 16, 65,536 items, 64 KiB of text, 1 MiB in all, each counted as the moduledoc states. A forged count larger than the input is refused before anything is read.Trinity.N6.Body). Key 0 is the schema version; a body is checked against its declared schema with no unknown key, and a field declared a set must be sorted by encoded bytes with no duplicate.Trinity.N6.Digest). SHA-384 over foreign bytes exactly as given, as[-43, digest]and a reference carrying the exact length.Trinity.N6.COSE). The protected header is closed toalg-50 (ML-DSA-87),kidandtyp, plus CWT claims for a SCITT-renderabletyp.kidis the RFC 9679 SHA-384 thumbprint over RFC 9964's key members. ToBeSigned is RFC 9052's, with an empty external_aad. Signing takes the private key as the 32-byte seed or the expanded key. Verification answers the profile's exit classes; a runtime that cannot run ML-DSA-87 answers no trust (5,alg_unavailable), never a crash and never a pass. Both exchange forms, detached and tagged-attached, render from the same three parts.lib/, each classified. Four sites re-encode data from elsewhere before hashing it; they are declared there with what it would take to hash the exact bytes, and none changes in this PR.Vectors
scripts/n6_vectors.exswritestest/fixtures/n6/(338 files, 67 KB) in the layout the draft gives. Every expected encoding is a hex literal, copied from RFC 8949 Appendix A or built by hand from CBOR heads, so no vector is the encoder's own output. The thumbprint vector uses NIST ACVP's published ML-DSA-87 keyGen case; no key of this project's is published.sha384sum -c SHA384SUMSchecks the set from its directory, and a test holds the checked-in set to the generator byte for byte.Evidence
fipsjob's mode-off step runs these.mix test --only n6_corpus): 1,000,000 generated bodies round-tripped, and 13,000,000 mutants from thirteen operators were all refused with their operators' codes (34.6 s).Not in this PR
Receipts keep their slice 024 format; moving them is a later slice. Two-signer carriers, the attribution exit classes (6, 7), the RFC 9995 hash envelope, and any classical algorithm in N6 are outside it.