Ring signature
Come dimostrare "possiedo una di queste chiavi" senza dire quale
Una ring signature (firma ad anello) dimostra che chi firma conosce la chiave privata di una delle n chiavi pubbliche del ring, senza rivelare quale. Monero ne usa una versione collegabile (linkable): insieme alla firma viene fornita una key image, così lo stesso output non può essere speso due volte. Lo schema attuale è CLSAG, con ring di dimensione 16.
Prima: una semplice firma di Schnorr
Per capire i ring, vediamo prima come dimostrare la conoscenza di una chiave x per P = x·G:
- Chi firma sceglie un
αcasuale e calcolaα·G. - Calcola la sfida
c = Hs(message ‖ α·G). - Calcola la risposta
s = α − c·x. La firma è(c, s). - Il verificatore ricostruisce
s·G + c·P = (α − cx)·G + c·x·G = α·Ge controlla cheHs(message ‖ α·G) = c.
Senza conoscere x non si può trovare un s per un dato c: c dipende da α·G, che deve essere fissato prima di conoscere c.
L'idea del ring: chiudere la catena delle sfide
Ora abbiamo n chiavi pubbliche P₀ … Pₙ₋₁ e conosciamo la chiave di una sola, diciamo Pπ. Il trucco: ogni sfida si calcola dall'anello precedente, e la catena si chiude ad anello.
- Nella posizione π della chiave reale, prendi un
αcasuale e calcola la sfida successiva:c_{π+1} = Hs(m ‖ α·G). - Per ogni chiave (estranea) successiva scegli un
sᵢcasuale e calcolac_{i+1} = Hs(m ‖ sᵢ·G + cᵢ·Pᵢ). Fai il giro del ring. - Torna a π, conoscendo ora
c_π. Perché il ring si chiuda serves_π·G + c_π·P_π = α·G, cioès_π = α − c_π·x. Questo si può calcolare solo conoscendo x. - Firma:
(c₀, s₀, s₁, …, sₙ₋₁).
Il verificatore parte da c₀, percorre ogni anello con la stessa formula e controlla di essere tornato allo stesso c₀. Tutti gli anelli si somigliano: dalla firma non si capisce dove sia avvenuta la "chiusura".
Collegabilità: LSAG
Una ring signature semplice non impedisce che lo stesso output venga speso due volte in ring diversi. Per questo Monero usa una firma collegabile (linkable): chi firma pubblica una key image I = x·Hp(P_π) e in ogni anello dimostra in più che lo stesso x collega I e Hp(Pᵢ):
Due usi della stessa chiave producono la stessa I, e la rete rifiuta la seconda spesa.
MLSAG → CLSAG
In RingCT bisogna dimostrare non una ma due affermazioni per ogni membro del ring: la conoscenza della chiave dell'output e che la differenza dei commitment è un commitment a zero (vedi RingCT). All'inizio (2017) lo si faceva con MLSAG, in pratica due ring incollati insieme: due valori s per ogni membro del ring.
A ottobre 2020 (hard fork v13) è stato sostituito da CLSAG (Concise LSAG): le due chiavi in una posizione vengono fuse in una tramite una combinazione lineare casuale con coefficienti derivati da hash. Un solo s per membro del ring. La firma è diventata circa il 25% più piccola e più veloce da verificare.
Storia della dimensione del ring
| Quando | Membri minimi | Commento |
|---|---|---|
| 2014 | 1 (nessuna esca) | Eredità di CryptoNote: transazioni "0-mixin" consentite |
| 2016 | 3 | Hard fork, vietati i ring senza esche |
| 2017 | 5 | Insieme a RingCT |
| Aprile 2018 | 7 | Dopo le ricerche sulle reazioni a catena |
| Ottobre 2018 | 11, fisso | Dimensione del ring resa uguale per tutti |
| Agosto 2022 | 16, fisso | Hard fork v15 (con Bulletproofs+ e view tag) |
Perché fissa? Se ognuno scegliesse la propria, una dimensione del ring non standard diventerebbe un'impronta del wallet.
Perché non 1000?
La dimensione di CLSAG e il tempo di verifica crescono in modo lineare con la dimensione del ring. Un ring da 1000 membri significa ~32 KB per input e una sincronizzazione dei nodi decine di volte più lenta. Sono stati studiati schemi con dimensione logaritmica (Triptych, Arcturus, Seraphis), ma alla fine Monero ha scelto l'opzione radicale: FCMP++, dove il "ring" è l'intera blockchain.