Bitcoin Secret Sharing

Introduzione

Hai appena creato il tuo wallet Bitcoin e hai annotato le 12 o 24 parole della seed phrase su un foglio. A questo punto temi di perderlo o che si rovini, quindi pensi di farne una copia. Ma così ti ritrovi a dover nascondere due fogli in posti sicuri, aumentando la probabilità che qualcuno possa trovarli e ottenere la seed phrase, con la conseguenza di poter accedere ai tuoi fondi.

Allora provi a “spezzare” la seed phrase, distribuendo le parole su più fogli in modo che nessuno contenga l’elenco completo. Questa soluzione, però, è più rischiosa di quanto sembri: in alcuni casi, un malintenzionato che ottiene anche solo una parte delle parole potrebbe comunque ricostruire l’intera seed phrase.

Esiste però un metodo più sicuro, chiamato Shamir Secret Sharing, basato sulla matematica, che permette di dividere la seed phrase in più parti senza comprometterne la sicurezza.

Anatomia di un wallet

Per capire davvero quali pratiche possono mettere a rischio la sicurezza dei propri bitcoin, conviene partire da come funziona un wallet Bitcoin.

Un wallet è, in sostanza, un insieme di coppie di chiavi pubbliche e private. La chiave privata deve rimanere segreta e serve a firmare le transazioni. La chiave pubblica, invece, è derivata matematicamente dalla privata e permette di verificare pubblicamente la validità della firma digitale.

Per rendere più semplice la gestione, il backup e la portabilità, gli standard BIP32 e BIP44 (Bitcoin Improvement Proposal) definiscono un metodo per derivare in modo deterministico tutte le chiavi private di un wallet a partire da una stringa di entropia di 128 o 256 bit.

Per facilitare la trascrizione di questa entropia, lo standard BIP39 la rappresenta tramite una lista di parole inglesi.

In pratica, annotare su carta le 12 o 24 parole della seed phrase consente al wallet di rigenerare in modo deterministico tutte le chiavi private.

L’entropia di 256 bit consiste in una sequenza di 256 valori binari (0 o 1) generati casualmente, che corrispondono a un numero binario enorme: per un attaccante senza informazioni a priori, provare a ricavare l’entropia di un wallet corrisponderebbe a indovinare un numero tra 00 e 22561.157910772^{256} \approx 1.1579 \cdot 10^{77} (un numero più grande degli atomi presenti nell’universo visibile!).

Per un attaccante, possedere una parte dell’entropia fornirebbe un vantaggio esponenziale, compromettendo la sicurezza dei fondi.

Secret Sharing

Come funziona il metodo

Il Secret Sharing consente di suddividere un segreto (in questo caso, l’entropia del wallet) in più parti, senza ridurne la sicurezza.

Si definiscono due parametri: il numero totale di parti nn e la soglia mm. Il segreto originale può essere ricostruito solo disponendo di almeno mm parti su nn.

Se si possiedono meno di mm parti, invece, non si ottiene alcuna informazione utile sul segreto.

Per esempio, è possibile dividere l’entropia in 3 parti e richiederne 2 per la ricostruzione: qualunque coppia di parti tra le 3 è sufficiente. Allo stesso modo si possono usare schemi 3 su 5, 4 su 6, e così via. In questo modo si mantiene la possibilità di recupero anche se una parte va persa o diventa inaccessibile, senza offrire vantaggi a un attaccante che non raggiunga la soglia.

Descrizione matematica

Dal punto di vista matematico, il metodo si basa sul principio per cui per identificare univocamente una funzione polinomiale di grado gg, siano necessari g+1=mg+1=m punti.

Possedere un numero di punti inferiore a quello richiesto per determinare univocamente la funzione è completamente inutile, poiché esisterebbero infinite funzioni passanti per quei punti.

La funzione polinomiale può essere rappresentata in questa forma:

Πg(x)=y0ψ0(x)+y1ψ1(x)+\Pi_g(x) = y_0 \psi_0(x) + y_1 \psi_1(x) + ...+ynψg(x)... + y_n\psi_g(x)

dove l’informazione originale **è rappresentata dal punto a0a_0 (l’intersezione della funzione con l’asse yy).

Le funzioni ψi\psi_i sono i polinomi caratteristici, i cui coefficienti possono essere ricostruiti mediante il metodo di interpolazione di Lagrange:

Πg(x)=k=0gykψk(x)=\Pi_g(x) = \sum_{k=0}^g{y_k \psi_k(x)} = =i=0gykj=0,jigxxjxixj= \sum_{i=0}^g{y_k \prod_{j=0,j\neq i}^g{\frac{x-x_j}{x_i-x_j}}}

Implementazione

Per semplificare il processo di divisione e ricostruzione dell’entropia tramite le mnemonics, ho implementato un semplice programma in Rust, consultabile nel repository pubblico https://github.com/damianobacchin/bitcoin-secret-sharing

Nota: il codice è realizzato a scopo puramente didattico. Non utilizzarlo per custodire fondi reali, poiché un uso scorretto potrebbe comportare la perdita dei fondi.