Ci occupiamo da tempo del tema dell'anonimato nelle criptovalute e cerchiamo di seguire lo sviluppo delle tecnologie in questo campo. Negli articoli abbiamo già analizzato in dettaglio i principi di funzionamento in Monero, e abbiamo anche effettuato delle tecnologie esistenti in questo settore. Tuttavia, tutte le criptovalute anonime ad oggi si basano su un modello di dati proposto da Bitcoin — Unspent Transaction Output (UTXO). Per i blockchain basati su account come Ethereum, le soluzioni esistenti per implementare l'anonimato e la riservatezza (ad esempio, o ) hanno cercato di replicare il modello UTXO nei contratti intelligenti.
Nel febbraio 2019, un gruppo di ricercatori dell'Università di Stanford e di Visa Research hanno rilasciato intitolato «Zether: Verso la riservatezza nel mondo dei contratti intelligenti». Gli autori hanno proposto per la prima volta un approccio per garantire l'anonimato nei blockchain basati su account e hanno presentato due varianti di contratto intelligente: per transazioni riservate (cancellazione dei saldi e degli importi delle transazioni) e anonime (cancellazione del destinatario e del mittente). Consideriamo interessante la tecnologia proposta e vorremmo condividerne il funzionamento, oltre a discutere del motivo per cui il problema dell'anonimato nei blockchain basati su account sia considerato molto complesso e se gli autori siano riusciti a risolverlo completamente.
Sullo sviluppo di questi modelli di dati
Nel modello UTXO, una transazione è composta da «ingressi» e «uscite». Un'analogia diretta alle «uscite» sono le banconote nel tuo portafoglio: ogni «uscita» ha un certo valore. Quando paghi qualcuno (creando una transazione), spendi una o più «uscite», che diventano «ingressi» della transazione, e la blockchain le segna come spese. Il destinatario del tuo pagamento (o tu stesso, se hai bisogno di resto) riceve di nuovo le «uscite» generate. Schema alla mano, si può rappresentare così:

I blockchain basati su account funzionano più o meno come il tuo conto bancario. Operano solo sull'importo nel tuo conto e sull'importo della transazione. Quando trasferisci un certo importo dal tuo conto, non bruci alcuna «uscita», e la rete non ha bisogno di tenere a mente quali monete sono state spese e quali no. In caso più semplice, la verifica della transazione si riduce al controllo della firma del mittente e dell'importo sul suo saldo:

Analisi della tecnologia
In seguito parleremo di come Zether nasconda l'importo delle transazioni, il destinatario e il mittente. Durante la descrizione dei principi di funzionamento, evidenzieremo le differenze tra la variante riservata e quella anonima. Poiché garantire la riservatezza nelle blockchain basate su account è molto più semplice, alcune delle limitazioni imposte dall'anonimizzazione non saranno rilevanti per la versione confidenziale della tecnologia.
Nascondere i saldi e gli importi delle transazioni
Per crittografare saldi e importi delle transazioni in Zether viene utilizzato uno schema di crittografia . Funziona nel seguente modo. Quando Alice vuole inviare a Bob b monete al suo indirizzo (la sua chiave pubblica) Y, sceglie un numero casuale r e crittografa l'importo:

dove C — importo crittografato, D — valore ausiliario necessario per decriptare questo importo, G — punto fisso sulla curva ellittica, la cui moltiplicazione per la chiave segreta produce la chiave pubblica.
Quando Bob riceve questi valori, li somma semplicemente al suo saldo crittografato nello stesso modo, il che rende conveniente questo schema.
In modo analogo, Alice sottrae dal suo saldo gli stessi valori, usando invece Y la sua chiave pubblica.
Nascondere il destinatario e il mittente
La miscelazione delle "uscite" in UTXO è emersa sin dai primi giorni delle criptovalute e aiuta a nascondere il mittente. Per questo, il mittente stesso, durante un trasferimento, seleziona a caso delle "uscite" nella blockchain e le mescola con le sue. Poi firma le "uscite" con una firma ad anello — un meccanismo crittografico che consente di convincere il verificatore che tra le "uscite" mescolate sono presenti monete del mittente. Le monete mescolate, ovviamente, non vengono spese.
Tuttavia, per nascondere il destinatario non possiamo generare "uscite" false. Pertanto, in UTXO ogni "uscita" ha il proprio indirizzo unico, ed è crittograficamente legata all'indirizzo del destinatario di queste monete. Al momento non esiste un modo per rivelare il collegamento tra l'indirizzo unico dell'"uscita" e l'indirizzo del destinatario, senza conoscere le sue chiavi segrete.
Nel modello basato su account non possiamo utilizzare indirizzi usa e getta (altrimenti si tratterebbe già di un modello di "uscite"). Pertanto, il destinatario e il mittente devono essere mescolati tra altri account nella blockchain. In questo modo, dagli account mescolati vengono addebitati 0 monete crittografate (o si aggiunge 0 — nel caso del mescolamento del destinatario), senza modificare il loro saldo reale.
Poiché sia il mittente che il destinatario hanno sempre un indirizzo fisso, qui sorge la necessità di utilizzare gli stessi gruppi per il mescolamento quando si effettuano trasferimenti verso gli stessi indirizzi. È più facile considerarlo con un esempio.
Supponiamo che Alice decida di fare una donazione alla fondazione benefica di Bob, ma preferisca che questo trasferimento rimanga anonimo per un osservatore esterno. Allora, per camuffarsi nel campo del mittente, inserisce anche gli account di Adam e Adele. E per nascondere Bob — nel campo del destinatario aggiunge gli account di Ben e Bill. Facendo la successiva donazione, Alice decide di accanto a sé inserire Alex e Amanda, mentre accanto a Bob — Bruce e Benja. In questo caso, analizzando la blockchain, in queste due transazioni si troverà solo una coppia intersecante di partecipanti — Alice e Bob, il che deanonimizza queste transazioni.

Corsa alle transazioni
Come abbiamo già accennato, per nascondere il proprio saldo nei sistemi basati su account, l'utente cripta il proprio saldo e l'importo della transazione. Allo stesso tempo, deve dimostrare che il saldo sul suo conto rimane non negativo. Il problema è che, formattando la transazione, l'utente costruisce una prova rispetto al suo stato attuale del conto. E cosa succede se Bob invia una transazione ad Alice, e questa viene accettata prima di quella inviata da Alice? Allora la transazione di Alice sarà considerata non valida, poiché la prova del saldo è stata costruita prima dell'accettazione della transazione di Bob.

