Handtekeningmethode

Ed25519 wiskundig uitgelegd

De handtekening die aan elke McGesund-beoordeling hangt — van de kromme via de sleutel tot de vergelijking die de browser van de lezer narekent.

Stand: 2026-09-07

1. Waar het hier over gaat

Een beoordeling bij McGesund is geen tekstveld in een database dat u maar moet geloven. Zij wordt bij het verzenden digitaal ondertekend, en elke bezoeker kan die handtekening later in de eigen browser narekenen.

Voor deze handtekening gebruiken wij Ed25519. Anders dan FALCON en ML-DSA, die er als extra stempel naast kunnen worden gelegd, is Ed25519 geen optie: elke ondertekende beoordeling draagt haar, ongeacht tarief en manier van indienen.

Vooraf van belang:

Ed25519 is geen versleuteling. De beoordelingstekst is immers bedoeld om gelezen te worden. De handtekening bewijst geen geheimhouding, maar herkomst en integriteit.


2. Wat er precies wordt ondertekend

Ondertekend wordt niet de lopende tekst, maar een compact gegevensobject dat de tekst en al het overige eenduidig vastlegt:

{
  "v":   1,
  "typ": "rev-comment",
  "f":   "<bedrijfs-ID>",
  "c":   "<beoordelings-ID>",
  "h":   "<SHA-256 van de beoordelingstekst>",
  "rh":  "<SHA-256 van het volledige ingediende record>",
  "rv":  1,
  "qh":  "<SHA-256 van de QR-envelop, alleen bij QR-beoordelingen>",
  "kid": "<sleutel-ID>",
  "iat": 1757203200
}

Dit object wordt naar CBOR gecodeerd. Die bytereeks — niet de nette weergave hierboven — is ons bericht mm. Handtekening en bericht gaan samen in een envelop:

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

De 33 is de formaatversie. Meer staat er niet in — met name geen post-quantumhandtekening: die ligt, als zij bestaat, naast het record en niet in de envelop.


3. Wat de handtekening moet leveren

Een lezer die op een ondernemingsprofiel terechtkomt, staat voor twee vragen:

  1. Komt deze beoordeling werkelijk uit het McGesund-systeem?
  2. Is zij achteraf gewijzigd?

Daarvoor bestaat een sleutelpaar:

  • een private sleutel — blijft in de ondertekeningsdienst
  • een openbare sleutel — mag iedereen hebben, wordt via de sleutel-ID (kid) in de payload aangesproken

Ondertekend wordt met de private sleutel. Gecontroleerd wordt met de openbare — en wel in de browser van de lezer, niet op onze server. Dat is het punt: een controle die wij zelf uitvoeren en waarvan wij het resultaat meedelen, zou geen controle zijn, maar een bewering.


4. Waarom een elliptische kromme?

Elke handtekening heeft een berekening nodig die in de ene richting eenvoudig en in de andere praktisch onmogelijk is. Bij Ed25519 is dat de scalaire vermenigvuldiging op een elliptische kromme:

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

Uit het geheime getal aa het openbare punt AA berekenen kost microseconden. Uit AA terugrekenen naar aa is het discretelogaritmeprobleem — daarvoor is geen methode bekend die bij deze omvang binnen menselijke tijdschalen klaar is.

De praktische winst ten opzichte van oudere methoden zoals RSA is de omvang:

openbare sleutelhandtekening
RSA-3072384 B384 B
Ed2551932 B64 B

Bij een vergelijkbaar beveiligingsniveau. 64 byte per beoordeling is ook bij miljoenen beoordelingen geen omvang om over na te denken.


5. De kromme edwards25519

Er wordt gerekend modulo een priemgetal:

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

Vandaar de naam. De kromme is een getwiste Edwards-kromme:

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

