poulpy/poulpy-core/src/layouts/glwe_tensor.rs
poulpy-core/src/layouts/glwe_tensor.rsRaw
1use poulpy_hal::{
2 layouts::{Data, DataMut, DataRef, FillUniform, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos},
3 source::Source,
4};
5
6use crate::layouts::{Base2K, Degree, GLWE, GLWEInfos, GLWEToMut, GLWEToRef, LWEInfos, Rank, SetGLWEInfos, TorusPrecision};
7use std::fmt;
8
9#[derive(PartialEq, Eq, Clone)]
10pub struct GLWETensor<D: Data> {
11 pub(crate) data: VecZnx<D>,
12 pub(crate) base2k: Base2K,
13 pub(crate) rank: Rank,
14 pub(crate) k: TorusPrecision,
15}
16
17impl<D: DataMut> SetGLWEInfos for GLWETensor<D> {
18 fn set_base2k(&mut self, base2k: Base2K) {
19 self.base2k = base2k
20 }
21
22 fn set_k(&mut self, k: TorusPrecision) {
23 self.k = k
24 }
25}
26
27impl<D: DataRef> GLWETensor<D> {
28 pub fn data(&self) -> &VecZnx<D> {
29 &self.data
30 }
31}
32
33impl<D: DataMut> GLWETensor<D> {
34 pub fn data_mut(&mut self) -> &mut VecZnx<D> {
35 &mut self.data
36 }
37}
38
39impl<D: Data> LWEInfos for GLWETensor<D> {
40 fn base2k(&self) -> Base2K {
41 self.base2k
42 }
43
44 fn k(&self) -> TorusPrecision {
45 self.k
46 }
47
48 fn n(&self) -> Degree {
49 Degree(self.data.n() as u32)
50 }
51
52 fn size(&self) -> usize {
53 self.data.size()
54 }
55}
56
57impl<D: Data> GLWEInfos for GLWETensor<D> {
58 fn rank(&self) -> Rank {
59 self.rank
60 }
61}
62
63impl<D: DataRef> fmt::Debug for GLWETensor<D> {
64 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65 write!(f, "{self}")
66 }
67}
68
69impl<D: DataRef> fmt::Display for GLWETensor<D> {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 write!(f, "GLWETensor: base2k={} k={}: {}", self.base2k().0, self.k().0, self.data)
72 }
73}
74
75impl<D: DataMut> FillUniform for GLWETensor<D> {
76 fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
77 self.data.fill_uniform(log_bound, source);
78 }
79}
80
81impl GLWETensor<Vec<u8>> {
82 pub fn alloc_from_infos<A>(infos: &A) -> Self
83 where
84 A: GLWEInfos,
85 {
86 Self::alloc(infos.n(), infos.base2k(), infos.k(), infos.rank())
87 }
88
89 pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
90 let cols: usize = rank.as_usize() + 1;
91 let pairs: usize = (((cols + 1) * cols) >> 1).max(1);
92 GLWETensor {
93 data: VecZnx::alloc(n.into(), pairs, k.0.div_ceil(base2k.0) as usize),
94 base2k,
95 k,
96 rank,
97 }
98 }
99
100 pub fn bytes_of_from_infos<A>(infos: &A) -> usize
101 where
102 A: GLWEInfos,
103 {
104 Self::bytes_of(infos.n(), infos.base2k(), infos.k(), infos.rank())
105 }
106
107 pub fn bytes_of(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
108 let cols: usize = rank.as_usize() + 1;
109 let pairs: usize = (((cols + 1) * cols) >> 1).max(1);
110 VecZnx::bytes_of(n.into(), pairs, k.0.div_ceil(base2k.0) as usize)
111 }
112}
113
114impl<D: DataRef> GLWEToRef for GLWETensor<D> {
115 fn to_ref(&self) -> GLWE<&[u8]> {
116 GLWE {
117 k: self.k,
118 base2k: self.base2k,
119 data: self.data.to_ref(),
120 }
121 }
122}
123
124impl<D: DataMut> GLWEToMut for GLWETensor<D> {
125 fn to_mut(&mut self) -> GLWE<&mut [u8]> {
126 GLWE {
127 k: self.k,
128 base2k: self.base2k,
129 data: self.data.to_mut(),
130 }
131 }
132}