1use crate::{
2 vector::{fp::NapiVecVecFp, fq::NapiVecVecFq, NapiFlatVector},
3 wrappers::field::{NapiPastaFp, NapiPastaFq},
4};
5use kimchi::circuits::lookup::{
6 lookups::{LookupFeatures, LookupInfo, LookupPatterns},
7 runtime_tables::{RuntimeTable, RuntimeTableCfg},
8 tables::LookupTable,
9};
10use mina_curves::pasta::{Fp, Fq};
11use napi::bindgen_prelude::*;
12use napi_derive::napi;
13use paste::paste;
14use serde::{Deserialize, Serialize};
15use wasm_types::{FlatVector, FlatVectorElem};
16
17#[napi(object, js_name = "WasmLookupPatterns")]
22#[derive(Clone, Copy, Debug, Serialize, Deserialize, Default)]
23pub struct NapiLookupPatterns {
24 pub xor: bool,
25 pub lookup: bool,
26 #[napi(js_name = "range_check")]
27 pub range_check: bool,
28 #[napi(js_name = "foreign_field_mul")]
29 pub foreign_field_mul: bool,
30}
31
32impl From<LookupPatterns> for NapiLookupPatterns {
33 fn from(value: LookupPatterns) -> Self {
34 Self {
35 xor: value.xor,
36 lookup: value.lookup,
37 range_check: value.range_check,
38 foreign_field_mul: value.foreign_field_mul,
39 }
40 }
41}
42
43impl From<NapiLookupPatterns> for LookupPatterns {
44 fn from(value: NapiLookupPatterns) -> Self {
45 LookupPatterns {
46 xor: value.xor,
47 lookup: value.lookup,
48 range_check: value.range_check,
49 foreign_field_mul: value.foreign_field_mul,
50 }
51 }
52}
53
54#[napi(object, js_name = "WasmLookupFeatures")]
55#[derive(Clone, Debug, Default, Serialize, Deserialize)]
56pub struct NapiLookupFeatures {
57 pub patterns: NapiLookupPatterns,
58 #[napi(js_name = "joint_lookup_used")]
59 pub joint_lookup_used: bool,
60 #[napi(js_name = "uses_runtime_tables")]
61 pub uses_runtime_tables: bool,
62}
63
64impl From<LookupFeatures> for NapiLookupFeatures {
65 fn from(value: LookupFeatures) -> Self {
66 Self {
67 patterns: value.patterns.into(),
68 joint_lookup_used: value.joint_lookup_used,
69 uses_runtime_tables: value.uses_runtime_tables,
70 }
71 }
72}
73
74impl From<NapiLookupFeatures> for LookupFeatures {
75 fn from(value: NapiLookupFeatures) -> Self {
76 LookupFeatures {
77 patterns: value.patterns.into(),
78 joint_lookup_used: value.joint_lookup_used,
79 uses_runtime_tables: value.uses_runtime_tables,
80 }
81 }
82}
83
84#[napi(object, js_name = "WasmLookupInfo")]
85#[derive(Clone, Debug, Default, Serialize, Deserialize)]
86pub struct NapiLookupInfo {
87 #[napi(js_name = "max_per_row")]
88 pub max_per_row: i32,
89 #[napi(js_name = "max_joint_size")]
90 pub max_joint_size: i32,
91 pub features: NapiLookupFeatures,
92}
93
94impl From<LookupInfo> for NapiLookupInfo {
95 fn from(value: LookupInfo) -> Self {
96 Self {
97 max_per_row: value.max_per_row as i32,
98 max_joint_size: value.max_joint_size as i32,
99 features: value.features.into(),
100 }
101 }
102}
103
104impl From<NapiLookupInfo> for LookupInfo {
105 fn from(value: NapiLookupInfo) -> Self {
106 LookupInfo {
107 max_per_row: value.max_per_row as usize,
108 max_joint_size: value.max_joint_size as u32,
109 features: value.features.into(),
110 }
111 }
112}
113
114macro_rules! impl_lookup_wrappers {
119 ($field_name:ident, $field:ty, $NapiF:ty, $vec_vec:ty) => {
120 paste! {
121 #[napi(js_name = [<"WasmPasta" $field_name:camel "LookupTable">])]
122 #[derive(Clone)]
123 pub struct [<NapiPasta $field_name:camel LookupTable>] {
124 id: i32,
125 data: $vec_vec,
126 }
127
128 #[napi]
129 impl [<NapiPasta $field_name:camel LookupTable>] {
130 #[napi(constructor)]
131 pub fn new(id: i32, data: $vec_vec) -> Self {
132 Self {
133 id,
134 data: data.clone(),
135 }
136 }
137
138 #[napi(getter)]
139 pub fn id(&self) -> i32 {
140 self.id
141 }
142
143 #[napi(setter)]
144 pub fn set_id(&mut self, id: i32) {
145 self.id = id;
146 }
147
148 #[napi(getter)]
149 pub fn data(&self) -> $vec_vec {
150 self.data.clone()
151 }
152
153 #[napi(setter)]
154 pub fn set_data(&mut self, data: $vec_vec) {
155 self.data = data.clone();
156 }
157 }
158
159 impl From<LookupTable<$field>> for [<NapiPasta $field_name:camel LookupTable>] {
160 fn from(value: LookupTable<$field>) -> Self {
161 Self {
162 id: value.id,
163 data: value.data.into(),
164 }
165 }
166 }
167
168 impl From<[<NapiPasta $field_name:camel LookupTable>]> for LookupTable<$field> {
169 fn from(value: [<NapiPasta $field_name:camel LookupTable>]) -> Self {
170 Self {
171 id: value.id,
172 data: value.data.into(),
173 }
174 }
175 }
176
177 #[napi(js_name = [<"WasmPasta" $field_name:camel "RuntimeTableCfg">])]
178 #[derive(Clone)]
179 pub struct [<NapiPasta $field_name:camel RuntimeTableCfg>] {
180 id: i32,
181 first_column: Vec<$field>,
182 }
183
184 #[napi]
185 impl [<NapiPasta $field_name:camel RuntimeTableCfg>] {
186 #[napi(constructor)]
187 pub fn new(id: i32, first_column: Uint8Array) -> Result<Self> {
188 let bytes = first_column.as_ref().to_vec();
189 let elements: Vec<$field> = FlatVector::<$NapiF>::from_bytes(bytes)
190 .into_iter()
191 .map(Into::into)
192 .collect();
193 Ok(Self { id, first_column: elements })
194 }
195
196 #[napi(getter)]
197 pub fn id(&self) -> i32 {
198 self.id
199 }
200
201 #[napi(setter)]
202 pub fn set_id(&mut self, id: i32) {
203 self.id = id;
204 }
205
206 #[napi(getter, js_name = "first_column")]
207 pub fn first_column(&self) -> Result<Uint8Array> {
208 let mut bytes = Vec::with_capacity(self.first_column.len() * <$NapiF>::FLATTENED_SIZE);
209 for value in &self.first_column {
210 let element = <$NapiF>::from(*value);
211 bytes.extend(element.flatten());
212 }
213 Ok(Uint8Array::from(bytes))
214 }
215 }
216
217 impl From<RuntimeTableCfg<$field>> for [<NapiPasta $field_name:camel RuntimeTableCfg>] {
218 fn from(value: RuntimeTableCfg<$field>) -> Self {
219 Self {
220 id: value.id,
221 first_column: value.first_column,
222 }
223 }
224 }
225
226 impl From<[<NapiPasta $field_name:camel RuntimeTableCfg>]> for RuntimeTableCfg<$field> {
227 fn from(value: [<NapiPasta $field_name:camel RuntimeTableCfg>]) -> Self {
228 Self {
229 id: value.id,
230 first_column: value.first_column,
231 }
232 }
233 }
234
235 #[napi(object, js_name = [<"Wasm" $field_name:camel "RuntimeTable">])]
236 #[derive(Clone)]
237 pub struct [<Napi $field_name:camel RuntimeTable>] {
238 pub id: i32,
239 pub data: NapiFlatVector<$NapiF>,
240 }
241
242 impl From<RuntimeTable<$field>> for [<Napi $field_name:camel RuntimeTable>] {
243 fn from(value: RuntimeTable<$field>) -> Self {
244 Self {
245 id: value.id,
246 data: value.data.into_iter().map(Into::into).collect(),
247 }
248 }
249 }
250
251 impl From<[<Napi $field_name:camel RuntimeTable>]> for RuntimeTable<$field> {
252 fn from(value: [<Napi $field_name:camel RuntimeTable>]) -> Self {
253 Self {
254 id: value.id,
255 data: value.data.into_iter().map(Into::into).collect(),
256 }
257 }
258 }
259 }
260 };
261}
262
263impl_lookup_wrappers!(Fp, Fp, NapiPastaFp, NapiVecVecFp);
264impl_lookup_wrappers!(Fq, Fq, NapiPastaFq, NapiVecVecFq);