Tecnico › Quanto?

Commitment di Pedersen

Come sommare importi che nessuno può vedere e verificare che il bilancio torni

In breve

Un importo v è nascosto nel punto C = y·G + v·H, dove y è una "maschera" casuale. I commitment si possono sommare: la somma dei commitment è un commitment alla somma degli importi. La rete verifica che Σ input − Σ output − fee·H sia un commitment a zero senza conoscere alcun importo.

Cos'è un commitment

Un commitment (impegno) è una "busta sigillata con dentro un numero". Ha due proprietà:

  • Occultamento (hiding): dalla busta non si può ricavare il numero.
  • Vincolo (binding): non si può aprire la busta rivelando un numero diverso.

Un commitment di Pedersen su una curva ellittica:

C = y·G + v·H v: importo in unità atomiche (1 XMR = 10¹² unità), y: fattore di accecamento casuale, G e H: due punti indipendenti

Senza la maschera y avremmo C = v·H, e l'importo si potrebbe trovare facilmente per forza bruta (gli importi possibili non sono poi così tanti). La maschera rende C indistinguibile da un punto casuale.

Perché conta il secondo generatore H

H si ottiene facendo l'hash di G verso un punto, quindi nessuno conosce un k tale che H = k·G. Se qualcuno conoscesse k, potrebbe "riaprire" un commitment: y·G + v·H = (y + k(v − v'))·G + v'·H, e stampare denaro dal nulla. Il vincolo si basa proprio sul fatto che k non è noto.

Omomorfismo: sommare alla cieca

C₁ + C₂ = (y₁ + y₂)·G + (v₁ + v₂)·H

La somma di due buste è una busta che contiene la somma. Così la rete può verificare la conservazione:

C_in (5 XMR)importo nascosto = C_out1 (3 XMR)al destinatario + C_out2 (1.99)resto + 0.01·Hcommiss. C_in − C_out1 − C_out2 − fee·H = (y_in − y₁ − y₂)·G + 0·H → un commitment a zero: un punto della forma z·G

Resta da dimostrare che la differenza ha davvero la forma z·G (e non z·G + qualcosa·H). Basta firmare usandola come chiave pubblica: la firma funziona solo se conosci z e non c'è alcuna componente H. La commissione è pubblica, quindi il suo commitment è semplicemente fee·H, senza maschera.

Pseudo-output: come funziona con i ring

C'è un problema: l'input è un ring di 16 output, e non possiamo dire quale commitment sia quello reale. La soluzione di RingCT è il commitment pseudo-output C̃:

  1. per ogni input il mittente crea un nuovo commitment C̃ = y'·G + v·H con lo stesso importo ma una nuova maschera;
  2. le maschere vengono scelte in modo che Σ C̃ = Σ C_out + fee·H esattamente (il bilancio si verifica usando gli pseudo-output);
  3. in CLSAG, per ogni membro del ring, si dimostra che C_i − C̃ è un commitment a zero per il membro reale: C_π − C̃ = (y − y')·G.

Così la ring signature dimostra contemporaneamente il possesso dell'output e che l'importo dello pseudo-output è uguale a quello dell'input reale.

Come il destinatario scopre importo e maschera

Mittente e destinatario condividono il segreto Hs(8rA ‖ i) (vedi indirizzi monouso). Da esso ricavano:

y = Hs( "commitment_mask" ‖ Hs(8rA ‖ i) )
amount_enc = v ⊕ Keccak( "amount" ‖ Hs(8rA ‖ i) )[0..8]

L'importo cifrato (8 byte) si trova nella transazione. Il destinatario decifra v, calcola y e verifica che y·G + v·H coincida con C sulla blockchain.

Cosa impedisce un importo negativo?

Tutta l'aritmetica è modulo l. "−1" è l − 1, un numero enorme. Si potrebbe creare un output da 1000 XMR e un output da "−999 XMR": il bilancio terrebbe e 999 XMR spunterebbero dal nulla. I commitment non lo vedono. Per questo ogni output è accompagnato da una range proof.