Signaturmetoder

Ed25519 forklaret matematisk

Underskriften, der hænger på hver eneste McGesund-anmeldelse — fra kurven over nøglen til den ligning, som læserens browser regner efter.

Opdateret: 2026-09-07

1. Hvad det handler om

En anmeldelse hos McGesund er ikke et tekstfelt i en database, som man bare må tro på. Den bliver digitalt signeret, når den sendes af sted, og enhver besøgende kan senere regne signaturen efter i sin egen browser.

Til denne underskrift bruger vi Ed25519. I modsætning til FALCON og ML-DSA, der kan lægges ved som ekstra stempler, er Ed25519 ikke valgfri: Hver signeret anmeldelse bærer den, uanset abonnement og indsendelsesvej.

Vigtigt at slå fast først:

Ed25519 er ikke kryptering. Anmeldelsesteksten skal jo kunne læses. Signaturen beviser ikke hemmeligholdelse, men oprindelse og uforanderlighed.


2. Hvad der præcist bliver underskrevet

Det er ikke den løbende tekst, der signeres, men et kompakt dataobjekt, som utvetydigt fastnagler teksten og alt det øvrige:

{
  "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>",
  "kid": "<nøgle-id>",
  "iat": 1757203200
}

Dette objekt bliver kodet til CBOR. Denne bytefølge — ikke den pæne visning ovenfor — er vores besked mm. Signatur og besked rejser sammen i en konvolut:

Envelope=MCG1:    base64url(CBOR[3,  m,  σ])\text{Envelope} = \texttt{MCG1:} \;\|\; \mathrm{base64url}\bigl(\mathrm{CBOR}[\,3,\; m,\; \sigma\,]\bigr)

33-tallet er formatversionen. Mere står der ikke i den — og navnlig ingen post-kvantesignatur: Findes den, ligger den ved siden af datasættet og ikke i konvolutten.


3. Hvad signaturen skal kunne

En læser, der lander på en virksomhedsprofil, står med to spørgsmål:

  1. Stammer denne anmeldelse virkelig fra McGesund-systemet?
  2. Er den blevet ændret bagefter?

Til det findes der et nøglepar:

  • en privat nøgle — bliver i signaturtjenesten
  • en offentlig nøgle — må alle have, adresseres via nøgle-id'et (kid) i payloaden

Der signeres med den private nøgle. Der verificeres med den offentlige — og det sker i læserens browser, ikke på vores server. Det er hele pointen: En kontrol, som vi selv udfører og hvis resultat vi meddeler, ville ikke være en kontrol, men en påstand.


4. Hvorfor en elliptisk kurve?

Enhver signatur kræver en beregning, der er let den ene vej og praktisk talt umulig den anden. Ved Ed25519 er det skalarmultiplikationen på en elliptisk kurve:

a    A=aB.a \;\longmapsto\; A = a\cdot B.

At beregne det offentlige punkt AA ud fra det hemmelige tal aa koster mikrosekunder. At slutte fra AA tilbage til aa er det diskrete logaritmeproblem — og der kendes ingen metode, der ved denne størrelse bliver færdig inden for menneskelige tidsrum.

Den praktiske gevinst i forhold til ældre metoder som RSA er størrelsen:

offentlig nøglesignatur
RSA-3072384 B384 B
Ed2551932 B64 B

Ved sammenligneligt sikkerhedsniveau. 64 byte pr. anmeldelse er heller ikke ved millioner af anmeldelser en størrelse, man behøver tænke over.


5. Kurven edwards25519

Der regnes modulo et primtal:

p=225519.p = 2^{255}-19.

Deraf navnet. Kurven er en snoet Edwards-kurve:

x2+y2  =  1+dx2y2,d=121665121666modp.-x^2+y^2 \;=\; 1 + d\,x^2y^2, \qquad d = -\frac{121665}{121666} \bmod p.

Et „punkt" er et talpar (x,y)(x,y) fra {0,,p1}\{0,\dots,p-1\}, der opfylder denne ligning. Der er ingen kurve at se — tegningen i næste afsnit er en anskuelseshjælp over de reelle tal, ikke et billede af det faktiske regnerum.

