Oracol aleatoriu bazat pe semnătura digitală în blockchain

De la idee la implementare: modificăm schema existentă de semnătură digitală cu curbă eliptică astfel încât să fie deterministă, iar pe baza acesteia oferim funcții pentru obținerea de numere pseudoaleatoare verificabile în cadrul blockchain-ului.

Oracol aleatoriu bazat pe semnătura digitală în blockchain

Idee

În toamna lui 2018, a inclus blockchain-ul Waves primele contracte inteligente activate, imediat a apărut întrebarea despre posibilitatea obținerii numere pseudoaleatoarepoti avea incredere.

Încercând această întrebare, am ajuns în sfârșit la concluzia: orice blockchain este o celulă; este imposibil să obții o sursă de entropie de încredere într-un sistem închis.

Dar tot mi-a plăcut o idee: dacă oracol aleatoriu va semna datele utilizatorului cu un algoritm determinist, apoi utilizatorul va putea întotdeauna să verifice o astfel de semnătură folosind cheia publică și va fi sigur că valoarea rezultată este unică. Oracolul, oricât de mult dorește, nu poate schimba nimic; algoritmul produce un rezultat clar. În esență, utilizatorul înregistrează rezultatul, dar nu îl știe până când oracolul îl publică. Se pare că nu puteți avea deloc încredere în oracol, dar verificați rezultatul muncii sale. Apoi, în cazul verificării cu succes, o astfel de semnătură poate fi considerată o sursă de entropie pentru un număr pseudoaleator.

Platforma blockchain Waves folosește o schemă de semnătură EdDSA opțiune Ed25519. În această schemă, semnătura constă din valorile R și S, unde R depinde de o valoare aleatorie, iar S este calculată pe baza mesajului care este semnat, a cheii private și a aceluiași număr aleatoriu ca R. Se dovedește că nu există o dependență unică pentru același. Există multe semnături valide pentru un mesaj de utilizator.

Evident, în forma sa pură, o astfel de semnătură nu poate fi folosită ca sursă de numere pseudoaleatoare, deoarece este nedeterministă și, prin urmare, poate fi ușor manipulată de către oracol.

Dar, după cum sa dovedit, este de fapt posibil să o facem deterministă.

Aveam mari speranțe funcție aleatorie verificabilă (VRF), dar după ce am studiat hardware-ul, a trebuit să renunț la această opțiune. Deși VRF oferă o versiune deterministă a semnăturii și a dovezii sale, există un loc ciudat în algoritm care deschide o gaură neagră pentru manipularea oracolului. Și anume, atunci când se calculează valoarea lui k (secțiunea 5.1) se folosește o cheie privată, care rămâne necunoscută utilizatorului, ceea ce înseamnă că utilizatorul nu poate verifica corectitudinea calculului lui k, ceea ce înseamnă că oracolul poate folosi orice valoare a lui k de care are nevoie și, în același timp, poate menține o bază de date de corespondențe de k și datele semnate pentru a putea întotdeauna recalcula rezultatul corect din punctul de vedere al VRF . Dacă vedeți un desen bazat pe VRF fără a dezvălui cheia privată, puteți fi inteligent: indicați necesitatea fie de a dezvălui cheia, fie de a o exclude din calculul lui k, atunci cheia privată se va dezvălui automat când apare prima semnătură . În general, așa cum am menționat deja, o schemă ciudată pentru un oracol aleatoriu.

După puțină gândire și cu sprijinul analiștilor locali, a luat naștere schema de lucru VECRO.

VECRO este o abreviere pentru Verifiable Elliptic Curve Random Oracle, care în limba rusă înseamnă oracol verificabil aleatoriu pe curbele eliptice.

Totul s-a dovedit a fi destul de simplu; pentru a obține determinism, trebuie să fixați valoarea lui R înainte să apară mesajul de semnat. Dacă R este comis și face parte din mesajul care este semnat, ceea ce asigură în continuare că R este comis în mesajul care este semnat, valoarea lui S este determinată în mod unic de mesajul utilizatorului și, prin urmare, poate fi folosită ca sursă pentru numere pseudoaleatoare.

Într-o astfel de schemă, nu contează cum este fixat R; aceasta rămâne responsabilitatea oracolului. Este important ca S să fie determinat în mod unic de către utilizator, dar valoarea lui este necunoscută până când oracolul îl publică. Tot ce ne-am dorit!

Apropo de R fix, rețineți că reutilizat R la semnarea diferitelor mesaje, dezvăluie în mod unic cheia privată în schema EdDSA. Devine extrem de important pentru proprietarul oracolului să elimine posibilitatea de a reutiliza R pentru a semna diferite mesaje de utilizator. Adică, cu orice manipulare sau coluziune, oracolul va risca întotdeauna să-și piardă cheia privată.

