BLS signatures are everywhere, from Ethereum’s consensus to EigenLayer. But it’s easy to use them wrong. What are BLS signatures? Let’s talk about the right way and the wrong way to use them:
But first, what are BLS signatures? BLS signatures are a cryptographic primitive used for signing messages, like ECDSA. Here’s how the math works. It’s built on top of elliptic curve pairings. But what makes them so special? Why use these fancy pairings?
BLS’s killer feature: signature aggregation. You can combine many BLS signatures into a single signature. This lets you transmit and check N signatures all at once, more space and time efficient! And on-chain, optimizations are hugely important for gas savings.
For an in-depth look into how BLS signatures work, along with the process of building aggregation and multi-signatures, check out the full blog post linked at the end of this thread! Now, let’s see how BLS signatures can go wrong, and how EigenLayer uses them (properly, avoiding these pitfalls)!
EigenLayer is a restaking layer for Ethereum. In EigenLayer AVSes, validators sign the results of their validation computations. The aggregator collects all these signatures and pushes them on chain. The aggregated signatures are verified on-chain.
The task contains the block number when the task was created and a threshold indicating the percentage of operator validation, which is necessary to validate the task. The operators that opted into the AVS can get those tasks to compute the task answer and then the operator can send the answer with their BLS signature of the task to the aggregator. As soon as the threshold of identical answers is reached, the aggregator merges all the BLS signatures into a unique aggregate signature and sends it back to the AVS contract. The contract verifies that the signature is correct and opens a challenging period when a challenger can give proof that the validation was incorrect, and if so, the misbehaving operators are slashed.
In the contract, the verification happens in the `trySignatureAndApkVerification` function:
However, multi-signatures, if used incorrectly, come with a serious issue called rogue-key attacks. Let’s say an honest user has a public key, `pk_0`. An attacker who has previously seen `pk_0` can choose their public key as pk_1 = sk_1⋅G_1—pk_0. The attacker would not know the private key associated with the public key. However, the multi-signature verification would give the following:
Only `sk_1` is needed to sign a message resulting in a valid multi-signature, even though the first user may not have signed it. This is easily generalized to any number `r` of honest users by choosing the rogue key, being:
This is a dangerous threat since, in our previous AVS example, a malicious aggregator that would have previously registered a rogue key could send aggregate signatures not signed by the validators but still be accepted by the contract. This would lead to validators being slashed even if they did not misbehave.
So, to prevent a rogue-key attack, the common method is to request users to prove they know the private key matches their public key, known as proof of possession. Thus, in the first registration step, the user is requested to register their public key together with proof of possession π such that:
Basically, the user is requested to sign their public key or any other identification message. In AVS, the message is the operator address. In the EigenLayer contract, the proof of possession is verified by the `registerBLSPublicKey` function:
The function `pubkeyRegistrationMessageHash` is used to hash the custom domain separator `PUBKEY_REGISTRATION_TYPEHASH` and the operator address.
After registration, the public key is added to the contract. We can verify its value by calling the `getRegisteredPubkey` function. Here is an example of a BLS public key registered for EigenDA AVS:
Proof of possession is basically a BLS signature. However, it is also not advisable to use multi-signatures during the proof-of-possession step, for example, to register multiple public keys for a single participant. If so, the participant would achieve a splitting-zero attack. In this case, the participant could register keys that would cancel out when summed together and could bypass the proof of possession.
We’ve seen that BLS multi-signatures offer a significant optimization opportunity. EigenLayer’s implementation demonstrates the power of BLS signatures and also highlights the complexities involved in their practical deployment. However, multi-signatures introduce security risks such as rogue-key attacks, which necessitate safeguards like proof of possession. But with the Pectra upgrade supporting BLS12-381, we may see further implementation and improvements in Solidity, and thus we hope this post helps to avoid known implementation bugs and vulnerabilities.
For a deeper dive into BLS signatures, building aggregation, and multi-signatures, check out our recently published blog post below:
64,22K