Everything I wish I'd known before I started fiddling with this thing.
The elliptic curve BLS12-381 has become something of a celebrity in recent years. Many protocols are putting it to use for digital signatures and zero-knowledge proofs: Zcash, Ethereum 2.0, Skale, Algorand, Dfinity, Chia, and more.
Unfortunately, existing material about BLS12-381 is full of obscure incantations like "instantiating its sextic twist", and "optimal extension field towers". I'm here to fix that :smile:[1]
I won't be giving a general introduction to elliptic curves and their exciting group properties. There are already some great primers out there and I will be assuming basic knowledge of these things. Equally, there's much in here that is not specific to BLS12-381, and applies to other curves.
BLS12-381 is a pairing-friendly elliptic curve.
Pairing-based cryptography has been developed over the last couple of decades, enabling useful new applications such as short digital signatures that are efficiently aggregatable, identity-based cryptography, single-round multi-party key exchange, and efficient polynomial commitment schemes such as KZG commitments.
Pairing-friendly elliptic curves are curves with both a favourable embedding degree (to be explained below!), and a large prime-order subgroup (also see below). These are rare. If you create an elliptic curve at random, it has a miniscule chance of being pairing-friendly. However, they can be constructed, and BLS curves are explicitly constructed to be pairing-friendly. Several other families of pairing-friendly curves are also known.
Some good reading if you want to learn more about pairing-based cryptography:
If you really want to understand this stuff then Pairings for Beginners is awesome. It turns out to be a lot less scary than it looks if you work through it carefully, studying the examples as you go. I really recommend this (I'm perpetually half way through it…).
Curve BLS12-381 was designed by Sean Bowe in early 2017 as the foundation for an upgrade to the Zcash protocol. It is both pairing-friendly (making it efficient for digital signatures) and effective for constructing zkSnarks.
A proliferation of "next-generation", scalable blockchain protocols has put a premium on generating short digital signatures that can be efficiently aggregated or easily thresholded. The properties of BLS12-381 frequently make it the curve of choice for these protocols.
Several cryptographic libraries–-established ones such as Apache's Milagro, and emerging ones such as Herumi and Blst–-support BLS12-381. And there are already moves to include BLS12-381 in IETF standards, such as Pairing-Friendly Curves, Hashing to Elliptic Curves, and BLS signatures. This is good news for protocol interoperability!
BLS12-381 is part of a family of curves described by Barreto, Lynn, and Scott (they are the B, L, and S in view here - a different BLS trio will appear later).
The 12 is the embedding degree of the curve: neither too low, nor too high. We'll discuss embedding degrees in a little while.
The 381 is the number of bits needed to represent coordinates on the curve: the field modulus,
The basic equation of the BLS12-381 curve is
The key parameters for a BLS curve are set using a single parameter
Specific design goals for BLS12-381 are:
The value
Parameter | Equation | Value (hexadecimal) | Comments | |
---|---|---|---|---|
Field modulus | 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab | 381 bits, prime | ||
Subgroup size | 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 | 255 bits, prime |
Reference for much of this section. Lots of curve data is also in the IETF specification.
Field extensions are fundamental to elliptic curve pairings. The "12" is BLS12-381 is not only the embedding degree, it is also (relatedly) the degree of field extension that we will need to use.
The field
I totally failed to find any straightforward explainers of field extensions out there, so here's my attempt after wrestling with this for a while.
Let's construct an
Adding two elements is easy:
What about multiplying?
We need a rule for reducing polynomials so that they have a degree less than two. In this example we're going to take
Applying our rule, by substituting
Complex numbers can't be extended any further because there are no irreducible polynomials over the complex numbers. But for finite fields, if we can find an irreducible
Also worth noting is that modular reductions like this (our reduction rule) can be chosen so that they play nicely with the twisting operation.
In practice, large extension fields like
One of the initially non-obvious things about BLS12-381 is that we're really dealing with two curves, not one. Both curves share more-or-less the same curve equation, but are defined over different fields.
The simpler one is over the finite field
The other curve is defined over an extension of
As an aside, the curve order of
In this section and the next I'll explain how BLS12-381 ended up having two curve equations rather than one.
A pairing is a bilinear map. This means that it takes as input two points, each from a group of the same order,
Unfortunately, our simple curve
However, if we keep extending the field over which
This number
For completeness, note that each of
So, at this point, we have a group
But there's another challenge. As discussed earlier, doing arithmetic in
Or are we? Well, there's a twist in the tale…[8]
A twist is something like a coordinate transformation. Rather wonderfully, this can be used to transform our
BLS12-381 uses a "sextic twist". This means that it reduces the degree of the extension field by a factor of six. So
I haven't seen this written down anywhere–-but attempting to decode section 3 of this–-if we find a
When the twist is done correctly, the resulting
So these are the two groups we will be using:
And that's the story of why BLS12-381 looks like two curves, not one.
Note that coordinates of points in the
So, what's this pairing thing all about?
As far as BLS12-381 is concerned, a pairing simply takes a point
Pairings are usually denoted
What we are interested in is that:
From this, we can deduce that all of the following identities hold:
This is just what we need when verifying digital signatures.
If it helps, you can loosely think of a pairing as being a way to "multiply" a point in
We've mentioned the embedding degree several times, and it is significant enough to appear in the name of the curve.
The embedding degree,
It turns out that this number gives the smallest field extension
These are the conditions we need to satisfy for pairings to be possible.
The choice of an embedding degree is a balance between security and efficiency (as ever). On the security front, the embedding degree is also known as the security multiplier: a higher embedding degree makes the discrete logarithm problem harder to solve in
Embedding degrees of 12 or 24 seem to be a current sweet-spot for many applications. Once again, the embedding degree of BLS12-381 is 12 - it's in the name.
Security of cryptographic systems is measured in bits. Informally, I take
For elliptic curve cryptography, security is all about making the discrete logarithm problem hard. That is, given a point
For pairing-friendly curves, the discrete logarithm problem must be hard in each of the three of the groups we are using. Thus, to target
BLS12-381 was intended to offer around a 128 bit security level, based on these criteria, and this was supported by initial analyses. See Table 1.1 in the Taxonomy, for example.
However, on closer examination it seems that "the finite extension field of size 3072 = 12 × 256 bits is not big enough" (quoting section 2 here), in view of the second criterion above.
According to a report by NCC Group, citing other sources, the actual security level is probably between 117 and 120 bits (see page 8). They regard this as a perfectly adequate level of security: "The value of reaching '128-bit' [being] mostly psychological". Sean Bowe has also commented on the security level in the light of the original design goals.
A subgroup's cofactor is the ratio of the size of the whole group to the size of the subgroup. Normal elliptic curve cryptography requires the cofactor to be very small, usually one, in order to avoid small subgroup attacks on discrete logarithms. In pairing-based cryptography, however, this is not the case, and the cofactors of the
It turns out that, with care, we can have large cofactors and still be secure. Namely, when the cofactors of
For reference, the cofactors of
Group | Cofactor | Equation | Value (hexadecimal) |
---|---|---|---|
0x396c8c005555e1568c00aaab0000aaab | |||
0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 |
What's the point of all this? Well, multiplying by the cofactor turns out to be a straightforward way to map any arbitrary point on the elliptic curve into the respective subgroup
Just a note on roots of unity, because they come up in two completely different and unrelated contexts, which can be confusing.
First, we said that to support zkSnark schemes with this curve, for some biggish
Second, and completely unrelated, the effect of the pairing is to map the two points from
Let's briefly revisit our discussion of extending the base field for
This section is a miscellany of things relevant to using BLS12-381 in practice.
Now it's time to introduce the other BLS: Boneh, Lynn and Shacham. (The L is the same L as in BLS12-381; the B and the S are different.)
BLS signatures were introduced back in 2001, a little before the BLS curve family was published in 2002. But, pleasingly, they go hand-in-hand. (BLS signatures can use other curves; BLS curves have uses other than signatures. But it's nice when they come together.)
There's a pretty concise but lucid description of the BLS signature scheme in the draft IETF standard. See also the GitHub repo.
The private/secret key (to be used for signing) is just a randomly chosen number between
The corresponding public key (if we're using
The discrete logarithm problem means that it is unfeasible to recover
To sign a message
We sign the message by calculating the signature
Given a message
This is where pairing comes in. The signature is valid if, and only if,
We can confirm this using the properties of pairings:
A really neat property of BLS signatures is that they can be aggregated (see also the original paper), so that we need only two pairings to verify a single message signed by
It's possible to aggregate signatures over different messages, or signatures over the same message. In the case of Ethereum 2.0 we aggregate over the same message, so for brevity I'm just going to consider that.
To aggregate signatures we just have to add up the
Now the magic of pairings means that we can just verify that
As noted in section 1.1 here, when aggregating signatures over the same message, we need to take care of a possible "rogue public key attack".
Say your public key is
Now, when verifying, my claim checks out: it looks like you signed the message when you didn't:
One relatively simple defence against this–-the one we are using in Ethereum 2.0–-is to force validators to register a "proof of possession" of the private key corresponding to their claimed public key. You see, the attacker doesn't have the
More complex schemes, not requiring proof of knowledge of the secret key (KOSK), are available
For the purposes of digital signatures, the
The trade-offs are execution speed and storage size.
With respect to Zcash, most other implementations are "reversed". In Ethereum 2.0 we use
(Note that sometimes, the twisting operation is referred to as point compression - that's something completely different to what we're discussing here.)
For storing and transmitting elliptic curve points, it is common to drop the
Any elliptic curve point can be regenerated from the
Since field elements are 381 bits, and 48 bytes is 384 bits, we have a few bits to spare for flags. The most important is a flag to show which of the
For both
The specific details of how the flag bits and
When dealing with any point with an unknown origin, whether it comes to us compressed or uncompressed, it's important that we check that it lies in the correct subgroup. The point decompression described above only results in a point on the curve; we don't know whether it lies in the appropriate
The main issue seems to be that both
Subgroup checks are easy in principle: simply multiply our point by
Unfortunately, this is slow in practice, especially for
Generator points for
These were chosen as follows:
The generators of
and are computed by finding the lexicographically smallest valid x-coordinate, and its lexicographically smallest y-coordinate and scaling it by the cofactor such that the result is not the point at infinity.
By my calculations, with
p1 = (0x04, 0x0a989badd40d6212b33cffc3f3763e9bc760f988c9926b26da9dd85e928483446346b8ed00e1de5d5ea93e354abe706c)
and the
p2 = ([0x02, 0x00],[0x013a59858b6809fca4d9a3b6539246a70051a3c88899964a42bc9a69cf9acdd9dd387cfa9086b894185b9a46a402be73,0x02d27e0ec3356299a346a09ad7dc4ef68a483c3aed53f9139d2f929a3eecebf72082e5e58c6da24ee32e03040c406d4f])
(I think "lexicographically smallest" means treating all numbers in the base field as non-negative, and just taking the smaller one, prioritising real parts over imaginary parts.)
Calculation of a pairing has two parts: the Miller loop and the final exponentiation. Both are quite expensive, but there's a nice hack you can do to reduce the impact of the final exponentiation.
Normally, we calculate two full pairings in order to perform signature verification, to check whether
If we denote as
We know how to multiply in group
So, to verify a signature, we do the two Miller loops, one with a negated input value, multiply the results and then do a single final exponentiation. If the result is unity in
To calculate a digital signature over a message, we first need to transform an arbitrary message (byte string) to a point on the
The initial implementation in Eth2 was "hash-and-check". This is very simple.
About half the points that we try will result in a point on the curve, so this is not constant time–-we don't know how many iterations it will take to find one. In one sense it doesn't matter: all the information is public, so we're not leaking anything. However, it does open up a griefing attack. An attacker could pre-calculate messages that take a very long time to find a point (1 in one million messages will take 20 tries, for example) and slow us down considerably.
We are now adopting a better approach which is described in this paper and used in the new (draft) IETF standard for hashing to curves. As before (but a bit differently to ensure a uniform distribution of output points) we first create a field point by hashing the message mod
Now we use a special map (the SWU map) that is guaranteed to translate that field point into a valid point on an elliptic curve. For technical reasons, this is not the curve
You can take a look at my implementation of this in Java , based on the reference code in Python. The idea is for this approach to be generally adopted to enhance the interoperability of blockchains.
We discussed multiplying by the cofactor as a way to make an arbitrary point on
The
The endomorphism we want to use was subject to a patent, but this has now expired everywhere.
As a workaround to the patent, instead of multiplying by the
The idea is that, now that the patent has expired, the endomorphism can be just dropped in as a replacement for the effective cofactor multiplication.
Recall our discussion of field extensions? In practice, rather than implementing a massive 12th-degree extension directly, it is more efficient to build it up from smaller extensions: a tower of extensions.
For BLS12-381, the
As long as the modular reduction polynomial (our reduction rule) is irreducible (can't be factored) in the field being extended at each stage, then this all works out fine.
Interpreting these in terms of our previous explanation:
This towered extension can replace the direct extension as a basis for pairings, and when well-implemented can save a huge amount of arithmetic when multiplying
Finding the inverse of a field element (i.e. division) is an expensive operation, so implementations of elliptic curve arithmetic try to avoid it as much as possible. It helps if we choose the right coordinate system for representing our points.
Affine coordinates are the traditional representation of points with just an
However, it is not always the most efficient form to use when actually working with points, and there are two other schemes I'm aware of that are used for BLS12-381.
The basic idea is to represent the coordinate using notional fractions, reducing the number of actual division operations needed. To do this, a third coordinate is introduced and we use
The two systems I know of in use for BLS12-381 are Standard Projective coordinates and Jacobian coordinates.
The Standard Projective coordinate point
These are also called homogeneous projective coordinates because the curve equation takes on the homogeneous form
Standard Projective coordinates are used by the Apache Milagro BLS12-381 library under the hood.
A different kind of projective coordinates are Jacobian coordinates. In this scheme, the Jacobian point
The sample code for the constant-time hash-to-curve uses Jacobian coordinates under the hood.
Note that, in both schemes, the easiest way to import the Affine point
There are lots of references linked in the above, and I'm not going to repeat many here. I'll just pick out a few particularly useful or interesting things.
Useful reference material:
In general, implementations of pairing libraries tend to be highly optimised and/or very generic (supporting many curves) which makes them quite hard to learn from. The Noble BLS12-381 library in JavaScript/TypeScript by Paul Miller is definitely among the easier to follow.
Finally, a couple of fun and interesting reads:
That's all, folks!
Many thanks to my esteemed colleagues Olivier Bégassat, Thomas Piellard, Herman Junge, Błażej Kolad, and Gus Gutoski for review, sanity check and comments. (I made some changes since you last saw it, guys - any screw-ups are all my own.)
Ben Edgington, ben@benjaminion.xyz
PegaSys, ConsenSys
I studied mathematics many years ago, but diligently shirked anything to do with pure maths, including group theory. I regret that now. Anyway, this will not be too technical, but I'm also not an expert, so might get some things wrong and will be a bit hand-wavy in general. In case it's not obvious, I am not a cryptographer. ↩︎
Our rule is "an extension field modular reduction" (terminology from here). ↩︎
Another point on
Sometimes
Here's a point on the
Note that we lost the
The "trace zero subgroup" qualifies as an obscure incantation. Basically, the trace of a point is
:joy: Please forgive me. ↩︎
…because we previously selected the trace zero subgroup. Pairings for Beginners dives into the details on this. ↩︎
Thank you to my reviewers for this insight ↩︎
Numbers in this world are truly enormous. The number of times
This is easy to see. The subgroup
This is a general property of roots of unity in multiplicative groups, not special to elliptic curves or pairings ↩︎
This should have been "increment the message and go back to one" on failure, which is more secure. ↩︎