În total, oracolul trebuie să ofere utilizatorilor două funcții: inițializare, care fixează valoarea R și semnătură, care returnează valoarea S. În acest caz, perechea R, S este semnătura uzuală verificabilă a unui mesaj de utilizator care conține un mesaj fix. valoarea R și date arbitrare ale utilizatorului.

Se poate argumenta că această schemă pentru blockchain nu este altceva decât obișnuită schema commit-expand. În esență, da, este ea. Dar există mai multe nuanțe. În primul rând, oracolul funcționează întotdeauna cu aceeași cheie în toate operațiunile, de exemplu, acest lucru este convenabil de utilizat în contracte. În al doilea rând, există riscul ca oracolul să piardă cheia privată dacă se comportă incorect, de exemplu, oracolul vă permite să faceți mostre ale rezultatului, atunci este suficient să faceți doar două teste pentru a afla cheia privată și pentru a obține totalul acces la portofel. În al treilea rând, o semnătură care este verificabilă nativ pe blockchain și este o sursă de aleatorie este frumoasă.

Timp de șase luni ideea implementării mi-a fiert în cap, până când în cele din urmă a apărut motivația în formă grant de la Waves Labs. Cu un grant mare vine o mare responsabilitate, așa că proiectul va fi acolo!

punerea în aplicare

Deci, în acest proiect VECRO a fost implementat pe blockchain-ul Waves în modul cerere-răspuns folosind tranzacții de transfer între utilizator și oracol. În același timp, pe contul Oracle este instalat un script care controlează activitatea strict în conformitate cu logica descrisă mai sus. Tranzacțiile Oracle sunt verificate și întregul lanț de interacțiune cu utilizatorul este restabilit. Toate cele patru tranzacții sunt implicate în verificarea valorii finale; contractul inteligent le leagă împreună cu un fir de verificare strict, verificând toate valorile pas cu pas și nu lăsând loc nici unei manipulări.

Încă o dată, să-l las deoparte și să fie mai clar. Oracolul nu funcționează doar conform schemei propuse. Activitatea sa este complet controlată la nivel de blockchain de către cei stabiliti strâns cu un contract inteligent. Treceți la stânga și tranzacția pur și simplu nu va avea loc. Deci, dacă o tranzacție este inclusă în blockchain, utilizatorul nici măcar nu trebuie să verifice nimic; sute de noduri de rețea au verificat deja totul pentru el.

În prezent, există un VECRO care rulează pe rețeaua principală Waves (puteți rula pe propriul dvs., nu este dificil, doar aruncați o privire la exemplul de configurare). Codul curent rulează în PHP (on WavesKit, despre care ți-am spus mai devreme).

Pentru a utiliza serviciul oracle trebuie să:

  • Fix R;
    • Trimiteți cel puțin 0.005 Waves la oracle alias init@vecr;
    • Primiți codul R în câmpul de atașare în transferul a 1 jeton R-vecr de la oracol la utilizator;
  • Obțineți o semnătură;
    • Trimiteți cel puțin 0.005 Waves către alias-ul oracol random@vecr și, de asemenea, TREBUIE să indice codul R primit anterior și date suplimentare de utilizator în câmpul de atașare;
    • Primiți codul S în câmpul de atașare în transferul a 1 jeton S-vecr de la oracol la utilizator;
  • Utilizați codul S ca sursă de număr pseudo-aleatoriu.

Nuanțe ale implementării actuale:

  • Valurile trimise la oracol sunt folosite ca comision pentru tranzacția de retur către utilizator, până la maximum 1 Val;
  • Codul R este concatenarea unui octet cu caracterul „R” și a unei valori R codificate în bază32 de 58 de octeți;
  • Codul R din atașament ar trebui să fie primul, datele utilizatorului vin după codul R;
  • Codul S este concatenarea unui octet cu caracterul „S” și a unei valori codificate în bază32 de 58 de octeți a lui S;
  • S este rezultatul diviziunii modulo, deci nu puteți folosi S ca număr pseudoaleator complet de 256 de biți (acest număr poate fi considerat un număr pseudoaleator de maximum 252 de biți);
  • Cea mai simplă opțiune este să folosești codul S ca număr pseudo-aleatoriu.

Exemplu de primire a codului S:

Din punct de vedere tehnic, oracolul este complet gata de lucru, îl puteți folosi în siguranță. Din punctul de vedere al utilizării de către utilizatorul mediu, lipsește o interfață grafică convenabilă; aceasta va trebui să aștepte.

Voi fi bucuros să răspund la întrebări și să accept comentarii, vă mulțumesc.

Sursa: www.habr.com

Adauga un comentariu