|
LLZK 3.0.0
An open-source IR for Zero Knowledge (ZK) circuits
|
Allows LLZK to be lowered to PCL (Picus Constraint Language) for use with the Picus verifier
PCL
Field addition
Syntax:
Traits: AlwaysSpeculatableImplTrait, Commutative, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Finite field element |
| rhs | Finite field element |
| Result | Description |
|---|---|
| result | Finite field element |
Boolean conjunction (lhs && rhs)
Syntax:
Traits: AlwaysSpeculatableImplTrait, Commutative, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Boolean in {0,1} |
| rhs | Boolean in {0,1} |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Bool to felt conversion
Syntax:
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| value | Boolean in {0,1} |
| Result | Description |
|---|---|
| result | Finite field element |
Assert that a boolean holds
Syntax:
| Operand | Description |
|---|---|
| cond | Boolean in {0,1} |
Assume the given value is deterministic
Syntax:
| Operand | Description |
|---|---|
| v | Finite field element |
Constant felt
Syntax:
Traits: AlwaysSpeculatableImplTrait, ConstantLike
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Attribute | MLIR Type | Description |
|---|---|---|
value | ::pcl::FeltAttr | Field element represented as an arbitrary precision integer |
| Result | Description |
|---|---|
| res | Finite field element |
Returns true iff $expr deterministic
Syntax:
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| value | Finite field element |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Lhs == rhs (field equality)
Syntax:
Traits: AlwaysSpeculatableImplTrait, Commutative
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Finite field element |
| rhs | Finite field element |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Constant false value
Syntax:
Traits: AlwaysSpeculatableImplTrait, ConstantLike
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Result | Description |
|---|---|
| res | Boolean in {0,1} |
Lhs >= rhs
Syntax:
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Finite field element |
| rhs | Finite field element |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Lhs > rhs
Syntax:
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Finite field element |
| rhs | Finite field element |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Boolean equivalence (lhs <=> rhs)
Syntax:
Traits: AlwaysSpeculatableImplTrait, Commutative, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Boolean in {0,1} |
| rhs | Boolean in {0,1} |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Boolean implication (lhs => rhs)
Syntax:
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Boolean in {0,1} |
| rhs | Boolean in {0,1} |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Lhs <= rhs
Syntax:
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Finite field element |
| rhs | Finite field element |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Lhs < rhs
Syntax:
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Finite field element |
| rhs | Finite field element |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Field multiplication
Syntax:
Traits: AlwaysSpeculatableImplTrait, Commutative, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Finite field element |
| rhs | Finite field element |
| Result | Description |
|---|---|
| result | Finite field element |
Field negation
Syntax:
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| value | Finite field element |
| Result | Description |
|---|---|
| result | Finite field element |
Boolean negation (!cond)
Syntax:
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| value | Boolean in {0,1} |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Boolean disjunction (lhs || rhs)
Syntax:
Traits: AlwaysSpeculatableImplTrait, Commutative, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Boolean in {0,1} |
| rhs | Boolean in {0,1} |
| Result | Description |
|---|---|
| result | Boolean in {0,1} |
Post-condition on function outputs
Syntax:
| Operand | Description |
|---|---|
| cond | Boolean in {0,1} |
Field subtraction
Syntax:
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Operand | Description |
|---|---|
| lhs | Finite field element |
| rhs | Finite field element |
| Result | Description |
|---|---|
| result | Finite field element |
Constant true value
Syntax:
Traits: AlwaysSpeculatableImplTrait, ConstantLike
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Result | Description |
|---|---|
| res | Boolean in {0,1} |
Declare a felt variable.
Syntax:
The var op creates a new variable associated with a name. It additionally takes a parameter is_output which indicates an output variable if true and an intermediate otherwise.
Example:
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::StringAttr | string attribute |
is_output | ::mlir::BoolAttr | bool attribute |
| Result | Description |
|---|---|
| res | Finite field element |
Field element represented as an arbitrary precision integer
Syntax:
| Parameter | C++ type | Description |
|---|---|---|
| value | llzk::DynamicAPIntValue | felt constant value |
Boolean value
Syntax:
| Parameter | C++ type | Description |
|---|---|---|
| value | bool |
Prime field modulus for this module
Syntax:
Attach this as a named attribute (e.g. pcl.prime) on builtin.module. Use a signed arbitrary-precision literal so very large primes are supported.
| Parameter | C++ type | Description |
|---|---|---|
| value | llzk::DynamicAPIntValue | field prime modulus |
Boolean in {0,1}
Syntax: !pcl.bool
Finite field element
Syntax: !pcl.felt
Run llzk-opt input.llzk --llzk-full-pcl-lowering to normalize while loops, canonicalize loop bounds, flatten templates and unroll loops rooted at llzk.main, then scalarize PODs and arrays before converting to PCL. Canonicalization also runs after flattening and scalarization. Common subexpression elimination runs before and after POD/array scalarization, followed by redundant read/write elimination before PCL conversion.
This pipeline preserves component boundaries; it does not inline structs or free functions. Existing PCL restrictions still apply, including the requirement that each struct has a public output. In particular, assertion-only components and a main component with no public outputs still require separate handling.
Use --llzk-to-pcl directly when the input has already been prepared.
When PCL is enabled, C clients can append the pipeline to a module pass manager with llzkBuildFullPCLLoweringPipeline. Alternatively, call llzkRegisterPCLConversionPassPipelines and parse builtin.module(llzk-full-pcl-lowering) with mlirParsePassPipeline.
PCL felt constants and prime moduli use signed arbitrary-precision integers. Arithmetic intermediates grow as needed and are reduced modulo the module's prime. Literal storage widths have no semantic meaning. During LLZK-to-PCL conversion, the prime modulus is inferred from the felt types used across the circuit and stored in the top-level module's pcl.prime attribute. Conversion requires a single field for the entire circuit. Its value must be at least two; the PCL verifier does not check primality.