plonk_wasm/
gate_vector.rs

1//! A GateVector: this is used to represent a list of gates.
2
3use 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, // type of the gate
47                pub wires: WasmGateWires,  // gate wires
48                #[wasm_bindgen(skip)] pub coeffs: Vec<$WasmF>,  // constraints vector
49            }
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
187//
188// Fq
189//
190
191pub 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}