sp1_recursion_compiler/ir/
arithmetic.rs

1use std::{cell::UnsafeCell, mem::ManuallyDrop};
2
3use p3_field::{AbstractExtensionField, AbstractField, Field};
4
5use crate::ir::DslIr;
6
7use super::{Config, Ext, Felt, InnerBuilder, Var};
8
9#[derive(Debug)]
10pub struct VarHandle<N> {
11    ptr: *mut (),
12
13    add_var: fn(*mut (), Var<N>, Var<N>) -> Var<N>,
14    add_var_const: fn(*mut (), Var<N>, N) -> Var<N>,
15
16    sub_var: fn(*mut (), Var<N>, Var<N>) -> Var<N>,
17    sub_var_const: fn(*mut (), Var<N>, N) -> Var<N>,
18    sub_const_var: fn(*mut (), N, Var<N>) -> Var<N>,
19
20    neg_var: fn(ptr: *mut (), lhs: Var<N>) -> Var<N>,
21
22    mul_var: fn(*mut (), Var<N>, Var<N>) -> Var<N>,
23    mul_var_const: fn(*mut (), Var<N>, N) -> Var<N>,
24}
25
26#[derive(Debug)]
27pub struct FeltHandle<F> {
28    ptr: *mut (),
29
30    pub ext_handle_ptr: *mut (),
31
32    add_felt: fn(*mut (), Felt<F>, Felt<F>) -> Felt<F>,
33    add_const_felt: fn(*mut (), Felt<F>, F) -> Felt<F>,
34
35    sub_felt: fn(*mut (), Felt<F>, Felt<F>) -> Felt<F>,
36    sub_const_felt: fn(*mut (), F, Felt<F>) -> Felt<F>,
37    sub_felt_const: fn(*mut (), Felt<F>, F) -> Felt<F>,
38
39    neg_felt: fn(ptr: *mut (), lhs: Felt<F>) -> Felt<F>,
40
41    mul_felt: fn(*mut (), Felt<F>, Felt<F>) -> Felt<F>,
42    mul_felt_const: fn(ptr: *mut (), lhs: Felt<F>, rhs: F) -> Felt<F>,
43
44    div_felt: fn(*mut (), Felt<F>, Felt<F>) -> Felt<F>,
45    div_felt_const: fn(*mut (), Felt<F>, F) -> Felt<F>,
46    div_const_felt: fn(*mut (), F, Felt<F>) -> Felt<F>,
47}
48
49#[derive(Debug)]
50pub struct ExtHandle<F, EF> {
51    ptr: *mut (),
52
53    add_ext: fn(*mut (), Ext<F, EF>, Ext<F, EF>) -> Ext<F, EF>,
54    add_const_ext: fn(*mut (), Ext<F, EF>, EF) -> Ext<F, EF>,
55    add_ext_base: fn(*mut (), Ext<F, EF>, Felt<F>) -> Ext<F, EF>,
56    add_const_base: fn(*mut (), Ext<F, EF>, F) -> Ext<F, EF>,
57    add_felt_const_ext: fn(*mut (), Felt<F>, EF, *mut Self) -> Ext<F, EF>,
58
59    sub_ext: fn(*mut (), Ext<F, EF>, Ext<F, EF>) -> Ext<F, EF>,
60    sub_ext_base: fn(*mut (), Ext<F, EF>, Felt<F>) -> Ext<F, EF>,
61    sub_base_ext: fn(*mut (), Felt<F>, Ext<F, EF>) -> Ext<F, EF>,
62    sub_felt_const_ext: fn(*mut (), Felt<F>, EF, *mut Self) -> Ext<F, EF>,
63    sub_const_ext: fn(*mut (), Ext<F, EF>, EF) -> Ext<F, EF>,
64    sub_ext_const: fn(*mut (), EF, Ext<F, EF>) -> Ext<F, EF>,
65
66    neg_ext: fn(ptr: *mut (), lhs: Ext<F, EF>) -> Ext<F, EF>,
67
68    div_ext: fn(*mut (), Ext<F, EF>, Ext<F, EF>) -> Ext<F, EF>,
69    div_const_ext: fn(*mut (), Ext<F, EF>, EF) -> Ext<F, EF>,
70    div_ext_base: fn(*mut (), Ext<F, EF>, Felt<F>) -> Ext<F, EF>,
71    div_base_ext: fn(*mut (), Felt<F>, Ext<F, EF>) -> Ext<F, EF>,
72    div_const_base: fn(*mut (), Ext<F, EF>, F) -> Ext<F, EF>,
73    div_ext_const: fn(*mut (), EF, Ext<F, EF>) -> Ext<F, EF>,
74    div_felt_const_ext: fn(*mut (), Felt<F>, EF, *mut Self) -> Ext<F, EF>,
75
76    mul_ext: fn(*mut (), Ext<F, EF>, Ext<F, EF>) -> Ext<F, EF>,
77    mul_const_ext: fn(*mut (), Ext<F, EF>, EF) -> Ext<F, EF>,
78    mul_ext_base: fn(*mut (), Ext<F, EF>, Felt<F>) -> Ext<F, EF>,
79    mul_felt_const_ext: fn(*mut (), Felt<F>, EF, *mut Self) -> Ext<F, EF>,
80}
81
82pub(crate) trait VarOperations<N> {
83    fn add_var(ptr: *mut (), lhs: Var<N>, rhs: Var<N>) -> Var<N>;
84    fn add_const_var(ptr: *mut (), lhs: Var<N>, rhs: N) -> Var<N>;
85
86    fn sub_var(ptr: *mut (), lhs: Var<N>, rhs: Var<N>) -> Var<N>;
87    fn sub_var_const(ptr: *mut (), lhs: Var<N>, rhs: N) -> Var<N>;
88    fn sub_const_var(ptr: *mut (), lhs: N, rhs: Var<N>) -> Var<N>;
89
90    fn neg_var(ptr: *mut (), lhs: Var<N>) -> Var<N>;
91
92    fn mul_var(ptr: *mut (), lhs: Var<N>, rhs: Var<N>) -> Var<N>;
93    fn mul_const_var(ptr: *mut (), lhs: Var<N>, rhs: N) -> Var<N>;
94
95    fn var_handle(element: &mut Box<Self>) -> VarHandle<N> {
96        VarHandle {
97            ptr: element.as_mut() as *mut Self as *mut (),
98            add_var: Self::add_var,
99            sub_var: Self::sub_var,
100            mul_var: Self::mul_var,
101            neg_var: Self::neg_var,
102            add_var_const: Self::add_const_var,
103            sub_var_const: Self::sub_var_const,
104            sub_const_var: Self::sub_const_var,
105            mul_var_const: Self::mul_const_var,
106        }
107    }
108}
109
110pub(crate) trait FeltOperations<F> {
111    fn add_felt(ptr: *mut (), lhs: Felt<F>, rhs: Felt<F>) -> Felt<F>;
112    fn sub_felt(ptr: *mut (), lhs: Felt<F>, rhs: Felt<F>) -> Felt<F>;
113    fn mul_felt(ptr: *mut (), lhs: Felt<F>, rhs: Felt<F>) -> Felt<F>;
114    fn add_felt_const(ptr: *mut (), lhs: Felt<F>, rhs: F) -> Felt<F>;
115    fn sub_felt_const(ptr: *mut (), lhs: Felt<F>, rhs: F) -> Felt<F>;
116    fn mul_const_felt(ptr: *mut (), lhs: Felt<F>, rhs: F) -> Felt<F>;
117    fn sub_const_felt(ptr: *mut (), lhs: F, rhs: Felt<F>) -> Felt<F>;
118    fn div_felt(ptr: *mut (), lhs: Felt<F>, rhs: Felt<F>) -> Felt<F>;
119    fn div_felt_const(ptr: *mut (), lhs: Felt<F>, rhs: F) -> Felt<F>;
120    fn div_const_felt(ptr: *mut (), lhs: F, rhs: Felt<F>) -> Felt<F>;
121    fn neg_felt(ptr: *mut (), lhs: Felt<F>) -> Felt<F>;
122
123    fn felt_handle(element: &mut Box<Self>, ext_handle_ptr: *mut ()) -> FeltHandle<F> {
124        FeltHandle {
125            ptr: element.as_mut() as *mut Self as *mut (),
126            ext_handle_ptr,
127            add_felt: Self::add_felt,
128            sub_felt: Self::sub_felt,
129            mul_felt: Self::mul_felt,
130            add_const_felt: Self::add_felt_const,
131            mul_felt_const: Self::mul_const_felt,
132            sub_felt_const: Self::sub_felt_const,
133            sub_const_felt: Self::sub_const_felt,
134            div_felt: Self::div_felt,
135            div_felt_const: Self::div_felt_const,
136            div_const_felt: Self::div_const_felt,
137            neg_felt: Self::neg_felt,
138        }
139    }
140}
141
142pub(crate) trait ExtOperations<F, EF> {
143    fn add_ext(ptr: *mut (), lhs: Ext<F, EF>, rhs: Ext<F, EF>) -> Ext<F, EF>;
144    fn add_felt_const_ext(
145        ptr: *mut (),
146        lhs: Felt<F>,
147        rhs: EF,
148        handle: *mut ExtHandle<F, EF>,
149    ) -> Ext<F, EF>;
150    fn add_ext_base(ptr: *mut (), lhs: Ext<F, EF>, rhs: Felt<F>) -> Ext<F, EF>;
151    fn add_const_ext(ptr: *mut (), lhs: Ext<F, EF>, rhs: EF) -> Ext<F, EF>;
152    fn add_const_base(ptr: *mut (), lhs: Ext<F, EF>, rhs: F) -> Ext<F, EF>;
153
154    fn neg_ext(ptr: *mut (), lhs: Ext<F, EF>) -> Ext<F, EF>;
155
156    fn sub_ext(ptr: *mut (), lhs: Ext<F, EF>, rhs: Ext<F, EF>) -> Ext<F, EF>;
157    fn sub_ext_base(ptr: *mut (), lhs: Ext<F, EF>, rhs: Felt<F>) -> Ext<F, EF>;
158    fn sub_base_ext(ptr: *mut (), lhs: Felt<F>, rhs: Ext<F, EF>) -> Ext<F, EF>;
159    fn sub_ext_const(ptr: *mut (), lhs: EF, rhs: Ext<F, EF>) -> Ext<F, EF>;
160    fn sub_const_ext(ptr: *mut (), lhs: Ext<F, EF>, rhs: EF) -> Ext<F, EF>;
161    fn sub_felt_const_ext(
162        ptr: *mut (),
163        lhs: Felt<F>,
164        rhs: EF,
165        handle: *mut ExtHandle<F, EF>,
166    ) -> Ext<F, EF>;
167
168    fn div_ext(ptr: *mut (), lhs: Ext<F, EF>, rhs: Ext<F, EF>) -> Ext<F, EF>;
169    fn div_ext_base(ptr: *mut (), lhs: Ext<F, EF>, rhs: Felt<F>) -> Ext<F, EF>;
170    fn div_base_ext(ptr: *mut (), lhs: Felt<F>, rhs: Ext<F, EF>) -> Ext<F, EF>;
171    fn div_const_ext(ptr: *mut (), lhs: Ext<F, EF>, rhs: EF) -> Ext<F, EF>;
172    fn div_ext_const(ptr: *mut (), lhs: EF, rhs: Ext<F, EF>) -> Ext<F, EF>;
173    fn div_const_base(ptr: *mut (), lhs: Ext<F, EF>, rhs: F) -> Ext<F, EF>;
174    fn div_felt_const_ext(
175        ptr: *mut (),
176        lhs: Felt<F>,
177        rhs: EF,
178        handle: *mut ExtHandle<F, EF>,
179    ) -> Ext<F, EF>;
180
181    fn mul_ext(ptr: *mut (), lhs: Ext<F, EF>, rhs: Ext<F, EF>) -> Ext<F, EF>;
182    fn mul_const_ext(ptr: *mut (), lhs: Ext<F, EF>, rhs: EF) -> Ext<F, EF>;
183    fn mul_felt_const_ext(
184        ptr: *mut (),
185        lhs: Felt<F>,
186        rhs: EF,
187        handle: *mut ExtHandle<F, EF>,
188    ) -> Ext<F, EF>;
189    fn mul_ext_base(ptr: *mut (), lhs: Ext<F, EF>, rhs: Felt<F>) -> Ext<F, EF>;
190
191    fn ext_handle(element: &mut Box<Self>) -> ExtHandle<F, EF> {
192        ExtHandle {
193            ptr: element.as_mut() as *mut Self as *mut (),
194            add_ext: Self::add_ext,
195            add_ext_base: Self::add_ext_base,
196            add_felt_const_ext: Self::add_felt_const_ext,
197            sub_ext: Self::sub_ext,
198            sub_base_ext: Self::sub_base_ext,
199            add_const_base: Self::add_const_base,
200            add_const_ext: Self::add_const_ext,
201            neg_ext: Self::neg_ext,
202            sub_ext_base: Self::sub_ext_base,
203            sub_felt_const_ext: Self::sub_felt_const_ext,
204            sub_const_ext: Self::sub_const_ext,
205            div_ext: Self::div_ext,
206            div_const_ext: Self::div_const_ext,
207            div_felt_const_ext: Self::div_felt_const_ext,
208            div_ext_base: Self::div_ext_base,
209            sub_ext_const: Self::sub_ext_const,
210            div_base_ext: Self::div_base_ext,
211            div_const_base: Self::div_const_base,
212            mul_ext: Self::mul_ext,
213            mul_const_ext: Self::mul_const_ext,
214            mul_ext_base: Self::mul_ext_base,
215            mul_felt_const_ext: Self::mul_felt_const_ext,
216            div_ext_const: Self::div_ext_const,
217        }
218    }
219}
220
221impl<C: Config> VarOperations<C::N> for UnsafeCell<InnerBuilder<C>> {
222    fn add_var(ptr: *mut (), lhs: Var<C::N>, rhs: Var<C::N>) -> Var<C::N> {
223        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
224        let inner = inner.get_mut();
225        let idx = inner.variable_count;
226        let res = Var::new(idx, lhs.handle);
227        inner.variable_count += 1;
228
229        inner.operations.push(DslIr::AddV(res, lhs, rhs));
230
231        res
232    }
233
234    fn sub_var(ptr: *mut (), lhs: Var<C::N>, rhs: Var<C::N>) -> Var<C::N> {
235        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
236        let inner = inner.get_mut();
237        let idx = inner.variable_count;
238        let res = Var::new(idx, lhs.handle);
239        inner.variable_count += 1;
240
241        inner.operations.push(DslIr::SubV(res, lhs, rhs));
242
243        res
244    }
245
246    fn mul_var(ptr: *mut (), lhs: Var<C::N>, rhs: Var<C::N>) -> Var<C::N> {
247        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
248        let inner = inner.get_mut();
249        let idx = inner.variable_count;
250        let res = Var::new(idx, lhs.handle);
251        inner.variable_count += 1;
252
253        inner.operations.push(DslIr::MulV(res, lhs, rhs));
254
255        res
256    }
257
258    fn add_const_var(ptr: *mut (), lhs: Var<C::N>, rhs: C::N) -> Var<C::N> {
259        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
260        let inner = inner.get_mut();
261        let idx = inner.variable_count;
262        let res = Var::new(idx, lhs.handle);
263        inner.variable_count += 1;
264
265        inner.operations.push(DslIr::AddVI(res, lhs, rhs));
266
267        res
268    }
269
270    fn mul_const_var(ptr: *mut (), lhs: Var<C::N>, rhs: C::N) -> Var<C::N> {
271        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
272        let inner = inner.get_mut();
273        let idx = inner.variable_count;
274        let res = Var::new(idx, lhs.handle);
275        inner.variable_count += 1;
276
277        inner.operations.push(DslIr::MulVI(res, lhs, rhs));
278
279        res
280    }
281
282    fn sub_const_var(ptr: *mut (), lhs: C::N, rhs: Var<C::N>) -> Var<C::N> {
283        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
284        let inner = inner.get_mut();
285        let idx = inner.variable_count;
286        let res = Var::new(idx, rhs.handle);
287        inner.variable_count += 1;
288
289        inner.operations.push(DslIr::SubVIN(res, lhs, rhs));
290
291        res
292    }
293
294    fn sub_var_const(ptr: *mut (), lhs: Var<C::N>, rhs: C::N) -> Var<C::N> {
295        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
296        let inner = inner.get_mut();
297        let idx = inner.variable_count;
298        let res = Var::new(idx, lhs.handle);
299        inner.variable_count += 1;
300
301        inner.operations.push(DslIr::SubVI(res, lhs, rhs));
302
303        res
304    }
305
306    fn neg_var(ptr: *mut (), lhs: Var<C::N>) -> Var<C::N> {
307        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
308        let inner = inner.get_mut();
309        let idx = inner.variable_count;
310        let res = Var::new(idx, lhs.handle);
311        inner.variable_count += 1;
312
313        inner.operations.push(DslIr::NegV(res, lhs));
314
315        res
316    }
317}
318
319impl<C: Config> FeltOperations<C::F> for UnsafeCell<InnerBuilder<C>> {
320    fn add_felt(ptr: *mut (), lhs: Felt<C::F>, rhs: Felt<C::F>) -> Felt<C::F> {
321        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
322        let inner = inner.get_mut();
323        let idx = inner.variable_count;
324        let res = Felt::new(idx, lhs.handle);
325        inner.variable_count += 1;
326
327        inner.operations.push(DslIr::AddF(res, lhs, rhs));
328
329        res
330    }
331
332    fn sub_felt(ptr: *mut (), lhs: Felt<C::F>, rhs: Felt<C::F>) -> Felt<C::F> {
333        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
334        let inner = inner.get_mut();
335        let idx = inner.variable_count;
336        let res = Felt::new(idx, lhs.handle);
337        inner.variable_count += 1;
338
339        inner.operations.push(DslIr::SubF(res, lhs, rhs));
340
341        res
342    }
343
344    fn neg_felt(ptr: *mut (), lhs: Felt<C::F>) -> Felt<C::F> {
345        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
346        let inner = inner.get_mut();
347        let idx = inner.variable_count;
348        let res = Felt::new(idx, lhs.handle);
349        inner.variable_count += 1;
350
351        inner.operations.push(DslIr::NegF(res, lhs));
352
353        res
354    }
355
356    fn mul_felt(ptr: *mut (), lhs: Felt<C::F>, rhs: Felt<C::F>) -> Felt<C::F> {
357        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
358        let inner = inner.get_mut();
359        let idx = inner.variable_count;
360        let res = Felt::new(idx, lhs.handle);
361        inner.variable_count += 1;
362
363        inner.operations.push(DslIr::MulF(res, lhs, rhs));
364
365        res
366    }
367
368    fn add_felt_const(ptr: *mut (), lhs: Felt<C::F>, rhs: C::F) -> Felt<C::F> {
369        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
370        let inner = inner.get_mut();
371        let idx = inner.variable_count;
372        let res = Felt::new(idx, lhs.handle);
373        inner.variable_count += 1;
374
375        inner.operations.push(DslIr::AddFI(res, lhs, rhs));
376
377        res
378    }
379
380    fn sub_felt_const(ptr: *mut (), lhs: Felt<C::F>, rhs: C::F) -> Felt<C::F> {
381        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
382        let inner = inner.get_mut();
383        let idx = inner.variable_count;
384        let res = Felt::new(idx, lhs.handle);
385        inner.variable_count += 1;
386
387        inner.operations.push(DslIr::SubFI(res, lhs, rhs));
388
389        res
390    }
391
392    fn sub_const_felt(ptr: *mut (), lhs: C::F, rhs: Felt<C::F>) -> Felt<C::F> {
393        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
394        let inner = inner.get_mut();
395        let idx = inner.variable_count;
396        let res = Felt::new(idx, rhs.handle);
397        inner.variable_count += 1;
398
399        inner.operations.push(DslIr::SubFIN(res, lhs, rhs));
400
401        res
402    }
403
404    fn mul_const_felt(ptr: *mut (), lhs: Felt<C::F>, rhs: C::F) -> Felt<C::F> {
405        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
406        let inner = inner.get_mut();
407        let idx = inner.variable_count;
408        let res = Felt::new(idx, lhs.handle);
409        inner.variable_count += 1;
410
411        inner.operations.push(DslIr::MulFI(res, lhs, rhs));
412
413        res
414    }
415
416    fn div_felt(ptr: *mut (), lhs: Felt<C::F>, rhs: Felt<C::F>) -> Felt<C::F> {
417        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
418        let inner = inner.get_mut();
419        let idx = inner.variable_count;
420        let res = Felt::new(idx, lhs.handle);
421        inner.variable_count += 1;
422
423        inner.operations.push(DslIr::DivF(res, lhs, rhs));
424
425        res
426    }
427
428    fn div_felt_const(ptr: *mut (), lhs: Felt<C::F>, rhs: C::F) -> Felt<C::F> {
429        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
430        let inner = inner.get_mut();
431        let idx = inner.variable_count;
432        let res = Felt::new(idx, lhs.handle);
433        inner.variable_count += 1;
434
435        inner.operations.push(DslIr::DivFI(res, lhs, rhs));
436
437        res
438    }
439
440    fn div_const_felt(ptr: *mut (), lhs: C::F, rhs: Felt<C::F>) -> Felt<C::F> {
441        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
442        let inner = inner.get_mut();
443        let idx = inner.variable_count;
444        let res = Felt::new(idx, rhs.handle);
445        inner.variable_count += 1;
446
447        inner.operations.push(DslIr::DivFIN(res, lhs, rhs));
448
449        res
450    }
451}
452
453impl<C: Config> ExtOperations<C::F, C::EF> for UnsafeCell<InnerBuilder<C>> {
454    fn add_ext(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: Ext<C::F, C::EF>) -> Ext<C::F, C::EF> {
455        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
456        let inner = inner.get_mut();
457        let idx = inner.variable_count;
458        let res = Ext::new(idx, lhs.handle);
459        inner.variable_count += 1;
460
461        inner.operations.push(DslIr::AddE(res, lhs, rhs));
462
463        res
464    }
465
466    fn add_ext_base(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: Felt<C::F>) -> Ext<C::F, C::EF> {
467        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
468        let inner = inner.get_mut();
469        let idx = inner.variable_count;
470        let res = Ext::new(idx, lhs.handle);
471        inner.variable_count += 1;
472
473        inner.operations.push(DslIr::AddEF(res, lhs, rhs));
474
475        res
476    }
477
478    fn add_const_base(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: C::F) -> Ext<C::F, C::EF> {
479        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
480        let inner = inner.get_mut();
481        let idx = inner.variable_count;
482        let res = Ext::new(idx, lhs.handle);
483        inner.variable_count += 1;
484
485        inner.operations.push(DslIr::AddEFI(res, lhs, rhs));
486
487        res
488    }
489
490    fn add_const_ext(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: C::EF) -> Ext<C::F, C::EF> {
491        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
492        let inner = inner.get_mut();
493        let idx = inner.variable_count;
494        let res = Ext::new(idx, lhs.handle);
495        inner.variable_count += 1;
496
497        inner.operations.push(DslIr::AddEI(res, lhs, rhs));
498
499        res
500    }
501
502    fn add_felt_const_ext(
503        ptr: *mut (),
504        lhs: Felt<C::F>,
505        rhs: C::EF,
506        handle: *mut ExtHandle<C::F, C::EF>,
507    ) -> Ext<C::F, C::EF> {
508        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
509        let idx = inner.get_mut().variable_count;
510        let res = Ext::new(idx, handle);
511        let inner = inner.get_mut();
512
513        inner.variable_count += 1;
514        inner.operations.push(DslIr::AddEFFI(res, lhs, rhs));
515
516        res
517    }
518
519    fn sub_ext(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: Ext<C::F, C::EF>) -> Ext<C::F, C::EF> {
520        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
521        let inner = inner.get_mut();
522        let idx = inner.variable_count;
523        let res = Ext::new(idx, lhs.handle);
524        inner.variable_count += 1;
525
526        inner.operations.push(DslIr::SubE(res, lhs, rhs));
527
528        res
529    }
530
531    fn sub_ext_base(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: Felt<C::F>) -> Ext<C::F, C::EF> {
532        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
533        let inner = inner.get_mut();
534        let idx = inner.variable_count;
535        let res = Ext::new(idx, lhs.handle);
536        inner.variable_count += 1;
537
538        inner.operations.push(DslIr::SubEF(res, lhs, rhs));
539
540        res
541    }
542
543    fn sub_const_ext(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: C::EF) -> Ext<C::F, C::EF> {
544        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
545        let inner = inner.get_mut();
546        let idx = inner.variable_count;
547        let res = Ext::new(idx, lhs.handle);
548        inner.variable_count += 1;
549
550        inner.operations.push(DslIr::SubEI(res, lhs, rhs));
551
552        res
553    }
554
555    fn sub_ext_const(ptr: *mut (), lhs: C::EF, rhs: Ext<C::F, C::EF>) -> Ext<C::F, C::EF> {
556        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
557        let inner = inner.get_mut();
558        let idx = inner.variable_count;
559        let res = Ext::new(idx, rhs.handle);
560        inner.variable_count += 1;
561
562        inner.operations.push(DslIr::SubEIN(res, lhs, rhs));
563
564        res
565    }
566
567    fn sub_felt_const_ext(
568        ptr: *mut (),
569        lhs: Felt<C::F>,
570        rhs: C::EF,
571        handle: *mut ExtHandle<C::F, C::EF>,
572    ) -> Ext<C::F, C::EF> {
573        Self::add_felt_const_ext(ptr, lhs, -rhs, handle)
574    }
575
576    fn sub_base_ext(ptr: *mut (), lhs: Felt<C::F>, rhs: Ext<C::F, C::EF>) -> Ext<C::F, C::EF> {
577        // TODO: optimize to one opcode.
578        let rhs = Self::neg_ext(ptr, rhs);
579        Self::add_ext_base(ptr, rhs, lhs)
580    }
581
582    fn neg_ext(ptr: *mut (), lhs: Ext<C::F, C::EF>) -> Ext<C::F, C::EF> {
583        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
584        let inner = inner.get_mut();
585        let idx = inner.variable_count;
586        let res = Ext::new(idx, lhs.handle);
587        inner.variable_count += 1;
588
589        inner.operations.push(DslIr::NegE(res, lhs));
590
591        res
592    }
593
594    fn mul_ext(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: Ext<C::F, C::EF>) -> Ext<C::F, C::EF> {
595        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
596        let inner = inner.get_mut();
597        let idx = inner.variable_count;
598        let res = Ext::new(idx, lhs.handle);
599        inner.variable_count += 1;
600
601        inner.operations.push(DslIr::MulE(res, lhs, rhs));
602
603        res
604    }
605
606    fn mul_ext_base(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: Felt<C::F>) -> Ext<C::F, C::EF> {
607        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
608        let inner = inner.get_mut();
609        let idx = inner.variable_count;
610        let res = Ext::new(idx, lhs.handle);
611        inner.variable_count += 1;
612
613        inner.operations.push(DslIr::MulEF(res, lhs, rhs));
614
615        res
616    }
617
618    fn mul_const_ext(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: C::EF) -> Ext<C::F, C::EF> {
619        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
620        let inner = inner.get_mut();
621        let idx = inner.variable_count;
622        let res = Ext::new(idx, lhs.handle);
623        inner.variable_count += 1;
624
625        inner.operations.push(DslIr::MulEI(res, lhs, rhs));
626
627        res
628    }
629
630    fn mul_felt_const_ext(
631        ptr: *mut (),
632        lhs: Felt<C::F>,
633        rhs: C::EF,
634        handle: *mut ExtHandle<C::F, C::EF>,
635    ) -> Ext<C::F, C::EF> {
636        // TODO: optimize to one opcode.
637        let lhs = Self::add_felt_const_ext(ptr, lhs, C::EF::zero(), handle);
638        Self::mul_const_ext(ptr, lhs, rhs)
639    }
640
641    fn div_ext(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: Ext<C::F, C::EF>) -> Ext<C::F, C::EF> {
642        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
643        let inner = inner.get_mut();
644        let idx = inner.variable_count;
645        let res = Ext::new(idx, lhs.handle);
646        inner.variable_count += 1;
647
648        inner.operations.push(DslIr::DivE(res, lhs, rhs));
649
650        res
651    }
652
653    fn div_const_base(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: C::F) -> Ext<C::F, C::EF> {
654        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
655        let inner = inner.get_mut();
656        let idx = inner.variable_count;
657        let res = Ext::new(idx, lhs.handle);
658        inner.variable_count += 1;
659
660        inner.operations.push(DslIr::DivEFI(res, lhs, rhs));
661
662        res
663    }
664
665    fn div_const_ext(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: C::EF) -> Ext<C::F, C::EF> {
666        Self::mul_const_ext(ptr, lhs, rhs.inverse())
667    }
668
669    fn div_base_ext(ptr: *mut (), lhs: Felt<C::F>, rhs: Ext<C::F, C::EF>) -> Ext<C::F, C::EF> {
670        // TODO: optimize to one opcode.
671        let lhs = Self::add_felt_const_ext(ptr, lhs, C::EF::zero(), rhs.handle);
672        Self::div_ext(ptr, lhs, rhs)
673    }
674
675    fn div_ext_base(ptr: *mut (), lhs: Ext<C::F, C::EF>, rhs: Felt<C::F>) -> Ext<C::F, C::EF> {
676        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
677        let inner = inner.get_mut();
678        let idx = inner.variable_count;
679        let res = Ext::new(idx, lhs.handle);
680        inner.variable_count += 1;
681
682        inner.operations.push(DslIr::DivEF(res, lhs, rhs));
683
684        res
685    }
686
687    fn div_ext_const(ptr: *mut (), lhs: C::EF, rhs: Ext<C::F, C::EF>) -> Ext<C::F, C::EF> {
688        let mut inner = unsafe { ManuallyDrop::new(Box::from_raw(ptr as *mut Self)) };
689        let inner = inner.get_mut();
690        let idx = inner.variable_count;
691        let res = Ext::new(idx, rhs.handle);
692        inner.variable_count += 1;
693
694        inner.operations.push(DslIr::DivEIN(res, lhs, rhs));
695
696        res
697    }
698
699    fn div_felt_const_ext(
700        ptr: *mut (),
701        lhs: Felt<C::F>,
702        rhs: C::EF,
703        handle: *mut ExtHandle<C::F, C::EF>,
704    ) -> Ext<C::F, C::EF> {
705        Self::mul_felt_const_ext(ptr, lhs, rhs.inverse(), handle)
706    }
707}
708
709impl<N> VarHandle<N> {
710    pub fn add_v(&self, lhs: Var<N>, rhs: Var<N>) -> Var<N> {
711        (self.add_var)(self.ptr, lhs, rhs)
712    }
713
714    pub fn sub_v(&self, lhs: Var<N>, rhs: Var<N>) -> Var<N> {
715        (self.sub_var)(self.ptr, lhs, rhs)
716    }
717
718    pub fn neg_v(&self, lhs: Var<N>) -> Var<N> {
719        (self.neg_var)(self.ptr, lhs)
720    }
721
722    pub fn mul_v(&self, lhs: Var<N>, rhs: Var<N>) -> Var<N> {
723        (self.mul_var)(self.ptr, lhs, rhs)
724    }
725
726    pub fn add_const_v(&self, lhs: Var<N>, rhs: N) -> Var<N> {
727        (self.add_var_const)(self.ptr, lhs, rhs)
728    }
729
730    pub fn add_v_const(&self, lhs: N, rhs: Var<N>) -> Var<N> {
731        self.add_const_v(rhs, lhs)
732    }
733
734    pub fn mul_const_v(&self, lhs: Var<N>, rhs: N) -> Var<N> {
735        (self.mul_var_const)(self.ptr, lhs, rhs)
736    }
737
738    pub fn mul_v_const(&self, lhs: N, rhs: Var<N>) -> Var<N> {
739        self.mul_const_v(rhs, lhs)
740    }
741
742    pub fn sub_const_v(&self, lhs: N, rhs: Var<N>) -> Var<N> {
743        (self.sub_const_var)(self.ptr, lhs, rhs)
744    }
745
746    pub fn sub_v_const(&self, lhs: Var<N>, rhs: N) -> Var<N> {
747        (self.sub_var_const)(self.ptr, lhs, rhs)
748    }
749}
750
751impl<F> FeltHandle<F> {
752    pub fn add_f(&self, lhs: Felt<F>, rhs: Felt<F>) -> Felt<F> {
753        (self.add_felt)(self.ptr, lhs, rhs)
754    }
755
756    pub fn add_const_f(&self, lhs: Felt<F>, rhs: F) -> Felt<F> {
757        (self.add_const_felt)(self.ptr, lhs, rhs)
758    }
759
760    pub fn add_f_const(&self, lhs: F, rhs: Felt<F>) -> Felt<F> {
761        self.add_const_f(rhs, lhs)
762    }
763
764    pub fn sub_f(&self, lhs: Felt<F>, rhs: Felt<F>) -> Felt<F> {
765        (self.sub_felt)(self.ptr, lhs, rhs)
766    }
767
768    pub fn sub_f_const(&self, lhs: Felt<F>, rhs: F) -> Felt<F> {
769        (self.sub_felt_const)(self.ptr, lhs, rhs)
770    }
771
772    pub fn sub_const_f(&self, lhs: F, rhs: Felt<F>) -> Felt<F> {
773        (self.sub_const_felt)(self.ptr, lhs, rhs)
774    }
775
776    pub fn neg_f(&self, lhs: Felt<F>) -> Felt<F> {
777        (self.neg_felt)(self.ptr, lhs)
778    }
779
780    pub fn mul_f(&self, lhs: Felt<F>, rhs: Felt<F>) -> Felt<F> {
781        (self.mul_felt)(self.ptr, lhs, rhs)
782    }
783
784    pub fn mul_const_f(&self, lhs: Felt<F>, rhs: F) -> Felt<F> {
785        (self.mul_felt_const)(self.ptr, lhs, rhs)
786    }
787
788    pub fn mul_f_const(&self, lhs: F, rhs: Felt<F>) -> Felt<F> {
789        self.mul_const_f(rhs, lhs)
790    }
791
792    pub fn div_f(&self, lhs: Felt<F>, rhs: Felt<F>) -> Felt<F> {
793        (self.div_felt)(self.ptr, lhs, rhs)
794    }
795
796    pub fn div_f_const(&self, lhs: Felt<F>, rhs: F) -> Felt<F> {
797        (self.div_felt_const)(self.ptr, lhs, rhs)
798    }
799
800    pub fn div_const_f(&self, lhs: F, rhs: Felt<F>) -> Felt<F> {
801        (self.div_const_felt)(self.ptr, lhs, rhs)
802    }
803}
804
805impl<F: Field, EF: AbstractExtensionField<F>> ExtHandle<F, EF> {
806    pub fn add_e(&self, lhs: Ext<F, EF>, rhs: Ext<F, EF>) -> Ext<F, EF> {
807        (self.add_ext)(self.ptr, lhs, rhs)
808    }
809
810    pub fn add_e_f(&self, lhs: Ext<F, EF>, rhs: Felt<F>) -> Ext<F, EF> {
811        (self.add_ext_base)(self.ptr, lhs, rhs)
812    }
813
814    pub fn add_f_e(&self, lhs: Felt<F>, rhs: Ext<F, EF>) -> Ext<F, EF> {
815        self.add_e_f(rhs, lhs)
816    }
817
818    pub fn add_e_const_f(&self, lhs: Ext<F, EF>, rhs: F) -> Ext<F, EF> {
819        (self.add_const_base)(self.ptr, lhs, rhs)
820    }
821
822    pub fn add_f_const_e(
823        &self,
824        lhs: Felt<F>,
825        rhs: EF,
826        handle: *mut ExtHandle<F, EF>,
827    ) -> Ext<F, EF> {
828        (self.add_felt_const_ext)(self.ptr, lhs, rhs, handle)
829    }
830
831    pub fn add_const_e_f(
832        &self,
833        lhs: EF,
834        rhs: Felt<F>,
835        handle: *mut ExtHandle<F, EF>,
836    ) -> Ext<F, EF> {
837        self.add_f_const_e(rhs, lhs, handle)
838    }
839
840    pub fn add_const_e(&self, lhs: Ext<F, EF>, rhs: EF) -> Ext<F, EF> {
841        (self.add_const_ext)(self.ptr, lhs, rhs)
842    }
843
844    pub fn add_e_const(&self, lhs: EF, rhs: Ext<F, EF>) -> Ext<F, EF> {
845        (self.add_const_ext)(self.ptr, rhs, lhs)
846    }
847
848    pub fn sub_e(&self, lhs: Ext<F, EF>, rhs: Ext<F, EF>) -> Ext<F, EF> {
849        (self.sub_ext)(self.ptr, lhs, rhs)
850    }
851
852    pub fn sub_e_f(&self, lhs: Ext<F, EF>, rhs: Felt<F>) -> Ext<F, EF> {
853        (self.sub_ext_base)(self.ptr, lhs, rhs)
854    }
855
856    pub fn sub_f_e(&self, lhs: Felt<F>, rhs: Ext<F, EF>) -> Ext<F, EF> {
857        (self.sub_base_ext)(self.ptr, lhs, rhs)
858    }
859
860    pub fn sub_e_const_f(&self, lhs: Ext<F, EF>, rhs: F) -> Ext<F, EF> {
861        (self.sub_const_ext)(self.ptr, lhs, EF::from_base(rhs))
862    }
863
864    pub fn sub_f_const_e(
865        &self,
866        lhs: Felt<F>,
867        rhs: EF,
868        handle: *mut ExtHandle<F, EF>,
869    ) -> Ext<F, EF> {
870        (self.sub_felt_const_ext)(self.ptr, lhs, rhs, handle)
871    }
872
873    pub fn sub_const_e_f(
874        &self,
875        lhs: EF,
876        rhs: Felt<F>,
877        handle: *mut ExtHandle<F, EF>,
878    ) -> Ext<F, EF> {
879        // TODO: optimize to one opcode.
880        let rhs = self.add_f_const_e(rhs, EF::zero(), handle);
881        self.sub_e_const(lhs, rhs)
882    }
883
884    pub fn sub_const_e(&self, lhs: Ext<F, EF>, rhs: EF) -> Ext<F, EF> {
885        (self.sub_const_ext)(self.ptr, lhs, rhs)
886    }
887
888    pub fn sub_e_const(&self, lhs: EF, rhs: Ext<F, EF>) -> Ext<F, EF> {
889        (self.sub_ext_const)(self.ptr, lhs, rhs)
890    }
891
892    pub fn neg_e(&self, lhs: Ext<F, EF>) -> Ext<F, EF> {
893        (self.neg_ext)(self.ptr, lhs)
894    }
895
896    pub fn mul_e(&self, lhs: Ext<F, EF>, rhs: Ext<F, EF>) -> Ext<F, EF> {
897        (self.mul_ext)(self.ptr, lhs, rhs)
898    }
899
900    pub fn mul_e_f(&self, lhs: Ext<F, EF>, rhs: Felt<F>) -> Ext<F, EF> {
901        (self.mul_ext_base)(self.ptr, lhs, rhs)
902    }
903
904    pub fn mul_f_e(&self, lhs: Felt<F>, rhs: Ext<F, EF>) -> Ext<F, EF> {
905        self.mul_e_f(rhs, lhs)
906    }
907
908    pub fn mul_e_const_f(&self, lhs: Ext<F, EF>, rhs: F) -> Ext<F, EF> {
909        (self.mul_const_ext)(self.ptr, lhs, EF::from_base(rhs))
910    }
911
912    pub fn mul_f_const_e(
913        &self,
914        lhs: Felt<F>,
915        rhs: EF,
916        handle: *mut ExtHandle<F, EF>,
917    ) -> Ext<F, EF> {
918        (self.mul_felt_const_ext)(self.ptr, lhs, rhs, handle)
919    }
920
921    pub fn mul_const_e_f(
922        &self,
923        lhs: EF,
924        rhs: Felt<F>,
925        handle: *mut ExtHandle<F, EF>,
926    ) -> Ext<F, EF> {
927        self.mul_f_const_e(rhs, lhs, handle)
928    }
929
930    pub fn mul_const_e(&self, lhs: Ext<F, EF>, rhs: EF) -> Ext<F, EF> {
931        (self.mul_const_ext)(self.ptr, lhs, rhs)
932    }
933
934    pub fn mul_e_const(&self, lhs: EF, rhs: Ext<F, EF>) -> Ext<F, EF> {
935        (self.mul_const_ext)(self.ptr, rhs, lhs)
936    }
937
938    pub fn div_e(&self, lhs: Ext<F, EF>, rhs: Ext<F, EF>) -> Ext<F, EF> {
939        (self.div_ext)(self.ptr, lhs, rhs)
940    }
941
942    pub fn div_e_f(&self, lhs: Ext<F, EF>, rhs: Felt<F>) -> Ext<F, EF> {
943        (self.div_ext_base)(self.ptr, lhs, rhs)
944    }
945
946    pub fn div_f_e(&self, lhs: Felt<F>, rhs: Ext<F, EF>) -> Ext<F, EF> {
947        (self.div_base_ext)(self.ptr, lhs, rhs)
948    }
949
950    pub fn div_e_const_f(&self, lhs: Ext<F, EF>, rhs: F) -> Ext<F, EF> {
951        (self.div_const_base)(self.ptr, lhs, rhs)
952    }
953
954    pub fn div_f_const_e(
955        &self,
956        lhs: Felt<F>,
957        rhs: EF,
958        handle: *mut ExtHandle<F, EF>,
959    ) -> Ext<F, EF> {
960        (self.div_felt_const_ext)(self.ptr, lhs, rhs, handle)
961    }
962
963    pub fn div_const_e(&self, lhs: Ext<F, EF>, rhs: EF) -> Ext<F, EF> {
964        (self.div_const_ext)(self.ptr, lhs, rhs)
965    }
966
967    pub fn div_e_const(&self, lhs: EF, rhs: Ext<F, EF>) -> Ext<F, EF> {
968        (self.div_ext_const)(self.ptr, lhs, rhs)
969    }
970}