Continuăm seria noastră despre blockchain-ul Monero, iar articolul de astăzi se va concentra pe protocolul RingCT (Ring Confidential Transactions), care introduce tranzacții confidențiale și noi semnături de inel. Din păcate, există puține informații pe Internet despre cum funcționează și am încercat să umplem acest gol.
Vom vorbi despre modul în care rețeaua ascunde sumele de transfer folosind acest protocol, de ce au abandonat semnăturile clasice de inel criptonote și despre cum se va dezvolta această tehnologie în continuare.
Deoarece acest protocol este una dintre cele mai complexe tehnologii din Monero, cititorul va avea nevoie de cunoștințe de bază despre designul acestui blockchain și de cunoștințe trecătoare de criptografie cu curbe eliptice (pentru a perfecționa aceste cunoștințe, puteți citi primele capitole ale noastre articol anterior despre
Protocolul RingCT
Unul dintre posibilele atacuri asupra monedelor criptonote este analiza blockchain bazată pe cunoașterea cantității și timpului tranzacției trimise. Asta permite
Este de remarcat faptul că ideea de a ascunde sume nu este nouă. Dezvoltatorul Bitcoin Core, Greg Maxwell, a fost unul dintre primii care l-au descris în el
Printre altele, protocolul ajută la eliminarea problemelor legate de amestecarea ieșirilor de praf - ieșiri de o cantitate mică (de obicei primite sub formă de schimbare din tranzacții), care au creat mai multe probleme decât meritau.
În ianuarie 2017, a avut loc o hard fork a rețelei Monero, permițând utilizarea opțională a tranzacțiilor confidențiale. Și deja în septembrie același an, cu versiunea 6 hard fork, astfel de tranzacții au devenit singurele permise în rețea.
RingCT folosește mai multe mecanisme simultan: semnături de grup anonime spontane, conectate cu mai multe straturi (Multilayered Linkable Spontaneous Anonymous Group Signature, denumită în continuare MLSAG), o schemă de angajament (Pedersen Commitments) și dovezi ale intervalului (acest termen nu are o traducere stabilită în rusă) .
Protocolul RingCT introduce două tipuri de tranzacții anonime: simple și complete. Portofelul generează primul atunci când o tranzacție folosește mai mult de o intrare, al doilea - în situația opusă. Ele diferă prin validarea sumelor tranzacțiilor și a datelor semnate cu o semnătură MLSAG (vom vorbi mai multe despre asta mai jos). Mai mult, tranzacțiile de tip full pot fi generate cu orice număr de intrări, neexistând o diferență fundamentală. In carte
Semnătura MLSAG
Să ne amintim ce sunt intrările de tranzacție semnate. Fiecare tranzacție cheltuiește și generează niște fonduri. Generarea de fonduri are loc prin crearea de ieșiri ale tranzacției (o analogie directă sunt facturile), iar ieșirea pe care o cheltuiește tranzacția (la urma urmei, în viața reală cheltuim bancnote) devine intrare (ai grijă, este foarte ușor să te confuzi). Aici).
O intrare face referire la mai multe ieșiri, dar cheltuiește doar una, creând astfel o „cortină de fum” pentru a face dificilă analiza istoricului traducerii. Dacă o tranzacție are mai multe intrări, atunci o astfel de structură poate fi reprezentată ca o matrice, unde rândurile sunt intrările și coloanele sunt ieșirile mixte. Pentru a demonstra rețelei că tranzacția își cheltuiește exact ieșirile (cunoaște cheile lor secrete), intrările sunt semnate cu o semnătură de inel. O astfel de semnătură garantează că semnatarul cunoștea cheile secrete pentru toate elementele oricărei coloane.
Tranzacțiile confidențiale nu le mai folosesc pe cele clasice
Se numesc multistrat deoarece semnează mai multe intrări simultan, fiecare dintre ele amestecată cu mai multe altele, adică o matrice este semnată și nu un rând. După cum vom vedea mai târziu, acest lucru ajută la economisirea dimensiunii semnăturii.
Să ne uităm la modul în care se formează o semnătură de inel, folosind exemplul unei tranzacții care cheltuiește 2 ieșiri reale și utilizează m - 1 aleatorii din blockchain pentru amestecare. Să notăm cheile publice ale ieșirilor pe care le cheltuim
, și imagini cheie pentru ei în consecință: Astfel, obținem o matrice de dimensiune 2 x m. În primul rând, trebuie să calculăm așa-numitele provocări pentru fiecare pereche de rezultate:
Începem calculele cu ieșirile, pe care le cheltuim folosind cheile lor publice:și numere aleatoriiCa rezultat, obținem următoarele valori:
, pe care îl folosim pentru a calcula provocarea
următoarea pereche de ieșiri (pentru a înțelege mai ușor cu ce înlocuim, am evidențiat aceste valori în diferite culori). Toate următoarele valori sunt calculate într-un cerc folosind formulele prezentate în prima ilustrație. Ultimul lucru de calculat este provocarea pentru o pereche de rezultate reale.
După cum putem vedea, toate coloanele, cu excepția celei care conține rezultate reale, folosesc numere generate aleatoriu. Pentru π- coloana vom avea nevoie si de ele. Să ne transformămîn s:
Semnătura în sine este un tuplu din toate aceste valori:
Aceste date sunt apoi scrise într-o tranzacție.
După cum putem vedea, MLSAG conține o singură provocare c0, care vă permite să economisiți dimensiunea semnăturii (care necesită deja mult spațiu). Mai departe, orice inspector, folosind datele, restabilește valorile c1,…, cm și verifică asta. Astfel, inelul nostru este închis și semnătura a fost verificată.
Pentru tranzacțiile RingCT de tip complet, se adaugă încă o linie la matrice cu ieșiri mixte, dar despre asta vom vorbi mai jos.
Angajamente Pedersen
Angajamentele Monero sunt folosite pentru a ascunde sumele transferurilor și pentru a folosi cea mai comună opțiune - angajamentele Pedersen. Apropo, un fapt interesant - la început dezvoltatorii au propus ascunderea sumelor prin amestecare obișnuită, adică adăugarea de ieșiri pentru sume arbitrare pentru a introduce incertitudine, dar apoi au trecut la angajamente (nu este un fapt pe care au economisit pe mărimea tranzacției, așa cum vom vedea mai jos).
În general, angajamentul arată astfel:
unde C — sensul angajamentului în sine, a - suma ascunsa, H este un punct fix pe curba eliptică (generator suplimentar) și x — un fel de mască arbitrară, un factor de ascundere generat aleatoriu. Masca este necesară aici, astfel încât o terță parte să nu poată ghici pur și simplu valoarea angajamentului.
Atunci când este generată o nouă ieșire, portofelul calculează angajamentul pentru aceasta, iar atunci când este cheltuită, ia fie valoarea calculată în timpul generării, fie o recalculează, în funcție de tipul tranzacției.
RingCT simplu
În cazul tranzacțiilor RingCT simple, pentru a se asigura că tranzacția a creat ieșiri într-o sumă egală cu cantitatea de intrări (nu a produs bani din aer), este necesar ca suma angajamentelor primului și celui de-al doilea. cele să fie aceleași, adică:
Comisiile de angajament o consideră puțin diferit - fără mască:
Unde a — cuantumul comisionului, acesta este disponibil publicului.
Această abordare ne permite să dovedim părții de încredere că folosim aceleași sume fără a le dezvălui.
Pentru a clarifica lucrurile, să ne uităm la un exemplu. Să presupunem că o tranzacție cheltuiește două ieșiri (adică devin intrări) de 10 și 5 XMR și generează trei ieșiri în valoare de 12 XMR: 3, 4 și 5 XMR. Totodata plateste un comision de 3 XMR. Astfel, suma de bani cheltuită plus suma generată și comisionul este egal cu 15 XMR. Să încercăm să calculăm angajamentele și să ne uităm la diferența dintre sumele lor (amintiți-vă de matematică):
Aici vedem că pentru ca ecuația să convergă, avem nevoie ca sumele măștilor de intrare și de ieșire să fie aceleași. Pentru a face acest lucru, portofelul generează aleatoriu x1, y1, y2 și y3, iar restul x2 calculeaza astfel:
Folosind aceste măști, putem dovedi oricărui verificator că nu generăm mai multe fonduri decât cheltuim, fără a dezvălui suma. Original, nu?
RingCT plin
În tranzacțiile RingCT complete, verificarea sumelor de transfer este puțin mai complicată. În aceste tranzacții, portofelul nu recalculează angajamentele pentru intrări, ci le folosește pe cele calculate când au fost generate. În acest caz, trebuie să presupunem că nu vom mai obține diferența dintre sumele egale cu zero, ci în schimb:
Aici z — diferența dintre măștile de intrare și de ieșire. Dacă luăm în considerare zG ca cheie publică (care este de facto), atunci z este cheia privată. Astfel, cunoaștem cheile publice și private corespunzătoare. Cu aceste date în mână, le putem folosi în semnătura inelului MLSAG împreună cu cheile publice ale ieșirilor care sunt amestecate:
Astfel, o semnătură de inel validă ne va asigura că cunoaștem toate cheile private ale uneia dintre coloane și nu putem cunoaște cheia privată din ultimul rând decât dacă tranzacția nu generează mai multe fonduri decât cheltuiește. Apropo, iată răspunsul la întrebarea „de ce diferența dintre valorile angajamentelor nu duce la zero” - dacă zG = 0, apoi vom extinde coloana cu ieșiri reale.
Cum știe beneficiarul fondurilor câți bani i-au fost trimiși? Totul este simplu aici - expeditorul tranzacției și destinatarul schimbă cheile folosind protocolul Diffie-Hellman, folosind cheia de tranzacție și cheia de vizualizare a destinatarului și calculează secretul partajat. Expeditorul scrie date despre sumele de ieșire, criptate cu această cheie partajată, în câmpuri speciale ale tranzacției.
Dovezi de gamă
Ce se întâmplă dacă folosiți un număr negativ ca sumă în angajamente? Acest lucru poate duce la generarea de monede suplimentare! Acest rezultat este inacceptabil, așa că trebuie să garantăm că sumele pe care le folosim nu sunt negative (fără a dezvălui aceste sume, desigur, altfel e atât de multă muncă și totul în zadar). Cu alte cuvinte, trebuie să dovedim că suma este în interval [0, 2n - 1].
Pentru a face acest lucru, suma fiecărei ieșiri este împărțită în cifre binare și angajamentul este calculat pentru fiecare cifră separat. Este mai bine să vedeți cum se întâmplă acest lucru cu un exemplu.
Să presupunem că sumele noastre sunt mici și se potrivesc în 4 biți (în practică este de 64 de biți) și creăm o ieșire în valoare de 5 XMR. Calculăm angajamente pentru fiecare categorie și angajamentul total pentru întreaga sumă:
Apoi, fiecare angajament este amestecat cu un surogat (Ci-2iH) și este semnat în perechi cu semnătura inelului Borromeo (o altă semnătură a inelului), propusă de Greg Maxwell în 2015 (puteți citi mai multe despre aceasta
Luate împreună, aceasta se numește dovadă de interval și vă permite să vă asigurați că angajamentele folosesc sume din interval [0, 2n - 1].
Ce urmeaza?
În implementarea actuală, probele de interval ocupă mult spațiu - 6176 de octeți per ieșire. Acest lucru duce la tranzacții mai mari și, prin urmare, la comisioane mai mari. Pentru a reduce dimensiunea unei tranzacții Monero, dezvoltatorii introduc antiglonț în loc de semnături Borromeo - un mecanism de verificare a gamei fără angajamente pe biți.
Pune-ți întrebările, sugerează subiecte pentru articole noi despre tehnologii în domeniul criptomonedei și, de asemenea, abonează-te la grupul nostru în
Sursa: www.habr.com