Vi fortsætter vores cyklus om opbygningen af Monero-blockchain og dagens artikel vil fokusere på RingCT-protokol (Ring Confidential Transactions), der introducerer private transaktioner og nye ringtegn. Desværre er der lidt information tilgængelig online om, hvordan det fungerer, og vi har forsøgt at udfylde dette hul.

Vi vil tale om, hvordan netværket med denne protokol skjuler beløbene for overførsler, hvorfor man har opgivet de klassiske ringtegn for cryptonote, og hvordan denne teknologi vil udvikle sig fremadrettet.
Da denne protokol er en af de mest komplekse teknologier i Monero, vil læseren have brug for grundlæggende viden om opbygningen af denne blockchain og overfladisk kendskab til kryptografi med elliptiske kurver (for at friske op på dette, kan man læse de første kapitler af vores tidligere artikel om ).
RingCT-protokollen
En af de mulige angreb på cryptonote-valutaer er at analysere blockchainen baseret på kendskab til beløbet og tidspunket for den afsendte transaktion. Dette gør det muligt at indsnævre området for de udgange, der er af interesse for angriberen. For at beskytte mod sådan analyse er der blevet implementeret en protokol for anonyme transaktioner i Monero, som fuldstændigt skjuler beløbene for overførsler i netværket.
Det er værd at bemærke, at idéen om at skjule beløb ikke er ny. En af de første der beskrev den var Bitcoin Core-udvikleren Greg Maxwell i sin . Den nuværende implementering af RingCT fungerer som en modifikation af denne med mulighed for at bruge ringtegn (hvordan skulle man ellers?), og den fik sit navn — Ring Confidential Transactions.
Blandt andet hjælper protokolken med at eliminere problemer med at blande ‘dust’ -udgange — udgange med små beløb (normalt resultatet af bytte fra transaktioner), som har skabt flere problemer end de costede i værd.
I januar 2017 fandt der en hard fork sted i Monero-netværket, som muliggør frivillig brug af private transaktioner. Allerede i september samme år blev sådanne transaktioner, med hard forken af version 6, de eneste tilladte i netværket.
RingCT bruger flere mekanismer: multilayered linkable spontaneous anonymous group signatures (Multilayered Linkable Spontaneous Anonymous Group Signature, herefter — MLSAG), forpligtelsesskemaer (Pedersen Commitments) og range proofs (der findes ikke et etableret oversættelse af denne term til dansk).
RingCT-protokollen introducerer to typer anonyme transaktioner: simple og full. Den første type genereres, når transaktionen bruger mere end én indgang, mens den anden type gælder i den modsatte situation. De adskiller sig i valideringen af transaktionsbeløb og de data, der underskrives med MLSAG-underskrift (mere om dette senere). Det er desuden muligt at generere full-transaktioner med et vilkårligt antal indgange, uden grundlæggende forskel. I bogen nævnes det, at beslutningen om at begrænse full-transaktioner til én indgang blev taget hastigt og kan ændres i fremtiden.
MLSAG-underskrift
Lad os huske, hvad de underskrevne indgange i en transaktion repræsenterer. Hver transaktion bruger nogle midler og genererer. Genereringen af midler sker ved at skabe udgange for transaktionen (direkte analogi — sedler), og den udgang, som transaktionen bruger (for i det virkelige liv bruger vi netop pengesedler), bliver til indgang (pas på, her kan det være meget let at blive forvirret).
Indgangen henviser til flere udgange, men bruger kun én, hvilket skaber en 'røgslør' for at komplicere analysen af overførselshistorikken. Hvis transaktionen har mere end én indgang, kan denne struktur repræsenteres i en matrix, hvor rækkerne er indgange, og kolonnerne er de involverede udgange. For at bevise for netværket, at transaktionen faktisk bruger sine egne udgange (kender deres hemmelige nøgler), underskriver indgangene med en ring-underskrift. Denne underskrift giver garanti for, at den, der underskriver, kendte de hemmelige nøgler for alle elementerne i en hvilken som helst af kolonnerne.
Fortrolige transaktioner bruger ikke længere de klassiske ring-underskrifter; MLSAG er kommet i stedet — en tilpasset version af de samme enlags ring-underskrifter, der er designet til flere indgange. .
De kaldes mange-lagede, fordi de underskriver flere indgange på én gang, hver af dem blandes med flere andre, dvs. en matrix underskrives, ikke kun én række. Som vi senere vil se, hjælper dette med at spare på størrelsen af underskriften.
Lad os se på, hvordan en ring-underskrift dannes, ved at tage et eksempel på en transaktion, der bruger 2 faktiske udgange og blander m — 1 tilfældige fra blockchainen. Vi betegner de offentlige nøgler for de udgange, vi bruger, som
, og key images for dem henholdsvis:
Dermed får vi en matrix i størrelsen 2 x m. Først skal vi beregne de såkaldte challenges for hver udgangspair:

