Signaturmetoder
ML-DSA-87 forklaret matematisk
Sådan underskriver ML-DSA-87 (FIPS 204) en McGesund-anmeldelse — fra Module-LWE over rejection sampling til verifikationen i browseren.
Opdateret: 2026-09-07
1. Hvad det handler om
Når nogen afgiver en anmeldelse hos McGesund, sker der mere i baggrunden, end teksten lader ane. Anmeldelsen bliver digitalt signeret, når den sendes af sted. Denne signatur kan enhver besøgende senere regne efter i sin egen browser — uden at stole på os og uden at spørge os.
For kunder fra abonnementet Pro og opefter sker det blandt andet med ML-DSA-87. Dette indlæg forklarer, hvad der matematisk sker undervejs.
Vigtigt at slå fast først:
ML-DSA er ikke kryptering. Anmeldelsesteksten forbliver offentligt læsbar — det er jo meningen med en anmeldelse. ML-DSA beviser ikke hemmeligholdelse, men oprindelse og uforanderlighed.
ML-DSA er udviklet ud fra CRYSTALS-Dilithium og er standardiseret som FIPS 204. Tallet 87 betegner parameterniveauet. Der findes tre:
- ML-DSA-44
- ML-DSA-65
- ML-DSA-87
ML-DSA-87 er det højeste og ligger i NIST-sikkerhedskategori 5.
2. Hvad bliver præcist signeret?
Det er ikke anmeldelsesteksten selv, der vandrer ind i signaturen, men et kompakt dataobjekt, som utvetydigt fastnagler teksten. Hos McGesund ser det i kernen sådan ud:
{
"v": 1,
"typ": "rev-comment",
"f": "<virksomheds-id>",
"c": "<anmeldelses-id>",
"h": "<SHA-256 af anmeldelsesteksten>",
"rh": "<SHA-256 af hele det indsendte datasæt>",
"rv": 1,
"qh": "<SHA-256 af QR-konvolutten, kun ved QR-anmeldelser>",
"iat": 1757203200
}
Dette objekt er vores besked . Det binder seks udsagn sammen:
- Hvilken virksomhed anmeldelsen hører til (
f) - Hvilken anmeldelse der menes (
c) - Hvilken tekst der stod bag — som hashværdi (
h) - Hvilket datasæt der samlet blev indsendt (
rh): tekst, hjerter, geostatus og anledningsoplysninger, kanonisk serialiseret og hashet — i skemaversionenrv - Hvilken QR-kode anmeldelsen stammer fra (
qh); uden QR udgår feltet - Hvornår der blev signeret (
iat)
Ændrer nogen senere et eneste tegn i anmeldelsesteksten, passer h ikke længere — og rh heller ikke. Den, der i stedet kun skruer på hjerterne, lader h være urørt, men bryder rh. Ændrer nogen en af disse hashværdier, passer signaturen ikke længere. Netop denne kæde er pointen.
3. Hvad signaturen skal kunne
En besøgende, der læser anmeldelsen, skal selv kunne efterprøve tre ting:
- Anmeldelsen blev faktisk udstedt af McGesund.
- Teksten er ikke ændret siden indsendelsen.
- Ingen kan opfinde en ny anmeldelse, der ser gyldig ud.
Til det findes der et nøglepar:
- en privat nøgle — ligger udelukkende i signaturtjenesten
- en offentlig nøgle — må alle have, adresseres via nøgle-id'et (
kid) i konvolutten
Der signeres med den private nøgle. Der verificeres med den offentlige — og det sker i læserens browser, ikke på vores server.
4. Hvorfor overhovedet en post-kvantemetode?
Mange signaturmetoder, der er almindelige i dag, bygger på faktorisering af store tal eller på diskrete logaritmer. En tilstrækkelig kraftig kvantecomputer kunne løse netop disse problemer betydeligt hurtigere med kendte algoritmer.
For en anmeldelse er det ikke et akademisk spørgsmål. En anmeldelse skal stadig kunne verificeres om ti år. Den, der underskriver i dag, underskriver for hele opslagets levetid.
ML-DSA bruger derfor et andet grundlag:
Nærmere bestemt: Module-LWE og Module-SIS.
5. Hvad er et gitter?
Til at begynde med bare punkter i rummet. Lad os tage to vektorer:
Alle heltallige kombinationer
danner gitteret. For eksempel:
Det afgørende:
I små dimensioner er gitterproblemer lette. I meget høje dimensioner bliver bestemte opgaver ekstremt vanskelige.
6. Polynomier i stedet for enkelttal
ML-DSA regner ikke med 2D-vektorer, men med polynomier og vektorer af polynomier.
Et polynomium som
kan skrives som koefficientliste:
Der regnes i en ring:
Det betyder to ting:
- : regning modulo
- : en ekstra regel, der fastholder polynomielængden
For alle tre ML-DSA-niveauer gælder:
Et polynomium har altså 256 koefficienter, betragtet modulo 8.380.417. Det, der ændrer sig mellem niveauerne, er ikke eller , men matricernes størrelse — mere om det senere.
For øvrigt: Polynomiemultiplikation i denne ring foregår i praksis via NTT, den talteoretiske variant af den hurtige fouriertransformation. ML-DSA klarer sig altså på ingen måde uden FFT-idéer; de sidder blot i aritmetikken i stedet for i signaturprincippet.
7. Det centrale kneb: Module-LWE
Kerneidéen er Module Learning With Errors:
Heri er:
- — offentlig, tilsyneladende tilfældig matrix af polynomier
- — små hemmelige vektorer
- — offentlig værdi
En angriber kender og , men ikke . Ligningen ser for ham ud som en tilfældig ligning med støj. De små hemmeligheder skal han ikke kunne regne effektivt tilbage ud af den.
8. Et ganske lille taleksempel
Vi tager med vilje en latterligt lille variant — almindelige tal i stedet for polynomier, dimension 2 i stedet for 256, og
Lad
Så:
I dette miniformat kunne man prøve alle muligheder af. Ved ML-DSA-87 er en -matrix af polynomier med hver 256 koefficienter — det er over 14.000 ubekendte i gitterstrukturen.
9. Signaturtjenestens nøglepar
Den private nøgle indeholder blandt andet de små vektorer . Ved ML-DSA-87 stammer deres koefficienter fra intervallet
altså fra . Denne lidenhed er ikke en detalje, men kernen: Kun fordi hemmelighederne er små, opstår der overhovedet et vanskeligt gitterproblem.
Den offentlige nøgle er forenklet
er et seed, som deterministisk kan rekonstrueres ud fra — matricen skal altså ikke overføres. er de øverste bit af ; de nederste bit falder væk, hvilket gør nøglen markant mindre. Netop denne udeladelse er senere grunden til de såkaldte hints.
Dermed opstår den ønskede asymmetri:
10. Anmeldelsen bliver til et tal
Signaturtjenesten hasher først payload-objektet fra afsnit 2:
I vores legetøjseksempel tager vi en kunstig mini-hash. I det rigtige system er 512 bit lang og binder desuden den offentlige nøgle ind — derved kan en signatur ikke omtolkes til at høre til en anden nøgle.
11. Commitment
Signaturtjenesten trækker en tilfældig lille vektor . I vores eksempel:
Deraf opstår en mellemværdi, commitment:
Det er endnu ikke nogen signatur.
12. Ud af anmeldelsen bliver der en challenge
Besked og commitment hashes sammen:
Ved ML-DSA-87 er et polynomium med præcis koefficienter fra , alle øvrige 196 er nul. Denne struktur er tilsigtet: Den holder lille.
I vores legetøjseksempel sætter vi ganske enkelt
13. Selve signaturen
Med vores værdier:
14. Skridtet, man let overser: rejection sampling
Her ligger det punkt, hvor ML-DSA adskiller sig fra en naiv konstruktion — og det er ikke valgfrit.
indeholder hemmeligheden . Udleverede man bare hver gang, kunne regnes statistisk ud af tilstrækkeligt mange signaturer. Ved en anmeldelsesportal med meget mange signaturer om dagen er det ingen teoretisk risiko.
Derfor efterprøver signaturtjenesten inden udleveringen, om røber for meget, og kasserer ellers signaturen — så begyndes der forfra med et nyt tilfældigt . Det kaldes Fiat-Shamir with Aborts.
Betingelsen lyder i det væsentlige:
For ML-DSA-87 gælder og . Dertil kommer en anden grænse på de nederste bit. I praksis er flere gennemløb normalt — signeringen er altså en løkkemetode, ikke et enkelt skridt.
For verifikationen er det vigtigt: Netop denne grænse efterprøver browseren senere også. En signatur med for store koefficienter bliver afvist, selv om ligningen går op.
15. Hvorfor browseren kan verificere det
Læserens browser kender:
- anmeldelsen og dermed
- den offentlige nøgle
- signaturen
Den kender ikke . Den sammenhæng, der alligevel bringer den videre:
Og fordi
gælder, kan det ukendte erstattes af den offentlige værdi:
Det er den centrale ligning — og den siger noget vigtigt: Browseren rekonstruerer ikke eksakt, men kun op til det lille led .
16. Minieksemplet til ende
Vi havde:
Lad os regne efter:
Det oprindelige commitment var
Forskellen er
Altså præcis det forudsagte lille fejlled. Den, der verificerer, får ikke , men noget, der ligger tæt på .
Netop derfor sammenligner ML-DSA ikke værdierne selv, men deres øverste bit. Og netop derfor indeholder signaturen desuden en hint-vektor : Den meddeler kompakt, hvilke steder afrundingen er tippet over en grænse på grund af det lille fejlled. Ved ML-DSA-87 er højst sådanne hints tilladt. De røber ikke hemmeligheden — de reparerer kun afrundingen.
Til sidst beregner browseren challengen på ny. Stemmer den overens,
og ligger alle normer inden for grænserne, er signaturen gyldig.
17. Hvad sker der, hvis nogen ændrer anmeldelsen?
Antag, at nogen med databaseadgang — også nogen hos os — ændrer anmeldelsesteksten eller et af hjerterne. Så ændrer mindst en af de to hashværdier i payloaden sig (h ved teksten, rh ved ethvert felt i datasættet):
Dermed ændrer challengen sig:
Men den foreliggende signatur blev fremstillet til den gamle challenge. Browseren regner efter og konstaterer:
Den afgørende sætning hertil: Vi kan slette en anmeldelse, men vi kan ikke ændre den ubemærket. Hos McGesund kører den samme kontrol desuden hver nat serverside hen over hele bestanden — en anmeldelse, der ikke består denne kontrol, tæller ikke længere med i virksomhedens gennemsnit.
18. Hvorfor kan ingen opfinde en signatur?
En angriber kender og , men ikke . For at bygge en gyldig signatur skulle han finde en tripel , der
- opfylder verifikationsligningen og
- overholder normgrænserne og
- passer til den challenge, der fremgår af netop disse værdier selv.
Det løber i kernen ud på et vanskeligt gitterproblem — konkret på Module-SIS: at finde korte løsninger til en homogen ligning modulo . Lidenhedsbetingelsen er herved ikke pynt, men selve sværhedsgraden. Uden den ville en løsning være triviel.
19. Hvorfor „module"?
Ordet beskriver strukturen mellem simple vektorer og almindelige gitre. I stedet for at regne med enkelttal arbejder ML-DSA med vektorer af polynomier:
og med matricer af dem:
Fordelen: Man får et gitters høje dimension, men beholder en kompakt, effektivt beregnelig repræsentation. Sikkerheden kan finjusteres via matrixstørrelsen uden at skifte ring.
20. Hvorfor netop 87?
De tre niveauer adskiller sig ikke i ringen, men i dimensionerne:
| Parameter | ML-DSA-44 | ML-DSA-65 | ML-DSA-87 |
|---|---|---|---|
| Matrixstørrelse | |||
| Hemmelighedsinterval | 2 | 4 | 2 |
| Challenge-vægt | 39 | 49 | 60 |
| Offentlig nøgle | 1.312 B | 1.952 B | 2.592 B |
| Signatur | 2.420 B | 3.309 B | 4.627 B |
| NIST-kategori | 2 | 3 | 5 |
Bemærkelsesværdigt: ML-DSA-87 er ikke bare „ML-DSA-65, blot større". Hemmelighedsintervallet går fra 4 tilbage til 2; sikkerheden kommer her fra den større matrix, ikke fra større koefficienter. Der er tale om et selvstændigt, standardiseret parametervalg.
Prisen: 4.627 byte pr. signatur — pr. stempel, der skal gemmes og udleveres til browseren ved verifikationen. Derfor står også FALCON til valg hos McGesund ved siden af ML-DSA-87, og det klarer sig med 1.280 byte.
21. Fiat-Shamir: hvorfor det fungerer uden modpart
Et interaktivt bevis ville forløbe sådan:
- Signaturtjenesten sender et commitment.
- Den, der verificerer, sender en tilfældig challenge.
- Signaturtjenesten svarer.
- Den, der verificerer, regner efter.
Ved en anmeldelse findes denne dialog ikke — læseren kommer måneder senere. Løsningen er Fiat-Shamir-transformationen: Challengen bliver ikke slået med terning, men hashet ud af selve data:
Dermed bliver en dialog til et dokument. Signaturtjenesten kan ikke vælge sin challenge, for det ville kræve, at den kontrollerede hashen.
22. Hele forløbet
23. Hvad McGesund konkret bruger det til
Tre lag griber ind i hinanden:
Konvolutten. Hver signeret anmeldelse bærer en Ed25519-signatur. Det er den obligatoriske variant — klassisk, ganske lille, nativt verificerbar i enhver browser.
Post-kvantestemplerne. Derudover kan en eller to kvanteresistente signaturer lægges ved siden af. Hvilke, afhænger af abonnementet:
| Abonnement | tilgængelige signaturniveauer |
|---|---|
| Basis | Ed25519, FN-DSA-512 |
| Klassik | Ed25519, FN-DSA-512, FN-DSA-1024 |
| Pro | Ed25519, FN-DSA-1024, ML-DSA-87 |
| Premium | Ed25519, FN-DSA-1024, ML-DSA-87, begge parallelt |
Den parallelle variant er bevidst redundant. Skulle en af de to matematiske familier — NTRU-gitre ved FALCON, module-gitre ved ML-DSA — vise sig svagere end antaget i dag, bærer den anden videre.
Tidsankeret. Signaturnøglens fingeraftryk forankres via OpenTimestamps i en Bitcoin-blok. Dermed kan man ikke bare påvise, at signaturen er ægte, men også at den allerede eksisterede på et bestemt tidspunkt — uden at nogen behøver tro på vores tidsstempel.
Alt dette bliver verificeret i læserens browser via et WASM-modul. Vi leverer data; efterregningen sker på den besøgendes eget udstyr. Gik vi af nettet i morgen, ville en allerede hentet anmeldelse stadig kunne verificeres.
24. ML-DSA og FALCON side om side
| Egenskab | FALCON (FN-DSA) | ML-DSA |
|---|---|---|
| Type | digital signatur | digital signatur |
| Gitterfamilie | NTRU | Module-LWE / Module-SIS |
| Ring | , | , |
| Kernemekanisme | kort vektor via gaussisk sampling | challenge-svar med afbrydelser |
| FFT / NTT | flydende-komma-FFT, sikkerhedskritisk | NTT, kun aritmetik |
| Signaturstørrelse (højeste niveau) | 1.280 B | 4.627 B |
| Implementering | krævende (flydende komma) | forholdsvis ligefrem |
| Standardisering | tiltænkt som FIPS 206 (FN-DSA), endnu ikke færdiggjort | FIPS 204, færdiggjort |
Kort sagt: ML-DSA er lettere at implementere og efterprøve korrekt, FALCON leverer markant mere kompakte signaturer. I QR-koden sidder ingen af dem — dér står alene Ed25519-konvolutten. Signaturstørrelsen tæller derfor ved lagring og udlevering, robustheden ved implementeringen. Derfor tilbyder vi begge dele.
25. En sætning at tage med
Den, der besidder den hemmelige vektor, underskriver på millisekunder. Den, der ikke besidder den, skulle løse et gitterproblem i over 14.000 dimensioner — også med en kvantecomputer.
For den, der læser en anmeldelse, betyder det ganske enkelt: Han behøver ikke tro på os. Han kan regne efter.