Een „punt" is een getallenpaar (x,y)(x,y) uit {0,,p1}\{0,\dots,p-1\} dat aan deze vergelijking voldoet. Er valt geen kromme te zien — de tekening in het volgende hoofdstuk is een aanschouwelijk hulpmiddel over de reële getallen, geen afbeelding van de werkelijke rekenruimte.

Twee grootheden komen er nog bij:

  • een vast afgesproken basispunt BB,
  • de orde \ell van de door BB voortgebrachte ondergroep:
=2252+27742317777372353535851937790883648493.\ell = 2^{252} + 27742317777372353535851937790883648493.

\ell is priem. Dat betekent: telt u BB steeds opnieuw bij zichzelf op, dan doorloopt u precies \ell verschillende punten en belandt daarna weer bij het begin. Alle berekeningen met scalairen lopen daarom modulo \ell, alle berekeningen met coördinaten modulo pp. Deze twee getallen verwisselen is de klassieke beginnersfout.


6. Punten optellen

Twee punten worden volgens een vaste formule tot een derde verrekend:

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}.

Het neutrale element is (0,1)(0,1) — het punt waar het rekenen begint.

Deze formule heeft een eigenschap die u er niet aan afziet en die voor de veiligheid belangrijker is dan welke constante ook: zij is volledig. Zij werkt voor alle invoeren, zonder bijzondere gevallen voor „beide punten gelijk" of „resultaat is het neutrale element". Bij de oudere Weierstrass-krommen bestaan die bijzondere gevallen wel, en elk daarvan is een vertakking in het programma — een vertakking waarvan de looptijd meetbaar is. Wie meet hoe lang een handtekening duurt, komt bij zulke methoden iets over de geheime sleutel te weten.

Volledige formules betekenen: altijd dezelfde rekenweg, altijd dezelfde tijd, niets te meten.


7. Scalaire vermenigvuldiging — de eenrichtingsweg

nBn\cdot B betekent: BB precies nn keer bij zichzelf optellen. Bij een nn van 253 bit zou dat zinloos veel werk zijn — daarom wordt er verdubbeld:

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

en uit deze tussenresultaten wordt de gewenste nn samengesteld. Ongeveer 253 verdubbelingen volstaan voor elke nn. Dat is de weg vooruit.

Achteruit bestaat die kortere weg niet. Uit het punt AA het getal aa bepalen betekent het discretelogaritmeprobleem oplossen.

(0,1) — neutraal elementB2B3B4B5B6B
Een Edwards-kromme met de eerste veelvouden van het basispunt, berekend met de echte optelwet. Over de reële getallen verplaatsen zij zich nog zichtbaar geordend over de kromme — u zou de weg terug kunnen volgen. Modulo p verdwijnt precies die ordening, en daarop berust de veiligheid.

In de echte methode wordt modulo pp gerekend. Daar bestaat geen „links", geen „rechts" en geen nabijheid: uit 17B17\,B en 18B18\,B worden twee getallenparen zonder enige herkenbare verwantschap.


8. Het sleutelpaar van de ondertekeningsdienst

Aan het begin staan 32 willekeurige bytes, de seed. Al het overige wordt daaruit afgeleid:

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

Uit de eerste helft ontstaat de geheime scalair aa, zij het niet ongewijzigd. Drie bits worden gezet respectievelijk gewist — het zogenoemde clamping:

  • de onderste drie bits worden op nul gezet: aa wordt daardoor een veelvoud van 8. De reden is de cofactor 8 van de kromme — de volledige puntengroep is achtmaal zo groot als de ondergroep van orde \ell. Een door 8 deelbare aa belandt gegarandeerd in de juiste ondergroep en verraadt niets over punten van kleine orde.
  • het bovenste bit wordt gewist, het op één na bovenste gezet: aa heeft daarmee altijd dezelfde bitlengte. Een kortere aa zou minder verdubbelingen vergen — en opnieuw zou er aan de looptijd iets af te lezen zijn.

De openbare sleutel is dan eenvoudigweg

A=aB,A = a\cdot B,

