1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use crate::boolean::Boolean;
use crate::eq::EqGadget;
use crate::fields::fp::FpVar;
use crate::fields::FieldVar;
use ark_ff::PrimeField;
use ark_relations::r1cs::SynthesisError;
use ark_std::vec::Vec;
pub mod vanishing_poly;
#[derive(Clone, Debug)]
pub struct Radix2DomainVar<F: PrimeField> {
pub gen: F,
pub offset: FpVar<F>,
pub dim: u64,
}
impl<F: PrimeField> EqGadget<F> for Radix2DomainVar<F> {
fn is_eq(&self, other: &Self) -> Result<Boolean<F>, SynthesisError> {
if self.gen != other.gen || self.dim != other.dim {
Ok(Boolean::constant(false))
} else {
self.offset.is_eq(&other.offset)
}
}
}
impl<F: PrimeField> Radix2DomainVar<F> {
pub fn order(&self) -> usize {
1 << self.dim
}
fn powers_of_gen(&self, dim: usize) -> Vec<F> {
let mut result = Vec::new();
let mut cur = self.gen;
for _ in 0..dim {
result.push(cur);
cur = cur * cur;
}
result
}
pub fn size(&self) -> u64 {
1 << self.dim
}
pub fn query_position_to_coset(
&self,
query_pos: &[Boolean<F>],
coset_dim: u64,
) -> Result<Vec<FpVar<F>>, SynthesisError> {
let mut coset_index = query_pos;
assert!(
query_pos.len() == self.dim as usize
|| query_pos.len() == (self.dim - coset_dim) as usize
);
if query_pos.len() == self.dim as usize {
coset_index = &coset_index[0..(coset_index.len() - coset_dim as usize)];
}
let mut coset = Vec::new();
let powers_of_g = &self.powers_of_gen(self.dim as usize)[(coset_dim as usize)..];
let mut first_point_in_coset: FpVar<F> = FpVar::zero();
for i in 0..coset_index.len() {
let term = coset_index[i].select(&FpVar::constant(powers_of_g[i]), &FpVar::zero())?;
first_point_in_coset += &term;
}
first_point_in_coset *= &self.offset;
coset.push(first_point_in_coset);
for i in 1..(1 << (coset_dim as usize)) {
let new_elem = &coset[i - 1] * &FpVar::Constant(self.gen);
coset.push(new_elem);
}
Ok(coset)
}
}