Logo
    Efficient threshold BLS & Encryption onchain

    Efficient threshold BLS & Encryption onchain

    Created by
    D
    Deleted User
    Date
    March 21, 2023

    This post explains an inherent tension between threshold BLS signature and Elgamal encryption for onchain verification, and then presents a way to augment such threshold network such that a smart contract can efficiently verify a signature and decrypt/verify encryption onchain.

    Introduction

    For encryption/decryption and signing, we (usually) require a group, i.e. a single elliptic curve. However, using pairings, we have to choose between G1\mathbb{G_1}G1​ and G2\mathbb{G_2}G2​ (and even Gt\mathbb{G_t}Gt​), each group have their pros and cons depending on the cryptographic protocol we want to use. In practice, G1\mathbb{G_1}G1​ is usually preferred given it is much shorter and faster to compute in it, than its counter-parties.

    This choice of group comes up when designing threshold networks. Indeed, there is a distributed key lying in a group G\mathbb{G}G which could be any of the three groups aforementioned. In particular, when using pairing equipped curves, a threshold network can be used to create threshold BLS signatures but it can also be used as a decryption oracle. In the latter, users encrypts towards the threshold network and push the encryption on-chain.

    This posts shows the pros and cons of using G1\mathbb{G_1}G1​ and G2\mathbb{G_2}G2​ for each and shows there is a tension between the two. This posts then shows a simple solution to get the best of both worlds. The technique is heavily inspired by a post by Kobi Gurkan on efficient multisignature verification onchain, translated to the threshold setting.

    Reminder on the cryptographic schemes

    BLS Signatures

    There are many references on the web that will explain BLS signatures. This post by Remco Bloemen is one of them!

    Workflow: user creates a signature and push it onchain. The smart contract will verify the validity of this signature.

    Hashed El Gamal

    For succinctness and simplicity, we present this CCA version of El Gamal encryption scheme. Note that are many versions and also IBE based encryption scheme (such as the one used for timelock encryption), that will expose the same problem laid in this post.

    Workflow: a user encrypts a message, and push it onchain. The smart contract will verify the “validity” of this ciphertext.

    Assume we have a generic group G\mathbb{G}G, then

    • Encryption of msg m is happening on G\mathbb{G}G bundled with a DLEQ proof πG\pi_{\mathbb{G}}πG​ (such as the one used in Privacy Pass by Cloudflare) lying in group G\mathbb{G}G.
      • {rG, H(rP)⊕ m, πG}\{rG, H(rP) \oplus m, \pi_{\mathbb{G}}\}{rG, H(rP)⊕ m, πG​}
    💡
    💡 The purpose of the DLEQ proof is twofold: 1. CCA security: and more informally, to prove the author of the ciphertext really created it, i.e. that he knows the secret random scalar rrr used for encryption. 2. Replay protection: because we can embed a public identifier of the author inside the DLEQ transcript so it is not possible for anyone else to submit the same ciphertext.
    • Verification of the correctness of the ciphertext involves verifying the DLEQ proof using group operations on G\mathbb{G}G. We do not show it here for succinctness.
      • Verification of this proof is done on the smart contract !

    Distributed Key Generation

    Such protocol is used to generate a distributed private key, such that each node has a share of it, but no one individually can recover the private key. The public key is known. The set of all nodes can act as if it was a single entity.

    Let’s assume we have

    • nnn participants, with a threshold of ttt
    • a distributed public key P=xG∈G1P=xG \in \mathbb{G_1}P=xG∈G1​, with each node having a share xi∈Frx_i\in\mathbb{F_r}xi​∈Fr​
    • The “public share” can also be computed publicly Xi=xiG1∈G1X_i=x_iG_1\in\mathbb{G_1}Xi​=xi​G1​∈G1​

    To recover the private key xxx, the network would need to come together and compute:

    x=∑tLi(0)xix = \sum_t L_i(0) x_ix=t∑​Li​(0)xi​

    where Li(0)L_i(0)Li​(0) is the i-th Lagrange polynomial over this set evaluated at point 0.

    We invite you to read for example the documentation of drand that explains in depth how this all works.

    Pubkey in G1\mathbb{G_1}G1​, Signature in G2\mathbb{G_2}G2​

    • Threshold network public key P=xG1P=xG_1P=xG1​
    • Encryption to threshold network: {rG1, H(rP)⊕ m, πG1}\{rG_1, H(rP) \oplus  m, \pi_{\mathbb{G_1}}\}{rG1​, H(rP)⊕ m, πG1​​}
    • BLS signature σ verification from network:
      • e(P,H2(m))==e(G1,σ)e(P,H_2(m)) == e(G_1,\sigma)e(P,H2​(m))==e(G1​,σ) where σ=xH2(m)∈G2\sigma = xH_2(m) \in \mathbb{G_2}σ=xH2​(m)∈G2​
      • This is computed on the smart contract !

    In this situation, the trade off is as follow:

    • 🚀 DLEQ proof verification is FAST because only group operations in G1\mathbb{G_1}G1​ are involved.
    • ⌛ BLS signature verification is SLOW because of the the hash-to-curve H2(m)H_2(m)H2​(m) operations which requires to handle operations in Fq2\mathbb{F_{q^2}}Fq2​. This is especially relevant in context of blockchain where smart contract operations are usually costly.

    Pubkey in G2\mathbb{G_2}G2​, Signature in G1\mathbb{G_1}G1​

    • Threshold network public key P=xG2P=xG_2P=xG2​
    • Encryption to threshold network: {rG2,H(rP)⊕m,πG2}\{rG_2, H(rP) \oplus m, \pi_{\mathbb{G_2}}\}{rG2​,H(rP)⊕m,πG2​​}
    • BLS signature σ verification from network:
      • e(H1(m),P)==e(σ,G2)e(H_1(m),P) == e(\sigma,G_2)e(H1​(m),P)==e(σ,G2​) where σ=xH1(m)∈G1\sigma = xH_1(m) \in \mathbb{G_1}σ=xH1​(m)∈G1​

    In this situation, the trade off is on the opposite side:

    • ⌛ DLEQ verification is SLOW because group operations in G2\mathbb{G_2}G2​ are involved. It is especially relevant in the context of blockchain where we want to verify this DLEQ proof onchain.
    • 🚀 BLS signature verification is FAST because the hash-to-curve operation H1(m)H_1(m)H1​(m) is fast, as it only involves Fq\mathbb{F_q}Fq​ operations.

    Goal

    We want the best of both worlds:

    • “Encryption to public key”, especially the DLEQ proof, to lie on G1\mathbb{G_1}G1​ to get cheap decryption/verification
    • “Signature public key” on G2\mathbb{G_2}G2​ to get cheap signature verification
    • Still having the same “secret key” behind

    The end user now have to use the corresponding key depending on which protocol he needs.

    ‣
    Why not two separate network/keys then?

    In the following solution, each node only need to keep the same secret share, but express the public distributed key differently according to the operation to use. That allows us to keep the same trust assumption for the system. The nice thing about this solution is that it can be implemented on top of an already existing threshold network.

    Creating a G2\mathbb{G_2}G2​ key from the G1\mathbb{G_1}G1​ key

    The goal is to have a second public key P’=xG2∈G2P’=xG_2 \in \mathbb{G_2}P’=xG2​∈G2​, using the same share, representing the same secret key alongside P=xG1∈G1P = xG_1 \in \mathbb{G_1}P=xG1​∈G1​ !

    The network must perform the following steps (off chain):

    1. Each node creates its symmetrical version of its public share on G2\mathbb{G_2}G2​ and broadcasts it:
      1. Xi′ = xiG2∈G2X_{i}' = x_iG_2\in\mathbb{G_2}Xi′​ = xi​G2​∈G2​
    2. everyone (including third parties) can verify the validity of the new share using the following equations:
    (a)  e(Xi,G2)==e(G1,Xi′)⇔ e(G1,G2)xi==e(G1,G2)xi(a)\; e(X_i,G_2) == e(G_1,X_i') \\ \Leftrightarrow \\ e(G_1,G_2)^{x_i} == e(G_1,G_2)^{x_i}(a)e(Xi​,G2​)==e(G1​,Xi′​)⇔ e(G1​,G2​)xi​==e(G1​,G2​)xi​
    1. The “public key in G2\mathbb{G_2}G2​ can be recovered via regular Lagrange interpolation
    (b)  P′=xG2=∑tLi(0)Xi′(b)\; P' = xG_2 = \sum_t L_i(0)X_i'(b)P′=xG2​=t∑​Li​(0)Xi′​

    This key P’P’P’ can now be used for BLS signature on G2\mathbb{G_2}G2​ !

    Verification on chain of the equivalence

    How does the contract know what is the new P’P’P’ ? How can he verify it is correct ?

    We assume the contract already knows the original distributed key P.

    An aggregator that performs (a) and (b) can submit P’P’P’ on chain. Contract then only need to perform a simple pairing check

    e(P,G2)==e(G1,P′)e(P,G_2) == e(G_1,P')e(P,G2​)==e(G1​,P′)

    This works because both have the same dlog / secret key !

    Eviction of malicious node

    A node might not generate its second version of its share or give an invalid one. How do you attest of that fact to the smart contract so he can be slashed / excluded ?

    Given we now have “cheap” BLS signature, the threshold network (who have a majority of honest nodes) can “BLS sign” on the eviction of this node !

    Another solution would for the contract to check equation (a) using the malicious node values but that might be more expensive to perform because the smart contract may not know XiX_iXi​ in advance. Indeed, this requires evaluating the distributed public polynomial and this is linear in the threshold.

    Acknowledgements

    Thanks to Rosario Gennaro for help on the proof sketch, and Kobi Gurkan for his post on the idea of translating between G1\mathbb{G_1}G1​ and G2\mathbb{G_2}G2​.

    Appendix: Proof Sketch

    Publishing keys in both group is safe

    Assume we have groups G1,G2,GT\mathbb{G}_1, \mathbb{G}_2,\mathbb{G}_TG1​,G2​,GT​ and a pairing function e:G1×G2⟶GTe: \mathbb{G}_1 \times \mathbb{G}_2 \longrightarrow \mathbb{G}_Te:G1​×G2​⟶GT​

    Let P1=xG1∈G1 and P2=xG2∈G2P_1=xG_1 \in \mathbb{G}_1 \textrm{ and } P_2=xG_2 \in \mathbb{G}_2P1​=xG1​∈G1​ and P2​=xG2​∈G2​

    P2P_2P2​ is the public key of a BLS signature scheme where a message mmm is signed by first hashing it into G1\mathbb{G_1}G1​ as M=H(m)∈G1M = H(m)\in\mathbb{G_1}M=H(m)∈G1​ and the signature is computed as S=xM∈G1S=xM\in\mathbb{G}_1S=xM∈G1​

    The verification is e(S,G2)=e(M,P2)e(S,G_2)=e(M,P_2)e(S,G2​)=e(M,P2​)

    P1P_1P1​ is the public key of a Hashed ElGamal encryption scheme where the encryption of a message mmm is computed as (α,β)(\alpha,\beta)(α,β) with α=rG1\alpha=rG_1α=rG1​ and β=H^(rP1)⊕m\beta=\hat{H}(rP_1) \oplus mβ=H^(rP1​)⊕m together with a DLEQ proof π\piπ. Decryption is performed only if the proof holds and m=β⊕H^(xα)m=\beta \oplus \hat{H}(x\alpha)m=β⊕H^(xα). The DLEQ proof provides another group element γ=rG^1\gamma=r\hat{G}_1γ=rG^1​ and proves that log⁡G1α=log⁡G^1γ\log_{G_1}\alpha = \log_{\hat{G}_1}\gammalogG1​​α=logG^1​​γ.

    Let’s assume the following problem is hard in G1,G2,GT\mathbb{G}_1,\mathbb{G}_2,\mathbb{G}_TG1​,G2​,GT​

    Given P1=xG1,A=aG1,P2=xG2 compute B=(ax)G1P_1=xG_1,A=aG_1,P_2=xG_2 \textrm{ compute } B=(ax)G_1P1​=xG1​,A=aG1​,P2​=xG2​ compute B=(ax)G1​

    This is the Augmented Computational Diffie-Hellman problem in G1\mathbb{G_1}G1​ where we account for the fact that P2P_2P2​ is also known to the adversary.

    The aCDH problem is what is needed to prove BLS in Asymmetric Pairings setting (see page 15 of Boneh et al).

    Using same secret key for both BLS and El Gamal is safe

    We need to show that the simultaneous security of BLS (unforgeable under chosen message attack) and Hashed ElGamal (under chosen ciphertext attack).

    Our simulator is given P1P_1P1​, AAA, P2P_2P2​ from the aCDH problem. It sets P2P_2P2​ as the BLS public key, P1P_1P1​ as the Hashed ElGamal public key and sets G^1=λP1\hat{G}_1=\lambda P_1G^1​=λP1​ for a random λ\lambdaλ

    When the adversary is given P1,P2P_1,P_2P1​,P2​ and asks for a signature on a message mmm the simulator sets M=H(m)=rG1M=H(m)=rG_1M=H(m)=rG1​ for a random rrr and then the signature is S=rP1S=rP_1S=rP1​.

    If the adversary queries a ciphertext (α=rG1,β,γ,π)(\alpha=rG_1,\beta,\gamma,\pi)(α=rG1​,β,γ,π) to the decryptor, the simulator answers ⊥\bot⊥if the proof is not valid. Otherwise we know that γ=rG^1=rλP1\gamma=r\hat{G}_1=r \lambda P_1γ=rG^1​=rλP1​ and therefore rP1=λ−1γrP_1=\lambda^{-1} \gammarP1​=λ−1γ and m=β⊕H^(λ−1γ)m=\beta \oplus \hat{H}(\lambda^{-1} \gamma)m=β⊕H^(λ−1γ)

    On the message m^\hat{m}m^ that the adversary wants to forge (which is guessed at random by the simulator), the simulator sets M^=H(m^)=A\hat{M}=H(\hat{m})=AM^=H(m^)=A then the signature output by the forger must be S^=xA=B\hat{S}=xA=BS^=xA=B as desired.

    If the adversary issues a “distinguishing query” on Hashed ElGamal by presenting two messages m0,m1m_0,m_1m0​,m1​, the simulator chooses b∈{0,1}b \in \{0,1\}b∈{0,1} at random and encrypts mbm_bmb​ as (α=A,β=r^⊕mb,γ,π)(\alpha=A,\beta = \hat{r} \oplus m_b, \gamma, \pi)(α=A,β=r^⊕mb​,γ,π) where r^\hat{r}r^ is a random string, γ\gammaγ is a random group element and π\piπ is a simulated proof that log⁡G1α=log⁡G^1γ\log_{G_1} \alpha = \log_{\hat{G}_1} \gammalogG1​​α=logG^1​​γ. Note that the simulator is implicitly defining H(B)=r^H(B)=\hat{r}H(B)=r^ in the above simulation (implicitly since it does not know BBB). If the adversary guesses bbb with probability better than 1/2 it must have queried B to the random oracle. Note that the simulator can detect when B is queried since e(A,P2)=e(B,G2)e(A,P_2)=e(B,G_2)e(A,P2​)=e(B,G2​) so when that queries happens it answers with H(B)=r^H(B)=\hat{r}H(B)=r^ and outputs B as the desired solution.

    CryptoNet is a Protocol Labs initiative.