Descripción General de Programación de Circuitos
Achronyme es un lenguaje de modo dual. El mismo código fuente puede ejecutarse como un programa de propósito general o compilarse en un circuito aritmético para pruebas de conocimiento cero.
¿Qué es un Circuito?
Sección titulada «¿Qué es un Circuito?»Un circuito ZK es un sistema de restricciones polinomiales sobre un campo finito. Dadas entradas públicas (conocidas por el verificador) y entradas testigo (conocidas solo por el probador), el circuito fuerza que ciertas relaciones se cumplan — sin revelar el testigo.
En Achronyme, escribes circuitos usando la misma sintaxis que los programas regulares, con algunas restricciones.
Dos Formas de Construir Circuitos
Sección titulada «Dos Formas de Construir Circuitos»1. Archivo de circuito independiente
Sección titulada «1. Archivo de circuito independiente»circuit hash_check(output: Public, secret: Witness) { assert_eq(poseidon(secret, 0), output)}Compila con el CLI:
ach circuit hash.ach --inputs "output=17159...,secret=42"2. Bloque prove en línea
Sección titulada «2. Bloque prove en línea»let secret = 0p42let hash = 0p17159...
let p = prove(hash: Public) { assert_eq(poseidon(secret, 0), hash)}El bloque prove captura variables del ámbito, compila el cuerpo como un circuito vía ProveIR en tiempo de compilación, y genera una prueba en tiempo de ejecución. Las variables declaradas como name: Public son entradas públicas; las demás variables del ámbito externo se infieren automáticamente como testigos privados.
Qué Funciona en Circuitos
Sección titulada «Qué Funciona en Circuitos»| Característica | Comportamiento |
|---|---|
Aritmética (+, -, *, /, ^) | Se compila a operaciones de campo y restricciones |
Vinculaciones let | Alias (costo cero) |
if/else | Se compila a mux — ambas ramas se evalúan |
Bucles for (rango o array) | Desenrollado estático |
Llamadas fn | Se insertan en línea en cada punto de llamada |
| Anotaciones de tipo | Tipos opcionales Field/Bool en declaraciones y vinculaciones |
assert_eq(a, b) | Fuerza a == b (1 restricción) |
poseidon(a, b) | Hash Poseidon 2-a-1 (361 restricciones) |
range_check(x, bits) | El valor cabe en N bits |
Comparaciones (==, !=, <, <=, >, >=) | Gadgets seguros para campo |
Lógica booleana (&&, ||, !) | Con verificación booleana |
Qué No Funciona en Circuitos
Sección titulada «Qué No Funciona en Circuitos»| Característica | Razón |
|---|---|
Bucles while | Conteo de iteraciones desconocido — no se puede desenrollar |
break / continue | Requiere flujo de control dinámico |
print() | Efecto secundario, sin equivalente en circuito |
| Cadenas, mapas | No representables como elementos de campo |
| Recursión | Las funciones se insertan en línea, sin pila |
Estos se rechazan en tiempo de compilación con mensajes de error claros.
Pipeline de Compilación
Sección titulada «Pipeline de Compilación»Fuente → Parser → AST → Bajada a IR → SSA IR → Optimizar → Backend → Restricciones- Parsear — La gramática PEG produce un AST
- Bajar — El AST se convierte en instrucciones SSA planas (
Add,Mul,Mux,PoseidonHash, …) - Optimizar — Plegado de constantes, eliminación de código muerto, propagación booleana
- Compilar — El backend R1CS o Plonkish genera restricciones
- Testigo — Los valores concretos llenan el sistema de restricciones
- Exportar — Archivos binarios
.r1cs+.wtns(R1CS) o verificación en memoria (Plonkish)
Backends
Sección titulada «Backends»Achronyme soporta dos backends de sistema de restricciones:
R1CS (predeterminado) — Sistema de Restricciones de Rango 1. Cada restricción es A * B = C donde A, B, C son combinaciones lineales de cables. Compatible con Groth16 vía snarkjs.
Plonkish — Sistema basado en puertas con puertas personalizadas, lookups y restricciones de copia. Usa compromisos polinomiales KZG. Algunas operaciones (como range_check) son más eficientes con lookups.
Selecciona el backend con --backend:
ach circuit file.ach --backend plonkish --inputs "x=42"