Postupak potpisivanja

Ed25519 matematički objašnjen

Potpis koji stoji uz svaku McGesund recenziju — od krivulje preko ključa do jednadžbe koju preglednik čitatelja sam preračuna.

Stanje: 2026-09-07

1. O čemu je riječ

Recenzija na McGesundu nije tekstualno polje u bazi podataka kojemu se mora vjerovati. Pri slanju se digitalno potpisuje, a svaki posjetitelj taj potpis može kasnije preračunati u vlastitom pregledniku.

Za taj potpis koristimo Ed25519. Za razliku od FALCON-a i ML-DSA, koji se dodatno mogu priložiti kao pečat, Ed25519 nije opcija: svaka potpisana recenzija nosi ga, neovisno o tarifi i načinu predaje.

Važno unaprijed:

Ed25519 nije šifriranje. Tekst recenzije se ionako treba čitati. Potpis ne dokazuje tajnost, nego podrijetlo i cjelovitost.


2. Što se točno potpisuje

Ne potpisuje se tekući tekst, nego kompaktan podatkovni objekt koji tekst i sve ostalo jednoznačno prikiva:

{
  "v":   1,
  "typ": "rev-comment",
  "f":   "<ID tvrtke>",
  "c":   "<ID recenzije>",
  "h":   "<SHA-256 teksta recenzije>",
  "rh":  "<SHA-256 cijelog zapisa o predaji>",
  "rv":  1,
  "qh":  "<SHA-256 QR omotnice, samo kod QR recenzija>",
  "kid": "<ID ključa>",
  "iat": 1757203200
}

Taj se objekt kodira u CBOR. Taj niz bajtova — a ne njegov lijepi prikaz gore — jest naša poruka mm. Potpis i poruka zajedno putuju u omotnici:

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

Broj 33 je verzija formata. Više u njoj nema — posebno nema post-kvantnog potpisa: on, ako postoji, leži uz zapis, a ne u omotnici.


3. Što potpis treba postići

Čitatelj koji dođe na profil poduzeća pred dva je pitanja:

  1. Potječe li ova recenzija doista iz McGesund sustava?
  2. Je li naknadno izmijenjena?

Za to postoji par ključeva:

  • privatni ključ — ostaje u servisu za potpisivanje
  • javni ključ — smije ga imati svatko, adresira se preko ID-a ključa (kid) u payloadu

Potpisuje se privatnim ključem. Provjerava se javnim — i to u pregledniku čitatelja, a ne na našem poslužitelju. U tome je bit: provjera koju sami provedemo i čiji rezultat objavimo ne bi bila provjera, nego tvrdnja.


4. Zašto eliptična krivulja?

Svaki potpis treba račun koji je u jednom smjeru lagan, a u drugom praktički nemoguć. Kod Ed25519 to je skalarno množenje na eliptičnoj krivulji:

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

Izračunati javnu točku AA iz tajnog broja aa traje mikrosekunde. Zaključiti iz AA natrag na aa znači riješiti problem diskretnog logaritma — za njega nije poznat postupak koji bi pri ovoj veličini završio u ljudskim vremenskim okvirima.

Praktična prednost pred starijim postupcima poput RSA jest veličina:

javni ključpotpis
RSA-3072384 B384 B
Ed2551932 B64 B

Uz usporedivu razinu sigurnosti. 64 bajta po recenziji ni pri milijunima recenzija nisu veličina o kojoj treba razmišljati.


5. Krivulja edwards25519

Računa se modulo prostim brojem:

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

Otuda i ime. Krivulja je uvrnuta Edwardsova krivulja:

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

„Točka" je par brojeva (x,y)(x,y) iz {0,,p1}\{0,\dots,p-1\} koji zadovoljava tu jednadžbu. Nema tu krivulje za vidjeti — crtež u sljedećem odjeljku pomoćna je slika nad realnim brojevima, a ne prikaz stvarnog računskog prostora.

Dolaze još dvije veličine:

  • čvrsto dogovorena bazna točka BB,
  • red \ell podgrupe koju BB generira:
=2252+27742317777372353535851937790883648493.\ell = 2^{252} + 27742317777372353535851937790883648493.

\ell je prost. To znači: zbraja li se BB uvijek iznova sa samim sobom, prolazi se točno kroz \ell različitih točaka i zatim se ponovno završava na početku. Svi računi sa skalarima zato teku modulo \ell, a svi računi s koordinatama modulo pp. Zamijeniti ta dva broja klasična je početnička pogreška.


6. Zbrajanje točaka

Dvije se točke po čvrstoj formuli spajaju u treću:

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

