Procedimenti di firma
SLH-DSA spiegato matematicamente
Come SLH-DSA-SHA2-256f (FIPS 205) firma senza nessun problema difficile al di fuori delle funzioni hash — dalle catene di hash agli alberi di Merkle fino alla foresta di alberi FORS.
Aggiornato: 2026-11-09
1. Di che cosa si tratta
Su McGesund i clienti con il piano Recensioni Premium e Segnali Premium possono scegliere il livello di firma PQ-Dual-Diversified. In tal caso ogni QR code porta, accanto alla classica firma Ed25519, due firme resistenti ai quanti: ML-DSA-87 e SLH-DSA-SHA2-256f.
Questo contributo spiega la seconda. È costruita in modo diverso da tutto il resto che utilizziamo.
SLH-DSA non è una cifratura. Il contenuto resta leggibile pubblicamente. SLH-DSA dimostra origine e integrità — come ogni firma digitale.
SLH-DSA sta per Stateless Hash-Based Digital Signature Algorithm. È stato sviluppato a partire da SPHINCS+ e standardizzato nel 2024 come FIPS 205. Il nome rivela già la sua particolarità: il procedimento utilizza soltanto funzioni hash. Niente reticoli, niente curve ellittiche, niente grandi numeri primi.
2. Che cosa viene firmato esattamente?
In McGesund SLH-DSA firma lo stesso insieme di dati coperto anche dalla firma Ed25519 nel QR code: il payload del QR code. Esso indica tra l'altro a quale azienda appartiene il codice (fid), di che tipo è (typ), quando è stato emesso (iat) e fino a quando è valido (exp) — come sequenza di byte codificata in forma compatta (CBOR).
Questa sequenza di byte è il nostro messaggio . Se qualcuno in seguito modifica un solo bit, nessuna delle firme torna più.
La firma SLH-DSA non si trova nel QR code stesso. Con circa 49 KB è di gran lunga troppo grande. È conservata come «timbro» separato presso il record del QR code nel backend di McGesund e viene caricata nel browser quando si clicca su «Verifica autenticità».
3. Perché un procedimento fatto solo di funzioni hash?
Ogni procedimento di firma si fonda su un compito praticamente irrisolvibile senza la chiave segreta:
| Procedimento | La sicurezza si fonda su |
|---|---|
| Ed25519 | logaritmo discreto su una curva ellittica |
| FALCON | vettori corti nei reticoli NTRU |
| ML-DSA | Module-LWE e Module-SIS (reticoli) |
| SLH-DSA | solo sulle proprietà della funzione hash |
Un grande computer quantistico romperebbe Ed25519. FALCON e ML-DSA sono considerati resistenti ai quanti — ma entrambi poggiano su problemi reticolari. Se un giorno si trovasse un attacco fondamentale ai reticoli, ne sarebbero colpiti entrambi contemporaneamente.
SLH-DSA, invece, ha bisogno soltanto che la funzione hash faccia ciò per cui è stata costruita:
È l'ipotesi studiata più a lungo e più a fondo dell'intera crittografia. Anche un computer quantistico qui aiuta solo in misura limitata: l'algoritmo di Grover dimezza i bit di sicurezza. Per questo la variante 256 usa valori hash di byte bit — dopo Grover restano comunque 128 bit.
Proprio per questo il livello si chiama Diversified: ML-DSA (reticoli) e SLH-DSA (hash) provengono da famiglie matematiche diverse. Se una cade, l'altra regge.
4. Elemento 1: firmare con le catene di hash (WOTS+)
L'idea di base è sorprendentemente semplice. Cominciamo con una sola cifra.
Si prende un valore casuale segreto e lo si sottopone a hash più e più volte:
La fine della catena, , viene pubblicata. È la chiave pubblica per questa singola cifra.
Per firmare una cifra compresa tra 0 e 15 si rivela il valore della catena in posizione :
Chi vuole verificare applica l'hash a altre volte. Se il risultato è esattamente , la firma è autentica:
Un mini-esempio
Firmiamo la cifra :
- Il firmatario pubblica .
- Il verificatore calcola e lo confronta con . Torna.
Un falsario che ha visto può calcolarne senza fatica , e così via — e dunque firmare cifre più grandi. Quelle più piccole no: per farlo dovrebbe calcolare l'hash all'indietro.
Il checksum contro il «conteggio in avanti»
Affinché nessuno possa semplicemente aumentare le cifre, viene firmato in aggiunta un checksum:
Se un falsario aumenta una cifra del messaggio, diventa più piccolo — e per questo dovrebbe calcolare all'indietro nella catena del checksum. In questo modo entrambe le direzioni sono bloccate.
Esteso a un valore hash
Un valore hash di 32 byte ha 64 cifre in base 16. A queste si aggiungono 3 cifre di checksum:
Una firma del genere si chiama WOTS+ (Winternitz One-Time Signature). Il suo grande difetto sta nel nome: one-time, cioè monouso. Chi firma due messaggi diversi con la stessa chiave rivela così tanti valori delle catene da rendere possibili le falsificazioni.
5. Elemento 2: tante chiavi monouso sotto un unico tetto (albero di Merkle)
Se ogni chiave può essere usata una sola volta, ne servono moltissime — ma si vuole pubblicare una sola chiave pubblica.
La soluzione è un albero di Merkle: le chiavi pubbliche di coppie WOTS+ formano le foglie. Due vicine alla volta vengono sottoposte insieme a hash, i risultati di nuovo a coppie, finché in cima rimane un'unica radice.
In SLH-DSA-SHA2-256f ogni albero ha altezza , cioè foglie.
Per dimostrare che una determinata foglia appartiene all'albero, si fornisce il percorso di autenticazione: i 4 nodi fratelli lungo il cammino verso l'alto. Con questi il verificatore risale per hash dalla foglia fino alla radice. Se ne esce la radice nota, la foglia ne fa parte.
6. Elemento 3: alberi sopra alberi (hypertree)
Naturalmente 16 chiavi monouso non bastano. Perciò SLH-DSA impila alberi uno sopra l'altro: la radice di un albero viene firmata con una chiave WOTS+ dell'albero soprastante. Questa torre si chiama hypertree.
In SLH-DSA-SHA2-256f ci sono strati, ciascuno di altezza 4:
In fondo sono quindi disponibili
foglie. La radice dell'albero più in alto si chiama — è la vera e propria chiave pubblica.
Importante: nessuno calcola questi alberi in anticipo. Tutti i valori segreti vengono derivati all'occorrenza da un valore iniziale segreto . Vengono memorizzati soltanto quattro valori da 32 byte ciascuno:
| Parte | Contenuto | Dimensione |
|---|---|---|
| SK.seed | valore iniziale per tutti i valori segreti delle catene | 32 B |
| SK.prf | valore iniziale per la componente casuale | 32 B |
| PK.seed | valore iniziale pubblico, separa le coppie di chiavi l'una dall'altra | 32 B |
| PK.root | radice dell'albero più in alto | 32 B |
La chiave privata è composta da tutti e quattro (128 byte), quella pubblica solo da PK.seed e PK.root (64 byte).
7. Elemento 4: una foresta contro le collisioni casuali (FORS)
Ora il vero problema: come fa il firmatario a sapere quale delle foglie è ancora inutilizzata?
I procedimenti basati su hash più vecchi (XMSS, LMS) tengono a questo scopo un contatore. Questo non deve mai essere azzerato — né da un backup, né da un secondo server. Se accade comunque, una chiave monouso viene usata due volte e il procedimento è violato. Tali procedimenti si dicono con stato.
SLH-DSA è senza stato: la foglia viene scelta in modo pseudocasuale a partire dal messaggio stesso. Può allora capitare che due messaggi colpiscano la stessa foglia. Per questo in fondo non c'è una firma monouso, bensì una firma per pochi usi: FORS (Forest of Random Subsets).
FORS è composto da piccoli alberi di Merkle con foglie ciascuno. Le foglie sono valori casuali segreti.
Per firmare, l'hash del messaggio viene suddiviso in 35 numeri da 9 bit ciascuno. Ogni numero sceglie esattamente una foglia nel «proprio» albero. Per ogni albero la firma contiene:
- il valore segreto di quella foglia
- il suo percorso di autenticazione (9 nodi)
Per un altro messaggio un falsario dovrebbe colpire in tutti i 35 alberi foglie i cui segreti siano già stati rivelati. Anche se la stessa istanza FORS è stata usata qualche volta, è un'impresa senza speranza.
8. L'intero processo di firma
- Componente casuale. Da , un numero casuale fresco e il messaggio si ottiene un valore di 32 byte.
- Hash del messaggio.
I 49 byte del digest vengono suddivisi: 40 byte scelgono le 35 foglie FORS, il resto determina quale albero (
idx_tree) e quale foglia (idx_leaf) in fondo all'hypertree vengono usati. - Firma FORS sul messaggio. Ne risulta una chiave pubblica FORS.
- Firma dell'hypertree su questa chiave FORS: 17 firme WOTS+, ciascuna con un percorso di autenticazione, strato dopo strato fino a .
La firma finita è semplicemente la concatenazione:
9. Perché la firma è grande 49.856 byte
Con i parametri di SLH-DSA-SHA2-256f la dimensione si può ricalcolare esattamente ( byte per valore hash):
| Parte | Calcolo | Byte |
|---|---|---|
| 32 | ||
| FORS | 11.200 | |
| Hypertree | 38.624 | |
| Totale | 49.856 |
Per confronto: una firma Ed25519 ha 64 byte, ML-DSA-87 ne ha 4.627. La dimensione è il prezzo che SLH-DSA paga per cavarsela con nient'altro che funzioni hash.
10. Come verifica il browser
Con SLH-DSA verificare significa: ricalcolare gli hash.
- Ricalcolare il digest da , chiave pubblica e messaggio.
- Dalle 35 foglie FORS rivelate e dai loro percorsi calcolare le 35 radici degli alberi e da queste la chiave pubblica FORS.
- Con ciascuna delle 17 firme WOTS+ portare a termine gli hash delle catene, formare la chiave pubblica WOTS+ e risalire per hash lungo il percorso fino alla radice dell'albero.
- Alla fine deve risultare esattamente .
Sono alcune migliaia di chiamate hash — per un computer una bazzecola. Nel browser, da noi, la verifica richiede circa da 6 a 12 millisecondi.
11. Che cosa succede se qualcuno modifica i dati?
Se cambia anche un solo bit del messaggio , il digest cambia completamente. I 35 numeri puntano allora ad altre foglie FORS e il procedimento a un altro punto dell'hypertree.
I segreti rivelati non combaciano più: le radici ricalcolate divergono e alla fine non risulta . La verifica fallisce.
Per costruire comunque una firma valida, un attaccante dovrebbe conoscere segreti mai pubblicati — dovrebbe cioè calcolare una funzione hash all'indietro.
12. Perché proprio 256f?
FIPS 205 definisce dodici insiemi di parametri: due famiglie di hash (SHA-2 e SHAKE), tre livelli di sicurezza (128, 192, 256) e per ciascuno una variante veloce («f») e una piccola («s»).
| Variante | Firma | Firmare (da noi) | Verificare |
|---|---|---|---|
| SHA2-256s | 29.792 B | ca. 2,6 s | ca. 3 ms |
| SHA2-256f | 49.856 B | ca. 0,26 s | ca. 6 ms |
256 significa categoria di sicurezza NIST 5 — lo stesso livello di FALCON-1024 e ML-DSA-87.
Abbiamo scelto «f» perché le aziende possono emettere fino a 500 QR code in un colpo solo. Con «s» la firma richiederebbe oltre 20 minuti, con «f» meno di un minuto. In compenso la firma è più grande — poiché non sta nel QR code, è sostenibile.
SHA-2 anziché SHAKE, perché SHA-256 e SHA-512 sono accelerati in hardware praticamente su ogni dispositivo.
13. Il caso nella firma
FIPS 205 consente due modi di generare :
- deterministico: stesso messaggio, stessa firma
- randomizzato («hedged»): vi confluisce un numero casuale fresco
Noi usiamo la variante randomizzata. Due firme sullo stesso messaggio hanno quindi un aspetto diverso — entrambe sono valide. Ciò rende più difficili gli attacchi che combinano misurazioni sul dispositivo (consumo di corrente, tempo) con firme ripetute.
14. Che cosa ne fa concretamente McGesund
Il livello. PQ-Dual-Diversified è disponibile in Recensioni Premium e Segnali Premium. Un QR code porta allora tre firme:
| Firma | Famiglia | Posizione |
|---|---|---|
| Ed25519 | curva ellittica | nel QR code |
| ML-DSA-87 | reticoli | timbro nel backend |
| SLH-DSA-SHA2-256f | funzioni hash | timbro nel backend |
La firma. Una firma SLH-DSA costa circa un quarto di secondo di tempo di calcolo. Affinché nel frattempo il server resti raggiungibile per tutti gli altri, i calcoli vengono svolti da thread in background dedicati.
La verifica. Il browser del lettore carica entrambi i timbri e li verifica con lo stesso modulo WASM usato per tutte le altre firme PQ. Noi forniamo i dati; i calcoli avvengono sul dispositivo del visitatore.
Il confronto con NIST. Il nostro modulo supera i vettori di test ufficiali NIST per SLH-DSA-SHA2-256f: dai valori iniziali di NIST nascono byte per byte le stesse chiavi, e tutte le firme manipolate di proposito vengono respinte. Può verificarlo Lei stesso nel browser sulla pagina di test NIST.
L'ancoraggio temporale. Come per tutte le chiavi, l'impronta digitale della chiave SLH-DSA viene ancorata tramite OpenTimestamps in un blocco Bitcoin.
15. SLH-DSA, ML-DSA e FALCON a confronto
| Proprietà | FALCON (FN-DSA) | ML-DSA-87 | SLH-DSA-SHA2-256f |
|---|---|---|---|
| Fondamento | reticoli NTRU | reticoli modulari | solo funzioni hash |
| Standard | FIPS 206 (in lavorazione) | FIPS 204, definitivo | FIPS 205, definitivo |
| Chiave pubblica | 1.793 B | 2.592 B | 64 B |
| Firma | 1.280 B | 4.627 B | 49.856 B |
| Firmare | millisecondi | millisecondi | ca. 0,26 s |
| Verificare | millisecondi | millisecondi | millisecondi |
| Ipotesi | problema reticolare | problema reticolare | funzione hash |
In breve: SLH-DSA è il più lento e il più grande dei tre procedimenti — e il più conservativo. Non si basa su nulla che ogni altra firma non presupponga già comunque: una funzione hash sicura.
16. Una frase da portare a casa
Chi possiede il valore iniziale segreto firma in un quarto di secondo. Chi non lo possiede dovrebbe calcolare SHA-256 o SHA-512 all'indietro — anche con un computer quantistico.
Per il lettore di una recensione ciò significa: anche se un giorno dovessero cadere tutti i procedimenti basati su reticoli, questa firma resta verificabile. Non deve crederci. Può ricalcolare.