Oracolo casuale basato sulla firma digitale in blockchain

Dall'idea alla realizzazione: modifichiamo lo schema di firma digitale esistente a curva ellittica in modo che sia deterministico, e sulla base di esso forniamo funzioni per ottenere numeri pseudo-casuali verificabili all'interno della blockchain.

Oracolo casuale basato sulla firma digitale in blockchain

Idea

Nell'autunno del 2018 è stata inclusa la blockchain di Waves attivati ​​i primi smart contract, è sorta immediatamente la domanda sulla possibilità di ottenere numeri pseudocasualiPuoi fidarti.

Perplesso su questa domanda, sono finalmente giunto alla conclusione: qualsiasi blockchain è una cellula; è impossibile ottenere una fonte affidabile di entropia in un sistema chiuso.

Ma mi piaceva ancora un'idea: se oracolo casuale firmerà i dati dell'utente con un algoritmo deterministico, quindi l'utente potrà sempre verificare tale firma utilizzando la chiave pubblica, e sarà sicuro che il valore risultante sia univoco. L'oracolo, per quanto lo voglia, non è in grado di cambiare nulla; l'algoritmo produce un risultato inequivocabile. In sostanza, l'utente registra il risultato, ma non lo sa finché l'oracolo non lo pubblica. Si scopre che non puoi fidarti affatto dell'oracolo, ma controlla il risultato del suo lavoro. Quindi, in caso di verifica riuscita, tale firma può essere considerata una fonte di entropia per un numero pseudocasuale.

La piattaforma blockchain Waves utilizza uno schema di firma EdDSA вариант Ed25519. In questo schema, la firma è composta dai valori R e S, dove R dipende da un valore casuale e S viene calcolato in base al messaggio firmato, alla chiave privata e allo stesso numero casuale di R. Si scopre che non esiste una dipendenza univoca per lo stesso. Esistono molte firme valide per un messaggio utente.

Ovviamente, nella sua forma pura, tale firma non può essere utilizzata come fonte di numeri pseudo-casuali, poiché non è deterministica e, quindi, può essere facilmente manipolata dall'oracolo.

Ma, come si è scoperto, è effettivamente possibile renderlo deterministico.

Avevo grandi speranze funzione casuale verificabile (VRF), ma dopo aver studiato l'hardware ho dovuto abbandonare questa opzione. Sebbene VRF offra una versione deterministica della firma e della sua prova, c'è uno strano punto nell'algoritmo che apre un buco nero per la manipolazione dell'oracolo. Vale a dire, quando si calcola il valore di k (sezione 5.1) viene utilizzata una chiave privata, che rimane sconosciuta all'utente, il che significa che l'utente non può verificare la correttezza del calcolo di k, il che significa che l'oracolo può utilizzare qualsiasi valore di k di cui ha bisogno e allo stesso tempo mantenere un database di corrispondenze di k e i dati firmati in modo da poter sempre ricalcolare il risultato corretto dal punto di vista VRF . Se vedi un disegno basato su VRF senza rivelare la chiave privata, puoi essere furbo: indica la necessità di rivelare la chiave, oppure escluderla dal calcolo di k, poi la chiave privata si rivelerà automaticamente quando apparirà la prima firma . In generale, come già accennato, uno strano schema per un oracolo casuale.

Dopo una breve riflessione e il supporto degli analisti locali, è nato lo schema di lavoro VECRO.

VECRO è l'abbreviazione di Verifying Elliptic Curve Random Oracle, che in russo significa oracolo casuale verificabile su curve ellittiche.

Tutto si è rivelato abbastanza semplice: per ottenere il determinismo è necessario fissare il valore di R prima che appaia il messaggio da firmare. Se R è impegnato ed è parte del messaggio da firmare, il che garantisce ulteriormente che R sia impegnato nel messaggio da firmare, il valore di S è determinato in modo univoco dal messaggio dell'utente e può quindi essere utilizzato come fonte per numeri pseudocasuali.

In un tale schema, non importa come viene fissato R; questa rimane la responsabilità dell'oracolo. È importante che S sia determinato in modo univoco dall'utente, ma il suo valore è sconosciuto finché l'oracolo non lo pubblica. Tutto ciò che volevamo!

A proposito di R fissa, notalo riutilizzato R firmando i vari messaggi rivela in modo univoco la chiave privata nello schema EdDSA. Diventa estremamente importante per il proprietario dell'oracolo eliminare la possibilità di riutilizzare R per firmare messaggi di utenti diversi. Cioè, con qualsiasi manipolazione o collusione, l’oracolo rischierà sempre di perdere la sua chiave privata.