opgeslagen als 32 byte: de yy-coördinaat, en in het hoogste bit het teken van xx. De xx rekent de controleur zelf terug uit de krommevergelijking — beide oplossingen verschillen alleen in het teken, en welke bedoeld is, zegt dat ene bit.

De tweede helft van de hashwaarde, de prefix, is voor de sleutel niet nodig. Zij komt in het volgende hoofdstuk aan bod.


9. Waarom het toeval hier geen toeval is

Elke handtekening van deze bouwwijze heeft een eenmalige waarde rr nodig, vaak nonce genoemd. Die mag zich nooit herhalen: wie twee handtekeningen met dezelfde rr heeft, kan de geheime sleutel met schoolalgebra uitrekenen.

Precies daarop zijn reële systemen stukgelopen. Het bekendste geval is de handtekeningcontrole van een spelcomputer, waarvan de fabrikant in 2010 steeds dezelfde nonce gebruikte — de private sleutel was daarmee openbaar reconstrueerbaar.

Ed25519 lost dat op door helemaal geen toeval te gebruiken:

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

De nonce hangt aan de geheime prefix en aan het bericht. Daaruit volgt tweeërlei:

  • Twee verschillende beoordelingen leveren met overweldigende waarschijnlijkheid verschillende rr op — het herhalingsgeval treedt niet op.
  • Dezelfde beoordeling levert altijd dezelfde handtekening op. Een ondertekening laat zich daarmee reproduceren, en een slechte toevalsgenerator op de server kan niets kapotmaken, omdat er geen nodig is.

Voor een beoordelingsportaal met veel handtekeningen per dag is dat geen academisch voordeel. Het is het verschil tussen „een fout in de toevalsbron zou fataal zijn" en „er is geen toevalsbron die kan uitvallen".


10. Ondertekenen

Drie regels, meer is het niet:

r=H(prefix    m)mod,R=rB,r = H(\text{prefix}\;\|\;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.

De handtekening is het paar

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

32 byte voor het punt RR, 32 byte voor het getal SS — samen 64 byte.

De tweede regel is opmerkelijk: in kk gaan RR, de openbare sleutel AA en het bericht mee. Dat AA mee wordt gehasht, is geen bijzaak — het verhindert aanvallen waarbij een handtekening naar een andere sleutel wordt omgeduid.


11. Controleren

De browser van de lezer kent: de beoordeling mm, de handtekening (R,S)(R,S) en de openbare sleutel AA. Hij rekent kk opnieuw uit en controleert één enkele vergelijking:

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

Klopt zij, dan is de handtekening geldig. RFC 8032 staat daarnaast de met de cofactor vermenigvuldigde versie 8SB=8R+8kA8S\cdot B = 8R + 8k\cdot A toe, die enkele randgevallen ruimhartiger behandelt.

Er wordt geen server gevraagd, geen dienst hoeft beschikbaar te zijn. De openbare sleutel volstaat.


12. Waarom de vergelijking klopt

Invullen volstaat:

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.

De hele truc zit in de middelste omvorming: de scalaire vermenigvuldiging verdraagt zich met de optelling. Wie aa kent, kan een SS uitrekenen die aan de vergelijking voldoet. Wie aa niet kent, zou bij een zelfgekozen kk een passende SS moeten vinden — en dat betekent het discrete logaritme oplossen.


13. Een volledig doorgerekend minivoorbeeld

Met de echte getallen valt niets na te rekenen — 253-bitwaarden laten zich niet uit het hoofd controleren. Daarom dezelfde methode in een piepkleine groep, waarin elke stap met de rekenmachine te volgen is.

Stap 1: De groep

Wij rekenen met de resten modulo 2323 en nemen g=2g = 2. Er geldt

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

gg brengt dus een ondergroep van orde =11\ell = 11 voort. De machten zijn:

nn1234567891011
gng^n248169181336121

gg neemt de rol van het basispunt BB over, de vermenigvuldiging die van de puntoptelling. Scalairen rekenen modulo 1111, waarden modulo 2323.

Stap 2: Het sleutelpaar

Geheim zij a=6a = 6. Dan is

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

A=18A = 18 mag iedereen weten.

Stap 3: Nonce en commitment

Uit prefix en beoordeling volge r=4r = 4. Daaruit:

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

Stap 4: De challenge

De hash over RR, AA en de beoordeling levere

k=5.k = 5.

Stap 5: De handtekening

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.

De handtekening is het paar (R,S)=(16,1)(R,S) = (16,\,1).

Stap 6: De browser controleert

Hij rekent beide zijden uit. Links:

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

Rechts, met 1853(mod23)18^5 \equiv 3 \pmod{23}:

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

Beide zijden leveren 22 op:

Handtekening geldig\boxed{\text{Handtekening geldig}}

Stap 7: Iemand wijzigt de beoordelingstekst

De tekst gaat mee in de hash, dus verandert de challenge — zeg naar k=7k' = 7. De handtekening blijft ongewijzigd (16,1)(16,1), de rechterzijde echter niet. Met 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
Handtekening ongeldig\boxed{\text{Handtekening ongeldig}}

Wij kunnen een beoordeling verwijderen. Veranderen kunnen wij haar niet zonder dat het opvalt.

Eerlijkheidshalve over dit voorbeeld

Er is hier gerekend in de multiplicatieve groep modulo 2323, niet op een kromme: gSg^S staat voor SBS\cdot B, het product RAkR\cdot A^k voor de puntoptelling R+kAR + k\cdot A. De structuur is dezelfde, en daar gaat het om. Verschillend zijn de ordes van grootte: =11\ell = 11 tegenover 2252\ell \approx 2^{252}, en daar is de sleutel niet door het uitproberen van elf mogelijkheden te vinden.


14. Wat er gebeurt wanneer iemand de beoordeling wijzigt

Stel dat iemand met databasetoegang — ook iemand bij ons — de beoordelingstekst of een van de hartjes wijzigt. Dan verandert het record en daarmee ten minste een van de twee hashwaarden h en rh in de payload. Daarmee verandert mm, daarmee de challenge kk, daarmee de rechterzijde van de controlevergelijking. De oude handtekening past niet meer.

De doorslaggevende zin daarbij: wij kunnen een beoordeling verwijderen, maar wij kunnen haar niet onopgemerkt veranderen. Bij McGesund loopt dezelfde controle daarnaast elke nacht aan serverzijde over het bestand — een beoordeling die haar niet doorstaat, telt niet meer mee in het gemiddelde van de onderneming.


15. Waarom een aanvaller strandt

Hij kent de openbare sleutel AA, het basispunt BB, de kromme en elke tot nu toe afgegeven handtekening. Wat hem ontbreekt, is aa.

De beste bekende klassieke aanval op het discretelogaritmeprobleem in een groep van orde \ell vergt ongeveer \sqrt{\ell} stappen. Bij 2252\ell \approx 2^{252} zijn dat ruwweg

21262^{126}

bewerkingen. Ter vergelijking: zelfs een machine die een miljard miljard (101810^{18}) stappen per seconde haalt, zou daarvoor een veelvoud van de leeftijd van het heelal nodig hebben.

Vervalsen zonder de sleutel zou betekenen: bij een zelfgekozen kk een passende SS vinden — dezelfde opgave in een andere vermomming.


16. Waarom Ed25519 en niet ECDSA

Beide berusten op hetzelfde probleem. Het verschil zit in alles wat eromheen gebeurt:

ECDSA (NIST-krommen)Ed25519
Noncevers toeval nodigdeterministisch uit prefix en bericht
Formulesbijzondere gevallen, gegevensafhankelijke vertakkingenvolledig, één rekenweg
Krommeparametersherkomst van de constanten nooit volledig verklaarduit navolgbare criteria gekozen
Handtekeninggrootte64–72 B, variabele coderingvast 64 B
In de browseral lang beschikbaarsinds 2023/2024 natief, anders als JS-bibliotheek

Voor ons was de nonce het doorslaggevende argument. Een beoordelingsportaal ondertekent vaak en geautomatiseerd; een methode waarbij één enkele zwakke toevalswaarde de sleutel prijsgeeft, is daarvoor de verkeerde keuze.


17. Wat Ed25519 niet levert

Ed25519 berust op het discrete logaritme — en precies dat probleem lost een voldoende grote quantumcomputer met het algoritme van Shor efficiënt op. Of en wanneer zulke machines er zijn, is open. Voor een beoordeling die over tien jaar nog controleerbaar moet zijn, is dat desondanks een vraag die vandaag beantwoord moet worden.

Daarom kan naast de Ed25519-handtekening een quantumresistent stempel komen te staan:

Beide vervangen Ed25519 niet, zij komen ernaast te liggen. Breekt een van de methoden, dan draagt de andere verder.


18. Het verloop in beeld

ONDERTEKENINGSDIENST (MCGESUND)BROWSER VAN DE BEZOEKERprivate scalair a + prefix (uit de seed)payload m = {bedrijf, beoordeling, h, rh, iat}r = H(prefix ‖ m) mod ℓR = r · Bk = H(R ‖ A ‖ m) mod ℓS = (r + k · a) mod ℓhandtekening σ = (R, S) + kidbeoordeling + σ + openbare sleutel Ak opnieuw berekenen uit R, A en mS · B = R + k · A ?geldigongeldig
Van payload tot het vinkje in de browser. Boven de scheidingslijn gebeurt alles eenmalig bij het verzenden, daaronder bij elke lezer opnieuw — op zijn apparaat, alleen met de openbare sleutel.

19. Wat McGesund er concreet mee doet

De envelop. Elke ondertekende beoordeling draagt een MCG1:-envelop met formaatversie, payload en Ed25519-handtekening. De kid in de payload zegt welke sleutel bedoeld is; de bijbehorende openbare sleutel levert de server op aanvraag uit — hij is openbaar, daaraan valt niets te beschermen.

De controle in de browser. Chrome en Firefox kunnen Ed25519 sinds 2023/2024 natief via de WebCrypto-interface. Safari niet — daar werpt de aanroep een fout in plaats van te controleren. Daarom valt onze controlecode terug op een zuivere JavaScript-implementatie, die alleen daar wordt nageladen waar zij nodig is. De handtekeningcontrole loopt daarmee in elke browser door, en wel op het apparaat van de lezer.

Het tijdanker. De vingerafdruk van de ondertekeningssleutel wordt via OpenTimestamps in een Bitcoin-blok verankerd. Daarmee valt niet alleen aan te tonen dat de handtekening echt is, maar ook dat de sleutel op een bepaald tijdstip al bestond — zonder dat iemand ons tijdstempel hoeft te geloven.

De inhoudsbinding. De payload draagt rh, de hash over het volledige ingediende record: tekst, hartjes, geostatus, gegevens over de aanleiding en herkomst. De Ed25519-handtekening bindt daarmee niet alleen de tekst, maar alles wat naast de beoordeling wordt getoond.


20. Eén zin om te onthouden

Ed25519 maakt van een geheim getal een vergelijkingdie iedereen kan narekenen en niemand kan verzinnen.\boxed{ \begin{array}{c} \text{Ed25519 maakt van een geheim getal een vergelijking}\\ \text{die iedereen kan narekenen en niemand kan verzinnen.} \end{array}}

Wie de geheime scalair bezit, ondertekent in microseconden. Wie hem niet bezit, zou een discreet logaritme in een groep met ongeveer 22522^{252} elementen moeten oplossen.

Voor de lezer van een beoordeling betekent dat eenvoudigweg: hij hoeft ons niet te geloven. Hij kan narekenen.