To størrelser kommer til:

  • et fast aftalt basispunkt BB,
  • ordenen \ell for den undergruppe, BB frembringer:
=2252+27742317777372353535851937790883648493.\ell = 2^{252} + 27742317777372353535851937790883648493.

\ell er et primtal. Det betyder: Lægger man BB til sig selv igen og igen, gennemløber man præcis \ell forskellige punkter og lander så igen ved begyndelsen. Alle beregninger med skalarer foregår derfor modulo \ell, alle beregninger med koordinater modulo pp. At forveksle disse to tal er den klassiske begynderfejl.


6. At addere punkter

To punkter regnes efter en fast formel sammen til et tredje:

x3=x1y2+y1x21+dx1x2y1y2,y3=y1y2x1x21dx1x2y1y2.x_3=\frac{x_1y_2+y_1x_2}{1+d\,x_1x_2y_1y_2}, \qquad y_3=\frac{y_1y_2-x_1x_2}{1-d\,x_1x_2y_1y_2}.

Det neutrale element er (0,1)(0,1) — punktet, hvor regningen begynder.

Denne formel har en egenskab, man ikke kan se på den, og som betyder mere for sikkerheden end nogen konstant: Den er fuldstændig. Den fungerer for alle input, uden særtilfælde for „begge punkter ens" eller „resultatet er det neutrale element". Ved de ældre Weierstrass-kurver findes disse særtilfælde, og hvert af dem er en forgrening i programmet — en forgrening, hvis køretid kan måles. Den, der måler, hvor lang tid en signatur tager, får ved sådanne metoder noget at vide om den hemmelige nøgle.

Fuldstændige formler betyder: altid den samme beregningsvej, altid den samme tid, intet at måle på.


7. Skalarmultiplikation — envejsgaden

nBn\cdot B betyder: at lægge BB til sig selv præcis nn gange. Ved et nn på 253 bit ville det være meningsløst meget arbejde — derfor fordobles der:

B2B4B8BB \to 2B \to 4B \to 8B \to \dots

og ud af disse mellemresultater sammensættes det ønskede nn. Omkring 253 fordoblinger rækker til ethvert nn. Det er vejen fremad.

Baglæns findes denne genvej ikke. At bestemme tallet aa ud fra punktet AA betyder at løse det diskrete logaritmeproblem.

(0,1) — neutralt elementB2B3B4B5B6B
En Edwards-kurve med basispunktets første multipla, beregnet med den ægte additionslov. Over de reelle tal vandrer de stadig i synlig orden hen over kurven — man kunne følge vejen tilbage. Modulo p forsvinder præcis denne orden, og derpå hviler sikkerheden.

I den rigtige metode regnes der modulo pp. Dér findes hverken „venstre" eller „højre" og ingen nærhed: Af 17B17\,B og 18B18\,B bliver to talpar uden noget genkendeligt slægtskab.


8. Signaturtjenestens nøglepar

I begyndelsen står 32 tilfældige byte, seedet. Alt det øvrige udledes deraf:

h=SHA-512(seed),h=h0..31  a    h32..63præfiks.h = \mathrm{SHA\text{-}512}(\text{seed}), \qquad h = \underbrace{h_{0..31}}_{\to\;a}\;\|\;\underbrace{h_{32..63}}_{\text{præfiks}}.

Af den første halvdel opstår den hemmelige skalar aa, dog ikke uændret. Tre bit bliver sat eller slettet — den såkaldte clamping:

  • de nederste tre bit sættes til nul: aa bliver derved et multiplum af 8. Grunden er kurvens kofaktor 8 — den fulde punktgruppe er otte gange så stor som undergruppen af orden \ell. Et aa, der er deleligt med 8, lander garanteret i den rigtige undergruppe og røber intet om punkter af lille orden.
  • det øverste bit slettes, det næstøverste sættes: aa har dermed altid den samme bitlængde. Et kortere aa ville kræve færre fordoblinger — og igen ville køretiden røbe noget.

Den offentlige nøgle er så ganske enkelt

A=aB,A = a\cdot B,

