Field

Our zkEVM is designed to have its execution traces encoded in a particular prime field , with . A nice property of this field is that it can represent the results of many common u32 operations. For example, (widening) u32 multiplication has a maximum value of , which is less than . In fact a u32 multiply-add has a maximum value of , so the result can be represented with a single field element, although if we were to add a carry in bit, this no longer holds.

This field also enables a very efficient reduction method. Observe that and consequently

To reduce a 128-bit number , we first rewrite as , where is 64 bits and are 32 bits each. Then

After computing , which can be done with a shift and subtraction, we add the first two terms, subtracting if overflow occurs. We then subtract , adding if underflow occurs.

At this point we have reduced to a u64. This partial reduction is adequate for most purposes, but if we needed the result in canonical form, we would perform a final conditional subtraction.