La prima soluzione che viene in mente in una situazione del genere è congelare l'account fino all'esecuzione della transazione. Ma questo approccio non è praticabile, poiché, oltre alla complessità di risolvere tale compito in un sistema distribuito, nel modello anonimo non sarà chiaro quale account bloccare.
Per risolvere questo problema, la tecnologia separa le transazioni in entrata e in uscita: la spesa ha un effetto immediato sul saldo, mentre gli incassi hanno un effetto differito. Per questo motivo, viene introdotto il concetto di «epoca» — gruppi di blocchi di dimensioni fisse. L'«epoca» attuale è definita dalla divisione dell'altezza del blocco per la dimensione del gruppo. Elaborando una transazione, la rete aggiorna immediatamente il saldo del mittente, mentre i fondi del destinatario vengono accumulati. I fondi accumulati diventano disponibili per il destinatario del pagamento solo all'inizio di una nuova «epoca».
Di conseguenza, l'utente può inviare transazioni indipendentemente da quanto frequentemente riceve fondi (fino a che il suo saldo lo consente, naturalmente). La dimensione dell'epoca viene determinata in base alla velocità con cui i blocchi si propagano nella rete e a quanto velocemente una transazione entra in un blocco.
Questa soluzione funziona bene in caso di trasferimenti riservati, ma con le transazioni anonime, come vedremo più avanti, crea seri problemi.
Protezione dagli attacchi di replay
Nei blockchain basati su account, ogni transazione è firmata con la chiave privata del mittente, il che convince il verificatore che la transazione non è stata modificata e che è stata creata dal possessore di tale chiave. Ma cosa succede se un malintenzionato che ha intercettato il canale di trasmissione cattura questo messaggio e lo invia esattamente per la seconda volta? Il verificatore confronterà la firma della transazione e sarà convinto della sua autenticità, e la rete addebiterà la stessa somma dal saldo del mittente di nuovo.
Questa attacco è chiamato attacco di replay. Nella UTXO-model, tali attacchi non sono rilevanti, dato che il malintenzionato cercherà di utilizzare le uscite già spese, il che di per sé non è valido e viene rifiutato dalla rete.
Per evitare che ciò accada, nella transazione viene incorporato un campo con dati casuali, chiamato nonce o semplicemente «sale». Durante l'invio ripetuto di una transazione con il «sale», il verificatore controlla se questo nonce è stato utilizzato in precedenza e, se no, considera valida questa transazione. Per non memorizzare nella blockchain l'intera storia dei nonce degli utenti, di solito nella prima transazione viene accettato uguale a zero, e poi aumenta di uno. Alla rete rimane solo da verificare che il nonce della nuova transazione sia diverso da quello precedente di uno.
Nello schema di trasferimenti anonimi sorge il problema della validazione dei nonce per le transazioni. Non possiamo legare il nonce in modo esplicito all'indirizzo del mittente, poiché questo, ovviamente, de-anonimizzerebbe il trasferimento. Non possiamo neanche incrementare di uno i nonce di tutti gli account coinvolti, poiché questo potrebbe confliggere con altri trasferimenti in fase di elaborazione.
Gli autori di Zether propongono di generare il nonce in modo crittografico — in base all'"epoca". Ad esempio:

Qui x — la chiave segreta del mittente, e Gepoch — un generatore aggiuntivo per l'epoca, ottenuto tramite l'hashing di una stringa del tipo 'Zether + '. Ora il problema sembra risolto: non riveliamo il nonce del mittente e non interferiamo con i nonce dei partecipanti non coinvolti. Ma questo approccio impone una seria limitazione: un account può inviare non più di una transazione per "epoca". Purtroppo, questo problema rimane irrisolto e, al momento attuale, rende la versione anonima di Zether, dal nostro punto di vista, poco utilizzabile.
La difficoltà delle prove a zero conoscenza
In UTXO, il mittente deve dimostrare alla rete che non sta spendendo un importo negativo, altrimenti diventa possibile generare nuove monete dal nulla (perché questo è possibile, ne abbiamo parlato in uno dei precedenti ). E deve anche firmare gli "input" con una firma ad anello, per dimostrare che tra le monete mischiate ci sono fondi che gli appartengono.
Nella versione anonima del blockchain basato su account, le espressioni per la prova diventano di gran lunga più complesse. Il mittente deve dimostrare che:
- L'importo inviato è positivo;
- Il saldo rimane non negativo;
- Il mittente ha crittografato correttamente gli importi dei trasferimenti (compresi quelli nulli);
- Il saldo cambia solo per il mittente e il destinatario;
- Il mittente possiede la chiave segreta del proprio account e questa è effettivamente presente nell'elenco dei mittenti (tra quelli coinvolti);
- Il nonce utilizzato nella transazione è composto correttamente.
Per questa prova complessa, gli autori utilizzano una combinazione (uno degli autori, tra l'altro, ha partecipato alla sua creazione) e , chiamata Sigma-bullets. La prova formale di tale affermazione è un compito piuttosto complesso e limita notevolmente il numero di persone disposte a occuparsi dell'implementazione della tecnologia.
Qual è il risultato finale?
Secondo noi, la parte di Zether che introduce la riservatezza nei blockchain basati su account può già essere utilizzata. Tuttavia, al momento, la versione anonima della tecnologia presenta seri limiti al suo utilizzo, e la sua complessità complica la realizzazione. Non dobbiamo dimenticare che gli autori l'hanno rilasciata solo pochi mesi fa, e potrebbe essere che qualcun altro trovi una soluzione ai problemi attuali. È proprio così che si fa scienza.
Fonte: habr.com
