Circuit Programming Overview
Achronyme is a dual-mode language. The same source code can run as a general-purpose program or compile into an arithmetic circuit for zero-knowledge proofs.
What Is a Circuit?
Section titled “What Is a Circuit?”A ZK circuit is a system of polynomial constraints over a finite field. Given public inputs (known to the verifier) and witness inputs (known only to the prover), the circuit enforces that certain relationships hold — without revealing the witness.
In Achronyme, you write circuits using the same syntax as regular programs, with a few restrictions.
Two Ways to Build Circuits
Section titled “Two Ways to Build Circuits”1. Standalone circuit file
Section titled “1. Standalone circuit file”public outputwitness secret
assert_eq(poseidon(secret, 0), output)Compile with the CLI:
ach circuit hash.ach --inputs "output=17159...,secret=42"2. Inline prove {} block
Section titled “2. Inline prove {} block”let secret = field(42)let hash = field("17159...")
let p = prove { witness secret public hash assert_eq(poseidon(secret, 0), hash)}The prove {} block runs inside the VM, captures variables from scope, compiles the body as a circuit, and generates a proof.
What Works in Circuits
Section titled “What Works in Circuits”| Feature | Behavior |
|---|---|
Arithmetic (+, -, *, /, ^) | Compiles to field operations and constraints |
let bindings | Aliases (zero cost) |
if/else | Compiles to mux — both branches evaluated |
for loops (range or array) | Statically unrolled |
fn calls | Inlined at each call site |
assert_eq(a, b) | Enforces a == b (1 constraint) |
poseidon(a, b) | Poseidon 2-to-1 hash (361 constraints) |
range_check(x, bits) | Value fits in N bits |
Comparisons (==, !=, <, <=, >, >=) | Field-safe gadgets |
Boolean logic (&&, ||, !) | With boolean enforcement |
What Doesn’t Work in Circuits
Section titled “What Doesn’t Work in Circuits”| Feature | Reason |
|---|---|
while loops | Unknown iteration count — can’t unroll |
break / continue | Requires dynamic control flow |
print() | Side effect, no circuit equivalent |
| Strings, maps | Not representable as field elements |
| Recursion | Functions are inlined, no stack |
These are rejected at compile time with clear error messages.
Compilation Pipeline
Section titled “Compilation Pipeline”Source → Parser → AST → IR Lowering → SSA IR → Optimize → Backend → Constraints- Parse — PEG grammar produces an AST
- Lower — AST becomes flat SSA instructions (
Add,Mul,Mux,PoseidonHash, …) - Optimize — Constant folding, dead code elimination, boolean propagation
- Compile — R1CS or Plonkish backend generates constraints
- Witness — Concrete values fill the constraint system
- Export — Binary
.r1cs+.wtnsfiles (R1CS) or in-memory verification (Plonkish)
Backends
Section titled “Backends”Achronyme supports two constraint system backends:
R1CS (default) — Rank-1 Constraint System. Each constraint is A * B = C where A, B, C are linear combinations of wires. Compatible with Groth16 via snarkjs.
Plonkish — Gate-based system with custom gates, lookups, and copy constraints. Uses KZG polynomial commitments. Some operations (like range_check) are more efficient with lookups.
Select the backend with --backend:
ach circuit file.ach --backend plonkish --inputs "x=42"