Signaturmetoder

ML-DSA-87 matematiskt förklarat

Hur ML-DSA-87 (FIPS 204) undertecknar ett omdöme på McGesund — från Module-LWE över Rejection Sampling till verifieringen i webbläsaren.

Uppdaterat: 2026-09-07

1. Vad det handlar om

När någon lämnar ett omdöme på McGesund sker mer i bakgrunden än texten låter ana. Omdömet signeras digitalt när det skickas in. Denna signatur kan varje besökare senare räkna efter i sin egen webbläsare — utan att lita på oss och utan att fråga oss.

För kunder från abonnemanget Pro och uppåt sker det bland annat med ML-DSA-87. Denna artikel förklarar vad som matematiskt sker.

Viktigt att slå fast först:

ML-DSA är ingen kryptering. Omdömestexten förblir offentligt läsbar — det är ju hela poängen med ett omdöme. ML-DSA bevisar inte sekretess, utan ursprung och oförändrat innehåll.

ML-DSA utvecklades ur CRYSTALS-Dilithium och är standardiserad som FIPS 204. Talet 87 betecknar parameternivån. Det finns tre:

  • ML-DSA-44
  • ML-DSA-65
  • ML-DSA-87

ML-DSA-87 är den högsta och ligger i NIST:s säkerhetskategori 5.


2. Vad signeras egentligen?

Det är inte omdömestexten själv som vandrar in i signaturen, utan ett kompakt dataobjekt som entydigt spikar fast texten. Hos McGesund ser det i kärnan ut så här:

{
  "v":   1,
  "typ": "rev-comment",
  "f":   "<Företags-ID>",
  "c":   "<Omdömes-ID>",
  "h":   "<SHA-256 av omdömestexten>",
  "rh":  "<SHA-256 av hela den inskickade datamängden>",
  "rv":  1,
  "qh":  "<SHA-256 av QR-envelopen, endast vid QR-omdömen>",
  "iat": 1757203200
}

Detta objekt är vårt meddelande mm. Det binder samman sex utsagor:

  1. Till vilket företag omdömet hör (f)
  2. Vilket omdöme som avses (c)
  3. Vilken text som låg bakom — som hashvärde (h)
  4. Vilken datamängd i sin helhet som lämnades in (rh): text, hjärtan, geostatus och uppgifter om anledning, kanoniskt serialiserade och hashade — i schemaversionen rv
  5. Ur vilken QR-kod omdömet kommer (qh); utan QR utgår fältet
  6. När signeringen skedde (iat)

Ändrar någon senare ett enda tecken i omdömestexten stämmer h inte längre — och inte rh heller. Den som i stället bara skruvar på hjärtana lämnar h orört, men bryter rh. Ändrar någon ett av dessa hashvärden stämmer signaturen inte längre. Just denna kedja är poängen.


3. Vad signaturen ska åstadkomma

En besökare som läser omdömet ska själv kunna kontrollera tre saker:

  1. Omdömet utfärdades faktiskt av McGesund.
  2. Texten har inte ändrats sedan inskickandet.
  3. Ingen kan hitta på ett nytt, giltigt utseende omdöme.

För detta finns ett nyckelpar:

  • en privat nyckel — ligger uteslutande i signaturtjänsten
  • en offentlig nyckel — får alla ha, adresseras via nyckel-ID:t (kid) i envelopen

Signeringen sker med den privata nyckeln. Verifieringen sker med den offentliga — och det i läsarens webbläsare, inte på vår server.


4. Varför över huvud taget en post-kvantmetod?

Många i dag vanliga signaturmetoder vilar på faktorisering av stora tal eller på diskreta logaritmer. En tillräckligt kraftfull kvantdator skulle kunna lösa just dessa problem avsevärt snabbare med kända algoritmer.

För ett omdöme är det ingen akademisk fråga. Ett omdöme ska gå att kontrollera även om tio år. Den som undertecknar i dag undertecknar för hela postens livslängd.

ML-DSA använder därför en annan grund:

Gitterproblem\boxed{\text{Gitterproblem}}

Närmare bestämt: Module-LWE och Module-SIS.


5. Vad är ett gitter?

Till att börja med bara punkter i rummet. Låt oss ta två vektorer:

b1=(2,0),b2=(1,2).b_1=(2,0), \qquad b_2=(1,2).

Alla heltalskombinationer