Vi starter beregningerne med de udgange, som vi bruger deres offentlige nøgler:
og tilfældige tal
Resultatet bliver værdierne:
, som vi bruger til at beregne challenge
for den næste udgangspair (for at gøre det lettere at forstå, hvad vi indsætter, har vi fremhævet disse værdier med forskellige farver). Alle følgende værdier beregnes i en cyklus ifølge formlerne præsenteret i det første billede. Den sidste challenge beregnes for parret med de faktiske udgange.
Som vi kan se, anvendes tilfældigt genererede tal i alle kolonner, bortset fra den der indeholder de faktiske udgange.
. For π-te kolonne vil også være nødvendig. Lad os omdanne
til s:
Selve signaturen udgør et tuple af alle disse værdier:

Derefter registreres disse data i transaktionen.
Som vi kan se, indeholder MLSAG kun én challenge c0, hvilket sparer pladsen i signaturen (som allerede kræver meget plads). Enhver verificerer, der bruger dataene
, genskaber værdierne c1,…, cm og kontrollerer, at
. Dermed er vores ring blevet lukket, og signaturen har bestået kontrollen.
For RingCT-transaktioner af typen full tilføjes endnu en række til matrixen med de blandede udgange, men det vil vi forklare senere.
Pedersen Commitments
(den engelske term — commitments) bruges, så én part kan bevise, at den kender en hemmelighed (et tal) uden at afsløre den. For eksempel, du kaster et bestemt tal med terningerne, beregner commitment og giver det til den verificerende part. På dette tidspunkt, ved afsløringen af det hemmelige tal, beregner den verificerende selv commitment, dermed sikrer sig, at du ikke har snydt.
I Monero bruges commitments til at skjule overførselernes beløb og anvender den mest udbredte variant — Pedersen commitments. Forresten, en interessant fakta — først foreslog udviklerne at skjule beløbene gennem almindelig blanding, dvs. tilsætte udgange til vilkårlige beløb for at skabe usikkerhed, men skiftede derefter til commitments (det er ikke sikkert, at de sparede plads i transaktionen, som vi vil se senere).
Generelt ser en commitment således ud:
Where C — værdien af selve commitmenten, en — det skjulte beløb, i giver ikke andre deltagere mulighed for at genskabe den private komponent — et fast punkt på en elliptisk kurve (ekstra generator), og x — en vilkårlig maske, en skjult faktor, der genereres tilfældigt. Masken er nødvendig her for at sikre, at tredjeparten ikke kan finde værdien af commitment ved simpel prøvning.
Når der genereres et nyt output, beregner tegnebogen commitment for det, og ved brug tager den enten den beregnede værdi fra genereringen eller beregner den igen — afhængigt af typen af transaktion.
RingCT simple
I tilfælde af simple RingCT-transaktioner, for at sikre at transaktionen har skabt outputs, der er lig med input summen (ikke skabt penge ud af den blå luft), er det nødvendigt, at summen af commitments for de første og anden er den samme, det vil sige:

Commitment for gebyrer beregnes lidt anderledes — uden maske:
, hvor en — summen af gebyret, det er offentligt tilgængeligt.
Denne tilgang gør det muligt at bevise for den kontrollerende part, at vi bruger de samme beløb uden at afsløre dem.
For at gøre det mere forståeligt, lad os se på et eksempel. Antag, at transaktionen bruger to outputs (dvs. de bliver inputs) på 10 og 5 XMR og genererer tre outputs til en sum af 12 XMR: 3, 4 og 5 XMR. I dette tilfælde betaler den et gebyr på 3 XMR. Dermed er summen af de anvendte penge plus summen af genererede beløb og gebyret lig med 15 XMR. Lad os prøve at beregne commitments og se på forskellen i deres summer (lad os huske matematikken):

