sp1_recursion_circuit_v2/
domain.rs1use p3_commit::{LagrangeSelectors, PolynomialSpace, TwoAdicMultiplicativeCoset};
2use p3_field::{AbstractExtensionField, AbstractField, Field, TwoAdicField};
3use sp1_recursion_compiler::prelude::*;
4
5pub trait PolynomialSpaceVariable<C: Config>: Sized + PolynomialSpace<Val = C::F> {
7 fn selectors_at_point_variable(
8 &self,
9 builder: &mut Builder<C>,
10 point: Ext<C::F, C::EF>,
11 ) -> LagrangeSelectors<Ext<C::F, C::EF>>;
12
13 fn zp_at_point_variable(
14 &self,
15 builder: &mut Builder<C>,
16 point: Ext<C::F, C::EF>,
17 ) -> Ext<C::F, C::EF>;
18
19 fn next_point_variable(
20 &self,
21 builder: &mut Builder<C>,
22 point: Ext<<C as Config>::F, <C as Config>::EF>,
23 ) -> Ext<<C as Config>::F, <C as Config>::EF>;
24
25 fn zp_at_point_f(
26 &self,
27 builder: &mut Builder<C>,
28 point: Felt<<C as Config>::F>,
29 ) -> Felt<<C as Config>::F>;
30}
31
32impl<C: Config> PolynomialSpaceVariable<C> for TwoAdicMultiplicativeCoset<C::F>
33where
34 C::F: TwoAdicField,
35{
36 fn next_point_variable(
37 &self,
38 builder: &mut Builder<C>,
39 point: Ext<<C as Config>::F, <C as Config>::EF>,
40 ) -> Ext<<C as Config>::F, <C as Config>::EF> {
41 let g = C::F::two_adic_generator(self.log_n);
42 builder.eval(point * g)
44 }
45
46 fn selectors_at_point_variable(
47 &self,
48 builder: &mut Builder<C>,
49 point: Ext<<C as Config>::F, <C as Config>::EF>,
50 ) -> LagrangeSelectors<Ext<<C as Config>::F, <C as Config>::EF>> {
51 let unshifted_point: Ext<_, _> = builder.eval(point * self.shift.inverse());
52 let z_h_expr = builder
53 .exp_power_of_2_v::<Ext<_, _>>(unshifted_point, Usize::Const(self.log_n))
54 - C::EF::one();
55 let z_h: Ext<_, _> = builder.eval(z_h_expr);
56 let g = C::F::two_adic_generator(self.log_n);
57 let ginv = g.inverse();
58 LagrangeSelectors {
59 is_first_row: builder.eval(z_h / (unshifted_point - C::EF::one())),
60 is_last_row: builder.eval(z_h / (unshifted_point - ginv)),
61 is_transition: builder.eval(unshifted_point - ginv),
62 inv_zeroifier: builder.eval(z_h.inverse()),
63 }
64 }
65
66 fn zp_at_point_variable(
67 &self,
68 builder: &mut Builder<C>,
69 point: Ext<<C as Config>::F, <C as Config>::EF>,
70 ) -> Ext<<C as Config>::F, <C as Config>::EF> {
71 let unshifted_power = builder.exp_power_of_2_v::<Ext<_, _>>(
72 point
73 * C::EF::from_base_slice(&[self.shift, C::F::zero(), C::F::zero(), C::F::zero()])
74 .inverse()
75 .cons(),
76 Usize::Const(self.log_n),
77 );
78 builder.eval(unshifted_power - C::EF::one())
79 }
80 fn zp_at_point_f(
81 &self,
82 builder: &mut Builder<C>,
83 point: Felt<<C as Config>::F>,
84 ) -> Felt<<C as Config>::F> {
85 let unshifted_power = builder
86 .exp_power_of_2_v::<Felt<_>>(point * self.shift.inverse(), Usize::Const(self.log_n));
87 builder.eval(unshifted_power - C::F::one())
88 }
89}