Continuiamo la nostra serie sulla blockchain Monero e l'articolo di oggi si concentrerà sul protocollo RingCT (Ring Confidential Transactions), che introduce transazioni riservate e nuove firme degli anelli. Sfortunatamente, ci sono poche informazioni su Internet su come funziona e abbiamo cercato di colmare questa lacuna.
Parleremo di come la rete nasconde gli importi dei trasferimenti utilizzando questo protocollo, del motivo per cui hanno abbandonato le classiche firme degli anelli di criptovaluta e di come questa tecnologia si svilupperà ulteriormente.
Poiché questo protocollo è una delle tecnologie più complesse di Monero, il lettore avrà bisogno di una conoscenza di base del design di questa blockchain e di una discreta conoscenza della crittografia a curva ellittica (per rispolverare questa conoscenza potete leggere i primi capitoli del nostro articolo precedente su
Protocollo RingCT
Uno dei possibili attacchi alle valute criptonote è l'analisi blockchain basata sulla conoscenza dell'importo e del tempo della transazione inviata. Questo permette
Vale la pena notare che l’idea di nascondere gli importi non è nuova. Lo sviluppatore di Bitcoin Core Greg Maxwell è stato uno dei primi a descriverlo nel suo
Tra le altre cose, il protocollo aiuta a eliminare i problemi legati alla miscelazione degli output di polvere: output di piccola quantità (di solito ricevuti sotto forma di resto dalle transazioni), che creavano più problemi di quanto valessero.
Nel gennaio 2017 ha avuto luogo un hard fork della rete Monero, consentendo l'utilizzo facoltativo di transazioni riservate. E già nel settembre dello stesso anno, con l’hard fork della versione 6, tali transazioni divennero le uniche consentite sulla rete.
RingCT utilizza diversi meccanismi contemporaneamente: firme di gruppo anonimo spontaneo collegato a più livelli (firma di gruppo anonimo spontaneo collegabile multistrato, di seguito denominata MLSAG), uno schema di impegno (impegni Pedersen) e prove di intervallo (questo termine non ha una traduzione consolidata in russo) .
Il protocollo RingCT introduce due tipologie di transazioni anonime: semplici e complete. Il portafoglio genera il primo quando una transazione utilizza più di un input, il secondo nella situazione opposta. Differiscono nella convalida degli importi delle transazioni e dei dati firmati con una firma MLSAG (ne parleremo più avanti). Inoltre, le transazioni di tipo full possono essere generate con qualsiasi numero di input, non vi è alcuna differenza fondamentale. Nel libro
Firma MLSAG
Ricordiamo quali sono gli input di transazione firmati. Ogni transazione spende e genera fondi. La generazione di fondi avviene creando output di transazione (un'analogia diretta sono le banconote), e l'output che la transazione spende (dopotutto, nella vita reale spendiamo banconote) diventa l'input (attenzione, è molto facile confondersi Qui).
Un input fa riferimento a più output, ma ne spende solo uno, creando così una “cortina fumogena” per rendere difficile l’analisi della cronologia delle traduzioni. Se una transazione ha più di un input, tale struttura può essere rappresentata come una matrice, dove le righe sono gli input e le colonne sono gli output misti. Per dimostrare alla rete che la transazione spende esattamente i suoi output (conosce le loro chiavi segrete), gli input vengono firmati con una firma ad anello. Una firma di questo tipo garantisce che il firmatario conoscesse le chiavi segrete di tutti gli elementi di una qualsiasi delle colonne.
Le transazioni riservate non utilizzano più quelle classiche
Si chiamano multistrato perché firmano più input contemporaneamente, ognuno dei quali è mescolato con molti altri, cioè viene firmata una matrice e non una riga. Come vedremo più avanti, questo aiuta a risparmiare sulla dimensione della firma.
Diamo un'occhiata a come si forma una firma ad anello, usando l'esempio di una transazione che spende 2 output reali e utilizza m - 1 casuali dalla blockchain per la miscelazione. Indichiamo con le chiavi pubbliche degli output che spendiamo
e le relative immagini chiave di conseguenza: Quindi, otteniamo una matrice di dimensioni 2 x m. Innanzitutto, dobbiamo calcolare le cosiddette sfide per ciascuna coppia di output:
Iniziamo i calcoli con gli output, che spendiamo utilizzando le loro chiavi pubbliche:e numeri casualiDi conseguenza, otteniamo i seguenti valori:
, che usiamo per calcolare la sfida
la prossima coppia di output (per rendere più facile capire cosa stiamo sostituendo e dove, abbiamo evidenziato questi valori in diversi colori). Tutti i seguenti valori vengono calcolati in un cerchio utilizzando le formule fornite nella prima illustrazione. L'ultima cosa da calcolare è la sfida per una coppia di risultati reali.
Come possiamo vedere, tutte le colonne tranne quella contenente output reali utilizzano numeri generati casualmente. Per π- colonna ne avremo bisogno anche noi. Trasformiamocinella s:
La firma stessa è una tupla di tutti questi valori:
Questi dati vengono quindi scritti in una transazione.
Come possiamo vedere, MLSAG contiene solo una sfida c0, che permette di risparmiare sulla dimensione della firma (che già richiede molto spazio). Inoltre, qualsiasi ispettore, utilizzando i dati, ripristina i valori c1,…, cm e controlla che. Quindi il nostro anello è chiuso e la firma è stata verificata.
Per le transazioni RingCT di tipo completo, viene aggiunta una riga in più alla matrice con output misti, ma di questo ne parleremo più avanti.
Impegni di Pedersen
Gli impegni Monero vengono utilizzati per nascondere gli importi dei trasferimenti e utilizzare l'opzione più comune: gli impegni Pedersen. A proposito, un fatto interessante: all'inizio gli sviluppatori hanno proposto di nascondere gli importi mediante miscelazione ordinaria, cioè aggiungendo output per importi arbitrari per introdurre incertezza, ma poi sono passati agli impegni (non è un dato di fatto che hanno risparmiato su la dimensione della transazione, come vedremo di seguito).
In generale, l’impegno si presenta così:
Где C — il significato stesso dell'impegno, a - importo nascosto, H è un punto fisso sulla curva ellittica (generatore aggiuntivo), e x - una sorta di maschera arbitraria, un fattore nascosto generato in modo casuale. Qui la maschera è necessaria affinché un terzo non possa semplicemente intuire il valore dell'impegno.
Quando viene generato un nuovo output, il portafoglio calcola l'impegno per esso e, una volta speso, prende il valore calcolato durante la generazione o lo ricalcola, a seconda del tipo di transazione.
AnelloCT semplice
Nel caso di transazioni RingCT semplici, per garantire che la transazione abbia creato output per un ammontare pari alla quantità di input (non abbia prodotto denaro dal nulla), è necessario che la somma degli impegni della prima e della seconda siano uguali, cioè:
Le commissioni di impegno lo considerano in modo leggermente diverso, senza maschera:
Dove a — l'importo della commissione è pubblicamente disponibile.
Questo approccio ci consente di dimostrare alla parte che fa affidamento che stiamo utilizzando gli stessi importi senza rivelarli.
Per rendere le cose più chiare, vediamo un esempio. Diciamo che una transazione spende due output (nel senso che diventano input) di 10 e 5 XMR e genera tre output del valore di 12 XMR: 3, 4 e 5 XMR. Allo stesso tempo paga una commissione di 3 XMR. Pertanto, l’importo di denaro speso più l’importo generato e la commissione è pari a 15 XMR. Proviamo a calcolare gli impegni e osserviamo la differenza nei loro importi (ricorda i calcoli):
Qui vediamo che affinché l'equazione converga, è necessario che le somme delle maschere di input e output siano le stesse. Per fare ciò, il portafoglio viene generato in modo casuale x1, y1, y2 e y3, e il restante x2 calcola così:
Utilizzando queste maschere, possiamo dimostrare a qualsiasi verificatore che non generiamo più fondi di quelli che spendiamo, senza rivelare l’importo. Originale, vero?
RingCT pieno
Nelle transazioni RingCT complete, il controllo degli importi del trasferimento è un po' più complicato. In queste transazioni, il portafoglio non ricalcola gli impegni per gli input, ma utilizza quelli calcolati al momento della loro generazione. In questo caso dobbiamo supporre che non otterremo più la differenza delle somme pari a zero, ma invece:
Qui z — differenza tra maschere di input e di output. Se consideriamo zG come chiave pubblica (cosa che di fatto è), quindi z è la chiave privata. Pertanto, conosciamo la chiave pubblica e quella privata corrispondente. Con questi dati in mano, possiamo usarli nella firma dell'anello MLSAG insieme alle chiavi pubbliche degli output mescolati:
Pertanto, una firma ad anello valida ci garantirà di conoscere tutte le chiavi private di una delle colonne, e potremo conoscere la chiave privata dell'ultima riga solo se la transazione non genera più fondi di quelli che spende. A proposito, ecco la risposta alla domanda "perché la differenza negli importi degli impegni non porta a zero" - se zG = 0, quindi espanderemo la colonna con output reali.
Come fa il destinatario dei fondi a sapere quanti soldi gli sono stati inviati? Qui tutto è semplice: il mittente della transazione e il destinatario si scambiano le chiavi utilizzando il protocollo Diffie-Hellman, utilizzando la chiave della transazione e la chiave di visualizzazione del destinatario e calcolano il segreto condiviso. Il mittente scrive i dati sugli importi in uscita, crittografati con questa chiave condivisa, in campi speciali della transazione.
Prove di portata
Cosa succede se utilizzi un numero negativo come importo negli impegni? Ciò potrebbe portare alla generazione di monete aggiuntive! Questo risultato è inaccettabile, quindi dobbiamo garantire che gli importi che utilizziamo non siano negativi (senza renderli pubblici, ovviamente, altrimenti c’è tanto lavoro e tutto invano). In altre parole, dobbiamo dimostrare che la somma è nell'intervallo [0, 2n - 1].
Per fare ciò, la somma di ciascun output viene divisa in cifre binarie e l'impegno viene calcolato separatamente per ciascuna cifra. È meglio vedere come ciò avviene con un esempio.
Supponiamo che i nostri importi siano piccoli e rientrino in 4 bit (in pratica sono 64 bit) e creiamo un output del valore di 5 XMR. Calcoliamo gli impegni per ogni categoria e l'impegno totale per l'intero importo:
Successivamente, ogni impegno viene mescolato con un surrogato (Ci-2iH) ed è firmato in coppia con la firma dell'anello Borromeo (un'altra firma dell'anello), proposto da Greg Maxwell nel 2015 (puoi leggere di più a riguardo
Nel loro insieme, questo è chiamato range proof e consente di garantire che gli impegni utilizzino importi compresi nel range [0, 2n - 1].
Quali sono le prospettive?
Nell'attuale implementazione, le prove di intervallo occupano molto spazio: 6176 byte per output. Ciò porta a transazioni più grandi e quindi a commissioni più elevate. Per ridurre le dimensioni di una transazione Monero, gli sviluppatori stanno introducendo bulletproof invece delle firme Borromeo: un meccanismo di prova di intervallo senza impegni bit a bit.
Poni le tue domande, suggerisci argomenti per nuovi articoli sulle tecnologie nel campo della criptovaluta e iscriviti anche al nostro gruppo in
Fonte: habr.com