gemt som 32 byte: yy-koordinaten, og i det højeste bit fortegnet for xx. xx regner den, der verificerer, selv tilbage ud fra kurveligningen — de to løsninger adskiller sig kun i fortegnet, og hvilken der menes, siger netop dette ene bit.

Hashværdiens anden halvdel, præfikset, bruges ikke til nøglen. Den kommer i brug i næste afsnit.


9. Hvorfor tilfældigheden her ikke er tilfældig

Enhver signatur af denne type kræver en engangsværdi rr, ofte kaldet nonce. Den må aldrig gentage sig: Den, der har to signaturer med det samme rr, kan regne den hemmelige nøgle ud med almindelig skolealgebra.

Netop dét er virkelige systemer strandet på. Det mest kendte tilfælde er signaturkontrollen i en spillekonsol, hvis producent i 2010 altid brugte den samme nonce — den private nøgle kunne derved rekonstrueres offentligt.

Ed25519 løser det ved slet ikke at bruge tilfældighed:

r=SHA-512(præfiks    m)mod.r = \mathrm{SHA\text{-}512}(\text{præfiks}\;\|\;m) \bmod \ell.

Noncen hænger på det hemmelige præfiks og på beskeden. Deraf følger to ting:

  • To forskellige anmeldelser giver med overvældende sandsynlighed forskellige rr — gentagelsestilfældet indtræffer ikke.
  • Den samme anmeldelse giver altid den samme signatur. En signeringshandling kan dermed efterprøves, og en dårlig tilfældighedsgenerator på serveren kan ikke ødelægge noget, fordi der ikke bruges nogen.

For en anmeldelsesportal med mange signaturer om dagen er det ingen akademisk fordel. Det er forskellen mellem „en fejl i tilfældighedskilden ville være fatal" og „der findes ingen tilfældighedskilde, der kunne svigte".


10. At signere

Tre linjer, mere er det ikke:

r=H(præfiks    m)mod,R=rB,r = H(\text{præfiks}\;\|\;m) \bmod \ell, \qquad R = r\cdot B,
k=H(R    A    m)mod,k = H(R \;\|\; A \;\|\; m) \bmod \ell,
S=(r+ka)mod.S = (r + k\,a) \bmod \ell.

Signaturen er parret

σ=(R,S),\sigma = (R,\,S),

32 byte til punktet RR, 32 byte til tallet SS — tilsammen 64 byte.

Bemærkelsesværdig er den anden linje: I kk indgår RR, den offentlige nøgle AA og beskeden. At AA hashes med, er ikke pynt — det forhindrer angreb, hvor en signatur omtolkes til at høre til en anden nøgle.


11. At verificere

Læserens browser kender: anmeldelsen mm, signaturen (R,S)(R,S) og den offentlige nøgle AA. Den beregner kk på ny og efterprøver en eneste ligning:

SB  =  R+kA\boxed{S\cdot B \;=\; R + k\cdot A}

Passer den, er signaturen gyldig. RFC 8032 tillader desuden den med kofaktoren multiplicerede udgave 8SB=8R+8kA8S\cdot B = 8R + 8k\cdot A, som behandler enkelte grænsetilfælde mere lempeligt.

Ingen server bliver spurgt, ingen tjeneste skal være tilgængelig. Den offentlige nøgle er nok.


12. Hvorfor ligningen går op

Indsættelse er nok:

SB=(r+ka)B=rB+k(aB)=R+kA.S\cdot B = (r + k\,a)\cdot B = r\cdot B + k\,(a\cdot B) = R + k\cdot A.

Hele fidusen ligger i den midterste omskrivning: Skalarmultiplikationen er forenelig med additionen. Den, der kender aa, kan beregne et SS, der opfylder ligningen. Den, der ikke kender aa, skulle til et selvvalgt kk finde et passende SS — og det betyder at løse den diskrete logaritme.


13. Et fuldt gennemregnet minieksempel

Med de rigtige tal er der intet at regne efter — 253-bit-værdier kan ikke efterprøves i hovedet. Derfor den samme metode i en ganske lille gruppe, hvor hvert skridt kan følges med lommeregner.

Trin 1: Gruppen