Neutralni element je (0,1)(0,1) — točka u kojoj računanje počinje.

Ta formula ima svojstvo koje se na njoj ne vidi, a za sigurnost je važnije od bilo koje konstante: ona je potpuna. Radi za sve ulaze, bez posebnih slučajeva za „obje su točke jednake" ili „rezultat je neutralni element". Kod starijih Weierstrassovih krivulja ti posebni slučajevi postoje i svaki je od njih grana u programu — grana čije se trajanje da izmjeriti. Tko mjeri koliko potpisivanje traje, kod takvih postupaka doznaje nešto o tajnom ključu.

Potpune formule znače: uvijek isti računski put, uvijek isto vrijeme, ništa za izmjeriti.


7. Skalarno množenje — jednosmjerna ulica

nBn\cdot B znači: zbrojiti BB točno nn puta sa samim sobom. Pri nn od 253 bita to bi bilo besmisleno mnogo posla — zato se udvostručuje:

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

a iz tih se međurezultata sastavi željeni nn. Oko 253 udvostručenja dovoljno je za svaki nn. To je put naprijed.

Unatrag te prečice nema. Odrediti broj aa iz točke AA znači riješiti problem diskretnog logaritma.

(0,1) — neutralni elementB2B3B4B5B6B
Edwardsova krivulja s prvim višekratnicima bazne točke, izračunatima pravim zakonom zbrajanja. Nad realnim brojevima oni se još vidljivo uređeno kreću krivuljom — put bi se dao slijediti unatrag. Modulo p nestaje upravo taj poredak, a na tome počiva sigurnost.

U stvarnom se postupku računa modulo pp. Ondje nema „lijevo", nema „desno" ni blizine: iz 17B17\,B i 18B18\,B nastaju dva para brojeva bez ikakve prepoznatljive srodnosti.


8. Par ključeva servisa za potpisivanje

Na početku stoje 32 slučajna bajta, Seed. Sve ostalo iz njega se izvodi:

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

Iz prve polovice nastaje tajni skalar aa, ali ne nepromijenjen. Tri se bita postavljaju odnosno brišu — takozvani clamping:

  • donja se tri bita postavljaju na nulu: aa time postaje višekratnik broja 8. Razlog je kofaktor 8 krivulje — puna grupa točaka osam je puta veća od podgrupe reda \ell. Skalar aa djeljiv s 8 zajamčeno završava u ispravnoj podgrupi i ne odaje ništa preko točaka malog reda.
  • najviši se bit briše, a drugi po redu postavlja: aa time uvijek ima istu duljinu u bitovima. Kraći aa trebao bi manje udvostručenja — i opet bi se iz trajanja nešto dalo iščitati.

Javni je ključ tada naprosto

A=aB,A = a\cdot B,

pohranjen kao 32 bajta: yy-koordinata i, u najvišem bitu, predznak od xx. Vrijednost xx provjeritelj sam izračuna natrag iz jednadžbe krivulje — dva se rješenja razlikuju samo u predznaku, a koje se misli, kaže taj jedan bit.

Druga polovica hash-vrijednosti, prefiks, ne treba za ključ. Ona dolazi na red u sljedećem odjeljku.


9. Zašto slučajnost ovdje nije slučajna

Svaki potpis ove izvedbe treba jednokratnu vrijednost rr, često zvanu nonce. Ona se nikada ne smije ponoviti: tko ima dva potpisa s istim rr, tajni ključ može izračunati školskom algebrom.

Upravo su na tome stvarni sustavi propali. Najpoznatiji je slučaj provjera potpisa jedne igraće konzole, čiji je proizvođač 2010. uvijek koristio isti nonce — privatni je ključ time bio javno rekonstruirljiv.

Ed25519 to rješava tako da uopće ne koristi slučajnost:

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

Nonce ovisi o tajnom prefiksu i o poruci. Iz toga slijedi dvoje:

  • Dvije različite recenzije daju s golemom vjerojatnošću različite rr — do ponavljanja ne dolazi.
  • Ista recenzija daje uvijek isti potpis. Postupak potpisivanja time je provjerljiv, a loš generator slučajnih brojeva na poslužitelju ne može ništa pokvariti jer se nijedan ne treba.

Za portal s recenzijama i mnogo potpisa dnevno to nije akademska prednost. To je razlika između „pogreška u izvoru slučajnosti bila bi kobna" i „nema izvora slučajnosti koji bi mogao zakazati".


10. Potpisivanje

Tri retka, više od toga nema:

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

Potpis je par

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

32 bajta za točku RR, 32 bajta za broj SS — zajedno 64 bajta.

