How ZisK Enforces Cross-Component Interaction with Arguments
How ZisK's components (CPU, memory, ALU…) stay consistent: cross-AIR arguments reduced to sumchecks via LogUp, with each component's partial sums combined through proof aggregation.
ZisK is a zero-knowledge virtual machine (zkVM) that proves the correct execution of programs compiled to the RISC-V instruction set. To achieve this, ZisK arithmetizes an entire computing system (CPU, ALU, memory, and other functional units) into a collection of modular components.
Each component is constrained based on an Algebraic Intermediate Representation (AIR) using the PIL2 language, which specifies the polynomial constraints that govern the component’s behavior. In this document, we use the terms component and AIR interchangeably: a component refers to the logical unit (e.g., the CPU or memory), while its AIR refers to the corresponding set of polynomial constraints.
Components operate independently but must interact consistently. For example, when the CPU executes a memory load instruction, it must receive the correct value from the memory component. These cross-component interactions are enforced via arguments, which are non-identity constraints that establish relationships between values across different AIRs.
This document describes the argument system used in ZisK, how arguments are reduced to sumchecks via the LogUp protocol, and how proof aggregation combines partial results from independent components into a single, globally consistent proof.
Preliminaries
Let be a finite field of prime order such that for some integer . Set , and let be a multiplicative subgroup of order .
An expression is a multivariate polynomial over , where each variable represents a univariate polynomial in (i.e., a polynomial of degree strictly less than ). Given such an expression, we obtain a univariate polynomial via the natural evaluation , where are the polynomials corresponding to .
A selector is an expression satisfying for all .
Given expressions , an argument is a constraint on the values that cannot be expressed as a polynomial identity. Arguments establish relationships between selected subsets of evaluations over .
Arguments
In ZisK, we mainly employ four types of arguments:
-
Permutation: Given two tuples of expressions and , where and are selectors, a permutation argument asserts that where denotes a multiset. That is, the selected rows form the same multiset (equality up to reordering).
-
Connection (Copy Constraint): Given expressions and a permutation , a connection argument asserts that for all : for specified pairs . This enforces that certain cells across (potentially different) columns contain identical values.
-
Lookup: Given expressions and a table (either fixed or defined by expressions with selector ), a lookup argument asserts that for all with : That is, every selected row in the source appears (at least once) in the table.
-
Range Check: Given expressions and bounds with , a range check argument asserts that for all with : This is typically implemented as a special case of a lookup into a precomputed range table .
The complete list of arguments and variations can be found in the PIL2 STD Lib.
Reduction to Sumcheck
Each component (AIR) in ZisK can have multiple arguments. All arguments within a component are reduced to a single univariate sumcheck via the LogUp protocol. For example, a range check is reduced by checking that:
where for , and for . Here, counts the multiplicity of each value in the range (i.e., how many times it was looked up).
Batching Vectors of Expressions
When an argument involves a vector of expressions rather than a single expression, we use a random linear combination (RLC) to batch them into a single value. Given a random challenge , we compute:
This reduces a lookup over -tuples to a lookup over single field elements, preserving soundness with high probability over the random choice of .
Preventing Cross-Argument Cancellation
A critical question arises: how do we prevent terms from multiple, presumably independent, arguments from canceling each other? If such cancellation were possible, a malicious prover could construct a valid overall sumcheck even when individual arguments are incorrect.
To address this, we introduce a unique identifier (UID) for each argument. Each argument is associated with a unique identifier , a known field element that is incorporated into the sumcheck via a RLC.
Following with the range check example, we transform the input expressions as:
The sumcheck reduction is then applied to and instead of the original expressions.
For arguments involving vectors of expressions , the UID is incorporated into the same RLC used for batching:
By placing the UID as the constant term, we ensure that each argument’s contribution to the sumcheck is tagged with its unique identifier, preventing malicious cancellation across independent arguments.
Cross-Component Consistency
Recall that ZisK arithmetizes a complete computing system as a collection of independent components. Each component is defined by its own AIR, and consistency between components is enforced via shared arguments.
For example, the CPU component processes the sequence of instructions in a program. When it executes a memory operation, it “requests” the result from the memory component via a lookup argument. The CPU commits to the input/output tuple of the operation, and the memory component must later prove that this tuple corresponds to a valid memory access. The complete list of ZisK components can be found here.
Partial Sumchecks Across Components
A consequence of this modular design is that arguments with the same UID can be invoked from different arithmetization components. Therefore, a single component might not be able to certify the full sumcheck between the input expressions of an argument:
Instead, each component proves the result of a partial sum:
where is the field element that the prover claims as the result of the partial summation over the subgroup corresponding to component.
Aggregating Partial Sums via Proof Composition
ZisK uses proof aggregation to combine these partial results into a complete verification. The process works as follows:
-
Leaf proofs: Each arithmetization component independently generates a proof that includes its partial sum as a public output.
-
Aggregation tree: These leaf proofs are combined in a tree structure. At each level, an aggregation circuit:
- Verifies the child proofs
- Adds together the partial sums:
- Outputs the accumulated sum for the next level
-
Root verification: At the top of the aggregation tree, the final accumulated sums are checked to satisfy the original sumcheck equation. The verifier checks:
where are the partial sums from components sending values (e.g., the CPU requesting memory operations) and are the partial sums from components receiving values (e.g., the memory component fulfilling those requests).
This hierarchical aggregation ensures that even though individual components only prove local consistency, the global correctness of all cross-component interactions is verified at the root level, without requiring any single componente to handle the entire computation.
Appendix
The Degree Dilemma
Once all arguments within a component have been reduced via RLC, a grand-sum polynomial is constructed to satisfy for all :
where are the Lagrange basis polynomials at and , respectively, and is a known field element.
The problem is that the first constraint has unbounded degree due to the sum of rational expressions, and every proving system imposes a bound on the constraint degree.
Intermediate Polynomials
ZisK resolves this by introducing intermediate polynomials that decompose the sum of rational expressions into bounded-degree pieces. Given the previous sum, we generate intermediate polynomials such that:
Each aggregates a subset of terms. Let be a partition of . Depending on which form yields a lower-degree constraint, each intermediate is defined either as:
or in inverse form:
The partition is chosen so that all resulting constraints respect the degree bound. More details can be found in the PIL Standard Library.
Complete Constraint Set
With intermediate polynomials, the complete set of constraints becomes:
The key insight is that by clearing denominators in the intermediate definitions, each constraint becomes a polynomial identity of bounded degree. The partition is chosen such that:
where is the maximum allowable constraint degree in the proving system. This transforms the original unbounded-degree rational constraint into a collection of bounded-degree polynomial constraints.