Pokračujeme v našom cykle o fungovaní blockchainu Monero a dnešný článok bude venovaný protokolu RingCT (Ring Confidential Transactions), ktorý predstavuje dôverné transakcie a nové kruhové podpisy. Bohužiaľ, na internete je málo informácií o tom, ako to funguje, a snažili sme sa zaplniť tento nedostatok.

Budeme sa zaoberať tým, ako tento protokol skrýva sumy prevodov v sieti, prečo sa vzdali klasických kruhových podpisov typu cryptonote a ako sa táto technológia bude ďalej vyvíjať.
Vzhľadom na to, že tento protokol je jednou z najzložitejších technológií v Monero, čitateľ bude potrebovať základné vedomosti o fungovaní tohto blockchainu a povrchové znalosti kryptografie na eliptických krivkách (na osvieženie týchto vedomostí je možné prečítať prvé kapitoly našej predchádzajúcej článku o ).
Protokol RingCT
Jedným z možných útokov na cryptonote meny je analýza blockchainu založená na poznaní sumy a času odoslanej transakcie. To umožňuje výrazne zúžiť oblasť vyhľadávania relevantných výstupov pre útočníka. Na ochranu pred takouto analýzou bol v Monero implementovaný protokol anonymných transakcií, ktorý úplne skrýva sumy prevodov v sieti.
Je potrebné poznamenať, že myšlienka skrývania súm nie je nová. Jedným z prvých ju opísal vývojár Bitcoin Core Greg Maxwell vo svojej . Súčasná implementácia RingCT predstavuje jej modifikáciu s možnosťou používania kruhových podpisov (kam bez nich) a preto dostala svoje meno — Ring Confidential Transactions.
Okrem iného protokol pomáha zbaviť sa problémov so zamieňaním prachových výstupov — výstupov na malú sumu (zvyčajne sa dostávajú vo forme vrátenia z transakcií), ktoré spôsobili viac problémov, ako stáli samotné.
V januári 2017 sa uskutočnil hardfork siete Monero, ktorý umožnil voliteľné používanie dôverných transakcií. A už v septembri toho istého roku sa z hardforku verzie 6 tieto transakcie stali jediné povolené v sieti.
RingCT používa niekoľko mechanizmov: viacúrovňové spojiteľné spontánne anonymné skupinové podpisy (Multilayered Linkable Spontaneous Anonymous Group Signature, ďalej len — MLSAG), schému záväzkov (Pedersen Commitments) a range proofs (ustanovený preklad tohto termínu do slovenčiny neexistuje).
Protokol RingCT zavádza dva typy anonymných transakcií: simple a full. Prvý typ generuje peňaženka, keď transakcia využíva viac ako jeden vstup, druhý typ — v opačnej situácii. Líšia sa validáciou súm transakcií a podpísanými dátami s MLSAG podpisom (o tom budeme hovoriť nižšie). Transakcie typu full možno generovať s akýmkoľvek počtom vstupov, principiálne nie je žiadny rozdiel. V knihe sa uvádza, že rozhodnutie obmedziť full transakcie na jeden vstup bolo prijaté na rýchlo a v budúcnosti sa môže zmeniť.
MLSAG podpis
Pripomeňme si, čo predstavujú podpísané vstupy transakcie. Každá transakcia míňa nejaké prostriedky a generuje. Generovanie prostriedkov prebieha vytvorením výstupov transakcie (priamy analóg — bankovky), a výstup, ktorý transakcia míňa (veď v reálnom živote míňame práve bankovky), sa stáva vstupom (pozor, tu je veľmi ľahké sa zamotať).
Vstup odkazuje na niekoľko výstupov, ale míňa iba jeden, čím vytvára „dýmovú clonu“, aby sťažilo analýzu histórie prevodov. Ak má transakcia viac ako jeden vstup, túto štruktúru si môžeme predstaviť vo forme matice, kde riadky sú vstupy a stĺpce sú zamiešané výstupy. Aby mala sieť dôkaz, že transakcia míňa práve svoje výstupy (pozná ich tajné kľúče), vstupy podpisujú kruhovým podpisom. Tento podpis zaručuje, že podpisujúci poznal tajné kľúče od všetkých elementov niektorého zo stĺpcov.
Dôverné transakcie už nepoužívajú klasické pre kruhové podpisy, ich nahradili MLSAG — verzia prispôsobená na viac vstupov, ktorá vychádza z podobných jednovrstvových kruhových podpisov, .
Sú nazývané mnohovrstvové, pretože podpisujú naraz viac vstupov, z ktorých každý je zamiešaný s niekoľkými ďalšími, tj. podpisuje sa matica, nie jeden riadok. Ako neskôr uvidíme, to pomáha šetriť na veľkosti podpisu.
Poďme sa pozrieť, ako sa vytvára kruhový podpis na príklade transakcie, ktorá míňa 2 reálne výstupy a používa na zamiešanie m — 1 náhodných z blockchainu. Označme verejné kľúče výstupov, ktoré míňame, ako
, a key images pre ne príslušne:
Takže dostávame maticu veľkosti 2 x m. Najprv musíme vypočítať takzvané challenges pre každý pár výstupov:

Vypočítania začíname od výstupov, ktoré používame, pomocou ich verejných kľúčov:
a náhodných čísel
Nakoniec dostávame hodnoty:
, ktoré používame na výpočet challenge
pre nasledujúci pár výstupov (aby bolo jasnejšie, čo kam vkladáme, zvýraznili sme tieto hodnoty rôznymi farbami). Všetky nasledujúce hodnoty sa vypočítavajú cyklicky podľa vzorcov uvedených na prvej ilustrácii. Posledný sa vypočíta challenge pre pár skutočných výstupov.
Ako vidíme, vo všetkých stĺpcoch, okrem tých, ktoré obsahujú skutočné výstupy, sa používajú náhodne generované čísla
. Pre π-tý stĺpec ich budeme tiež potrebovať. Prevedieme
na s:
Podpis v sebe predstavuje tuple všetkých týchto hodnôt:

Tieto údaje sa potom zapíšu do transakcie.
Ako vidíme, MLSAG obsahuje len jeden challenge c0, čo umožňuje ušetriť na veľkosti podpisu (ktoré aj bez toho vyžadujú veľa miesta). Následne každý overovateľ, pomocou údajov
, obnoví hodnoty c1,…, cm a overí, že
. Takže naše krúžok sa uzavrel a podpis prešiel overením.
Pre RingCT transakcie typu full sa pridáva ďalší riadok do matice so zamiešanými výstupmi, ale o tom sa dozvieme neskôr.
Pedersen Commitments
(častejšie sa používa anglický termín — commitments) slúžia na to, aby jedna strana mohla dokázať, že pozná určitý tajomstvo (číslo), prakticky ho neodhalujúc. Napríklad hodíte kostkami určité číslo, vypočítate commitment a odovzdáte ho overovateľskej strane. Takže v momente odhalenia tajného čísla overovateľ sám vypočíta commitment, tým sa uistí, že ste ho neoklamali.
V Monero sa záväzky používajú na skrytie súm prevodov a používajú najrozšírenejšiu variantu — Pedersen commitments. Mimochodom, zaujímavý fakt — pôvodne vývojári navrhovali skrývať súmy bežným zamiešaním, teda pridaním výstupov na náhodné sumy, aby sa vniesla neurčitosť, ale potom prešli na commitments (pritom nie je isté, že ušetrili na veľkosti transakcie, ako uvidíme nižšie).
Vo všeobecnosti vzhľad záväzku vyzerá nasledovne:
Kde C — hodnota samotného záväzku, a — skrytá suma, H — fixný bod na eliptickej krivke (dodatkový generátor), a x — nejaká náhodná maska, skrytý faktor, generovaný náhodne. Maska je potrebná na to, aby tretia strana nemohla jednoduchým overovaním získať hodnotu commitment.
Pri generovaní nového výstupu peňaženka vypočíta preň commitment, a pri výdajoch používa buď vypočítanú hodnotu pri generovaní, alebo ju prepočítava znovu — v závislosti od typu transakcie.
RingCT simple
V prípade simple RingCT transakcií, aby sa zabezpečilo, že transakcia vytvorila výstupy v súmene rovnakej sume ako vstupy (nevyrobila peniaze z vzduchu), musí byť suma commitments prvých a druhých rovnaká, to znamená:

Commitment poplatkov sa počíta trochu inak — bez masky:
, kde a — suma poplatku, je verejne prístupná.
Takýto prístup nám umožňuje dokázať kontrolujúcej strane, že používame rovnaké sumy, bez odhalenia.
Aby sme to urobili jasnejšie, pozrime sa na príklad. Predpokladajme, že transakcia míňa dva výstupy (to znamená, že sa stávajú vstupmi) na 10 a 5 XMR a generuje tri výstupy v súmene 12 XMR: 3, 4 a 5 XMR. Pri tom platí poplatok 3 XMR. Takže suma vynaložených peňazí plus suma generovaných a poplatok je rovná 15 XMR. Poďme sa pokúsiť vypočítať commitments a pozrieť sa na rozdiel ich súm (spomeňme si na matematiku):

