sp1_recursion_compiler/ir/
utils.rs1use slop_algebra::{AbstractExtensionField, AbstractField};
2use sp1_primitives::{SP1ExtensionField, SP1Field};
3use std::ops::{Mul, MulAssign};
4
5use super::{Builder, Config, DslIr, Ext, Felt, SymbolicExt, Var, Variable};
6
7impl<C: Config> Builder<C> {
8 pub fn generator(&mut self) -> Felt<SP1Field> {
12 self.eval(SP1Field::generator())
13 }
14
15 pub fn select_v(&mut self, cond: Var<C::N>, a: Var<C::N>, b: Var<C::N>) -> Var<C::N> {
17 let c = self.uninit();
18 self.push_op(DslIr::CircuitSelectV(cond, a, b, c));
19 c
20 }
21
22 pub fn select_f(
24 &mut self,
25 cond: Var<C::N>,
26 a: Felt<SP1Field>,
27 b: Felt<SP1Field>,
28 ) -> Felt<SP1Field> {
29 let c = self.uninit();
30 self.push_op(DslIr::CircuitSelectF(cond, a, b, c));
31 c
32 }
33
34 pub fn select_ef(
36 &mut self,
37 cond: Var<C::N>,
38 a: Ext<SP1Field, SP1ExtensionField>,
39 b: Ext<SP1Field, SP1ExtensionField>,
40 ) -> Ext<SP1Field, SP1ExtensionField> {
41 let c = self.uninit();
42 self.push_op(DslIr::CircuitSelectE(cond, a, b, c));
43 c
44 }
45
46 pub fn exp_power_of_2<V: Variable<C>, E: Into<V::Expression>>(
48 &mut self,
49 e: E,
50 power_log: usize,
51 ) -> V
52 where
53 V::Expression: MulAssign<V::Expression> + Clone,
54 {
55 let mut e = e.into();
56 for _ in 0..power_log {
57 e *= e.clone();
58 }
59 self.eval(e)
60 }
61
62 pub fn exp_f_bits(&mut self, x: Felt<SP1Field>, power_bits: Vec<Var<C::N>>) -> Felt<SP1Field> {
64 let mut result = self.eval(SP1Field::one());
65 let mut power_f: Felt<_> = self.eval(x);
66 for i in 0..power_bits.len() {
67 let bit = power_bits[i];
68 let tmp = self.eval(result * power_f);
69 result = self.select_f(bit, tmp, result);
70 power_f = self.eval(power_f * power_f);
71 }
72 result
73 }
74
75 pub fn exp_e_bits(
77 &mut self,
78 x: Ext<SP1Field, SP1ExtensionField>,
79 power_bits: Vec<Var<C::N>>,
80 ) -> Ext<SP1Field, SP1ExtensionField> {
81 let mut result = self.eval(SymbolicExt::from_f(SP1ExtensionField::one()));
82 let mut power_f: Ext<_, _> = self.eval(x);
83 for i in 0..power_bits.len() {
84 let bit = power_bits[i];
85 let tmp = self.eval(result * power_f);
86 result = self.select_ef(bit, tmp, result);
87 power_f = self.eval(power_f * power_f);
88 }
89 result
90 }
91
92 pub fn exp_power_of_2_v_circuit<V>(
94 &mut self,
95 base: impl Into<V::Expression>,
96 power_log: usize,
97 ) -> V
98 where
99 V: Copy + Mul<Output = V::Expression> + Variable<C>,
100 {
101 let mut result: V = self.eval(base);
102 for _ in 0..power_log {
103 result = self.eval(result * result)
104 }
105 result
106 }
107
108 pub fn ext_from_base_slice(
110 &mut self,
111 arr: &[Felt<SP1Field>],
112 ) -> Ext<SP1Field, SP1ExtensionField> {
113 assert!(arr.len() <= <SP1ExtensionField as AbstractExtensionField<SP1Field>>::D);
114 let mut res = SymbolicExt::from_f(SP1ExtensionField::zero());
115 for i in 0..arr.len() {
116 res += arr[i]
117 * SymbolicExt::from_f(
118 <SP1ExtensionField as AbstractExtensionField<SP1Field>>::monomial(i),
119 );
120 }
121 self.eval(res)
122 }
123
124 pub fn felts2ext(&mut self, felts: &[Felt<SP1Field>]) -> Ext<SP1Field, SP1ExtensionField> {
125 assert_eq!(felts.len(), 4);
126 let out: Ext<SP1Field, SP1ExtensionField> = self.uninit();
127 self.push_op(DslIr::CircuitFelts2Ext(felts.try_into().unwrap(), out));
128 out
129 }
130
131 pub fn ext2felt_circuit(
133 &mut self,
134 value: Ext<SP1Field, SP1ExtensionField>,
135 ) -> [Felt<SP1Field>; 4] {
136 let a = self.uninit();
137 let b = self.uninit();
138 let c = self.uninit();
139 let d = self.uninit();
140 self.push_op(DslIr::CircuitExt2Felt([a, b, c, d], value));
141 [a, b, c, d]
142 }
143}