poulpy/rlwe/src/elem.rs
rlwe/src/elem.rsRaw
1use crate::parameters::Parameters;
2use base2k::{Infos, Module, VecZnx, VecZnxApi, VecZnxBorrow, VecZnxOps};
3
4
5impl Parameters {
6 pub fn bytes_of_elem(&self, log_q: usize, degree: usize) -> usize {
7 Elem::<VecZnx>::bytes_of(self.module(), self.log_base2k(), log_q, degree)
8 }
9
10 pub fn elem_from_bytes(&self, log_q: usize, degree: usize, bytes: &mut [u8]) -> Elem<VecZnx> {
11 Elem::<VecZnx>::from_bytes(self.module(), self.log_base2k(), log_q, degree, bytes)
12 }
13
14 pub fn elem_borrow_from_bytes(&self, log_q: usize, degree: usize, bytes: &mut [u8]) -> Elem<VecZnxBorrow> {
15 Elem::<VecZnxBorrow>::from_bytes(self.module(), self.log_base2k(), log_q, degree, bytes)
16 }
17}
18
19pub struct Elem<T: VecZnxApi + Infos> {
20 pub value: Vec<T>,
21 pub log_base2k: usize,
22 pub log_q: usize,
23 pub log_scale: usize,
24}
25
26pub trait ElemBasics<T>
27where
28 T: VecZnxApi + Infos,
29{
30 fn n(&self) -> usize;
31 fn degree(&self) -> usize;
32 fn limbs(&self) -> usize;
33 fn log_base2k(&self) -> usize;
34 fn log_scale(&self) -> usize;
35 fn log_q(&self) -> usize;
36 fn at(&self, i: usize) -> &T;
37 fn at_mut(&mut self, i: usize) -> &mut T;
38 fn zero(&mut self);
39}
40
41impl Elem<VecZnx> {
42 pub fn new(
43 module: &Module,
44 log_base2k: usize,
45 log_q: usize,
46 degree: usize,
47 log_scale: usize,
48 ) -> Self {
49 let limbs: usize = (log_q + log_base2k - 1) / log_base2k;
50 let mut value: Vec<VecZnx> = Vec::new();
51 (0..degree + 1).for_each(|_| value.push(module.new_vec_znx(limbs)));
52 Self {
53 value,
54 log_q,
55 log_base2k,
56 log_scale: log_scale,
57 }
58 }
59
60 pub fn bytes_of(module: &Module, log_base2k: usize, log_q: usize, degree: usize) -> usize {
61 let cols = (log_q + log_base2k - 1) / log_base2k;
62 module.n() * cols * (degree + 1) * 8
63 }
64
65 pub fn from_bytes(
66 module: &Module,
67 log_base2k: usize,
68 log_q: usize,
69 degree: usize,
70 bytes: &mut [u8],
71 ) -> Self {
72 let n: usize = module.n();
73 assert!(bytes.len() >= Self::bytes_of(module, log_base2k, log_q, degree));
74 let mut value: Vec<VecZnx> = Vec::new();
75 let limbs: usize = (log_q + log_base2k - 1) / log_base2k;
76 let size = VecZnx::bytes_of(n, limbs);
77 let mut ptr: usize = 0;
78 (0..degree + 1).for_each(|_| {
79 value.push(VecZnx::from_bytes(n, limbs, &mut bytes[ptr..]));
80 ptr += size
81 });
82 Self {
83 value,
84 log_q,
85 log_base2k,
86 log_scale: 0,
87 }
88 }
89}
90
91impl Elem<VecZnxBorrow> {
92
93 pub fn bytes_of(module: &Module, log_base2k: usize, log_q: usize, degree: usize) -> usize {
94 let cols = (log_q + log_base2k - 1) / log_base2k;
95 module.n() * cols * (degree + 1) * 8
96 }
97
98 pub fn from_bytes(
99 module: &Module,
100 log_base2k: usize,
101 log_q: usize,
102 degree: usize,
103 bytes: &mut [u8],
104 ) -> Self {
105 let n: usize = module.n();
106 assert!(bytes.len() >= Self::bytes_of(module, log_base2k, log_q, degree));
107 let mut value: Vec<VecZnxBorrow> = Vec::new();
108 let limbs: usize = (log_q + log_base2k - 1) / log_base2k;
109 let size = VecZnxBorrow::bytes_of(n, limbs);
110 let mut ptr: usize = 0;
111 (0..degree + 1).for_each(|_| {
112 value.push(VecZnxBorrow::from_bytes(n, limbs, &mut bytes[ptr..]));
113 ptr += size
114 });
115 Self {
116 value,
117 log_q,
118 log_base2k,
119 log_scale: 0,
120 }
121 }
122}
123
124
125impl<T: VecZnxApi + Infos> ElemBasics<T> for Elem<T> {
126 fn n(&self) -> usize {
127 self.value[0].n()
128 }
129
130 fn degree(&self) -> usize {
131 self.value.len()
132 }
133
134 fn limbs(&self) -> usize {
135 self.value[0].limbs()
136 }
137
138 fn log_base2k(&self) -> usize {
139 self.log_base2k
140 }
141
142 fn log_scale(&self) -> usize {
143 self.log_scale
144 }
145
146 fn log_q(&self) -> usize {
147 self.log_q
148 }
149
150 fn at(&self, i: usize) -> &T {
151 assert!(i <= self.degree());
152 &self.value[i]
153 }
154
155 fn at_mut(&mut self, i: usize) -> &mut T {
156 assert!(i <= self.degree());
157 &mut self.value[i]
158 }
159
160 fn zero(&mut self) {
161 self.value.iter_mut().for_each(|i| i.zero());
162 }
163}