Estrazione

Transazioni riservate - Gregory Maxwell

Principal Investigator: Greg Maxwell

Una delle più potenti nuove funzionalità esplorate in [Elements] ( // blockstream. Com / developers /) è Transazioni riservate, uno strumento crittografico per migliorare la privacy e la sicurezza di Bitcoin. Questa funzione mantiene gli importi trasferiti visibili solo ai partecipanti alla transazione (e a quelli designati).

La sicurezza del registro Bitcoin è resa possibile dalla verifica universale: ogni partecipante individua autonomamente e verifica che ogni transazione sia valida, senza affidarsi a terzi. Uno sfortunato effetto collaterale è che tutti i dati delle transazioni devono essere chiaramente visibili in modo da poter essere verificati, il che è in contrasto con la normale aspettativa della privacy per gli strumenti monetari tradizionali.

La privacy finanziaria insufficiente può avere gravi implicazioni sulla sicurezza e sulla privacy per transazioni commerciali e personali. Senza una protezione adeguata, ladri e truffatori possono concentrare i propri sforzi su obiettivi noti di alto valore, i concorrenti possono apprendere dettagli aziendali e le posizioni negoziali possono essere compromesse. Dal momento che la pubblicazione richiede spesso denaro, la mancanza di privacy può rilassare la libertà di parola. Una privacy insufficiente può anche comportare una perdita di fungibilità - dove alcune monete sono considerate più accettabili di altre - il che minerebbe ulteriormente l'utilità di Bitcoin come denaro.

Bitcoin affronta parzialmente il problema della privacy usando indirizzi pseudonimi. Se qualcuno non sa quali utenti possiedono quali indirizzi, l'impatto sulla privacy è ridotto. Ma ogni volta che scambi con qualcuno impari almeno uno dei loro indirizzi. Da lì, è possibile rintracciare altri indirizzi connessi e stimare i valori delle loro transazioni e partecipazioni. Ad esempio, supponiamo che il tuo datore di lavoro ti paghi con Bitcoin e in seguito spenderai quelle monete sul tuo affitto e generi alimentari. Il padrone di casa e il supermercato apprenderanno entrambi le tue entrate e potrebbero farti pagare prezzi più alti a mano a mano che le tue entrate cambiano o ti indirizzano al furto.

Esistono tecniche implementate esistenti che migliorano ulteriormente la privacy in Bitcoin (come CoinJoin, che unisce la cronologia delle transazioni degli utenti effettuando pagamenti congiunti), ma l'utilità di queste tecniche è ridotta dal fatto che è possibile tenere traccia degli importi.

Sono state proposte tecniche crittografiche per migliorare la privacy in sistemi simili a Bitcoin, ma finora tutte hanno comportato l'interruzione della "potatura" (sezione 7 di Bitcoin .pdf) e hanno portato i partecipanti alla ricerca di un database in perpetua crescita per verificare nuove transazioni, perché questi sistemi impediscono l'apprendimento di quali monete sono state spese. La maggior parte dei sistemi di privacy crittografici proposti ha anche prestazioni scadenti, costi generali elevati e / o richiede nuove e molto forti (e meno ben comprese) asserzioni crittografiche.

Le transazioni riservate migliorano la situazione rendendo privati ​​gli importi della transazione, preservando la capacità della rete pubblica di verificare che le voci della contabilità generale si sommano ancora.Lo fa senza aggiungere nuove assunzioni di crittografia di base al sistema Bitcoin e con un livello gestibile di overhead.

CT è possibile grazie alla tecnica crittografica di impegni omomorfi addizionalmente. Come effetto collaterale del suo design, CT consente anche lo scambio aggiuntivo di dati "memo" privati ​​(come numeri di fatture o indirizzi di rimborso) senza alcun ulteriore aumento delle dimensioni della transazione, recuperando la maggior parte del sovraccarico delle prove crittografiche CT.

La tecnologia alla base delle Transazioni riservate

Un primer tecnico di alto livello

------------------------------- --------------------------------------------

Questo lavoro era originariamente proposto da Adam Back su Bitcointalk nel suo thread del 2013 "bitcoin con valore omomorfico" [ // bitcointalk. org / index. php? topic = 305.791. 0]. Per costruire CT ho dovuto implementare diversi nuovi crittosistemi che lavorano di concerto, e ho inventato una generalizzazione delle firme degli anelli e diverse nuove ottimizzazioni per rendere il risultato ragionevolmente efficiente.

Lo strumento di base su cui si basa CT è un impegno di Pedersen.

Uno schema di impegno ti consente di mantenere segreto un dato di dati, ma di impegnarti in modo che tu non possa cambiarlo in un secondo momento. Un semplice schema di commit può essere costruito usando un hash crittografico:

commitment = SHA256 (blinding_factor || data)

Se comunichi a qualcuno solo l'impegno, allora non possono determinare quali dati stai impegnando (date alcune ipotesi sul proprietà dell'hash), ma in seguito è possibile rivelare sia i dati che il fattore di accecamento e possono eseguire l'hash e verificare che i dati che si sono impegnati alle corrispondenze. Il fattore accecante è presente perché senza uno, qualcuno potrebbe provare a indovinare i dati; se i tuoi dati sono piccoli e semplici, potrebbe essere facile indovinarlo e confrontare l'ipotesi con l'impegno.

Un impegno di Pedersen funziona come sopra ma con una proprietà aggiuntiva: gli impegni possono essere aggiunti e la somma di un insieme di impegni è uguale all'impegno per la somma dei dati (con un tasto accecante impostato come somma dei tasti accecanti):

C (BF1, dati1) + C (BF2, dati2) == C (BF1 + BF2, dati1 + dati2)

C (BF1, dati1) - C (BF1, dati1) == 0

In altre parole, l'impegno conserva l'aggiunta e si applica la proprietà commutativa.

Se data_n = {1, 1, 2} e BF_n = {5, 10, 15} quindi:

C (BF1, dati1) + C (BF2, dati2) - C (BF3, dati3) == 0

e così via.

I nostri specifici impegni Pedersen sono costruiti utilizzando punti di curva ellittica. [Il lettore non ha bisogno di capire la crittografia della curva ellittica, oltre ad accettare i comportamenti della scatola nera che descrivo qui.]

Normalmente un pubkey ECC viene creato moltiplicando un generatore per il gruppo (G) con la chiave segreta (x):

Pub = xG

Il risultato viene in genere serializzato come un array di 33 byte.

Le chiavi pubbliche ECC obbediscono alla proprietà omomorfica addizionata menzionata in precedenza:

Pub1 + Pub2 = (x1 + x2 (mod n)) G.

(Questo fatto è utilizzato dallo schema BIP32 HD per consentire a terzi di generare nuovi indirizzi Bitcoin per le persone.)

L'impegno di Pedersen viene creato selezionando un generatore aggiuntivo per il gruppo (che chiameremo H) in modo tale che nessuno conosca il registro discreto per H rispetto a G (o viceversa), il che significa che nessuno conosce un x tale che xG = H. Possiamo realizzare questo utilizzando l'hash crittografico di G per selezionare H:

H = to_point (SHA256 (ENCODE (G)))

Dove to_point () prende l'input come x valore di un nuovo punto, controlla che sia sulla curva e risolva il valore y.

Dati i nostri due generatori, possiamo costruire uno schema di impegno come questo:

impegno = xG + aH

Qui x è il nostro segreto fattore di accecamento, e a è l'importo a cui ci stiamo impegnando. È possibile verificare semplicemente utilizzando la proprietà commutativa di aggiunta che tutte le relazioni fornite per uno schema di impegno omomorfico addizionale sono valide.

Gli impegni di Pedersen sono informazioni teoricamente private: per ogni impegno che si vede, esiste un fattore accecante che farebbe corrispondere qualsiasi importo all'impegno. Persino un attaccante con potenza di calcolo infinita non è in grado di stabilire a quale ammontare ti impegni, se il tuo fattore accecante fosse davvero casuale. Sono computazionalmente sicuri contro l'impegno falso, in quanto non si può effettivamente calcolare quella mappatura arbitraria; se puoi, significa che puoi trovare il log discreto dei generatori l'uno rispetto all'altro, il che significa che la sicurezza del gruppo è compromessa.

Con questo strumento in mano possiamo andare e sostituire i normali numeri interi da 8 byte nelle transazioni Bitcoin con impegni di Pedersen di 33 byte.

Se l'autore di una transazione si occupa di raccogliere i loro fattori accecanti in modo che si sommano correttamente, la rete può ancora verificare la transazione verificando che i suoi impegni siano pari a zero:

(In1 + In2 + In3 + plaintext_input_amount * H ...) -

(Out1 + Out2 + Out3 + ... fees * H) == 0.

Ciò richiede esplicitare le commissioni in una transazione, ma generalmente è auspicabile.

L'impegno e il suo controllo sono abbastanza semplici. Sfortunatamente, senza ulteriori misure questo schema è insicuro.

Il problema è che il gruppo è ciclico e l'aggiunta è mod P (un numero primo a 256 bit che definisce l'ordine del gruppo). Di conseguenza, l'aggiunta di valori di grandi dimensioni può "overflow" e comportarsi come importi negativi. Ciò significa che un comportamento da somme a zero è ancora valido quando alcune uscite sono negative, consentendo effettivamente la creazione di 5 monete dal nulla:

