Cairo
Presentation: https://youtu.be/zNWatOe9Hmo
Introduction
Let us assume we are designing a zkDSL. There are two major architectural approaches to consider.
1. ASIC Approach
This is the Circom-style approach, where a program is taken as input and compiled into a circuit. The resulting circuit can prove only the execution of that specific program, making it essentially an application-specific circuit (ASIC).
In other words, whenever the program changes, a new circuit must be generated.
2. CPU (von Neumann) Approach
This is the Cairo-style approach, where a single universal circuit models a CPU architecture. In this model, a program is loaded into memory, and the program counter (PC) fetches, decodes, and executes instructions sequentially.
Thus, the same circuit can verify the execution of different programs.
The name Cairo originates from CPU AIR
When designing a DSL for zero-knowledge proving, the two most critical factors are programmability and efficiency.
Let us now explore why Cairo chose the CPU-based (von Neumann) approach to achieve this balance.
Description
ASIC vs CPU Approach
ASIC Approach
For example, to prove that , the statement can be arithmetized as follows:
In this ASIC approach, a circuit is generated specifically for a single program, which makes it highly efficient for that particular computation.
However, inefficiencies arise when handling conditional statements and loops.
Conditional Statement
A conditional statement can be expressed using a selector variable :
At runtime, only one branch is actually executed, but in the circuit, both branches must be represented as algebraic constraints.
Loop Statement
A loop is typically unrolled up to a predefined maximum bound , and the loop body is repeated times during arithmetization.
Even if the loop terminates earlier at runtime, all iterations are still represented as constraints — leading to redundant computations and reduced efficiency.
Summary
As a result, the ASIC approach has the following limitations:
Inefficient: unnecessary constraints arise from conditionals and loops
Non-reusable: every time the program changes, the circuit must be recompiled
CPU Approach
In contrast, the CPU approach introduces some overhead for instruction fetching and decoding, but Cairo minimizes this overhead through several architectural design choices.
1. Metrics-based Instruction Set Design
Cairo designs its instruction set to minimize the number of trace cells used.
For example, suppose we define two instruction sets: , which includes a specific instruction , and , which does not. Let denote the number of trace cells per cycle for instruction set , and denote the total number of cycles required to execute a program . Then, the total number of trace cells produced during execution is given by .
In general, Cairo selects an instruction set such that:
This ensures that, on average, the overall proof cost is minimized. In other words, the instruction set is chosen to optimize average proving efficiency.
2. Low-degree AIR Constraint
Cairo’s AIR (Algebraic Intermediate Representation) constraints are designed to remain mostly quadratic (degree 2). When a constraint of degree 3 is unavoidable, additional trace cells are introduced to reduce it back to degree 2 through algebraic transformation.
This approach ensures that the STARK proof system operates efficiently, maintaining low-degree polynomial constraints throughout the entire trace.
3. Builtins
If new instructions are added but rarely used, they introduce unnecessary overhead. Conversely, implementing every primitive operation purely as Cairo instructions would also be inefficient.
To resolve this trade-off, Cairo introduces the concept of builtins.
Each builtin has its own independent memory segment, and the Cairo program simply writes values into this segment to trigger the corresponding operation automatically under the AIR constraints.
For example, using a range-check builtin, one can efficiently verify that a value lies within a specific range — without introducing a new instruction.
Thus, Cairo’s builtins enable operation-level modularity that allows efficient computation through memory-based invocation rather than instruction expansion.

