â€‹Conditional expressionsâ€‹
â€‹Boolean operatorsâ€‹
â€‹Relational operatorsâ€‹
â€‹Arithmetic operationsâ€‹
â€‹Bitwise operatorsâ€‹
Circom
provides boolean, arithmetic and bitwise operators. They have the standard semantics but the arithmetic operators applied to numeric values work modulo p
, where
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
In the field F_p
we have all numbers from the set {0,...,p1}
and with them we can do additions and multiplications. The existence of additive inverses allow us to define positive and negative elements. Formally, we define the function val(z)
such that:
val(z) = zp
, if p/2 + 1 =< z < p
,
val(z) = z
, otherwise.
The idea is simple: the first half of numbers {0,...,(p+1)/2}
are positive and the second half becomes the set of negative numbers{(p+1)/2,...,1}
. See the following table for the finite field F_7
:
Field element 

0  0 
1  1 
2  2 
3  3 
4  3 
5  2 
6  1 
â€‹ðŸ‘‰ The consideration of positive and negative becomes particularly important when using relational operators. For example, in the finite field F_7
, the element 5
is greater than 1
as absolute numbers, but if we consider the sign of the elements, then 1
is greater than 5
, since 1 > 2
.
Boolean_condition ? true_value : false_value
var z = (x > y) ? x : y
This conditional expression is not allowed in a nested form, hence can only be used at the top level. See more about conditional expressions in the Control flow section.
Symbol  Meaning 
 AND 
 OR 
 NOT 
The relational operators take into account the sign of the elements in F_p
. Accordingly, their precise definition is the following:
x < y
is defined as val(x mod p) < val(y mod p)
x > y
is defined as val(x mod p) > val(y mod p)
x <= y
is defined as val(x mod p) <= val(y mod p)
x >= y
is defined as val(x mod p) >= val(y mod p)
Symbol  Meaning 
 Addition (both binary and unary) mod 
 Subtraction (both binary and unary) mod 
 Product mod 
 Multiplication by the inverse and then mod 
 Power mod 
 Quotient of integer division 
 Reminder of integer division 
x >> k
: shifts k
bits to the right x
x << k
: shifts k
bits to the left x
The precise definition of shift operations is the following:
For all k
with 0 =< k =< p/2
(integer division), we have that
x >> k = x\(2**k)
x << k = (x*(2**k) & (2**b  1)) mod p
, where b
is the number of significant bits of p
.
For all k
with (p\2 + 1) =< k < p
we have that
x >> k = x << (pk)
x << k = x >> (pk)
Note that k
is also the negative number kp
.
Expressions can be built using all these operators, provided that the conditional operator only occurs at the top level.
Additionally, there are operators that combine arithmetic or bitwise operators with a final assignment:
+=
, =
, *=
, /=
, **=
, \=
, %=
, ^=
, =
, &=
, >>=
, <<=
.
We also have the operators ++
and 
for unit increment and decrement, respectively. They are equivalent to the operations +=1
and =1
.
The precedence and association of the operators is like the ones in Rust, as defined here.
â€‹