(1 + 1) - (-5 + 7) == 0

Questo sarebbe interpretato come "qualcuno spende due bitcoin, ottiene un bitcoin '-5' fuori che scartano e un output 7 bitcoin".

Per evitare ciò, quando vi sono più uscite, è necessario dimostrare che ogni uscita impegnata si trova in un intervallo che non può traboccare (per esempio [0, 2 ^ 64)).

Potremmo semplicemente rivelare le quantità e i fattori accecanti in modo che la rete possa controllare, ma ciò perderebbe tutta la privacy. Quindi, invece, dobbiamo dimostrare che un importo impegnato rientra nell'intervallo ma non ne rivela nient'altro: abbiamo bisogno di un criptosistema aggiuntivo per dimostrare la portata dell'impegno di Pedersen.Usiamo uno schema simile alla decomposizione binaria di Schoenmakers ma con molte ottimizzazioni (incluso non usare il binario).

Per costruire questo iniziamo con una firma EC di base. Se una firma è costruita in modo che il 'messaggio' sia l'hash del pubkey, la firma dimostra che il firmatario conosceva la chiave privata, che è il log discreto del pubkey rispetto ad un generatore.

Per un 'pubkey' come P = xG + aH, nessuno conosce il log discreto di P rispetto a G a causa dell'aggiunta di H, perché nessuno conosce una x per xG = H ----_ unless_ a è 0. Se a è zero, allora P = xG e il registro discreto è solo x; qualcuno potrebbe firmare per quel pubkey.

