achronyme/achronyme

GitHub: achronyme/achronyme

一门支持双执行模式的零知识电路编程语言,可用同一份代码进行通用执行和 ZK 电路编译,内置证明生成与 Solidity 合约导出。

Stars: 5 | Forks: 0

# 缩写 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/538762407b165850.svg)](https://github.com/achronyme/achronyme/actions/workflows/ci.yml) [![Deploy Docs](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/0a3be27225165901.svg)](https://github.com/achronyme/achronyme/actions/workflows/docs.yml) 一种用于零知识电路的编程语言。 编写可读的代码。决定证明的内容。通用执行和 ZK 电路编译使用同一种语言。 ## 安装 ``` curl -fsSL https://achrony.me/install.sh | sh ``` 这会将 `ach` 二进制文件安装到 `~/.local/bin`。需要 Linux 或 macOS(x86_64 或 aarch64)。 ### 从源码构建 ``` git clone https://github.com/achronyme/achronyme.git cd achronyme cargo build --release cargo test --workspace # 2,000+ unit tests bash test/run_tests.sh # 150+ integration tests ``` ## 快速预览 ### 通用执行 ``` let make_counter = fn(init) { mut n = init return fn() { n = n + 1; return n } } let c = make_counter(0) print(c()) // 1 print(c()) // 2 ``` ### ZK 电路 ``` public root witness leaf witness path[3] witness indices[3] merkle_verify(root, leaf, path, indices) ``` ``` ach circuit merkle.ach --inputs "root=...,leaf=42,path_0=...,path_1=...,path_2=...,indices_0=0,indices_1=1,indices_2=0" # → circuit.r1cs + witness.wtns (兼容 snarkjs) ``` ### 内联证明生成 ``` let secret = 0p42 let hash = 0p17159... // poseidon(42, 0) let p = prove { witness secret public hash assert_eq(poseidon(secret, 0), hash) } print(proof_json(p)) // Groth16 proof, verifiable on-chain ``` ## 工作原理 Achronyme 从同一源码支持两种执行模式: **VM 模式** (`ach run`) —— 完整语言:闭包、递归、GC、数组、map、字符串、I/O。代码像任何脚本语言一样运行。 **电路模式** (`ach circuit`) —— 编译为 BN254 上的算术约束。运行时无循环,无 I/O —— 一切都被展开并扁平化为用于零知识证明的约束系统。 `prove {}` 块连接两者:它在 VM 内运行,将其主体编译为电路,从捕获的变量生成 witness,并产生加密证明 —— 所有这些都在一个表达式中完成。 ``` Source (.ach) │ ├─► Parser (Pratt) → AST │ │ │ ├─► Bytecode → VM (run mode) │ │ │ └─► SSA IR → Optimize │ │ │ ┌───┴───┐ │ ▼ ▼ │ R1CS Plonkish │ (Groth16) (KZG-PlonK) │ │ │ │ ▼ ▼ │ .r1cs Gates/Lookups │ .wtns Copy constraints │ │ │ │ └───┬───┘ │ ▼ │ Native proof │ └─► prove { } → compile + witness + verify + proof (inline) ``` ## 语言 ### 类型 | Type | Examples | |------|---------| | Int | `42`, `-7` | | Bool | `true`, `false` | | String | `"hello"` | | List | `[1, 2, 3]` | | Map | `{"a": 1, "b": 2}` | | Field | `0p42`, `0pxFF`, `0pb1010` | | BigInt256 | `0i256xFF`, `0i256d42` | | BigInt512 | `0i512xFF`, `0i512d100` | | Function | `fn(x) { x + 1 }` | | Proof | result of `prove { }` | | Nil | `nil` | ### 控制流 ``` if x > 0 { print("positive") } else { print("non-positive") } while n > 0 { n = n - 1 } for item in list { print(item) } for i in 0..10 { print(i) } ``` ### 函数与闭包 ``` let add = fn(a, b) { a + b } let fib = fn fib(n) { if n < 2 { return n } return fib(n - 1) + fib(n - 2) } // Closures capture environment let make_adder = fn(x) { fn(y) { x + y } } let add5 = make_adder(5) print(add5(3)) // 8 ``` ### 域元素 BN254 标量域。内部为 Montgomery 形式。使用 `0p` 前缀创建: ``` let a = 0p42 let b = 0pxFF let c = 0pb1010 let sum = a + b let prod = a * b let inv = 0p1 / a ``` ### BigInt(仅限 VM) 用于加密操作的固定宽度无符号整数(256 位和 512 位): ``` let a = 0i256xFF let b = bigint256(42) let bits = a.to_bits() let masked = a.bit_and(b) ``` ## 电路特性 ### 声明 ``` public output // public input (instance) witness secret // private input (witness) witness arr[4] // witness array (arr_0, arr_1, arr_2, arr_3) ``` ### 内置函数 | Builtin | Description | R1CS cost | Plonkish cost | |---------|-------------|-----------|---------------| | `assert_eq(a, b)` | 强制相等 | 1 | 1 | | `assert(expr)` | 强制布尔值为真 | 2 | 2 | | `poseidon(a, b)` | Poseidon 2 对 1 哈希 | 361 | 361 | | `poseidon_many(a, b, c, ...)` | 左折叠 Poseidon | 361*(n-1) | 361*(n-1) | | `mux(cond, a, b)` | 条件选择 | 2 | 1 | | `range_check(x, bits)` | 值适合 N 位 | bits+1 | 1 (lookup) | | `merkle_verify(root, leaf, path, indices)` | Merkle 成员证明 | ~1090/level | ~1090/level | | `len(arr)` | 编译时数组长度 | 0 | 0 | ### 电路中的运算符 | Operation | R1CS | Plonkish | |-----------|------|----------| | `+`, `-` | 0 | 0 | | `*` | 1 | 1 | | `/` | 2 | 2 | | `^` (constant exp) | O(log n) | O(log n) | | `==`, `!=` | 2 | 2 | | `<`, `<=`, `>`, `>=` | ~760 | ~760 | | `&&`, `\|\|` | 3 | 3 | | `!` | 1 | 1 | ### 电路中的函数 函数在每个调用点内联。无动态分发,无递归。 ``` witness a, b public out fn hash_pair(x, y) { poseidon(x, y) } assert_eq(hash_pair(a, b), out) ``` ### 电路中的控制流 `if/else` 编译为 `mux`(两个分支都会被求值)。`for` 循环静态展开。`while`、`break`、`continue` 会在编译时被拒绝。 ``` witness vals[4] public total let sum = vals[0] let sum = sum + vals[1] let sum = sum + vals[2] let sum = sum + vals[3] assert_eq(sum, total) ``` ## CLI ``` # 运行程序 ach run script.ach # 使用 PlonK prove 后端运行 ach run script.ach --prove-backend plonkish # 编译 circuit (源码内声明) ach circuit circuit.ach --inputs "x=42,y=7" # 编译 circuit (CLI 声明) ach circuit circuit.ach --public "out" --witness "a,b" --inputs "out=42,a=6,b=7" # Plonkish 后端 ach circuit circuit.ach --backend plonkish --inputs "x=42,y=7" # 生成 Plonkish 证明 ach circuit circuit.ach --backend plonkish --inputs "x=42" --prove # 生成 Solidity verifier 合约 ach circuit circuit.ach --inputs "x=42,y=7" --solidity # 编译为 bytecode ach compile script.ach --output script.achb # 反汇编 ach disassemble script.ach ``` 输出的 `.r1cs` 和 `.wtns` 文件与 snarkjs 兼容: ``` snarkjs groth16 setup circuit.r1cs pot12_final.ptau circuit.zkey snarkjs groth16 prove circuit.zkey witness.wtns proof.json public.json snarkjs groth16 verify verification_key.json public.json proof.json ``` ## 证明块 `prove {}` 编译电路,从封闭作用域捕获变量,生成 witness,并返回证明 —— 全部内联完成。 ``` let a = 0p6 let b = 0p7 let product = 0p42 let p = prove { witness a witness b public product assert_eq(a * b, product) } ``` `public`/`witness` 声明中的变量名必须与外部作用域中的 `let` 绑定匹配。整数值会自动提升为域元素。 结果是一个 `Proof` 对象(根据 `--prove-backend` 是 Groth16 或 PlonK)。使用 `proof_json(p)`、`proof_public(p)`、`proof_vkey(p)` 提取组件。使用 `verify_proof(p)` 进行验证。 如果没有可用的证明后端,该块仍会编译电路、生成 witness 并在本地验证约束(返回 `nil`)。 ## 优化遍 SSA IR 在生成约束之前运行四遍优化: - **常量折叠** —— 在编译时计算已知常量的算术运算 - **死代码消除** —— 移除未使用的指令 - **布尔传播** —— 跟踪已证明的布尔变量,跳过冗余强制 - **污点分析** —— 警告约束不足或未使用的输入 使用 `--no-optimize` 禁用。 ## 项目结构 ``` achronyme/ ├── achronyme-parser/ Hand-written Pratt lexer + recursive descent parser ├── ir/ SSA intermediate representation, optimization passes ├── compiler/ Bytecode compiler, R1CS backend, Plonkish backend ├── vm/ Register-based VM (37 opcodes, prototype method dispatch) ├── memory/ Heap, GC, FieldElement (BN254 Montgomery), BigInt ├── constraints/ R1CS/Plonkish systems, Poseidon hash, binary export ├── cli/ CLI, native Groth16 (ark-groth16) & PlonK (halo2-KZG) ├── std/ Standard library (NativeModule: parse_int, join, I/O) ├── ach-macros/ Proc-macros: #[ach_native], #[ach_module] ├── docs/ Documentation site (Astro + Starlight, 83 pages, EN/ES) └── test/ ├── vm/ VM/interpreter integration tests ├── circuit/ Circuit compilation tests ├── prove/ Prove block tests └── run_tests.sh Integration test runner (158 tests) ``` ## 全局函数 无需导入即可使用 16 个全局函数。大多数操作现在使用[方法语法](#methods)。 | Function | Arity | Description | |----------|-------|-------------| | `print(...)` | variadic | 打印值到 stdout | | `typeof(x)` | 1 | 类型名称作为 String | | `assert(x)` | 1 | 运行时断言 | | `time()` | 0 | Unix 时间戳 | | `gc_stats()` | 0 | GC 统计信息作为 map | | `poseidon(a, b)` | 2 | Poseidon 2 对 1 哈希 (BN254) | | `poseidon_many(a, b, ...)` | variadic | 左折叠 Poseidon 哈希 | | `verify_proof(p)` | 1 | 验证 Groth16 证明 | | `proof_json(p)` | 1 | 提取证明 JSON | | `proof_public(p)` | 1 | 提取公开输入 JSON | | `proof_vkey(p)` | 1 | 提取验证密钥 JSON | | `bigint256(x)` | 1 | 构造 256 位无符号整数 | | `bigint512(x)` | 1 | 构造 512 位无符号整数 | | `from_bits(bits, width)` | 2 | 位列表转 BigInt | | `parse_int(str)` | 1 | 解析字符串为整数 | | `join(list, sep)` | 2 | 用分隔符连接字符串 | ## 方法 值具有使用点语法调用的特定类型方法:`value.method(args)`。 ``` // String methods let upper = "hello".to_upper() // "HELLO" let words = "a,b,c".split(",") // ["a", "b", "c"] // List methods let doubled = [1, 2, 3].map(fn(n) { n * 2 }) // [2, 4, 6] let evens = [1, 2, 3, 4].filter(fn(n) { n % 2 == 0 }) // [2, 4] // Map methods let m = {name: "Alice", age: 30} assert(m.contains_key("name")) m.set("city", "NYC") // Int methods assert((-42).abs() == 42) assert(2.pow(10) == 1024) ``` 跨 6 种类型的 **50 个方法**:Int (6)、String (14)、List (13)、Map (8)、Field (2)、BigInt (7)。 **静态命名空间** 提供类型级常量:`Int::MAX`、`Int::MIN`、`Field::ZERO`、`Field::ONE`、`Field::ORDER`、`BigInt::from_bits`。 ## 状态 - 2,125+ 单元测试 + 158 集成测试 - 与 snarkjs 交叉验证(独立约束验证) - 2 个 ZK 后端:R1CS/Groth16 + Plonkish/KZG-PlonK - 原生进程内证明生成(无需外部工具) - 兼容 snarkjs 的二进制导出 - Solidity 验证合约生成 - Poseidon 哈希兼容 circomlibjs - 带源代码行号的运行时错误 - [文档](https://docs.achrony.me) ## 许可证 GPL-3.0
标签:Android, BN254, DSL, Groth16, R1CS, Rust, Web3, ZKP, zkSNARKs, 全同态加密, 区块链开发, 去中心化, 可视化界面, 密码学, 手动系统调用, 智能合约, 生成式AI安全, 电路编译, 编程语言, 编译器, 网络流量审计, 虚拟机, 通知系统, 隐私计算, 零知识证明, 默克尔树