Folytatjuk a Monero blokkláncról szóló sorozatunkat, mai cikkünk pedig a RingCT (Ring Confidential Transactions) protokollra fókuszál, amely bizalmas tranzakciókat és új gyűrűs aláírásokat vezet be. Sajnos az interneten kevés információ található a működéséről, és ezt a hiányt igyekeztünk pótolni.
Beszélni fogunk arról, hogy a hálózat hogyan rejti el az átutalási összegeket ezzel a protokollal, miért hagyták el a klasszikus kriptográfiai gyűrű aláírásokat, és hogyan fejlődik tovább ez a technológia.
Mivel ez a protokoll a Monero egyik legösszetettebb technológiája, az olvasónak alapismeretekre lesz szüksége ennek a blokkláncnak a tervezésével kapcsolatban, valamint az elliptikus görbe kriptográfiai ismereteire (a tudás felfrissítéséhez olvassa el az első fejezeteket korábbi cikk erről
RingCT protokoll
Az egyik lehetséges támadás a kriptonot valuták ellen a blokklánc-elemzés, amely az elküldött tranzakció mennyiségének és időpontjának ismeretén alapul. Ez lehetővé teszi
Érdemes megjegyezni, hogy az összegek elrejtésének ötlete nem új. A Bitcoin Core fejlesztője, Greg Maxwell az elsők között írta le ezt a sajátjában
A protokoll többek között segít megszabadulni a porkimenetek keverésével kapcsolatos problémáktól - kis mennyiségű (általában tranzakciókból származó változás formájában) származó kimenet, amely több problémát okozott, mint amennyit ér.
2017 januárjában a Monero hálózat hard forkjára került sor, amely lehetővé tette a bizalmas tranzakciók opcionális használatát. És már ugyanazon év szeptemberében, a 6-os hard fork verzióval az ilyen tranzakciók lettek az egyetlenek a hálózaton.
A RingCT egyszerre több mechanizmust használ: többrétegű összekapcsolt spontán névtelen csoportaláírásokat (többrétegű linkelhető spontán névtelen csoportaláírás, a továbbiakban: MLSAG), kötelezettségvállalási sémát (Pedersen Commitments) és tartománybizonyítékokat (ennek a kifejezésnek nincs megalapozott fordítása orosz nyelvre). .
A RingCT protokoll kétféle névtelen tranzakciót vezet be: egyszerű és teljes. A pénztárca generálja az elsőt, ha egy tranzakció több bemenetet használ, a másodikat pedig ellenkező helyzetben. Ezek különböznek a tranzakciós összegek és az MLSAG aláírással aláírt adatok érvényesítésében (erről lentebb lesz szó). Ráadásul a full típusú tranzakciók tetszőleges számú bemenettel generálhatók, nincs alapvető különbség. A könyvben
MLSAG aláírás
Emlékezzünk vissza, mik az aláírt tranzakciós bemenetek. Minden tranzakció költ és generál némi pénzt. A pénzeszközök generálása a tranzakciós kimenetek létrehozásával történik (közvetlen analógia a számlák), és a tranzakció által elköltött kimenet (végül is a való életben bankjegyeket költünk) lesz a bemenet (vigyázat, nagyon könnyű összezavarodni itt).
Egy bemenet több kimenetre hivatkozik, de csak egyet költ el, így „füstszűrőt” hoz létre, amely megnehezíti a fordítási előzmények elemzését. Ha egy tranzakciónak több bemenete van, akkor egy ilyen struktúra mátrixként ábrázolható, ahol a sorok a bemenetek, az oszlopok pedig a vegyes kimenetek. Annak bizonyítására a hálózat felé, hogy a tranzakció pontosan elkölti a kimeneteit (tudja a titkos kulcsukat), a bemeneteket gyűrűs aláírással írják alá. Egy ilyen aláírás garantálja, hogy az aláíró ismerte bármelyik oszlop összes elemének titkos kulcsát.
A bizalmas tranzakciók már nem használnak klasszikus tranzakciókat
Többrétegűnek nevezik őket, mert egyszerre több bemenetet írnak alá, amelyek mindegyike több másikkal keveredik, azaz egy mátrix van aláírva, nem pedig egy sor. Ahogy később látni fogjuk, ez segít megtakarítani az aláírás méretét.
Nézzük meg, hogyan jön létre a gyűrűs aláírás, egy olyan tranzakció példáján, amely 2 valós kimenetet költ el, és a blokkláncból m - 1 véletlenszerűt használ a keveréshez. Jelöljük azoknak a kimeneteknek a nyilvános kulcsait, amelyeket elköltünk
, és ennek megfelelően a kulcsképek: Így egy méretmátrixot kapunk 2 x m. Először is ki kell számítanunk az úgynevezett kihívásokat minden egyes kimenetpárhoz:
A számításokat a kimenetekkel kezdjük, amelyeket nyilvános kulcsaikkal töltünk el:és véletlen számokEnnek eredményeként a következő értékeket kapjuk:
, amelyet a kihívás kiszámításához használunk
a következő kimenetpár (hogy könnyebb legyen megérteni, hogy mit hova cserélünk, ezeket az értékeket különböző színekkel emeltük ki). Az összes következő érték egy körben van kiszámítva az első ábrán megadott képletekkel. Az utolsó dolog, amit ki kell számítani, a kihívás egy pár valós kimenetre.
Amint látjuk, a valódi kimeneteket tartalmazó oszlop kivételével minden oszlop véletlenszerűen generált számokat használ. For π- rovatban is szükségünk lesz rájuk. Váltsunk áts-ben:
Maga az aláírás az összes alábbi érték sorozata:
Ezek az adatok ezután egy tranzakcióba kerülnek.
Amint látjuk, az MLSAG egyetlen kihívást tartalmaz c0, amely lehetővé teszi az aláírás méretének megtakarítását (ami már sok helyet igényel). Továbbá bármely ellenőr, aki használja az adatokat, visszaállítja a c1,…, cm értékeket és ellenőrzi. Így a gyűrűnk bezárult, és az aláírást ellenőriztük.
A teljes típusú RingCT-tranzakcióknál egy további sor kerül a mátrixba vegyes kimenettel, de erről lentebb lesz szó.
Pedersen kötelezettségvállalások
A Monero kötelezettségvállalások az átutalások összegének elrejtésére és a legáltalánosabb lehetőség – a Pedersen kötelezettségvállalások – használatára szolgálnak. Egyébként egy érdekes tény - a fejlesztők eleinte az összegek elrejtését javasolták közönséges keveréssel, vagyis tetszőleges összegekhez való kimenet hozzáadását a bizonytalanság növelése érdekében, de aztán áttértek a kötelezettségvállalásokra (nem tény, hogy spóroltak a tranzakció mérete, amint azt alább látni fogjuk).
Az elkötelezettség általában így néz ki:
ahol C – magának az elkötelezettségnek a jelentése, a - rejtett mennyiség, H egy fix pont az elliptikus görbén (további generátor), és x — valamiféle tetszőleges maszk, véletlenszerűen generált rejtőfaktor. A maszkra azért van szükség, hogy egy harmadik fél ne tudja egyszerűen kitalálni az elkötelezettség értékét.
Új kimenet generálásakor a pénztárca lekötelezettséget számol rá, majd elköltéskor vagy a generálás során számított értéket veszi fel, vagy a tranzakció típusától függően újraszámolja.
RingCT egyszerű
Egyszerű RingCT-tranzakciók esetén annak biztosítása érdekében, hogy a tranzakció a bemenetek mennyiségével megegyező mennyiségű outputot hozzon létre (nem légből kapott pénzt), szükséges, hogy az első és a második kötelezettségvállalások összege az egyik ugyanaz, azaz:
A kötelezettségvállalási jutalékok egy kicsit másképp ítélik meg - maszk nélkül:
Ahol a — a jutalék összege, az nyilvánosan hozzáférhető.
Ez a megközelítés lehetővé teszi számunkra, hogy bebizonyítsuk az érintett félnek, hogy ugyanazokat az összegeket használjuk fel anélkül, hogy felfednénk azokat.
Hogy világosabb legyen a dolog, nézzünk egy példát. Tegyük fel, hogy egy tranzakció elkölt két 10 és 5 XMR kimenetet (azaz bemenetekké válnak), és három 12 XMR értékű kimenetet generál: 3, 4 és 5 XMR. Ugyanakkor 3 XMR jutalékot fizet. Így az elköltött pénzösszeg plusz a generált összeg és a jutalék 15 XMR-nek felel meg. Próbáljuk meg kiszámítani a kötelezettségvállalásokat, és nézzük meg az összegek különbségét (emlékezzünk a matematikára):
Itt azt látjuk, hogy az egyenlet konvergálásához szükségünk van arra, hogy a bemeneti és kimeneti maszk összege azonos legyen. Ehhez a pénztárca véletlenszerűen generál x1, y1, y2 és y3, és a maradék x2 így számol:
Ezekkel a maszkokkal az összeg nyilvánosságra hozatala nélkül bármely hitelesítőnek be tudjuk bizonyítani, hogy nem termelünk több pénzt, mint amennyit elköltünk. Eredeti, igaz?
RingCT tele
A teljes RingCT-tranzakciókban az átutalási összegek ellenőrzése kicsit bonyolultabb. Ezekben a tranzakciókban a pénztárca nem számítja újra a kötelezettségvállalásokat a bemenetekre, hanem a generáláskor számítottakat használja. Ebben az esetben azt kell feltételeznünk, hogy többé nem a nullával egyenlő összegek különbségét kapjuk, hanem:
Itt z — különbség a bemeneti és kimeneti maszkok között. Ha figyelembe vesszük zG nyilvános kulcsként (ami de facto az is), akkor z a privát kulcs. Így ismerjük a nyilvános és a hozzá tartozó privát kulcsokat. Ezekkel az adatokkal a kezünkben használhatjuk az MLSAG gyűrűaláírásban a kevert kimenetek nyilvános kulcsaival együtt:
Így egy érvényes gyűrűs aláírás biztosítja, hogy ismerjük az egyik oszlop összes privát kulcsát, és csak akkor tudhatjuk meg az utolsó sorban lévő privát kulcsot, ha a tranzakció nem termel több pénzt, mint amennyit elkölt. Egyébként itt a válasz arra a kérdésre, hogy „miért nem nullához vezet a kötelezettségvállalások összegének különbsége” – ha zG = 0, akkor az oszlopot valódi kimenetekkel bővítjük.
Honnan tudja a pénzeszközök címzettje, hogy mennyi pénzt küldtek neki? Itt minden egyszerű - a tranzakció feladója és a címzett kulcsokat cserél a Diffie-Hellman protokoll segítségével, a tranzakciós kulcsot és a címzett megtekintési kulcsát használja, és kiszámítja a megosztott titkot. A feladó a kimeneti mennyiségekről ezzel a megosztott kulccsal titkosítva adatokat ír a tranzakció speciális mezőibe.
Tartománybizonyítékok
Mi történik, ha negatív számot használ a kötelezettségvállalások összegeként? Ez további érmék generálásához vezethet! Ez az eredmény elfogadhatatlan, ezért garantálnunk kell, hogy az általunk felhasznált összegek ne legyenek negatívak (természetesen ezeknek az összegeknek a nyilvánosságra hozatala nélkül, különben annyi a munka, és minden hiába). Más szóval, bizonyítanunk kell, hogy az összeg az intervallumban van [0, 2n - 1].
Ehhez az egyes kimenetek összegét bináris számjegyekre osztják, és minden számjegyre külön számítják ki a kötelezettségvállalást. Jobb látni, hogyan történik ez egy példán.
Tegyük fel, hogy a mennyiségeink kicsik és 4 bitbe férnek bele (a gyakorlatban ez 64 bit), és 5 XMR értékű kimenetet hozunk létre. Minden kategóriára vállaljuk a kötelezettségvállalást és a teljes összegre a teljes kötelezettségvállalást:
Ezután minden elkötelezettség egy helyettesítővel keveredik (Ci-2iH) és párban van aláírva a Borromeo gyűrűs aláírással (egy másik gyűrűs aláírás), amelyet Greg Maxwell javasolt 2015-ben (erről bővebben olvashat
Összességében ezt tartományellenőrzésnek nevezik, és lehetővé teszi annak biztosítását, hogy a kötelezettségvállalások a tartományban lévő összegeket használják fel [0, 2n - 1].
Mi a következő lépés?
A jelenlegi megvalósításban a tartományellenőrzések sok helyet foglalnak el – kimenetenként 6176 bájtot. Ez nagyobb tranzakciókhoz és ezáltal magasabb díjakhoz vezet. A Monero-tranzakció méretének csökkentése érdekében a fejlesztők a Borromeo-aláírások helyett golyóállókat vezetnek be – egy bitenkénti kötelezettségvállalások nélküli hatótávolságú mechanizmust.
Tegye fel kérdéseit, javasoljon témákat új cikkekhez a kriptovaluta területén, valamint iratkozzon fel csoportunkra
Forrás: will.com