Un impegno di pedersen può essere dimostrato essere un impegno verso lo zero firmando semplicemente un hash dell'impegno con l'impegno come chiave pubblica. È necessario utilizzare la chiave pubblica nella firma per evitare di impostare la firma su valori arbitrari e risolvere l'impegno. La chiave privata utilizzata per la firma è solo il fattore accecante.

Andando oltre, diciamo che voglio dimostrare che C è un impegno per 1 senza dirti il ​​fattore accecante. Tutto quello che fai è calcolare

C '= C - 1H

e chiedermi di fornire una firma (rispetto a G) con il pubkey C'. Se posso farlo, il C deve essere un impegno per 1 (altrimenti ho rotto la sicurezza del registro discreto CE).

Per evitare di dare via la quantità necessaria abbiamo ancora un altro costrutto crittografico: una firma ad anello. Una firma ad anello è uno schema di firma in cui sono presenti due (o più) pubkeys e la firma dimostra che il firmatario conosce il registro discreto di almeno uno dei pubkey.

Quindi con questo possiamo costruire uno schema in cui provo che C è o 0 o 1 - la chiamiamo "prova OR".

Per prima cosa, ti do C, e tu computi C ':

C' = C - 1H

Poi fornisco una firma ad anello su {C, C '}.

Se C era un impegno per 1 allora non conosco il suo log discreto, ma C 'diventa un impegno per 0 e conosco il suo log discreto (solo il fattore accecante). Se C era un impegno per 0 conosco il suo log discreto, e non lo faccio per C '. Se era un impegno per qualsiasi altro importo, nessuno dei risultati sarà pari a zero e non potrò firmare.

Funziona con qualsiasi coppia di numeri, semplicemente preelaborando adeguatamente le quantità che vengono messe nel ring ... o anche per più di due numeri.

Dire che voglio dimostrarti che C è nel raggio [0, 32). Ora che abbiamo una prova OR, immagino di inviarti una serie di impegni e prove OR per ognuno di essi:

C1 è 0 o 1 C2 è 0 o 2 C3 è 0 o 4 C4 è 0 o 8 C5 è 0 o 16.

Se seleziono correttamente i fattori accecanti per C1 ... 5, posso sistemarlo in modo che C1 + C2 + C3 + C4 + C5 == C. In effetti ho accumulato il numero in binario e un 5 il numero di bit può essere solo nell'intervallo [0, 32).

Sono necessarie numerose ottimizzazioni per rendere questo più efficiente:

Prima , propongo una nuova formulazione della firma dell'anello, una [firma dell'anello Borromean] ( // github. Com / Blockstream / borromean_paper / raw / master / borromean_draft_0.01_8c3f9e7. pdf), che è particolarmente efficiente: richiede solo 32 byte per pubkey, oltre a 32 byte che possono essere condivisi da più anelli separati. Questo ha il doppio dell'efficienza asintotica delle costruzioni proposte in precedenza per questa applicazione.

Invece di esprimere direttamente l'importo, gli importi CT vengono espressi utilizzando un punto decimale in virgola mobile in cui le cifre vengono moltiplicate per un esponente di base 10. Ciò significa che puoi provare grandi quantità con piccole prove, purché abbiano poche cifre significative nella base 10: e. g. , 11. 2345 e. 0112345 può avere la stessa dimostrazione di dimensioni, anche se un numero è mille volte più grande.

Viene anche inviato un "importo minimo" non privato, che consente a una prova più piccola di coprire un intervallo più ampio se l'utente non mente perde alcune informazioni sull'importo minimo (che potrebbe già essere pubblico per motivi esterni) ; ciò consente anche che le cifre meno significative siano diverse da zero quando viene utilizzato un esponente. Gli importi minimi sono supportati sottraendo prima il minimo, quindi dimostrando che il risultato è non negativo.

La mantissa del punto mobile viene codificata utilizzando gli anelli di dimensione 4 (base 4) piuttosto che binari, poiché questo riduce al minimo il numero di impegni inviati senza utilizzare più dati di firma rispetto alla base 2.

La cifra della mantissa finale l'impegno può essere saltato, arretrato costruendolo dal valore provato e le altre cifre, ecc.

Infine , con l'uso attento della firma casuale nel prover, è possibile per il ricevitore delle monete - chi condivide un segreto con il mittente, grazie all'accordo chiave ECDH con il ricevitore pubkey - per "riavvolgere" la prova e utilizzarla per estrarre un messaggio inviato dal mittente che è l'80% della dimensione della prova. Usiamo questo per segnalare il valore e il fattore accecante al ricevitore, ma potrebbe anche essere usato per trasportare cose come numeri di riferimento o indirizzi di rimborso.

Il risultato è che una prova per un valore a 32 bit è 2564 byte e contemporaneamente può trasmettere 2048 byte di messaggio. Una prova a 32 bit può coprire un intervallo di 42. 94967296 BTC con precisione 1e-8 o 429. 4967296 BTC con precisione 1e-7 e così via. La mia implementazione è in grado di verificare oltre 1300 prove di intervallo a 32 bit al secondo su un i7-4770R, e ci sono ancora molte ottimizzazioni delle prestazioni possibili.

L'implementazione supporta prove di qualsiasi dimensione o esponente di mantissa, con i parametri controllati dal mittente. Le prestazioni e le dimensioni sono lineari nel numero di bit di mantissa e sono supportati numeri dispari di bit (passando a radix-2 per l'ultima cifra).