Vrijedi zamijetiti drugi redak: u kk ulaze RR, javni ključ AA i poruka. To što se AA uhashira nije ukras — sprječava napade u kojima se potpis pripiše drugom ključu.


11. Provjera

Preglednik čitatelja zna: recenziju mm, potpis (R,S)(R,S) i javni ključ AA. On iznova izračuna kk i provjeri jednu jedinu jednadžbu:

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

Vrijedi li ona, potpis je valjan. RFC 8032 dopušta dodatno i inačicu pomnoženu kofaktorom, 8SB=8R+8kA8S\cdot B = 8R + 8k\cdot A, koja neke rubne slučajeve tretira velikodušnije.

Nijedan se poslužitelj ne pita, nijedna usluga ne mora biti dostupna. Javni ključ je dovoljan.


12. Zašto jednadžba vrijedi

Dovoljno je uvrstiti:

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.

Cijeli je trik u srednjoj preinaci: skalarno se množenje slaže sa zbrajanjem. Tko zna aa, može izračunati SS koji jednadžbu zadovoljava. Tko aa ne zna, morao bi uz samostalno odabrani kk pronaći odgovarajući SS — a to znači riješiti diskretni logaritam.


13. Do kraja izračunat mini-primjer

S pravim brojevima nema se što preračunati — vrijednosti od 253 bita ne daju se provjeriti napamet. Zato isti postupak u sićušnoj grupi, u kojoj je svaki korak provjerljiv džepnim računalom.

Korak 1: Grupa

Računamo s ostacima modulo 2323 i uzimamo g=2g = 2. Vrijedi

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

gg dakle generira podgrupu reda =11\ell = 11. Potencije su:

nn1234567891011
gng^n248169181336121

gg preuzima ulogu bazne točke BB, a množenje ulogu zbrajanja točaka. Skalari se računaju modulo 1111, vrijednosti modulo 2323.

Korak 2: Par ključeva

Neka je tajno a=6a = 6. Tada je

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

A=18A = 18 smije znati svatko.

Korak 3: Nonce i commitment

Iz prefiksa i recenzije neka proizađe r=4r = 4. Odatle:

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

Korak 4: Izazov

Neka hash preko RR, AA i recenzije dade

k=5.k = 5.

Korak 5: Potpis

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.

Potpis je par (R,S)=(16,1)(R,S) = (16,\,1).

Korak 6: Preglednik provjerava

On izračuna obje strane. Lijevo:

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

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

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

Obje strane daju 22:

Potpis je valjan\boxed{\text{Potpis je valjan}}

Korak 7: Netko mijenja tekst recenzije

Tekst ulazi u hash, dakle mijenja se izazov — recimo na k=7k' = 7. Potpis ostaje nepromijenjen na (16,1)(16,1), ali desna strana ne. Uz 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
Potpis nije valjan\boxed{\text{Potpis nije valjan}}

Recenziju možemo obrisati. Izmijeniti je ne možemo a da se to ne primijeti.

Iskrena napomena uz primjer

Ovdje se računalo u multiplikativnoj grupi modulo 2323, a ne na krivulji: gSg^S stoji za SBS\cdot B, a umnožak RAkR\cdot A^k za zbrajanje točaka R+kAR + k\cdot A. Struktura je ista, i upravo je o tome riječ. Različiti su redovi veličine: =11\ell = 11 naspram 2252\ell \approx 2^{252}, a ondje se ključ ne nalazi isprobavanjem jedanaest mogućnosti.


14. Što se događa ako netko promijeni recenziju

Pretpostavimo da netko s pristupom bazi podataka — pa i netko kod nas — promijeni tekst recenzije ili jedno od srca. Tada se mijenja zapis, a time barem jedna od dviju hash-vrijednosti h i rh u payloadu. Time se mijenja mm, time izazov kk, time desna strana jednadžbe provjere. Stari potpis više ne odgovara.

Odlučujuća rečenica uz to: recenziju možemo obrisati, ali je ne možemo neopaženo izmijeniti. Na McGesundu ista provjera dodatno noću teče na poslužitelju preko cijelog fonda — recenzija koja je ne prođe više ne ulazi u prosjek poduzeća.


15. Zašto napadač ne uspijeva

On zna javni ključ AA, baznu točku BB, krivulju i svaki dosad izdani potpis. Nedostaje mu aa.

Najbolji poznati klasični napad na problem diskretnog logaritma u grupi reda \ell treba oko \sqrt{\ell} koraka. Pri 2252\ell \approx 2^{252} to je otprilike

