Small interpreter for a subset of LLZK.
Yes, this interpreter was vibecoded.
Implemented runtime support includes:
felt:const,add,sub,mul,div,uintdiv,umod,neg,bit_and,bit_or,bit_xor,shl,shr,powbool:cmp,and,or,not,assertconstrain.eqfunction.call,function.returnstruct.new,struct.readm,struct.writemarith:constant(forindex,i1, and arbitrary-widthiN)- arithmetic:
addi,subi,muli,divsi,divui,remsi,remui,ceildivsi,ceildivui,floordivsi - bitwise/shift:
andi,ori,xori,shli,shrsi,shrui - min/max:
maxsi,maxui,minsi,minui - comparison:
cmpi(all 10 predicates:eq,ne,slt,sle,sgt,sge,ult,ule,ugt,uge) - casts:
extsi,extui,trunci,index_cast,index_castui select
cast.toindex,cast.tofeltarray.new,array.read,array.writeram.load,ram.store(flat felt memory; unwritten cells read as zero)scf.if,scf.while,scf.condition,scf.yieldllzk.nondet(resolved from a pre-supplied FIFO queue viaInterpreter::set_nondet_values, falls back to zero when empty)
By default, the binary runs @compute and then @constrain:
llzk-interpreter <file.llzk> <struct_name> [felt_arg_decimals...]Explicit modes are also available:
llzk-interpreter check <file.llzk> <struct_name> [felt_arg_decimals...]
llzk-interpreter compute <file.llzk> <struct_name> [felt_arg_decimals...]check is the default mode. It prints the computed struct and then verifies
that @constrain succeeds for the same inputs.
Example:
cargo run -- path/to/program.llzk Circuit0 1 2 3Compute-only example:
cargo run -- compute path/to/program.llzk Circuit0 1 2 3Common targets:
make build
make test
make lint
make fmtOn macOS, the local scripts/build-macos.sh helper sets the LLVM / SDK /
Homebrew-related environment expected by the Rust LLZK bindings.
This interpreter is intentionally narrow. It aims to cover the LLZK surface
used by noir_llzk today, not every LLZK dialect operation or every possible
frontend lowering.