ab1+bb2,a,bZa\,b_1+b\,b_2, \qquad a,b\in\mathbb{Z}

bildar gittret. Till exempel:

2b1+b2=(4,0)+(1,2)=(5,2).2b_1+b_2 = (4,0)+(1,2) = (5,2).
b₁ = (2,0)b₂ = (1,2)(5,2)0
Två vektorer, alla heltalskombinationer av dem: ett gitter. Den markerade punkten uppstår ur två gånger b₁ och en gång b₂.

Det avgörande:

I små dimensioner är gitterproblem lätta. I mycket höga dimensioner blir vissa uppgifter extremt svåra.


6. Polynom i stället för enskilda tal

ML-DSA räknar inte med 2D-vektorer, utan med polynom och vektorer av polynom.

Ett polynom som

a(x)=1+2x+x3a(x)=1+2x+x^3

går att skriva som koefficientlista:

a=(1,2,0,1).a=(1,2,0,1).

Räkningen sker i en ring:

Rq=Zq[x]/(xn+1).R_q=\mathbb{Z}_q[x]/(x^n+1).

Det betyder två saker:

  • Zq\mathbb{Z}_q: räkning modulo qq
  • xn=1x^n=-1: en tilläggsregel som fixerar polynomlängden

För alla tre ML-DSA-nivåer gäller:

n=256,q=8380417.n=256, \qquad q=8380417.

Ett polynom har alltså 256 koefficienter, betraktade modulo 8 380 417. Det som ändras mellan nivåerna är inte nn eller qq, utan matrisernas storlek — mer om det senare.

För övrigt: polynommultiplikation i denna ring sker i praktiken via NTT, den talteoretiska varianten av den snabba fouriertransformen. ML-DSA klarar sig alltså ingalunda utan FFT-idéer; de sitter bara i aritmetiken i stället för i signaturprincipen.


7. Det centrala knepet: Module-LWE

Kärnidén är Module Learning With Errors:

t=As1+s2(modq).\mathbf{t}=\mathbf{A}\mathbf{s}_1+\mathbf{s}_2 \pmod q.

Här är:

  • A\mathbf{A} — offentlig, skenbart slumpmässig matris av polynom
  • s1,s2\mathbf{s}_1,\mathbf{s}_2 — små hemliga vektorer
  • t\mathbf{t} — offentligt värde

En angripare känner A\mathbf{A} och t\mathbf{t}, men inte s1,s2\mathbf{s}_1,\mathbf{s}_2. Ekvationen ser för honom ut som en slumpmässig ekvation med brus. De små hemligheterna ska han inte kunna räkna tillbaka ur den på ett effektivt sätt.


8. Ett pyttelitet sifferexempel

Vi tar avsiktligt en löjligt liten variant — vanliga tal i stället för polynom, dimension 2 i stället för 256, och

q=17.q=17.

Låt

A=(3572),s1=(11),s2=(10).A=\begin{pmatrix}3&5\\7&2\end{pmatrix}, \qquad \mathbf{s}_1=\begin{pmatrix}1\\-1\end{pmatrix}, \qquad \mathbf{s}_2=\begin{pmatrix}1\\0\end{pmatrix}.

Då:

As1=(3572)=(25),A\mathbf{s}_1=\begin{pmatrix}3-5\\7-2\end{pmatrix}=\begin{pmatrix}-2\\5\end{pmatrix},
t=As1+s2=(25)+(10)=(15)    (165)(mod17).\mathbf{t}=A\mathbf{s}_1+\mathbf{s}_2=\begin{pmatrix}-2\\5\end{pmatrix}+\begin{pmatrix}1\\0\end{pmatrix}=\begin{pmatrix}-1\\5\end{pmatrix} \;\equiv\; \boxed{\begin{pmatrix}16\\5\end{pmatrix}} \pmod{17}.

I detta miniformat skulle man kunna pröva alla möjligheter. Hos ML-DSA-87 är A\mathbf{A} en 8×78\times 7-matris av polynom med 256 koefficienter vardera — det är över 14 000 obekanta i gitterstrukturen.


9. Signaturtjänstens nyckelpar

Den privata nyckeln innehåller bland annat de små vektorerna s1,s2\mathbf{s}_1,\mathbf{s}_2. Hos ML-DSA-87 kommer deras koefficienter ur intervallet

