Dealing with large hardcoded numbers in Cairo

Hello, we are working on a circom export to cairo, this would allow us to verify circuits written in circom using a starknet verifier contract. We are having trouble with the size of the numbers outputted by snarkjs (which circom uses to generate the proof). They are too big to fit into a felt, and they are hardcoded into the verifier contract (as we use a template for this), so we don’t have a way to store this numbers in an appropriate structure (such as BigInt3) before they get “truncated”. Our temporary solution was to split these numbers beforehand (so the numbers that get hardcoded into the cairo code are small enough to fit into a felt), but we would like to avoid this if we can.

We tracked down where this problem starts, we think the problem is the constant DEFAULT_PRIME, which is used to set the prime cairo uses throughout the compilation and execution of a cairo program and which’s value is 2 ** 251 + 17 * 2 ** 192 + 1. This value is too small for us, as the numbers we need to manage are 256 bits long. For example, this prime is used by the ExpressionSimplifier in the compiler to turn values into felts :

def to_field_element(val: int, prime: Optional[int]) -> int:
  """
  Converts val to an integer in the range (-prime/2, prime/2) which is
  equivalent to val modulo prime.
  """
  if prime is None:
    return val
  half_prime = prime // 2
  return ((val + half_prime) % prime) - half_prime

This explains why our numbers were “truncated” as soon as our cairo program processed them.
We would like to know if there is a better way to solve this problem .

14 Likes