Le firme BLS sono ovunque, dal consenso di Ethereum a EigenLayer. Ma è facile usarle in modo sbagliato. Cosa sono le firme BLS? Parliamo del modo giusto e del modo sbagliato di usarle:
Ma prima di tutto, cosa sono le firme BLS? Le firme BLS sono un primitivo crittografico utilizzato per firmare messaggi, come l'ECDSA. Ecco come funziona la matematica. È costruito su accoppiamenti di curve ellittiche. Ma cosa le rende così speciali? Perché usare questi accoppiamenti sofisticati?
La caratteristica vincente di BLS: aggregazione delle firme. Puoi combinare molte firme BLS in un'unica firma. Questo ti consente di trasmettere e verificare N firme tutte in una volta, rendendo il processo più efficiente in termini di spazio e tempo! E sulla blockchain, le ottimizzazioni sono enormemente importanti per il risparmio di gas.
Per un'analisi approfondita su come funzionano le firme BLS, insieme al processo di costruzione di aggregazioni e multi-firme, dai un'occhiata al post del blog completo linkato alla fine di questo thread! Ora, vediamo come le firme BLS possono andare male e come EigenLayer le utilizza (correttamente, evitando queste insidie)!
EigenLayer è un layer di restaking per Ethereum. In EigenLayer AVSe, i validatori firmano i risultati delle loro computazioni di validazione. L'aggregatore raccoglie tutte queste firme e le inserisce sulla blockchain. Le firme aggregate vengono verificate sulla blockchain.
Il compito contiene il numero del blocco in cui il compito è stato creato e una soglia che indica la percentuale di validazione degli operatori, necessaria per convalidare il compito. Gli operatori che hanno aderito all'AVS possono ricevere quei compiti per calcolare la risposta al compito e poi l'operatore può inviare la risposta con la propria firma BLS del compito all'aggregatore. Non appena viene raggiunta la soglia di risposte identiche, l'aggregatore unisce tutte le firme BLS in un'unica firma aggregata e la restituisce al contratto AVS. Il contratto verifica che la firma sia corretta e apre un periodo di contestazione in cui un contestatore può fornire prova che la validazione era errata, e in tal caso, gli operatori che si comportano male vengono penalizzati.
Nel contratto, la verifica avviene nella funzione `trySignatureAndApkVerification`:
Tuttavia, le multi-firme, se utilizzate in modo errato, presentano un serio problema chiamato attacchi con chiave infedele. Supponiamo che un utente onesto abbia una chiave pubblica, `pk_0`. Un attaccante che ha precedentemente visto `pk_0` può scegliere la propria chiave pubblica come pk_1 = sk_1⋅G_1—pk_0. L'attaccante non conoscerà la chiave privata associata alla chiave pubblica. Tuttavia, la verifica della multi-firma darebbe quanto segue:
Solo `sk_1` è necessario per firmare un messaggio che risulta in una firma multipla valida, anche se il primo utente potrebbe non averlo firmato. Questo è facilmente generalizzabile a qualsiasi numero `r` di utenti onesti scegliendo la chiave sleale, che è:
Questa è una minaccia pericolosa poiché, nel nostro precedente esempio di AVS, un aggregatore malevolo che avrebbe precedentemente registrato una chiave fraudolenta potrebbe inviare firme aggregate non firmate dai validatori ma comunque essere accettate dal contratto. Questo porterebbe a sanzioni per i validatori anche se non si fossero comportati male.
Quindi, per prevenire un attacco con chiave non autorizzata, il metodo comune è richiedere agli utenti di dimostrare di conoscere la chiave privata che corrisponde alla loro chiave pubblica, noto come prova di possesso. Pertanto, nel primo passaggio di registrazione, all'utente viene richiesto di registrare la propria chiave pubblica insieme alla prova di possesso π in modo tale che:
Fondamentalmente, all'utente viene richiesto di firmare la propria chiave pubblica o qualsiasi altro messaggio di identificazione. In AVS, il messaggio è l'indirizzo dell'operatore. Nel contratto EigenLayer, la prova di possesso viene verificata dalla funzione `registerBLSPublicKey`:
La funzione `pubkeyRegistrationMessageHash` viene utilizzata per hashare il separatore di dominio personalizzato `PUBKEY_REGISTRATION_TYPEHASH` e l'indirizzo dell'operatore.
Dopo la registrazione, la chiave pubblica viene aggiunta al contratto. Possiamo verificarne il valore chiamando la funzione `getRegisteredPubkey`. Ecco un esempio di una chiave pubblica BLS registrata per EigenDA AVS:
La prova di possesso è fondamentalmente una firma BLS. Tuttavia, non è neanche consigliabile utilizzare firme multiple durante il passaggio di prova di possesso, ad esempio, per registrare più chiavi pubbliche per un singolo partecipante. Se così fosse, il partecipante potrebbe realizzare un attacco di splitting-zero. In questo caso, il partecipante potrebbe registrare chiavi che si annullerebbero quando sommate insieme e potrebbero eludere la prova di possesso.
Abbiamo visto che le multi-firme BLS offrono un'opportunità di ottimizzazione significativa. L'implementazione di EigenLayer dimostra il potere delle firme BLS e mette in evidenza anche le complessità coinvolte nel loro utilizzo pratico. Tuttavia, le multi-firme introducono rischi di sicurezza come gli attacchi con chiavi infette, il che richiede misure di protezione come la prova di possesso. Ma con l'aggiornamento Pectra che supporta BLS12-381, potremmo vedere ulteriori implementazioni e miglioramenti in Solidity, e quindi speriamo che questo post aiuti a evitare bug e vulnerabilità di implementazione noti.
Per un approfondimento sulle firme BLS, l'aggregazione della costruzione e le multi-firme, dai un'occhiata al nostro recente post sul blog qui sotto:
64,18K