zkPairing (Part 2): Technical Explainer
August 24, 2022
zkPairing (Part 2): Technical Explainer
by Jonathan W., Vincent H., and Yi Sun
In a previous post, we presented zkPairing, a proof-of-concept implementation of elliptic curve pairings in Circom. This post explains some of the techniques and optimizations which went into our work.
What are elliptic curve pairings?
Pairing-based cryptography relies on the construction of a special function known as a bilinear pairing. A pairing is a function
- bilinearity:
for elliptic curve points and non-zero integers . - non-degeneracy:
unless .
These properties imply the decisional Diffie-Hellman property
Most elliptic curves used in cryptography are assumed to satisfy the computational Diffie-Hellman assumption: given any point
Luckily, pairings satisfying these properties exist on many elliptic curves used in cryptography. In this post, we will be interested in the BLS12-381 curve and the Tate and optimal Ate pairings on it. The construction of these pairings originates in algebraic geometry (the study of solutions to polynomial equations) and is quite involved. You can find the gory details here, but at a high level the optimal Ate pairing involves the following operations:
- Miller loop: Using a recursive algorithm to compute a function
of the two input points. - Final exponentiation: Raising
to the large power .
How do BLS signatures work?
The BLS signature scheme is a signature scheme based on elliptic curve pairings. BLS signatures have several nice properties. First, unlike RSA or ECDSA signatures, they are unique and deterministic: given a key and message, there is only one possible valid signature. Second, BLS signatures can be efficiently adapted to create aggregate and threshold signatures, which involve checking that some number of people from a group have signed messages.
On an elliptic curve with group of points of order
To verify a signature
By the decisional Diffie-Hellman property discussed earlier, this implies that
Circuits and Techniques
Finite field extensions
Earlier in the post, we mentioned that the arguments to an elliptic curve pairing are points
The easiest way to understand finite field extensions is with an example. Consider the integers modulo
However, there is no element
The above example shows how, for a prime
Miller loop
Let
The rational function
where
Our Miller loop circuit performs this process with a few optimizations also present in non-ZK implementations:
- Instead of computing the points
directly, which requires elliptic curve arithmetic over , we use a twist to an elliptic curve over . - Because we will raise
to the power in the final exponentiation, we omit all of the vertical line evaluations , as they end up becoming when exponentiated.
Final exponentiation
The optimal Ate pairing is given by raising the outcome
Because
We break the computation of
where
Easy part (Frobenius operator)
In the easier first step, we compute
Hard part (cyclotomic subgroup)
We complete the exponentiation by computing
- We write
for small using [Section 5, HHT]. Then we compute and use the Frobenius operator to get .
We use one further optimization to speed up computation of the
BLS Signatures: Glued Miller loop and hashing to curve
Remember from earlier in the post that BLS signature verification requires checking that
The obvious way to do this is to compute two pairings: one on the left and one on the right. However we can do better: the bilinearity property of pairings tells us that
The left hand side is equal to
Hashing to curve
Up to now we have described how to verify BLS signatures given a hashed message
hashToField: Starting with, one hashes it to two elements u[0], u[1]ofusing a hash like SHA-256. This step depends on a DST(domain separation tag), which is highly implementation dependent, so be sure to check you are using the right one!- Optimized simplified SWU map for BLS12-381: [Section 4, Wahby-Boneh] provide an optimized method to go from elements
in to where is the twist of BLS12-381. This is based on a simplified version of the Shallue-van de Woestijne-Ulas (SWU) mapping. (Footnote: the sgn0function described in Wahby-Boneh is different from the one in the Internet Draft.) - Cofactor clearing: We now have an element
in . However it does not necessarily lie in the subgroup of elements of order . The size of is where the cofactor is quite large. To map to , the naive thing to do is to scalar multiply by . Since is huge, this is extremely expensive. Instead, there is a different, faster method to map to . This method uses an endomorphism by Budroni-Pintore which is closely related to the Frobenius operator.
Subgroup checks
For full security, we also need to check that the public key
Outlook and roadmap
Adapting to other elliptic curves
Although our circuits target the BLS12-381 curve, they can be easily adapted to other curves. We have recently modified our circuits to work for the BN254 curve, which Ethereum supports with precompiles for elliptic curve arithmetic and pairings. This used the following modifications:
- Field extension representation: The scalar field
of BN254 differs from that of BLS12-381, so we must change our representation for the field extensions and accordingly. - Curve coefficients: BLS12-381 and BN254 have different coefficients
and in the Weierstrass normal form , so we must update these. - Optimal Ate definition: BN254 lies in the Barreto-Naehrig family of curves, for which we must modify the
used for in the definition of the optimal Ate pairing. - Final exponentiation optimization: Because of the smaller size of the scalar field
and the higher Hamming weight of a certain parameter involved in defining and the curve order for BN254, we must reassess whether compressing to the cyclotomic subgroup still offers an advantage over the direct square-and-multiply method.
Recursive verification / proof aggregation
Implementing the optimal Ate pairing on BN254 opens up the possibility of implementing zkSNARK verification within a zkSNARK. For the Groth16 proof system, verifying a proof
where
Recursive verification and aggregate verification with techniques like SnarkPack allows us to construct zkSNARKs in a modular fashion. To give an example, suppose that Alice wants to generate a zkSNARK for the composition h(x) = f(g(x)) of two function calls. She can either (1) generate a SNARK for the large combined function h(x) or (2) generate a SNARK proof y = g(x) and a second SNARK proof for the two statements z = f(y) and "y = g(x)". The latter approach, enabled by recursion, allows Alice to prove that z = h(x) while only proving SNARKs smaller than the one for h(x). This is particularly useful in size-constrained settings where the composed SNARK has more constraints than the current largest trusted setup for Groth16 (~256M constraints).
PLONK and KZG commitment verification
Many of the most efficient modern ZKPs such as PLONK are based on the KZG polynomial commitment. Batch opening the value of a committed polynomial in the KZG commitment scheme at several points requires checking a single equality involving elliptic curve pairings. Our techniques for pairings thus open the path to verification for KZG commitments and thus verification for PLONK-type SNARKs which are based on batch openings of KZG commitments.
Circuit auditing and verification
As discussed in earlier posts on zk-ECDSA, these circuits are unaudited and not ready for production use. Due to the complexity and size of these circuits, ensuring their correctness is particularly difficult. We have implemented some basic unit tests for witness correctness, but a few directions we are exploring are:
- Testing for witness uniqueness using automated tools like Ecne. Our circuits are substantially larger than previous circuits Ecne has been applied to, and we are excited to see whether such tools can scale to our use case.
- We have created extensive documentation for each component of our circuits, including specifying pre- and post-conditions on each template. In addition to facilitating a human audit, this can form the first step towards a specification for formal verification of our circuits.
Conclusion
We invite you to check out our repo, and we'd love to hear your feedback or ideas for improvement. We are also actively exploring further applications of this work -- please reach out if you have an application of zkSNARKs for pairings!
This project was built during 0xPARC's ZK Identity Working Group with the support of the ZKxZK Gitcoin grant.
We use many optimization techniques from circom-ecdsa and xJsnark for big integer and elliptic curve arithmetic. We would also like to thank Jordi Baylina for his crucial help in teaching us how to use the Circom / snarkjs toolstack for large ZK circuits.