Tu vidíme, aby rovnica vyšla — sumy masiek vstupov a výstupov musia byť rovnaké. Na to peňaženka generuje náhodne x1, y1, y2 a y3, a zvyšok x2 vypočíta takto:
![]()
Použitím týchto masiek môžeme ktorejkoľvek kontrolujúcej strane dokázať, že nevytvárame prostriedky viac, ako míňame, bez odhalenia súm. Originálne, že?
RingCT full
V full RingCT transakciách kontrola súm prevodov prebieha trochu zložitejšie. V týchto transakciách peňaženka neprepočítava commitments pre vstupy, ale používa vypočítané pri ich generovaní. Pri tom musíme predpokladať, že rozdiel súm už nezíska nulovú hodnotu, a namiesto toho:

Tu z — rozdiel masiek vstupov a výstupov. Ak zvážime zG ako verejný kľúč (čím de facto aj je), potom z — je to súkromný kľúč. Tým pádom poznáme verejný aj jemu zodpovedajúci súkromný kľúč. S týmito údajmi ich môžeme použiť v kruhovom podpise MLSAG spolu s verejnými kľúčmi zamiešaných výstupov:

Takže platný kruhový podpis zaručí, že poznáme všetky súkromné kľúče jedného z stĺpcov, a súkromný kľúč v poslednom riadku môžeme poznať iba pokiaľ transakcia nevytvára prostriedky viac, než míňa. Mimochodom, tu je odpoveď na otázku „prečo tu rozdiel súm commitments nevedie k nule“ — ak zG = 0, tak odkryjeme stĺpec s reálnymi výstupmi.
A ako sa príjemca prostriedkov dozvie, koľko peňazí mu poslali? Tu je to jednoduché — odosielateľ transakcie a príjemca si vymenia kľúče podľa protokolu Diffie-Hellman, používajúc kľúč transakcie a view-kľúč príjemcu a vypočítajú spoločné tajomstvo. Odosielateľ zapisuje do špeciálnych polí transakcie údaje o výstupných sumách, zašifrované týmto spoločným kľúčom.
Range proofs
A čo sa stane, ak ako sumu v commitments použijeme záporné číslo? To môže viesť k generovaniu ďalších mincí! Takýto výsledok je neprípustný, preto potrebujeme záruku, že naše použité sumy nie sú záporné (bez odkrytia týchto súm, samozrejme, inak by sme vynaložili toľko práce zbytočne). Inými slovami, musíme dokázať, že suma sa nachádza v intervale [0, 2n — 1].
Na to sa suma každého výstupu rozdelí na dvojkové cifry a počíta sa commitment pre každú cifru zvlášť. Ako to prebieha, je najlepšie ukázať na príklade.
Predpokladajme, že naše sumy sú malé a zmestia sa do 4 bitov (v praxi je to 64 bitov), a vytvárame výstup na sumu 5 XMR. Počítame commitments pre každú cifru a celkový commitment pre celú sumu:
Následne sa každý commitment zamieša so surrogate (Ci-2iH) a párovne sa podpíše kruhovým podpisom Borromeo (ďalší kruhový podpis), ktorý navrhol Greg Maxwell v roku 2015 (podrobnejšie o ňom si môžete prečítať ):
Všetko spolu sa nazýva range proof a umožňuje zaručiť, že v commitments sú použité sumy v intervale [0, 2n — 1].
Čo ďalej?
V súčasnej implementácii range proofs zaberajú veľmi veľa miesta — 6176 bajtov na jeden výstup. To vedie k veľkým transakciám a tým pádom aj k vyšším poplatkom. Aby sa znížila veľkosť transakcie, vývojári Monero zavádzajú namiesto Borromeo podpisov bulletproofs — mechanizmus range proof bez bitových commitments. , sú schopné znížiť veľkosť range proof až o 94 %. Mimochodom, v polovici júla technológia prešla spoločnosti Kudelski Security, ktorá nezistila žiadne zásadné nedostatky ani v samotnej technológii, ani v jej implementácii. Technológia sa už používa v testovacej sieti a s novým hard forkom by mohla pravdepodobne prejsť aj do hlavnej siete.
Pýtajte sa na vaše otázky, navrhujte témy na nové články o technológiách v oblasti kryptomien a tiež sa prihláste do našej skupiny v , aby ste boli informovaní o našich udalostiach a publikáciách.
Zdroj: habr.com
