Spiegazione, passo dopo passo, delle transazioni Grin



Grin è una nuova ed entusiasmante crittovaluta che sfrutta il protocollo MimbleWimble. Ma notoriamente i tutorial su Grin non ne descrivono i dettagli.

Questo post ha lo scopo di condividere esattamente come funzionano le transazioni di Grin.

...

Un output in Grin è un Pedersen Commitment. Ogni output avrà la seguente forma:
Un output in Grin è un Pedersen Commitment

Un Pedersen Commitment è un modo intelligente per nascondere le informazioni. Se questa è la prima volta che sentite parlare di Commitment, pensate ad un "valore nascosto" ogni volta che vedete quella parola.

Di seguito, tratto dal wiki di Grin, un eccellente base di partenza su ciò che accade:
Se scegliamo un numero molto grande k come chiave privata, k*H è considerata la chiave pubblica corrispondente. Anche se si conosce il valore della chiave pubblica k*H, dedurre k è quasi impossibile.....
  • r è una chiave privata usata come blinding factor, G è un punto fisso sulla curva ellittica e il loro prodotto r*G è la chiave pubblica per r sulla curva.
  • v è il valore di un ingresso o uscita e H è un altro punto fisso sulla curva ellittica.....
(k+j)*H = k*H + j*H + j*H, con k e j entrambe chiavi private, dimostra che una chiave pubblica ottenuta dall'aggiunta di due chiavi private ((k+j)*H) è identica all'aggiunta delle chiavi pubbliche per ognuna di queste due chiavi private (k*H + j*H).
Un approfondimento della crittografia può essere trovato in questa introduzione su ECC, ma in breve, per spendere una Grin output devi conoscere sia il blinding factor (fattore di oscuramento) (r) che la quantità di Grin (v). E' impossibile ricostruire un commitment per dedurre questi valori. Si deve conoscerli in anticipo.

Il blinding factor esiste perché chiunque ti ha trasferito questi Grin conosce anche il valore di v (quanti Grin ti ha mandato). Ma solo tu - nemmeno il mittente dei Grin - conosce il blinding factor per tale output e quindi solo tu sei in grado di spendere questi output.

