plonk_wasm/
gate_vector.rs1use kimchi::circuits::{
4 gate::{Circuit, CircuitGate, GateType},
5 wires::Wire,
6};
7use o1_utils::hasher::CryptoDigest;
8use paste::paste;
9use wasm_bindgen::prelude::*;
10use wasm_types::FlatVector as WasmFlatVector;
11
12#[wasm_bindgen]
13#[derive(Clone, Copy, Debug)]
14pub struct WasmGateWires(
15 pub Wire,
16 pub Wire,
17 pub Wire,
18 pub Wire,
19 pub Wire,
20 pub Wire,
21 pub Wire,
22);
23
24#[wasm_bindgen]
25impl WasmGateWires {
26 #[wasm_bindgen(constructor)]
27 pub fn new(w0: Wire, w1: Wire, w2: Wire, w3: Wire, w4: Wire, w5: Wire, w6: Wire) -> Self {
28 WasmGateWires(w0, w1, w2, w3, w4, w5, w6)
29 }
30}
31
32macro_rules! impl_gate_vector {
33 ($name: ident,
34 $WasmF: ty,
35 $F: ty,
36 $field_name: ident) => {
37 paste! {
38 #[wasm_bindgen]
39 pub struct [<Wasm $field_name:camel GateVector>](
40 #[wasm_bindgen(skip)] pub Vec<CircuitGate<$F>>);
41 pub type WasmGateVector = [<Wasm $field_name:camel GateVector>];
42
43 #[wasm_bindgen]
44 pub struct [<Wasm $field_name:camel Gate>] {
45 pub typ: GateType, pub wires: WasmGateWires, #[wasm_bindgen(skip)] pub coeffs: Vec<$WasmF>, }
49
50 #[wasm_bindgen]
51 impl [<Wasm $field_name:camel Gate>] {
52 #[wasm_bindgen(constructor)]
53 pub fn new(
54 typ: GateType,
55 wires: WasmGateWires,
56 coeffs: WasmFlatVector<$WasmF>) -> Self {
57 Self {
58 typ,
59 wires,
60 coeffs: coeffs.into(),
61 }
62 }
63 }
64
65 impl From<CircuitGate<$F>> for [<Wasm $field_name:camel Gate>]
66 {
67 fn from(cg: CircuitGate<$F>) -> Self {
68 Self {
69 typ: cg.typ,
70 wires: WasmGateWires(
71 cg.wires[0],
72 cg.wires[1],
73 cg.wires[2],
74 cg.wires[3],
75 cg.wires[4],
76 cg.wires[5],
77 cg.wires[6]),
78 coeffs: cg.coeffs.into_iter().map(Into::into).collect(),
79 }
80 }
81 }
82
83 impl From<&CircuitGate<$F>> for [<Wasm $field_name:camel Gate>]
84 {
85 fn from(cg: &CircuitGate<$F>) -> Self {
86 Self {
87 typ: cg.typ,
88 wires: WasmGateWires(
89 cg.wires[0],
90 cg.wires[1],
91 cg.wires[2],
92 cg.wires[3],
93 cg.wires[4],
94 cg.wires[5],
95 cg.wires[6]),
96 coeffs: cg.coeffs.clone().into_iter().map(Into::into).collect(),
97 }
98 }
99 }
100
101 impl From<[<Wasm $field_name:camel Gate>]> for CircuitGate<$F>
102 {
103 fn from(ccg: [<Wasm $field_name:camel Gate>]) -> Self {
104 Self {
105 typ: ccg.typ,
106 wires: [
107 ccg.wires.0,
108 ccg.wires.1,
109 ccg.wires.2,
110 ccg.wires.3,
111 ccg.wires.4,
112 ccg.wires.5,
113 ccg.wires.6
114 ],
115 coeffs: ccg.coeffs.into_iter().map(Into::into).collect(),
116 }
117 }
118 }
119
120 #[wasm_bindgen]
121 pub fn [<caml_pasta_ $name:snake _plonk_gate_vector_create>]() -> WasmGateVector {
122 [<Wasm $field_name:camel GateVector>](Vec::new())
123 }
124
125 #[wasm_bindgen]
126 pub fn [<caml_pasta_ $name:snake _plonk_gate_vector_add>](
127 v: &mut WasmGateVector,
128 gate: [<Wasm $field_name:camel Gate>],
129 ) {
130 let gate: CircuitGate<$F> = gate.into();
131 v.0.push(gate);
132 }
133
134 #[wasm_bindgen]
135 pub fn [<caml_pasta_ $name:snake _plonk_gate_vector_get>](
136 v: &WasmGateVector,
137 i: i32,
138 ) -> [<Wasm $field_name:camel Gate>] {
139 (&(v.0)[i as usize]).into()
140 }
141
142 #[wasm_bindgen]
143 pub fn [<caml_pasta_ $name:snake _plonk_gate_vector_len>](
144 v: &WasmGateVector,
145 ) -> usize {
146 v.0.len()
147 }
148
149 #[wasm_bindgen]
150 pub fn [<caml_pasta_ $name:snake _plonk_gate_vector_wrap>](
151 v: &mut WasmGateVector,
152 t: Wire,
153 h: Wire,
154 ) {
155 (v.0)[t.row as usize].wires[t.col as usize] = h.into();
156 }
157
158 #[wasm_bindgen]
159 pub fn [<caml_pasta_ $name:snake _plonk_gate_vector_digest>](
160 public_input_size: usize,
161 v: &WasmGateVector
162 ) -> Box<[u8]> {
163 Circuit::new(public_input_size, &(v.0)).digest().to_vec().into_boxed_slice()
164 }
165
166 #[wasm_bindgen]
167 pub fn [<caml_pasta_ $name:snake _plonk_circuit_serialize>](
168 public_input_size: usize,
169 v: &WasmGateVector
170 ) -> String {
171 let circuit = Circuit::new(public_input_size, &v.0);
172 serde_json::to_string(&circuit).expect("couldn't serialize constraints")
173 }
174 }
175 };
176}
177
178pub mod fp {
179 use super::*;
180 use arkworks::WasmPastaFp as WasmF;
181 use mina_curves::pasta::Fp as F;
182
183 impl_gate_vector!(fp, WasmF, F, Fp);
184}
185
186pub mod fq {
191 use super::*;
192 use arkworks::WasmPastaFq as WasmF;
193 use mina_curves::pasta::Fq as F;
194
195 impl_gate_vector!(fq, WasmF, F, Fq);
196}