In totale, l'oracolo deve fornire agli utenti due funzioni: inizializzazione, che fissa il valore R, e firma, che restituisce il valore S. In questo caso, la coppia R, S è la solita firma verificabile di un messaggio utente contenente un valore fisso valore R e dati utente arbitrari.

Si può sostenere che questo schema per la blockchain non è altro che ordinario schema commit-espansione. In sostanza sì, è lei. Ma ci sono molte sfumature. In primo luogo, l'oracolo funziona sempre con la stessa chiave in tutte le operazioni, ad esempio è comodo da utilizzare nei contratti. In secondo luogo, c'è il rischio che l'oracolo perda la chiave privata se si comporta in modo errato, ad esempio l'oracolo consente di fare dei campioni del risultato, quindi è sufficiente fare solo due test per scoprire la chiave privata e ottenere il pieno accesso al portafoglio. In terzo luogo, è bella una firma che sia nativamente verificabile sulla blockchain e che sia fonte di casualità.

Per sei mesi l'idea dell'implementazione ribolliva nella mia testa, finché finalmente la motivazione non è apparsa sotto forma di forma sovvenzione da Waves Labs. Da una grande sovvenzione derivano grandi responsabilità, quindi il progetto sarà lì!

implementazione

Quindi, in questo progetto VECRO è stato implementato sulla blockchain Waves in modalità richiesta-risposta utilizzando transazioni di trasferimento tra l'utente e l'oracolo. Allo stesso tempo, sull'account Oracle viene installato uno script che controlla il lavoro rigorosamente secondo la logica sopra descritta. Le transazioni Oracle vengono verificate e l'intera catena di interazione dell'utente viene ripristinata. Tutte e quattro le transazioni sono coinvolte nella verifica del valore finale; lo smart contract le lega insieme con un rigido thread di verifica, controllando tutti i valori passo dopo passo e senza lasciare spazio ad alcuna manipolazione.

Ancora una volta, per metterlo da parte e renderlo più chiaro. L'oracolo non funziona solo secondo lo schema proposto. Il suo lavoro è completamente controllato a livello blockchain da chi è stabilito strettamente con uno smart contract. Fai un passo a sinistra e la transazione semplicemente non andrà a buon fine. Quindi, se una transazione è inclusa nella blockchain, l’utente non ha nemmeno bisogno di controllare nulla; centinaia di nodi della rete hanno già controllato tutto per lui.

Attualmente, c'è un VECRO in esecuzione sulla rete principale di Waves (puoi eseguirne uno tuo, non è difficile, basta dai un'occhiata all'esempio di configurazione). Il codice corrente viene eseguito in PHP (on WavesKit, riguardo quale Te l'ho detto prima).

Per poter utilizzare il servizio Oracle è necessario:

  • Correggi R;
    • Invia almeno 0.005 Wave all'alias oracle init@vecr;
    • Ricevi il codice R nel campo allegato nel trasferimento di 1 token R-vecr dall'oracolo all'utente;
  • Ottieni una firma;
    • Inviare almeno 0.005 Wave all'alias oracle random@vecr, e DEVE inoltre indicare nel campo dell'allegato il R-code ricevuto in precedenza e ulteriori dati utente;
    • Ricevi il codice S nel campo allegato nel trasferimento di 1 token S-vecr dall'oracolo all'utente;
  • Utilizzare il codice S come origine del numero pseudo-casuale.

Sfumature dell'attuale implementazione:

  • Le Onde inviate all'oracolo vengono utilizzate come commissione per la transazione di restituzione all'utente, fino ad un massimo di 1 Onde;
  • Il codice R è la concatenazione di un byte del carattere "R" e un valore R codificato base32 di 58 byte;
  • Il codice R in allegato dovrebbe essere il primo, i dati utente vengono dopo il codice R;
  • Il codice S è la concatenazione di un byte del carattere "S" e un valore codificato base32 di 58 byte di S;
  • S è il risultato della divisione del modulo, quindi non è possibile utilizzare S come numero pseudocasuale completo a 256 bit (questo numero può essere considerato un numero pseudocasuale massimo a 252 bit);
  • L'opzione più semplice è utilizzare l'hash del codice S come numero pseudo-casuale.

Esempio di ricezione del codice S:

Da un punto di vista tecnico, l'oracolo è completamente pronto per il lavoro, puoi usarlo tranquillamente. Dal punto di vista dell'utilizzo da parte dell'utente medio manca un'interfaccia grafica comoda, per questo bisognerà attendere.

Sarò felice di rispondere alle domande e accettare commenti, grazie.

Fonte: habr.com

Aggiungi un commento