lambdaworks_math/circle/
cosets.rs1extern crate alloc;
2use crate::circle::point::CirclePoint;
3use crate::field::fields::mersenne31::field::Mersenne31Field;
4#[cfg(feature = "alloc")]
5use alloc::vec::Vec;
6
7#[derive(Debug, Clone)]
14pub struct Coset {
15 pub log_2_size: u32, pub shift: CirclePoint<Mersenne31Field>,
19}
20
21impl Coset {
22 pub fn new(log_2_size: u32, shift: CirclePoint<Mersenne31Field>) -> Self {
23 Coset { log_2_size, shift }
24 }
25
26 pub fn new_standard(log_2_size: u32) -> Self {
28 let shift = CirclePoint::get_generator_of_subgroup(log_2_size + 1);
30 Coset { log_2_size, shift }
31 }
32
33 pub fn get_generator(&self) -> CirclePoint<Mersenne31Field> {
35 CirclePoint::GENERATOR.repeated_double(31 - self.log_2_size)
36 }
37
38 pub fn half_coset(coset: Self) -> Self {
40 Coset {
41 log_2_size: coset.log_2_size - 1,
42 shift: coset.shift,
43 }
44 }
45
46 pub fn conjugate(coset: Self) -> Self {
49 Coset {
50 log_2_size: coset.log_2_size,
51 shift: coset.shift.conjugate(),
52 }
53 }
54
55 #[cfg(feature = "alloc")]
58 pub fn get_coset_points(coset: &Self) -> Vec<CirclePoint<Mersenne31Field>> {
59 let generator_n = CirclePoint::get_generator_of_subgroup(coset.log_2_size);
61 let size: usize = 1 << coset.log_2_size;
62 core::iter::successors(Some(coset.shift.clone()), move |prev| {
63 Some(prev + &generator_n)
64 })
65 .take(size)
66 .collect()
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn coset_points_vector_has_right_size() {
76 let coset = Coset::new_standard(3);
77 let points = Coset::get_coset_points(&coset);
78 assert_eq!(1 << coset.log_2_size, points.len())
79 }
80
81 #[test]
82 fn antipode_of_coset_point_is_in_coset() {
83 let coset = Coset::new_standard(3);
84 let points = Coset::get_coset_points(&coset);
85 let point = points[2].clone();
86 let anitpode_point = points[6].clone();
87 assert_eq!(anitpode_point, point.antipode())
88 }
89
90 #[test]
91 fn coset_generator_has_right_order() {
92 let coset = Coset::new(2, CirclePoint::GENERATOR * 3);
93 let generator_n = coset.get_generator();
94 assert_eq!(generator_n.repeated_double(2), CirclePoint::zero());
95 }
96}