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