Ipotizziamo che questi output utilizzino un blinding factor di 20, e questo output consiste di 40 Grin. (Nota: Le quantità di Grin sono in realtà inviate come multipli dell'unità atomica 1 NanoGrin, per semplicità  qui usiamo Grin interi):
In questo output, il blinding factor è 20, e la quantità di Grin è 40.

Se osserviamo un blockchain explorer di Grin, tale output non è suddiviso in modo netto come sopra. Ecco come appare un output Grin reale, proprio come quello che abbiamo creato:
Come si presenta un output Grin (sotto la colonna Commit).
Nuovamente, dedurre "20" (il blinding factor) o "40" (la quantità di Grin) da questo output è impossibile.

Spendere gli output

Ipotizziamo che l'output che abbiamo mostrato appartenga ad Alice. Ora, Alice vuole mandare 25 di quei 40 Grin a Bob. Ignoriamo le mining fee per semplicità.

Se hai una banconota da 5 dollari e acquisti qualcosa per 3 dollari, ricevi due dollari di resto. Anche le transazioni Bitcoin funzionano in questo modo, e Grin non è diverso. Se Alice vuole inviare 25 Grin a Bob dal suo unspent output di 40 Grin, creerà anche un output in questa stessa transazione che restituisce a se stessa i restanti 15 Grin (il suo resto).

Alice specifica quanti Grin vuole mandare a Bob, e anche il suo resto.
Questi 15 Grin torneranno ad Alice, il che significa che solo lei dovrebbe essere in grado di controllarli e spenderli di nuovo. In altre parole, Bob non dovrebbe essere in grado di spendere il resto di Alice. A tal fine, Alice deve creare un nuovo blinding factor per il suo output di resto. Diciamo che Alice sceglie 34.

Alice, conoscendo sia la r (il blinding factor per il suo output di resto) che la v (la quantità di Grin, che è il suo resto), ha tutto ciò che le serve per creare il suo output di resto (co). Questo sarà registrato sulla blockchain come output, proprio come l'output che Alice andrà a generare per inviare 25 Grin a Bob.
L'output del resto di Alice.
Come ho detto prima, per spendere qualsiasi output, è necessario conoscere il blinding factor utilizzato in quell'output. Alice conosce il blinding factor usato nell'output che vuole spendere (20), ma ha bisogno di un modo per dimostrare al mondo di conoscerlo.

Ecco perché ha bisogno di creare un calcolo completamente separato, noto come la somma dei suoi blinding factor. Questo comporta che Alice prenda il blinding factor che ha appena creato per il suo output di resto (34) e sottragga da esso il blinding factor dall'output che desidera spendere (20).

Somma dei blinding factor di Alice.
rs (dove s è il mittente, che è Alice) rappresenta la somma di tutti i blinding factor di Alice, e in questo caso è pari a 14. (Nota: sto intenzionalmente tralasciando gli offset del kernel).

L'ultima cosa che Alice fa è creare un nonce ks casuale (s, di nuovo, indica il mittente). Utilizzerà questo nonce casuale per aiutare a costruire la sua firma per questa transazione, che mostreremo più avanti. Alice non invia il nonce a Bob. Piuttosto, invia ks • G, che è un commitment per quel nonce. Come spiegato in precedenza, moltiplicando il nonce per il punto G del generatore, Alice nasconde il valore del nonce reale.

Alice invia le seguenti informazioni a Bob. In pratica, i dati Grin non sono separati nei campi "Metadata" e "Data", ma qui per chiarezza lo facciamo.
Tutto ciò che Alice manda a Bob nel primo passaggio di questa transazione Grin.
I campi Metadati sono:

  • Importo da inviare: La quantità di Grin che Alice vuole inviare a Bob (in questo caso, 25).
  • TX UUID: Un identificatore univoco che Alice e Bob usano per identificare questa transazione mentre inviano i dati avanti e indietro.
  • TX fee: Il costo della transazione (che non viene spiegato in questo tutorial).
  • lock_height: Il numero di blocco nel quale questa transazione diventa valida.

I campi Dati sono:

  • TX Inputs: Gli unspent output che Alice usa come input per la sua transazione verso Bob.
  • co: L'output del resto di Alice.
  • ks • G: la nonce ks di Alice diventa un commitment verso tale nonce quando viene moltiplicato per il punto generatore G.
  • rs • G: La somma di tutti i blinding factor di Alice rs diventa un commitment a quel valore quando viene moltiplicato per il punto generatore G.
Alice manda tutto questo a Bob, che procede con il passo successivo.

Il turno di Bob

Dopo aver ricevuto questi dati da Alice, Bob concatenerà le variabili TX fee e lock_height per creare M, denominato "Messaggio" della transazione.
Il "messaggio" della transazione.
Bob sceglie un blinding factor rr (r è il destinatario, in questo caso Bob) per i 25 Grin che si aspetta di ricevere da Alice. Diciamo che sceglie 11. Sceglie anche il suo nonce kr casuale (r, di nuovo, è il destinatario).

Proprio come Alice, Bob crea un commitment per entrambi questi valori moltiplicandoli entrambi per  il punto generatore G. Con questi valori, Bob genera la Schnorr challenge per la transazione, indicata dalla variabile e:
La Schnorr challenge della transazione.
Nell'ordine, la Schnorr challenge consiste nell'hash SHA256 de:

  • Il messaggio della transazione.
  • La somma dei commitment ai nonce utilizzati da Alice e Bob.
  • La somma dei commitment al blinding factor di Bob (per il sua output di 25 Grin) e la somma di Alice di tutti i suoi blinding factor.

Bob usa e per generare la sua firma Schnorr per la transazione, sr (r è il destinatario). Anche se si tratta dell'intera firma di Bob, la chiamiamo firma parziale di Bob, perché alla fine verrà aggiunta alla firma parziale di Alice per creare la firma dell'intera transazione.
Firma parziale di Bob della transazione.
Quando Alice alla fine riceve sr, non sarà in grado di scoprire da questa i valori kr o rr.

Bob invia il seguente messaggio ad Alice:

Bob invia ad Alice la sua firma parziale, il commitment per il suo nonce, e il commitment per il suo blinding factor per il suo output.

In ordine, questo consiste in:
  • sr: Firma parziale di Bob.
  • kr • G: il commitment di Bob per il suo nonce.
  • rr - G: il commitment di Bob per il suo blinding factor per il 25 Grin che si aspetta di ricevere.

Ultimo passaggio: di nuovo da Alice

Alice ha ora tutto ciò di cui ha bisogno per calcolare localmente e, la Schnorr challenge per questa transazione. Dopo aver calcolato e localmente, Alice può quindi validare la firma parziale di Bob.

La firma parziale di Bob sr, come abbiamo detto, consiste in:
Firma parziale di Bob per questa transazione.
Sulla base delle proprietà delle curve ellittiche descritte in precedenza, Alice può inserire il punto generatore G in entrambi i lati dell'equazione, e l'uguaglianza rimarrà vera.
Alice moltiplica ogni lato dell'equazione per il punto generatore G.
Poiché Alice ha ricevuto kr • G (il commitment di Bob per il suo nonce) e rr • G (il commitment di Bob per il blinding factor che userà per i 25 Grin che si aspetta di ricevere) da Bob, e poiché lei ha già calcolato e localmente, Alice può convalidare la firma parziale sr di Bob semplicemente moltiplicandola per il generatore G e assicurandosi che il lato destro dell'equazione sia uguale a quel valore.

Così facendo, Alice lo ha dimostrato che:

  1. Bob sa quanti Grin riceverà (25).
  2. Bob conosce il suo nonce.
  3. Bob conosce il suo blinding factor per i 25 Grin che si aspetta di ricevere.

.... senza che Alice abbia mai dovuto conoscere il nonce di Bob o il blinding factor che ha scelto.

Alice quindi genera la sua firma parziale:
Alice quindi genera la sua firma parziale pr la transazione.
Alice può ora generare la firma della transazione, che consiste sia della sua firma parziale che quella di Bob:
La firma dell'operazione, costituita dalla somma delle firme parziali di Alice e Bob e dal commitment ai loro nonces.
Nell'ordine, la firma include:

  • La somma delle firme parziali di Alice e Bob.
  • La somma del commitment di Alice e Bob nei confronti dei loro nonce (nessuno dei due conosce il vero nonce dell'altro).

Riassumendo, questo appare come:
La firma per la transazione.
dove s = ss + sr e k = ks + kr.

Ricordate questa firma - tra poco avrà senso.

Completare la transazione

La moneta digitale richiede una "memoria" - cioè, quando si invia denaro a una persona, non si deve poter usare quello stesso denaro per inviarlo a qualcun altro. Con Grin, nascondiamo sia la quantità di Grin inviata che i destinatari. Quindi, come possiamo dimostrare che nessun denaro è stato speso due volte o stampato dal nulla?

In una transazione Grin, quando si sottraggono tutte output dagli input, la quantità di Grin rimanente dovrebbe essere pari a 0. Tornando alla nostra analogia con banconote da 5 dollari, si ha:

3 dollari al cassiere (output) + 2 dollari di resto tornano a me (output) - una banconota da 5 dollari (input) = 0
In Grin, proprio questa somma rende la somma dei valori v a zero quando una transazione è legittima. Ma come si può dimostrarlo senza rivelare quali sono i valori? Vediamo gli input e gli output utilizzati nella nostra transazione da Alice a Bob:
(34-G) + (15-H) + (11-G) + (25-H) - (20-G) - (40-H) = (25-G) + (0-H)
Qui l'aspetto intelligente è che quando le quantità di Grin si annullano (come dovrebbe essere quando non sono stati creati soldi dal nulla), tutto ciò che rimane dal sottrarre gli output dagli input è il commitment al "blinding factor in eccesso", o il "kernel in eccesso". Questo commitment al blinding factor in eccesso, nel nostro caso 25•G, serve come chiave pubblica sulla curva.

Se la somma degli output di una transazione Grin meno la somma degli input produce una chiave pubblica valida sulla curva, si sa che i valori v devono essere stati annullati. Se il lato destro dell'equazione non è della forma n•G + 0•H per qualche valore noto di n, si sa che la transazione non è valida. Ciò significa che o l'importo speso era maggiore della somma degli input (ad esempio, si da una banconota da 5 dollari per pagare alla cassa 3 dollari, e si ottengono 10 dollari di resto), oppure gli input erano maggiori degli output (ad esempio, si da una banconota da 5 dollari per pagare alla cassa 3 dollari, e non si riceve il resto).

Ricordate la firma di prima?
La firma per la transazione.
Questa firma in realtà ha già firmato il commitment per il blinding factor in eccesso che ho appena menzionato. Ecco come.

Se ricordate, questa è come appare la firma parziale di Bob quando si moltiplicano entrambi i lati dell'equazione per il generatore G.
La firma parziale di Bob quando si moltiplicano entrambi i lati per il generatore G.
Allo stesso modo, ecco come appare la firma parziale di Alice quando si moltiplicano entrambi i lati per il generatore G.
La firma parziale di Alice quando si moltiplicano entrambi i lati per il generatore G.
Cosa succede se si sommano le due equazioni? Si ottiene:
sr•G + ss•G = (kr • G) + (ks • G) + (e • (rr•G + rs•G))

Ricordate che rr è il blinding factor di Bob e rs è la somma dei blinding factor di Alice. Ricordate anche da prima che rr•G + rs•G è lo stesso di (rr + rs)•G .

Il commitment di Bob per il suo blinding factor era di 11•G. Il commitment di Alice per la somma dei suoi blinding factor era di 14•G. Aggiungendoli insieme si ottiene 25•G, che è il commitment per il blinding factor in eccesso per la transazione. Quindi, l'aggiunta di sr e ss, che sono le rispettive firme parziali di Bob e Alice, dimostra la validità dell'intera transazione perché si sommano al commitment per il blinding factor in eccesso.

Semplificando ulteriormente quell'equazione, si ottiene:
sr•G + ss•G = (k•G) + (e • (r•G))

o
sr•G + ss•G = (k•G) + (e • (25•G))

Tutto quello che rimane da controllare e' che il lato sinistro equivale al lato destro.

Ricordate, tutto ciò che in questa equazione (la somma delle firme parziali, tutto in e, il commitment al blinding factor in eccesso, il commitment alla somma dei nonce) è pubblicamente visibile a tutti, in modo che chiunque possa fare questa verifica. Non abbiamo richiesto né Alice né i blinding factor di Bob per convalidare la transazione. Aggiungendo le loro firme parziali e verificando che si sommano al commitment per il blinding factor in eccesso, abbiamo dimostrato:

Non è stato creato denaro dal nulla nel spendere il precedente input di Alice.
Alice e Bob conoscevano entrambi i blinding factor per i loro output quando hanno creato questa transazione. Questo significa che i nuoi output sono spendibili da loro, e non si perdono nell'abisso.
Le informazioni che abbiamo appena usato per convalidare la transazione vengono inserite in quello che viene chiamato il transaction kernel.

Il transaction kernel

Oltre agli output, il transaction kernel è l'altro pezzo di informazione che salta fuori da una transazione Grin. Ogni transazione produce un transaction kernel, ma non c'è modo di guardare la blockchain Grin e di collegare un output ad un transaction kernel. Ne  esiste uno per ogni transazione Grin, e contiene la prova che non è stato stampato denaro dal nulla.

Le seguenti informazioni vengono memorizzate nel kernel:

  • La firma della transazione (s, k • G).
  • La chiave pubblica associata al "blinding factor in eccesso" (in questo caso, 25-G). Come descritto sopra, questo può essere usato per convalidare s.
  • Il transaction fee e il lock_height della transazione. (Nota: se si trattasse di una transazione Coinbase, nessuno dei due sarebbe presente).

Riepilogo

Alla fine, tutto ciò che viene trasmesso della transazione alla rete sono:

  • Gli input utilizzati.
  • I nuovi output.
  • Il transaction kernel.
  • Il kernel offset (che qui non ho descritto).

Nessuno dei metadati della transazione di prima viene trasmesso. C'è di più, alcune di queste informazioni possono essere scartate, ma risparmiamocelo per un altro post.

Speriamo che questo post faccia luce su come funzionano le transazioni di Grin. Ho intenzionalmente tralasciato range proof, kernel offset, e fee. Cercate altri post su come funziona il cut-through in Grin, che aspetto hanno le transazioni multi-partecipanti, e alcune caratteristiche sperimentali.


Traduzione da:
26.02.2019 Brandon Arvanaghi, Grin Transactions Explained, Step-by-Step
https://medium.com/@brandonarvanaghi/grin-transactions-explained-step-by-step-fdceb905a853

Commenti

Posta un commento

Post popolari in questo blog

Il bitcoin non esiste

Bitcoin non compatibile con lo Stato

Decentralizzazione: perché le reti stupide sono le migliori