Her ser vi, at for at ligge lige — skal summen af maskerne for inputs og outputs være den samme. For dette genererer tegnebogen tilfældigt x1, y1, y2 og y3, og den resterende x2 beregnes således:
![]()
Ved at bruge disse masker kan vi bevise for enhver kontrollør, at vi ikke genererer mere midler, end vi bruger, uden at afsløre summen. Originalt, ikke?
RingCT full
I full RingCT-transaktioner er kontrollen af beløbene lidt mere kompliceret. I disse transaktioner beregner tegnebogen ikke commitments for inputs, men bruger de beregnede ved deres generering. I denne sammenhæng skal man antage, at forskellen i summen ikke længere vil være lig med nul, men i stedet:

Her z — forskellen mellem maskerne for inputs og outputs. Hvis vi betragter zG som den offentlige nøgle (hvilket det faktisk er), så z — dette er den private nøgle. Dermed kender vi den offentlige nøgle samt den tilsvarende private nøgle. Med disse oplysninger kan vi bruge dem i MLSAG ringunderskriften sammen med de offentlige nøgler fra de blandede udgange:

Således vil en gyldig ringunderskrift sikre, at vi kender alle private nøgler til en af kolonnerne, og den private nøgle i den sidste række kan vi kun kende, hvis transaktionen ikke genererer mere i midler, end den bruger. For øvrigt er her også svaret på spørgsmålet „hvorfor differensen af sums commitments ikke fører til nul” — hvis zG = 0, så vil vi afsløre kolonnen med de reelle udgange.
Hvordan vil modtageren af midlerne vide, hvor mange penge de har fået? Her er det simpelt — afsenderen af transaktionen og modtageren udveksler nøgler via Diffie-Hellman-protokollen, idet de bruger transaktionsnøglen og modtagers view-nøgle og beregner en fælles hemmelighed. Afsenderen indtaster oplysninger om udgangssummerne i specifikke felter i transaktionen, krypteret med den fælles nøgle.
Range proofs
Hvad sker der, hvis vi bruger et negativt tal som sum i commitments? Det kan føre til generation af ekstra mønter! En sådan situation er uacceptabel, så der er brug for en garanti for, at de beløb, vi bruger, ikke er negative (uden at afsløre disse beløb, naturligvis, ellers ville så meget arbejde være spildt). Med andre ord skal vi bevise, at summen ligger i intervallet [0, 2n — 1].
For at gøre dette opdeles summen af hver udgang i binære cifre, og der beregnes et commitment for hvert ciffer individuelt. Hvordan dette foregår, er bedre at se på et eksempel.
Lad os antage, at beløbene er små og kan placeres i 4 bits (i praksis er det 64 bits), og at vi laver en udgang på 5 XMR. Vi beregner commitments for hvert ciffer og det samlede commitment for hele summen:
Derefter blandes hvert commitment med en surrogate (Ci-2iH) og parvis underskrives med en Borromean ringunderskrift (endnu en ringunderskrift), som blev foreslået af Greg Maxwell i 2015 (du kan læse mere om det ):
Alt dette kaldes range proof og sikrer, at der bruges beløb i commitments, der ligger inden for intervallet [0, 2n — 1].
Hvad nu?
I den nuværende implementering tager range proofs meget plads — 6176 byte pr. udgang. Dette fører til store transaktioner og dermed højere gebyrer. For at reducere størrelsen på transaktionen introducerer Monero-udviklerne i stedet for Borromeo-signaturer bulletproofs — et mekanisme for range proofs uden bit-for-bit commitments. , kan de reducere størrelsen på range proof med op til 94%. For at nævne det, gennemgik teknologien i midten af juli af Kudelski Security, som ikke fandt nogen væsentlige mangler hverken i selve teknologien eller i dens implementering. Teknologien anvendes allerede i testnetværket, og med den nye hardfork kan den sandsynligvis også flytte til hovednetværket.
Stil dine spørgsmål, foreslå emner til nye artikler om teknologi inden for kryptovalutaer, og tilmeld dig vores gruppe på , så du kan holde dig opdateret om vores arrangementer og publikationer.
Kilde: habr.com
