openvm_native_recursion/
utils.rs1use openvm_native_compiler::ir::{Builder, CanSelect, Config, Felt, MemVariable, Var};
2use openvm_stark_backend::p3_field::{
3 coset::TwoAdicMultiplicativeCoset, PrimeCharacteristicRing, TwoAdicField,
4};
5use openvm_stark_sdk::config::FriParameters;
6
7use crate::fri::{types::FriConfigVariable, TwoAdicMultiplicativeCosetVariable};
8
9pub fn const_fri_config<C: Config>(
10 builder: &mut Builder<C>,
11 params: &FriParameters,
12) -> FriConfigVariable<C> {
13 let two_adicity = C::F::TWO_ADICITY;
14 let generators = builder.array(two_adicity + 1);
15 let subgroups = builder.array(two_adicity + 1);
16 for i in 0..=C::F::TWO_ADICITY {
17 let constant_generator = C::F::two_adic_generator(i);
18 builder.set(&generators, i, constant_generator);
19
20 let constant_domain = TwoAdicMultiplicativeCoset::new(C::F::ONE, i).unwrap();
21 let domain_value: TwoAdicMultiplicativeCosetVariable<_> = builder.constant(constant_domain);
22 builder.set_value(&subgroups, i, domain_value);
25 }
26 FriConfigVariable {
27 log_blowup: params.log_blowup,
28 blowup: 1 << params.log_blowup,
29 log_final_poly_len: params.log_final_poly_len,
30 num_queries: params.num_queries,
31 commit_proof_of_work_bits: params.commit_proof_of_work_bits,
32 query_proof_of_work_bits: params.query_proof_of_work_bits,
33 subgroups,
34 generators,
35 }
36}
37
38pub fn reduce_32<C: Config>(builder: &mut Builder<C>, vals: &[Felt<C::F>]) -> Var<C::N> {
40 let mut power = C::N::ONE;
41 let result: Var<C::N> = builder.eval(C::N::ZERO);
42 for val in vals.iter() {
43 let val = builder.cast_felt_to_var(*val);
44 builder.assign(&result, result + val * power);
45 power *= C::N::from_usize(1usize << 32);
46 }
47 result
48}
49
50pub fn split_32<C: Config>(builder: &mut Builder<C>, val: Var<C::N>, n: usize) -> Vec<Felt<C::F>> {
52 let felts = builder.var_to_64bits_f_circuit(val);
53 assert!(n <= felts.len());
54 felts[0..n].to_vec()
55}
56
57pub fn cond_eval<C: Config, V: MemVariable<C, Expression: Clone> + CanSelect<C>>(
60 builder: &mut Builder<C>,
61 cond: Var<C::N>,
62 v1: impl Into<V::Expression>,
63 v2: impl Into<V::Expression>,
64) -> [V; 2] {
65 let a: V;
66 let b: V;
67 if builder.flags.static_only {
68 let v1: V = builder.eval(v1.into());
69 let v2: V = builder.eval(v2.into());
70 a = V::select(builder, cond, v2.clone(), v1.clone());
71 b = V::select(builder, cond, v1, v2);
72 } else {
73 let v1 = v1.into();
74 let v2 = v2.into();
75 a = builder.uninit();
76 b = builder.uninit();
77 builder.if_eq(cond, C::N::ONE).then_or_else(
78 |builder| {
79 builder.assign(&a, v2.clone());
80 builder.assign(&b, v1.clone());
81 },
82 |builder| {
83 builder.assign(&a, v1.clone());
84 builder.assign(&b, v2.clone());
85 },
86 );
87 }
88 [a, b]
89}