21262^{126}

operacija. Za usporedbu: čak bi i stroj koji izvede milijardu milijardi (101810^{18}) koraka u sekundi za to trebao višekratnik starosti svemira.

Krivotvorenje bez ključa značilo bi uz samostalno odabrani kk pronaći odgovarajući SS — isti zadatak u drugom ruhu.


16. Zašto Ed25519, a ne ECDSA

Oba počivaju na istom problemu. Razlika je u svemu što se događa oko njega:

ECDSA (NIST krivulje)Ed25519
Noncepotrebna svježa slučajnostdeterministički iz prefiksa i poruke
Formuleposebni slučajevi, grane ovisne o podacimapotpune, jedan računski put
Parametri krivuljepodrijetlo konstanti nikad potpuno objašnjenoodabrani po provjerljivim kriterijima
Veličina potpisa64–72 B, promjenjivo kodiranječvrstih 64 B
U preglednikuodavno dostupannativno od 2023./2024., inače kao JS-biblioteka

Za nas je nonce bio presudan argument. Portal s recenzijama potpisuje često i automatizirano; postupak kod kojega jedna jedina slaba slučajna vrijednost odaje ključ za to je pogrešan izbor.


17. Što Ed25519 ne postiže

Ed25519 počiva na diskretnom logaritmu — a upravo taj problem dovoljno veliko kvantno računalo rješava učinkovito Shorovim algoritmom. Hoće li i kada takvi strojevi postojati, otvoreno je pitanje. Za recenziju koja bi i za deset godina trebala biti provjerljiva to je unatoč tome pitanje na koje se mora odgovoriti danas.

Zato uz Ed25519 potpis može stati kvantno otporan pečat:

Nijedan ne zamjenjuje Ed25519, nego staje uz njega. Pukne li jedan postupak, drugi nosi dalje.


18. Tijek postupka na slici

SERVIS ZA POTPISIVANJE (MCGESUND)PREGLEDNIK POSJETITELJAprivatni skalar a + prefiks (iz Seeda)Payload m = {tvrtka, recenzija, h, rh, iat}r = H(prefiks ‖ m) mod ℓR = r · Bk = H(R ‖ A ‖ m) mod ℓS = (r + k · a) mod ℓpotpis σ = (R, S) + kidrecenzija + σ + javni ključ Aponovno izračunati k iz R, A i mS · B = R + k · A ?valjannevaljan
Od payloada do kvačice u pregledniku. Iznad razdjelne crte sve se događa jednom pri slanju, ispod nje kod svakog čitatelja iznova — na njegovu uređaju, samo s javnim ključem.

19. Što McGesund konkretno radi s time

Envelope. Svaka potpisana recenzija nosi MCG1: omotnicu s verzijom formata, payloadom i Ed25519 potpisom. kid u payloadu kaže na koji se ključ misli; pripadni javni ključ poslužitelj izdaje na upit — on je javan, na njemu nema što štititi.

Provjera u pregledniku. Chrome i Firefox podržavaju Ed25519 od 2023./2024. nativno preko WebCrypto sučelja. Safari ne — ondje poziv baca pogrešku umjesto da provjeri. Zato se naš kôd za provjeru vraća na čistu JavaScript implementaciju, koja se dohvaća samo ondje gdje je potrebna. Provjera potpisa time prolazi u svakom pregledniku, i to na uređaju čitatelja.

Vremensko sidro. Otisak ključa za potpisivanje sidri se preko OpenTimestampsa u jednom Bitcoin bloku. Time se ne dokazuje samo da je potpis pravi, nego i da je ključ u određenom trenutku već postojao — a da pritom nitko ne mora vjerovati našem vremenskom žigu.

Vezanje sadržaja. Payload nosi rh, hash preko cijelog zapisa o predaji: teksta, srca, geo-statusa, podataka o povodu i podrijetla. Ed25519 potpis time veže ne samo tekst, nego sve što se uz recenziju prikazuje.


20. Jedna rečenica za kraj

Ed25519 od tajnog broja stvara jednadzˇbu kojusvatko mozˇe provjeriti, a nitko izmisliti.\boxed{ \begin{array}{c} \text{Ed25519 od tajnog broja stvara jednadžbu koju}\\ \text{svatko može provjeriti, a nitko izmisliti.} \end{array}}

Tko posjeduje tajni skalar, potpisuje u mikrosekundama. Tko ga ne posjeduje, morao bi riješiti diskretni logaritam u grupi s otprilike 22522^{252} elemenata.

Za čitatelja recenzije to naprosto znači: ne mora nam vjerovati. Može preračunati.