Vi regner med resterne modulo 2323 og tager g=2g = 2. Der gælder

211=2048=8923+11(mod23),2^{11} = 2048 = 89\cdot 23 + 1 \equiv 1 \pmod{23},

gg frembringer altså en undergruppe af orden =11\ell = 11. Potenserne er:

nn1234567891011
gng^n248169181336121

gg overtager basispunktet BB's rolle, multiplikationen punktadditionens. Skalarer regnes modulo 1111, værdier modulo 2323.

Trin 2: Nøgleparret

Lad det hemmelige være a=6a = 6. Så er

A=ga=26=6418(mod23).A = g^a = 2^6 = 64 \equiv 18 \pmod{23}.

A=18A = 18 må alle godt vide.

Trin 3: Nonce og commitment

Lad præfiks og anmeldelse give r=4r = 4. Deraf:

R=gr=24=16.R = g^r = 2^4 = 16.

Trin 4: Challenge

Lad hashen over RR, AA og anmeldelsen give

k=5.k = 5.

Trin 5: Signaturen

S=(r+ka)mod11=(4+56)mod11=34mod11=1.S = (r + k\,a) \bmod 11 = (4 + 5\cdot 6) \bmod 11 = 34 \bmod 11 = 1.

Signaturen er parret (R,S)=(16,1)(R,S) = (16,\,1).

Trin 6: Browseren verificerer

Den beregner begge sider. Venstre:

gS=21=2.g^S = 2^1 = 2.

Højre, med 1853(mod23)18^5 \equiv 3 \pmod{23}:

RAk=163=482(mod23).R\cdot A^{k} = 16\cdot 3 = 48 \equiv 2 \pmod{23}.

Begge sider giver 22:

Signatur gyldig\boxed{\text{Signatur gyldig}}

Trin 7: Nogen ændrer anmeldelsesteksten

Teksten indgår i hashen, altså ændrer challengen sig — lad os sige til k=7k' = 7. Signaturen forbliver uændret (16,1)(16,1), men det gør højresiden ikke. Med 1876(mod23)18^7 \equiv 6 \pmod{23}:

RAk=166=964(mod23)    2=gSR\cdot A^{k'} = 16\cdot 6 = 96 \equiv 4 \pmod{23} \;\neq\; 2 = g^S
Signatur ugyldig\boxed{\text{Signatur ugyldig}}

Vi kan slette en anmeldelse. Ændre den kan vi ikke, uden at det bliver opdaget.

Ærlighedsbemærkning til eksemplet

Der blev her regnet i den multiplikative gruppe modulo 2323, ikke på en kurve: gSg^S står for SBS\cdot B, produktet RAkR\cdot A^k for punktadditionen R+kAR + k\cdot A. Strukturen er den samme, og det er netop pointen. Forskellige er størrelsesordenerne: =11\ell = 11 over for 2252\ell \approx 2^{252}, og dér kan nøglen ikke findes ved at prøve de elleve muligheder af.


14. Hvad der sker, hvis nogen ændrer anmeldelsen

Antag, at nogen med databaseadgang — også nogen hos os — ændrer anmeldelsesteksten eller et af hjerterne. Så ændrer datasættet sig og dermed mindst en af de to hashværdier h og rh i payloaden. Dermed ændrer mm sig, dermed challengen kk, dermed højresiden af verifikationsligningen. Den gamle signatur passer ikke længere.

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 den, tæller ikke længere med i virksomhedens gennemsnit.


15. Hvorfor en angriber ikke kommer igennem

Han kender den offentlige nøgle AA, basispunktet BB, kurven og hver eneste hidtil udstedt signatur. Det, han mangler, er aa.

Det bedste kendte klassiske angreb på det diskrete logaritmeproblem i en gruppe af orden \ell kræver omkring \sqrt{\ell} skridt. Ved 2252\ell \approx 2^{252} er det cirka

21262^{126}

operationer. Til sammenligning: Selv en maskine, der klarer en milliard milliarder (101810^{18}) skridt i sekundet, ville skulle bruge et mangefold af universets alder.

At forfalske uden nøglen ville betyde at finde et passende SS til et selvvalgt kk — den samme opgave i en anden forklædning.


16. Hvorfor Ed25519 og ikke ECDSA

Begge bygger på det samme problem. Forskellen ligger i alt det, der sker rundt om:

ECDSA (NIST-kurver)Ed25519
Noncekræver frisk tilfældigheddeterministisk ud fra præfiks og besked
Formlersærtilfælde, dataafhængige forgreningerfuldstændige, én beregningsvej
Kurveparametrekonstanternes oprindelse aldrig fuldt forklaretvalgt ud fra gennemskuelige kriterier
Signaturstørrelse64–72 B, variabel kodningfast 64 B
I browserentilgængelig længenativt siden 2023/2024, ellers som JS-bibliotek

For os var noncen det afgørende argument. En anmeldelsesportal signerer ofte og automatiseret; en metode, hvor en enkelt svag tilfældig værdi røber nøglen, er det forkerte valg hertil.


17. Hvad Ed25519 ikke kan

Ed25519 bygger på den diskrete logaritme — og netop dette problem løser en tilstrækkelig stor kvantecomputer effektivt med Shors algoritme. Om og hvornår sådanne maskiner findes, er åbent. For en anmeldelse, der skal kunne verificeres om ti år, er det alligevel et spørgsmål, man må besvare i dag.

Derfor kan der ved siden af Ed25519-signaturen komme et kvanteresistent stempel:

Ingen af dem erstatter Ed25519, de lægger sig ved siden af. Bryder den ene metode sammen, bærer den anden videre.


18. Forløbet i billeder

SIGNATURTJENESTE (MCGESUND)DEN BESØGENDES BROWSERprivat skalar a + præfiks (fra seedet)payload m = {virksomhed, anmeldelse, h, rh, iat}r = H(præfiks ‖ m) mod ℓR = r · Bk = H(R ‖ A ‖ m) mod ℓS = (r + k · a) mod ℓsignatur σ = (R, S) + kidanmeldelse + σ + offentlig nøgle Aberegn k på ny ud fra R, A og mS · B = R + k · A ?gyldigugyldig
Fra payload til fluebenet i browseren. Over skillelinjen sker alting én gang ved indsendelsen, under den på ny hos hver læser — på hans eget udstyr, alene med den offentlige nøgle.

19. Hvad McGesund konkret bruger det til

Konvolutten. Hver signeret anmeldelse bærer en MCG1:-konvolut med formatversion, payload og Ed25519-signatur. kid i payloaden siger, hvilken nøgle der menes; den tilhørende offentlige nøgle udleverer serveren på forespørgsel — den er offentlig, der er intet at beskytte ved den.

Verifikationen i browseren. Chrome og Firefox kan Ed25519 nativt via WebCrypto-grænsefladen siden 2023/2024. Safari kan ikke — dér kaster kaldet en fejl i stedet for at verificere. Derfor falder vores verifikationskode tilbage på en ren JavaScript-implementering, som kun hentes ind dér, hvor den er nødvendig. Signaturkontrollen kører dermed igennem i enhver browser, og det på læserens eget udstyr.

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 nøglen allerede eksisterede på et bestemt tidspunkt — uden at nogen behøver tro på vores tidsstempel.

Indholdsbindingen. Payloaden bærer rh, hashen over hele det indsendte datasæt: tekst, hjerter, geostatus, anledningsoplysninger og oprindelse. Ed25519-signaturen binder dermed ikke kun teksten, men alt det, der vises ved siden af anmeldelsen.


20. En sætning at tage med

Ed25519 gør et hemmeligt tal til en ligning,som alle kan efterregne og ingen kan opfinde.\boxed{ \begin{array}{c} \text{Ed25519 gør et hemmeligt tal til en ligning,}\\ \text{som alle kan efterregne og ingen kan opfinde.} \end{array}}

Den, der besidder den hemmelige skalar, underskriver på mikrosekunder. Den, der ikke besidder den, skulle løse en diskret logaritme i en gruppe med omkring 22522^{252} elementer.

For den, der læser en anmeldelse, betyder det ganske enkelt: Han behøver ikke tro på os. Han kan regne efter.