It turns out that it is possible to make a bilinear map over elliptic curve points — that is, come up with a function e(P, Q) where the inputs P and Q are elliptic curve points, and where the output is what’s called an F_p¹² element (at least in the specific case we will cover here; the specifics differ depending on the details of the curve, more on this later), but the math behind doing so is quite complex.

First, let’s cover prime fields and extension fields. The pretty elliptic curve in the picture earlier in this post only looks that way if you assume that the curve equation is defined using regular real numbers. However, if we actually use regular real numbers in cryptography, then you can use logarithms to “go backwards”, and everything breaks; additionally, the amount of space needed to actually store and represent the numbers may grow arbitrarily. Hence, we instead use numbers in a prime field.

A prime field consists of the set of numbers 0, 1, 2… p-1, where p is prime, and the various operations are defined as follows:

a + b: (a + b) % p

a * b: (a * b) % p

a - b: (a - b) % p

a / b: (a * b^(p-2)) % p

Basically, all math is done modulo p (see here for an introduction to modular math). Division is a special case; normally, 3/2 is not an integer, and here we want to deal only with integers, so we instead try to find the number x such that x * 2 = 3, where * of course refers to modular multiplication as defined above. Thanks to Fermat’s little theorem, the exponentiation trick shown above does the job, but there is also a faster way to do it, using the Extended Euclidean Algorithm. Suppose p = 7; here are a few examples:

2 + 3 = 5 % 7 = 5

4 + 6 = 10 % 7 = 3

2 - 5 = -3 % 7 = 4

6 * 3 = 18 % 7 = 4

3 / 2 = (3 * 2^5) % 7 = 5

5 * 2 = 10 % 7 = 3

If you play around with this kind of math, you’ll notice that it’s perfectly consistent and satisfies all of the usual rules. The last two examples above show how (a / b) * b = a; you can also see that (a + b) + c = a + (b + c), (a + b) * c = a * c + b * c, and all the other high school algebraic identities you know and love continue to hold true as well. In elliptic curves in reality, the points and equations are usually computed in prime fields.

Now, let’s talk about extension fields. You have probably already seen an extension field before; the most common example that you encounter in math textbooks is the field of complex numbers, where the field of real numbers is “extended” with the additional element sqrt(-1) = i. Basically, extension fields work by taking an existing field, then “inventing” a new element and defining the relationship between that element and existing elements (in this case, i² + 1 = 0), making sure that this equation does not hold true for any number that is in the original field, and looking at the set of all linear combinations of elements of the original field and the new element that you have just created.

We can do extensions of prime fields too; for example, we can extend the prime field mod 7 that we described above with i, and then we can do:

(2 + 3i) + (4 + 2i) = 6 + 5i

(5 + 2i) + 3 = 1 + 2i

(6 + 2i) * 2 = 5 + 4i

4i * (2 + i) = 3 + i

That last result may be a bit hard to figure out; what happened there was that we first decompose the product into 4i * 2 + 4i * i, which gives 8i - 4, and then because we are working in mod 7 math that becomes i + 3. To divide, we do:

a / b: (a * b^(p^2-2)) % p

Note that the exponent for Fermat’s little theorem is now p² instead of p, though once again if we want to be more efficient we can also instead extend the Extended Euclidean Algorithm to do the job. Note that x^(p² - 1) = 1 for any x in this field, so we call p² - 1 the “order of the multiplicative group in the field”.

With real numbers, the Fundamental Theorem of Algebra ensures that the quadratic extension that we call the complex numbers is “complete” — you cannot extend it further, because for any mathematical relationship (at least, any mathematical relationship defined by an algebraic formula) that you can come up with between some new element j and the existing complex numbers, it’s possible to come up with at least one complex number that already satisfies that relationship. With prime fields, however, we do not have this issue, and so we can go further and make cubic extensions (where the mathematical relationship between some new element w and existing field elements is a cubic equation, so 1, w and w² are all linearly independent of each other), higher-order extensions, extensions of extensions, etc. And it is these kinds of supercharged modular complex numbers that elliptic curve pairings are built on.

For those interested in seeing the exact math involved in making all of these operations written out in code, prime fields and field extensions are implemented here: https://github.com/ethereum/research/blob/master/zksnark/bn128_field_elements.py