Any computation that you want to prove with a zkSNARK has to be expressed as arithmetic operations on a finite field. More specifically, this finite field is a prime field. You can think of it as a set of natural numbers smaller than a huge prime:

This set has two basic arithmetic operations, addition and multiplication, which are commutative and associative and together fulfill the distributive law:

This may look complex, but it simply says that you can add and multiply numbers as you’re used to; however, you need to apply the mod operation afterwards. The operations of a field always have an inverse: Hence, you can also subtract and divide. Note, however, that the division may behave unlike you’d expect.

Fortunately, when working with ZoKrates, you do not need to take care of the translation into prime field arithmetics. ZoKrates does all the magic for you as part of the compilation process in the background and provides an easy to use programming abstraction. Hence, the following ZoKrates DSL code

is actually computing a+b (mod p).

The important takeaway of this section is that in zkSNARK programming all variables are field elements and we perform all arithmetic operations modulo a large prime number p.

The prime field we work in when programming zkSNARKs is defined by the elliptic curve chosen to implement a zkSNARK proving system. To be more precise, the prime p which represents the field modulus is defined by the group order r of the elliptic curve. This will become clearer after elliptic curves have been introduced in the following section.

Ethereum provides pre-compiled contracts for the BN128 (also known as BN254) curve, which enable cheap curve operation on the blockchain. Operations inside a zkSNARK program, constructed using that curve, will wrap around the prime:

p = 21888242871839275222246405745257275088548364400416034343698204186575808495617

which equates to the group order r of BN128. Hence, if we want to be able to verify zkSNARKs on Ethereum, we use this p as the modulus in ZoKrates programs.

Elliptic Curves in 5 Minutes

Now, that we know which operations are available to us in zKSNARKs, let’s brielfy look at the core properties of elliptic curves, so we know what we need to implement.

From a high-level perspective, an elliptic curve is something very simple: A finite cyclic group. A group is a set with only one operation that fulfills closure, associativity, identity and invertibility. That’s just a fancy way of saying we have an “addition” operation which obeys all the basic arithmetic rules we’re intuitively used to. A finite group is a group with a finite number of elements. We refer to this finite number of elements in the group as the group’s order r.

What’s peculiar about elliptic curves is the way the elements in this group look and how the “addition” operation is defined: An element of an elliptic curve is a pair of prime field elements (remember, we know those from before!). Fun math fact: Since the prime field is finite, the set of pairs is also finite, which directly implies finiteness of the group constructed on top.