[η,η]medη=2,[-\eta,\eta] \quad\text{med}\quad \eta=2,

alltså ur {2,1,0,1,2}\{-2,-1,0,1,2\}. Denna litenhet är ingen detalj, utan själva kärnan: bara för att hemligheterna är små uppstår över huvud taget ett svårt gitterproblem.

Den offentliga nyckeln är förenklat

(ρ,t1).(\rho,\mathbf{t}_1).

ρ\rho är en seed ur vilken A\mathbf{A} deterministiskt går att rekonstruera — matrisen behöver alltså inte överföras. t1\mathbf{t}_1 är de övre bitarna av t\mathbf{t}; de undre d=13d=13 bitarna faller bort, vilket förminskar nyckeln avsevärt. Denna utelämning är senare skälet till de så kallade hintarna.

Därmed uppstår den önskade asymmetrin:

verifiera offentligt    signera hemligt\boxed{\text{verifiera offentligt}\;\neq\;\text{signera hemligt}}

10. Omdömet blir ett tal

Signaturtjänsten hashar först nyttolastobjektet ur avsnitt 2:

μ=H(m).\mu=H(m).

I vårt leksaksexempel tar vi en konstruerad minihash. I det verkliga systemet är μ\mu 512 bitar långt och binder dessutom in den offentliga nyckeln — därigenom går en signatur inte att omtolka till att gälla en annan nyckel.


11. Commitment

Signaturtjänsten drar en slumpmässig liten vektor y\mathbf{y}. I vårt exempel:

y=(21).\mathbf{y}=\begin{pmatrix}2\\-1\end{pmatrix}.

Ur den uppstår ett mellanvärde, commitmentet:

w=Ay=(32+5(1)72+2(1))=(112).\mathbf{w}=A\mathbf{y} =\begin{pmatrix}3\cdot2+5\cdot(-1)\\7\cdot2+2\cdot(-1)\end{pmatrix} =\begin{pmatrix}1\\12\end{pmatrix}.

Det är ännu ingen signatur.


12. Ur omdömet blir en utmaning

Meddelande och commitment hashas samman:

c=H(μ,w).c=H(\mu,\mathbf{w}).

Hos ML-DSA-87 är cc ett polynom med exakt τ=60\tau=60 koefficienter ur {1,+1}\{-1,+1\}, alla övriga 196 är noll. Denna struktur är avsiktlig: den håller cs1c\cdot\mathbf{s}_1 litet.

I vårt leksaksexempel sätter vi helt enkelt

c=2.c=2.

13. Själva signaturen

z=y+cs1.\mathbf{z}=\mathbf{y}+c\,\mathbf{s}_1.

Med våra värden:

cs1=2(11)=(22),c\,\mathbf{s}_1=2\begin{pmatrix}1\\-1\end{pmatrix}=\begin{pmatrix}2\\-2\end{pmatrix},
z=(21)+(22)=(43)\mathbf{z}=\begin{pmatrix}2\\-1\end{pmatrix}+\begin{pmatrix}2\\-2\end{pmatrix} =\boxed{\begin{pmatrix}4\\-3\end{pmatrix}}

14. Steget som man lätt förbiser: Rejection Sampling

Här ligger punkten där ML-DSA skiljer sig från en naiv konstruktion — och den är inte valfri.

z=y+cs1\mathbf{z}=\mathbf{y}+c\,\mathbf{s}_1 innehåller hemligheten s1\mathbf{s}_1. Om man alltid bara gav ut z\mathbf{z} skulle s1\mathbf{s}_1 gå att räkna fram statistiskt ur tillräckligt många signaturer. Hos en omdömesportal med mycket många signaturer per dag är det ingen teoretisk risk.

Därför prövar signaturtjänsten före utgivningen om z\mathbf{z} röjer för mycket, och förkastar annars signaturen — då börjar man om från början med ett nytt slumpmässigt y\mathbf{y}. Detta kallas Fiat-Shamir with Aborts.

Villkoret lyder i allt väsentligt:

z<γ1β.\|\mathbf{z}\|_\infty < \gamma_1-\beta.
Commitment w = AyUtmaning c = H(μ, w)Svar z = y + c · s₁‖z‖∞ < γ₁ − β ?jasignaturen ges utnej — nytt y
Tre steg och en slinga. Blir z för stort bättras det inte på — hela genomloppet förkastas och börjar om med ett färskt slumpmässigt y. Därför är signering här ett slingförfarande.