In Elements, le prove di intervallo sono richieste solo nei casi in cui sono presenti più valori di valore confidenziali (comprese le commissioni). Le transazioni che uniscono più importi confidenziali in un singolo output non richiedono prove di intervallo poiché il fatto che tutti gli input fossero nell'intervallo è sufficiente.

Condividendo la chiave di scansione utilizzata per stabilire il segreto condiviso utilizzato dalle prove di intervallo riavvolgibili, questo approccio è completamente compatibile con l'osservazione dei portafogli; gli utenti possono condividere queste chiavi con i revisori per consentire loro di visualizzare gli importi delle transazioni.

Il lavoro futuro può usare il fatto che le dimostrazioni possono supportare un valore minimo per consentire anche di saltare le prove di intervallo quando c'è un singolo output confidenziale anche quando vengono pagate le tasse, o consentire ai nodi di saltare o ritardare la verifica della maggior parte degli dimostrativi di intervallo usando prove di frode.

Il sistema presentato qui non dipende da nuove assunzioni crittografiche fondamentali, ma solo dalla durezza del problema del registro discreto nel gruppo secp256k1 e da un assunto oracolare casuale, proprio come le normali firme in Bitcoin.

Sebbene le dimensioni delle prove di intervallo non siano banali, sono comunque un ordine di grandezza più piccolo e più veloce da verificare rispetto ad alcune alternative (come Zerocoin) e la maggior parte del loro spazio può essere recuperato per comunicare dati aggiuntivi tra gli utenti, una funzione che è spesso richiesta ma difficile da giustificare in una rete pubblica di trasmissione. Simile alle firme, le prove di intervallo possono essere posizionate su rami di alberi separati in blocchi per consentire ai clienti a cui non interessa (ad esempio quelli storici) di ignorarli.

Ancora più importante, questo schema è compatibile con l'eliminazione e non fa in modo che lo stato di verifica per Bitcoin cresca per sempre. È anche compatibile con CoinJoin e CoinSwap, consentendo la privacy del grafico delle transazioni e contemporaneamente fissando la limitazione più severa di questi approcci alla privacy (la quantità di transazioni compromette la loro privacy).

A differenza di altre proposte, questo sistema non è solo speculazione o pura crittografia senza integrazione con il sistema Bitcoin.

Il crittosistema di base è implementato in un fork di libsecp256k1, disponibile all'indirizzo: // github. it / ElementsProject / secp256k1-zkp

Le transazioni riservate sono abilitate in Elements Alpha e utilizzate di default da tutte le transazioni ordinarie.