Plonk Script - Plonkish Rust-like 有 Halo2/Plonky3 - CIRCOM IDEN3 R1CS C-like 有 - - ZoKrates - R1CS Python-like 有 - - CirC - R1CS C/ZoKrates 有 - - SnarkyJs Mina R1CS Typescript 有 - - Leo Aleo R1CS Rust-like 有 - - Noir Aztec R1CS Rust-like 有 抽象出ACIR的中间表达(trace),后续后端自选 - use dep::std;
fn main (
root: pub Field,
index: Field,
hash_path: [Field; 2 ],
secret: Field,
proposalId: pub Field,
vote: pub Field
) -> pub Field {
let note_commitment = std::hash::pedersen_hash ([secret]);
let nullifier = std::hash::pedersen_hash ([root, secret, proposalId]);
let check_root = std::merkle::compute_merkle_root (note_commitment, index, hash_path);
assert (root == check_root);
nullifier
}
编译为ACIR,类似R1CS,支持原始循环。已有halo2后端并获得资助,适合ZK开发者使用。
lurk - R1CS Lisp 有 - - PIL Polygon zkEVM 约束定义 特殊 无 - - Cairo StarkWare VM Rust 有 - - Zinc zkSync VM Rust 有 - 官方于2021年已经放弃维护 AirScript Polygon Miden Plonkish Yaml-like 无 - - def ExampleAir
trace_columns:
main: [s , a , b , c ]
aux: [p ]
public_inputs:
stack_inputs: [16 ]
stack_outputs: [16 ]
periodic_columns:
k0: [1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 ]
boundary_constraints:
enf a.first = stack_inputs[0]
enf b.first = stack_inputs[1]
enf c.first = stack_inputs[2]
enf a.last = stack_outputs[0]
enf b.last = stack_outputs[1]
enf c.last = stack_outputs[2]
enf p.first = 1
integrity_constraints:
enf s^2 = s
enf k0 * (s' - s) = 0
enf (1 - s) * (c - a - b) = 0
enf s * (c - a * b) = 0
enf p' = p * (c + $rand[0])
只能做简单约束,缺乏对witness的可编程操作。
Vamp-IR anoma Plonkish Haskell-like 有 - 底层汇编级别的语言 // declare R to be public
pub R ;
// define the Pythagorean relation we are checking
def pyth a b c = {
a^2 + b^2 = c^2
};
// appends constraint x^2 + y^2 = R ^2 to the circuit
pyth x y R ;
作为中间表示IR,不支持witness编程,语法较原始。
ALucard anoma Plonkish Lisp 有 - 是Vamp-IR的上层高级语言 powdr Powdr lab Plonkish+VM JS-like 有 - 底层汇编级别的语言 machine HelloWorld {
degree 8 ;
reg pc[@pc ];
reg X[<=];
reg Y[<=];
reg A;
instr incr X -> Y {
Y = X + 1
}
instr decr X -> Y {
Y = X - 1
}
instr assert_zero X {
X = 0
}
function main {
A <=X= ${ ("input" , 0 ) };
A <== incr (A);
A <== decr (A);
assert_zero A;
return ;
}}
用于描述虚拟机汇编程序,较底层,支持RISCV前端接入。
Chiquito PSE Plonkish Rust/Python 有 - 更像是简化包装了Halo2的API class FiboStep (StepType ):
def setup (self: FiboStep ):
self .c = self .internal("c" )
self .constr(eq(self .circuit.a + self .circuit.b, self .c))
self .transition(eq(self .circuit.b, self .circuit.a.next ()))
self .transition(eq(self .c, self .circuit.b.next ()))
def wg (self: FiboStep, args: Tuple [int , int ] ):
a_value, b_value = args
self .assign(self .circuit.a, F(a_value))
self .assign(self .circuit.b, F(b_value))
self .assign(self .c, F(a_value + b_value))
class Fibonacci (Circuit ):
def setup (self: Fibonacci ):
self .a: Queriable = self .forward("a" )
self .b: Queriable = self .forward("b" )
self .fibo_step = self .step_type(FiboStep(self , "fibo_step" ))
self .pragma_num_steps(11 )
def trace (self: Fibonacci, args: Any ):
self .add(self .fibo_step, (1 , 1 ))
a = 1
b = 2
for i in range (1 , 11 ):
self .add(self .fibo_step, (a, b))
prev_a = a
a = b
b += prev_a
fibo = Fibonacci()
fibo_witness = fibo.gen_witness(None )
fibo.halo2_mock_prover(fibo_witness)
结构清晰,适合表达step-based系统,语法接近Python。
zkas Darkfi VM C-like 有 - - k = 13 ;
field = "pallas" ;
constant "Vote" {
EcFixedPointShort VALUE_COMMIT_VALUE ,
EcFixedPoint VALUE_COMMIT_RANDOM ,
EcFixedPointBase NULLIFIER_K ,
}
witness "Vote" {
Base process_id_0,
Base process_id_1,
Base secret_key,
Base vote,
Scalar vote_blind,
Uint32 leaf_pos,
MerklePath path,
}
circuit "Vote" {
process_id = poseidon_hash (process_id_0, process_id_1);
nullifier = poseidon_hash (secret_key, process_id);
constrain_instance (nullifier);
public_key = ec_mul_base (secret_key, NULLIFIER_K );
public_x = ec_get_x (public_key);
public_y = ec_get_y (public_key);
pk_hash = poseidon_hash (public_x, public_y);
root = merkle_root (leaf_pos, path, pk_hash);
constrain_instance (root);
vcv = ec_mul_short (vote, VALUE_COMMIT_VALUE );
vcr = ec_mul (vote_blind, VALUE_COMMIT_RANDOM );
vote_commit = ec_add (vcv, vcr);
vote_commit_x = ec_get_x (vote_commit);
vote_commit_y = ec_get_y (vote_commit);
constrain_instance (vote_commit_x);
constrain_instance (vote_commit_y);
}
偏向链上zkVM操作,资料较少,语法接近zk汇编。
Polylang Polybase VM JS-like 有 - 底层接MidenVM plaf - Plonkish toml-like - - - [info]
name = "Circuit Foo"
size = 4096
[columns.witness]
w0 = {}
w1 = {}
w2 = { phase = 2 }
[columns.fixed]
q0 = {}
q1 = {}
q2 = {}
q3 = {}
[constraints.poly]
"gate 1" = "q0 * ((w0 - 0) * (w0 - 1))"
"gate 2" = "q1 * (w0 - w1)"
"gate 3" = "q2 * w0 * w1 * w2"
"gate 4" = "q3 * (w1[1] = w0[0])"
[constraints.lookup]
"lookup 1" = [["w0" , "w1" ], ["w2[0]" , "w2[1]" ]]
"lookup 2" = [["w0" , "w0 + w1" ], ["w2 + w2" , "q0 * w2" ]]
[[constraints.copy]]
columns = ["w0" , "w1" ]
offsets = [[0 , 10 ], [1 , 11 ], [2 , 12 ]]
[[constraints.copy]]
columns = ["w0" , "w2" ]
offsets = [[0 , 1 ], [2 , 3 ], [4 , 5 ]]
无编程能力,仅为静态约束描述格式。
halo2-repl Axiom Plonkish JS 有 - - const input = arr.map (witness);
const start = witness (startIdx);
const end = witness (endIdx);
input.map (makePublic);
makePublic (start);
makePublic (end);
const numInRange = sub (end, start);
let out = [];
for (let i = 0 ; i < 10 ; i++) {
const idx = mod (add (start, constant (i)), constant (10 ));
const isIdxInRange = isLessThan (constant (i), numInRange);
const el = selectFromIdx (input, idx);
const res = mul (isIdxInRange, el);
out.push (res);
}
out.map (makePublic);
语法API感强,但REPL体验良好,适合交互式调试。
lir - Lookup IR 无 - 试图做纯lookup的IR,较粗糙,除了readme中的一句话,其他没找到example Keelung BTQ - - - 后端是Aurora - noname zksecurity - - - - - sunscreen - - - - 支持FHE和ZKP两种 - zirgen RISC0 - - - - - Zinnia HKUST - Python-like - - - @zk_circuit
def is_prime (number: int , prime: bool ):
assert 0 <= number <= 10000
if number < 2 :
assert not prime
else :
result = True
for i in range (2 , 101 ):
if i * i > number:
break
if number % i == 0 :
result = False
assert prime == result