För ML-DSA-87 gäller γ1=219\gamma_1=2^{19} och β=τη=602=120\beta=\tau\cdot\eta=60\cdot2=120. Därtill kommer en andra gräns på de undre bitarna. I praktiken är flera genomlopp normalt — signeringen är alltså ett slingförfarande, inte ett enda steg.

För verifieringen är det viktigt att: exakt denna gräns prövar webbläsaren senare också. En signatur med för stora koefficienter avvisas, även om ekvationen går ihop.


15. Varför webbläsaren kan pröva detta

Läsarens webbläsare känner till:

  • omdömet och därmed mm
  • den offentliga nyckeln (ρ,t1)(\rho,\mathbf{t}_1)
  • signaturen (c~,z,h)(\tilde c,\mathbf{z},\mathbf{h})

Den känner inte s1\mathbf{s}_1. Sambandet som ändå för den vidare:

z=y+cs1Az=Ay+cAs1.\mathbf{z}=\mathbf{y}+c\,\mathbf{s}_1 \quad\Longrightarrow\quad A\mathbf{z}=A\mathbf{y}+c\,A\mathbf{s}_1.

Och eftersom

t=As1+s2\mathbf{t}=A\mathbf{s}_1+\mathbf{s}_2

gäller, går det okända As1A\mathbf{s}_1 att ersätta med det offentliga värdet:

Azct=Aycs2.A\mathbf{z}-c\,\mathbf{t}=A\mathbf{y}-c\,\mathbf{s}_2.

Det är den centrala ekvationen — och den säger något viktigt: webbläsaren rekonstruerar AyA\mathbf{y} inte exakt, utan bara så när som på den lilla termen cs2c\,\mathbf{s}_2.


16. Miniexemplet ända till slutet

Vi hade:

A=(3572),t=(15),c=2,z=(43).A=\begin{pmatrix}3&5\\7&2\end{pmatrix},\quad \mathbf{t}=\begin{pmatrix}-1\\5\end{pmatrix},\quad c=2,\quad \mathbf{z}=\begin{pmatrix}4\\-3\end{pmatrix}.

Låt oss räkna efter:

Az=(1215286)=(322),ct=2(15)=(210),A\mathbf{z}=\begin{pmatrix}12-15\\28-6\end{pmatrix}=\begin{pmatrix}-3\\22\end{pmatrix}, \qquad c\,\mathbf{t}=2\begin{pmatrix}-1\\5\end{pmatrix}=\begin{pmatrix}-2\\10\end{pmatrix},
Azct=(112).A\mathbf{z}-c\,\mathbf{t}=\begin{pmatrix}-1\\12\end{pmatrix}.

Det ursprungliga commitmentet var

w=(112).\mathbf{w}=\begin{pmatrix}1\\12\end{pmatrix}.

Differensen är

(112)(112)=(20)=cs2.\begin{pmatrix}-1\\12\end{pmatrix}-\begin{pmatrix}1\\12\end{pmatrix} =\begin{pmatrix}-2\\0\end{pmatrix} =-c\,\mathbf{s}_2.

Alltså exakt den förutsagda lilla feltermen. Verifieraren får inte w\mathbf{w}, utan något som ligger nära w\mathbf{w}.

Just därför jämför ML-DSA inte värdena själva, utan deras övre bitar. Och just därför innehåller signaturen dessutom en hint-vektor h\mathbf{h}: den meddelar kompakt på vilka ställen avrundningen har tippat över en gräns på grund av den lilla feltermen. Hos ML-DSA-87 är högst ω=75\omega=75 sådana hintar tillåtna. De röjer inte hemligheten — de reparerar bara avrundningen.

Till slut beräknar webbläsaren utmaningen på nytt. Stämmer den överens,

cny=c,c_{\text{ny}}=c,

och ligger alla normer inom gränserna, är signaturen giltig.


17. Vad händer om någon ändrar omdömet?

Anta att någon med databasåtkomst — även någon hos oss — ändrar omdömestexten eller ett av hjärtana. Då ändras minst ett av de båda hashvärdena i nyttolasten (h vid texten, rh vid varje fält i datamängden):