Nondeterminism
Consider an NP-complete problem, such as SAT, and consider the following two algorithms:
Algorithm A takes a SAT instance and a candidate assignment as input, and returns True
if the assignment satisfies the formula.
Algorithm B takes a SAT instance and iterates over all possible assignments. If it finds one that satisfies the formula, it returns True
; otherwise, it returns False
.
If a prover wants to convince a verifier that a certain SAT formula is satisfiable, either algorithm can be used — since if either one returns True
, the formula is indeed satisfiable.
Of course, Algorithm A is much more efficient, so in practice, this approach is preferred for proof construction.
This style of proving — where the prover demonstrates that Algorithm A would return True
— is called nondeterministic programming.
In other words, instead of showing the entire computation, the prover can guess a potential solution and only prove that the guess is correct. This allows the proof to be much shorter and more efficient.
Cairo supports this style of nondeterministic proving through a mechanism called “Hint.”
For example, if the computation involves , the prover does not need to show the full algorithm for computing the square root. Instead, the prover can guess a value and then prove that .
In other words, Cairo focuses on proving the correctness of results, not the process of computation, thereby significantly reducing the overall proving cost.
Register
In a typical physical computing system, memory access is expensive, so general-purpose registers are used to store frequently accessed values.
However, in Cairo, memory access is extremely cheap (See why it's cheap later), and therefore no general-purpose registers are needed. All values are accessed directly through memory cells.
Cairo provides only three address registers, which serve as pointers:
pc: Program Counter — points to the current instruction.
ap: Allocation Pointer — used to allocate new memory cells during execution.
fp: Frame Pointer — used to access function arguments and local variables. At the start of a function, is initialized to the same value as . During function execution, it remains constant, and when the function returns, it is reset to its previous value.
Instruction
Cairo’s instructions operate according to the rules described in Section 4.5. An instruction occupies one word if it has no immediate value, and two words if it includes an immediate value.

To encode an instruction, the following constraint must hold: (I'll skip the definitions of each term)
Because each term must lie within the range a permutation range-check (see Section 9.9) is required to enforce this constraint.
For this representation to be valid, Cairo also requires that:
This ensures that all 63-bit instruction words fit within the field without wrap-around or overflow.
Cairo Machine
The Cairo Machine is not a general-purpose computer designed to perform arbitrary computation. Instead, its purpose is to verify the correctness of a computation.
Cairo defines two kinds of machines:
Deterministic Cairo Machine
Non-deterministic Cairo Machine
Here, let , and is an extension field of .
Deterministic Cairo Machine
A Deterministic Cairo Machine takes the following inputs:
The number of steps
A memory function
A sequence of states , where each state is defined as
If, for every , the transition is valid according to Cairo’s transition rules, the machine outputs “accept”; otherwise, it outputs “reject.”
Example
Suppose the following input is given:
Initial state
Initial memory function :
0
0x48307ffe7fff8000
1
0x010780017fff7fff
2
-1
3
1
4
1
1. First Instruction Execution
Decoded fields:
0–16
0
16–32
-1
32–48
-2
48–49
0
49–50
0
50–53
4
53–55
1
55–58
0
58–60
2
60–63
4
According to Section 4.5 transition rules:
Hence, , and the state updates to .
2. Second Instruction Execution
Decoded fields:
0–16
-1
16–32
-1
32–48
1
48–49
1
49–50
1
50–53
1
53–55
0
55–58
2
58–60
0
60–63
0
Transition rules:
Since , we have , which means the program counter loops back to the beginning.
Thus, this program repeatedly alternates between and
3. Memory Configuration for “accept”
To be accepted, memory should be given as follows: (and it's (continuous) read-only memory)
0
0x48307ffe7fff8000
1
0x010780017fff7fff
2
-1
3
1
4
1
5
2
6
3
7
5
8
8
9
13
Non-deterministic Cairo Machine
A Non-deterministic Cairo Machine takes the following inputs:
The number of steps
A partial memory function , where
Initial and final values of program counter and allocation pointer:
(The initial frame pointer is set to .)
If we define the initial and final states as:
then, if there exists a full memory extension of such that a valid transition sequence exists, the machine accepts; otherwise, it rejects. (This is non-determinism!)
Here, represents the public memory, which includes:
Program bytecode
for
Program input/output necessary for verification
A STARK prover then constructs a proof asserting that:
“The nondeterministic Cairo Machine accepts given the input .”
Cairo Runner
The Cairo Runner executes a compiled Cairo program and produces the following outputs:
Inputs that cause the Non-deterministic Cairo Machine to accept:
Inputs that cause the Deterministic Cairo Machine to accept:
While the Cairo Machine supports random-access memory by definition, an efficient Cairo AIR implementation requires that memory accesses be continuous in address order.
To achieve this, the Cairo Runner introduces the concept of relocatable memory segments.
Memory Segment Management
Whenever memory allocation is required during program execution, the Cairo Runner creates and assigns a new memory segment.
The size of each segment does not need to be specified in advance.
After program execution finishes, the Runner performs a relocation phase, where each segment is assigned a concrete base address so that the entire memory space can be linearized into one continuous address range.
Relocation Is Not Proven
The relocation process is not included in the proof. It is performed locally by the Cairo Runner and does not appear in the STARK proof itself.
In a read-write memory model, this could be problematic — a malicious prover could intentionally create overlapping segments, causing one segment’s write operation to inadvertently change the value in another segment.
Why This Is Safe in Cairo
In Cairo, memory is read-only (immutable). Once a value is written, it cannot be modified.
Therefore, even if two segments overlap, it does not matter which segment a value is read from — as long as the value itself is consistent.
In other words, as far as the Cairo execution model is concerned, overlapping segments and non-overlapping segments are indistinguishable.
Memory Layout
Function Call Stack
Function arguments provided by the caller are stored at memory addresses
Pointer to the caller’s frame is stored at
Return address — the instruction to be executed after the function returns — is stored at
Local variables allocated by the function are stored at
Additionally, function return values are stored in memory at , where is the value of the allocation pointer at the end of the function.

The figure above illustrates the call stack for the following code:
f:
call g
ret
g:
call h
call h
ret
h:
ret
Nondeterministic Continuous Read-Only Random-Access Memory
Description
Cairo implements a Nondeterministic Continuous Read-Only Random-Access Memory model. In this model, memory is read-only — once written, values cannot be modified — and memory accesses must be contiguous.
What does “contiguous” mean? It means:
If ,
and there is a memory access at ,
and there is a memory access at ,
then there must also exist a memory access at every address such that .
In this model, the cost depends on the number of memory accesses, not on how much total memory is used. Therefore, developers do not need to worry about freeing or reusing memory cells.
Constraints
Let
be two lists of memory accesses.
The following constraints ensure Cairo’s continuous, read-only memory behavior:
Continuity
→ Ensures consecutive addresses differ by exactly 1.
Single-valuedness
→ Ensures that if two accesses share the same address, their values must be identical.
Permutation
The permutation argument enforces that the two memory access lists correspond to the same mapping.
Initial value
Final value
Cumulative product step
If these constraints hold, forms a continuous read-only memory.
Summary
Each memory access uses five trace cells:
Each instruction performs three memory accesses:
Public Memory
Description
The program’s input, output, and bytecode that are required for verification must be shared with the verifier. These are provided as part of the input to the Non-deterministic Cairo Machine.
The prover must then demonstrate the existence of an extended memory function that is consistent with .
Constraints
Append pairs of to , and append to .
Modify the final value constraint as follows:
This ensures that the public memory is properly incorporated into the permutation argument used to verify memory consistency.
Program Input & Output
Program input: The data that serves as the program’s input. This data does not need to be shared with the verifier.
Program output: The data produced during program execution. This data is shared with the verifier.
For example, suppose the program input is , and the goal is to compute the -th Fibonacci number. Depending on how the program output is defined, the proof statement differs:
both and
“The -th Fibonacci number is .”
only
“I know some such that the -th Fibonacci number is .” (but is not revealed)
only
“I have computed the -th Fibonacci number.” (but the result is hidden)
Conclusion
Cairo demonstrates how a universal, proof-friendly CPU architecture can bridge the gap between programmability and efficiency in zero-knowledge proving systems.
Unlike ASIC-style zkDSLs, which generate a dedicated circuit for each program, Cairo models computation at the CPU level — allowing any program to be proven on the same proving system. This shift from “program-specific circuits” to “program-verifying machines” is what makes Cairo fundamentally scalable and expressive.
Reference
Last updated