H(m)H(m).H(m)\neq H(m').

Därmed ändras utmaningen:

cc.c\neq c'.

Den befintliga signaturen skapades dock för den gamla utmaningen. Webbläsaren räknar efter och konstaterar:

cnycsignaturSignatur ogiltigc_{\text{ny}}\neq c_{\text{signatur}} \quad\Longrightarrow\quad \boxed{\text{Signatur ogiltig}}

Den avgörande meningen om detta: vi kan radera ett omdöme, men vi kan inte ändra det obemärkt. Hos McGesund körs samma kontroll dessutom nattetid på serversidan över hela beståndet — ett omdöme som inte klarar denna kontroll räknas inte längre in i företagets snittbetyg.


18. Varför kan ingen hitta på en signatur?

En angripare känner A\mathbf{A} och t\mathbf{t}, men inte s1,s2\mathbf{s}_1,\mathbf{s}_2. För att bygga en giltig signatur skulle han behöva hitta en trippel (c~,z,h)(\tilde c,\mathbf{z},\mathbf{h}) som

  • uppfyller verifieringsekvationen och
  • håller sig inom normgränserna och
  • passar till den utmaning som följer ur just dessa värden själva.

Det leder i kärnan till ett svårt gitterproblem — konkret till Module-SIS: att hitta korta lösningar till en homogen ekvation modulo qq. Litenhetsvillkoret är därvid ingen utsmyckning, utan den egentliga svårighetsgraden. Utan det vore en lösning trivial.

offentliga data    sva˚rt gitterproblem\boxed{\text{offentliga data}\;\rightarrow\;\text{svårt gitterproblem}}

19. Varför "Module"?

Ordet beskriver strukturen mellan enkla vektorer och allmänna gitter. I stället för att räkna med enskilda tal arbetar ML-DSA med vektorer av polynom:

a=(a1(x),a2(x),,ak(x)),\mathbf{a}=(a_1(x),a_2(x),\ldots,a_k(x)),

och med matriser av dessa:

A=(a1,1(x)a1,2(x)a2,1(x)a2,2(x)).\mathbf{A}= \begin{pmatrix} a_{1,1}(x)&a_{1,2}(x)&\cdots\\ a_{2,1}(x)&a_{2,2}(x)&\cdots\\ \vdots&\vdots&\ddots \end{pmatrix}.

Fördelen: man får ett gitters höga dimension, men behåller en kompakt, effektivt beräkningsbar framställning. Säkerheten går att finjustera via matrisstorleken, utan att byta ring.


20. Varför just 87?

De tre nivåerna skiljer sig inte i ringen, utan i dimensionerna:

ParameterML-DSA-44ML-DSA-65ML-DSA-87
Matrisstorlek (k,)(k,\ell)4×44\times46×56\times58×78\times7
Hemlighetsintervall η\eta242
Utmaningsvikt τ\tau394960
Offentlig nyckel1 312 B1 952 B2 592 B
Signatur2 420 B3 309 B4 627 B
NIST-kategori235

Anmärkningsvärt: ML-DSA-87 är inte helt enkelt "ML-DSA-65, bara större". Hemlighetsintervallet η\eta går från 4 tillbaka till 2; säkerheten kommer här ur den större matrisen, inte ur större koefficienter. Det rör sig om ett eget, standardiserat parameterval.

sto¨rre matematisk strukturho¨gre sa¨kerhetsmarginal\boxed{\text{större matematisk struktur}\rightarrow\text{högre säkerhetsmarginal}}

Priset: 4 627 byte per signatur — per stämpel som lagras och levereras till webbläsaren vid verifieringen. Därför står hos McGesund även FALCON till buds vid sidan av ML-DSA-87, som klarar sig med 1 280 byte.


21. Fiat-Shamir: varför det fungerar utan motpart

Ett interaktivt bevis skulle löpa så här:

  1. Signaturtjänsten skickar ett commitment.
  2. Verifieraren skickar en slumpmässig utmaning.
  3. Signaturtjänsten svarar.
  4. Verifieraren räknar efter.

Vid ett omdöme finns inte denna dialog — läsaren kommer månader senare. Lösningen är Fiat-Shamir-transformationen: utmaningen slås inte fram med tärning, utan hashas fram ur uppgifterna själva:

c=H(offentlig nyckel,  meddelande,  commitment).c=H(\text{offentlig nyckel},\;\text{meddelande},\;\text{commitment}).

Därmed blir en dialog till ett dokument. Signaturtjänsten kan inte välja utmaningen, för då skulle den behöva kontrollera hashen.


22. Hela förloppet

SIGNATURTJÄNST (MCGESUND)BESÖKARENS WEBBLÄSAREprivat nyckel s₁, s₂Nyttolast m = {företag, omdöme, h, rh, iat}Hash μslumpmässig vektor yCommitment w = AyUtmaning c = H(μ, w)z = y + c · s₁Signatur (c, z, hintar) + kidOmdöme + signatur + off. nyckelAz − c·t → övre bitar + hintarräkna om utmaningenomräknad utmaning = medskickad?giltigogiltigförkasta om z blir för stort(Rejection Sampling)
Ett omdömes hela väg. Det streckade återhoppet är Rejection Sampling — det tas så många gånger tills z är litet nog att inte röja något om den hemliga nyckeln.

23. Vad McGesund konkret gör med detta

Tre nivåer griper i varandra:

Envelopen. Varje signerat omdöme bär en Ed25519-signatur. Det är obligatoriet — klassisk, pytteliten, nativt verifierbar i varje webbläsare.

Post-kvantstämplarna. Dessutom kan en eller två kvantresistenta signaturer läggas bredvid. Vilka beror på abonnemanget:

Abonnemangtillgängliga signaturnivåer
BasisEd25519, FN-DSA-512
KlassikEd25519, FN-DSA-512, FN-DSA-1024
ProEd25519, FN-DSA-1024, ML-DSA-87
PremiumEd25519, FN-DSA-1024, ML-DSA-87, båda parallellt

Den parallella varianten är medvetet redundant. Skulle en av de båda matematiska familjerna — NTRU-gitter hos FALCON, modulgitter hos ML-DSA — visa sig svagare än vad man i dag antar bär den andra vidare.

Tidsankaret. Signaturnyckelns fingeravtryck förankras via OpenTimestamps i ett Bitcoin-block. Därmed går det inte bara att belägga att signaturen är äkta, utan också att den redan fanns vid en bestämd tidpunkt — utan att någon behöver tro på vår tidsstämpel.

Allt detta verifieras i läsarens webbläsare, via en WASM-modul. Vi levererar data; efterräkningen sker på besökarens enhet. Om vi gick ned från nätet i morgon skulle ett en gång nedladdat omdöme förbli kontrollerbart.


24. ML-DSA och FALCON sida vid sida

EgenskapFALCON (FN-DSA)ML-DSA
Typdigital signaturdigital signatur
GitterfamiljNTRUModule-LWE / Module-SIS
RingZq[x]/(xn+1)\mathbb{Z}_q[x]/(x^n+1), q=12289q=12289Zq[x]/(x256+1)\mathbb{Z}_q[x]/(x^{256}+1), q=8380417q=8380417
Kärnmekanismkort vektor via gauss-samplingutmaning och svar med avbrott
FFT / NTTflyttals-FFT, säkerhetskritiskNTT, endast aritmetik
Signaturstorlek (högsta nivån)1 280 B4 627 B
Implementationkrävande (flyttal)jämförelsevis rättfram
Standardiseringavsedd som FIPS 206 (FN-DSA), ännu inte avslutadFIPS 204, avslutad

Kort sagt: ML-DSA är lättare att implementera och granska korrekt, FALCON levererar betydligt kompaktare signaturer. I QR-koden sitter ingen av dem — där står enbart Ed25519-envelopen. Signaturstorleken räknas därför vid lagring och leverans, robustheten vid implementationen. Därför erbjuder vi bådadera.


25. En mening att ta med sig

ML-DSA skapar ur en kort hemlig vektor ett svar pa˚ enutmaning som hashats fram ur omdo¨met sja¨lvt — pro¨vbartfo¨r alla som har den offentliga nyckeln.\boxed{ \begin{array}{c} \text{ML-DSA skapar ur en kort hemlig vektor ett svar på en}\\ \text{utmaning som hashats fram ur omdömet självt — prövbart}\\ \text{för alla som har den offentliga nyckeln.} \end{array}}

Den som äger den hemliga vektorn signerar på millisekunder. Den som inte äger den skulle behöva lösa ett gitterproblem i över 14 000 dimensioner — även med en kvantdator.

För läsaren av ett omdöme betyder det helt enkelt: han behöver inte tro oss. Han kan räkna efter.