poulpy/poulpy-core/src/layouts/lwe_to_glwe_ksk.rs
poulpy-core/src/layouts/lwe_to_glwe_ksk.rsRaw
1use std::fmt;
2
3use poulpy_hal::{
4 layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
5 source::Source,
6};
7
8use crate::layouts::{Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, TorusPrecision};
9
10#[derive(PartialEq, Eq, Copy, Clone, Debug)]
11pub struct LWEToGLWESwitchingKeyLayout {
12 pub n: Degree,
13 pub base2k: Base2K,
14 pub k: TorusPrecision,
15 pub rank_out: Rank,
16 pub dnum: Dnum,
17}
18
19impl LWEInfos for LWEToGLWESwitchingKeyLayout {
20 fn base2k(&self) -> Base2K {
21 self.base2k
22 }
23
24 fn k(&self) -> TorusPrecision {
25 self.k
26 }
27
28 fn n(&self) -> Degree {
29 self.n
30 }
31}
32
33impl GLWEInfos for LWEToGLWESwitchingKeyLayout {
34 fn rank(&self) -> Rank {
35 self.rank_out()
36 }
37}
38
39impl GGLWEInfos for LWEToGLWESwitchingKeyLayout {
40 fn rank_in(&self) -> Rank {
41 Rank(1)
42 }
43
44 fn dsize(&self) -> Dsize {
45 Dsize(1)
46 }
47
48 fn rank_out(&self) -> Rank {
49 self.rank_out
50 }
51
52 fn dnum(&self) -> Dnum {
53 self.dnum
54 }
55}
56
57#[derive(PartialEq, Eq, Clone)]
58pub struct LWEToGLWESwitchingKey<D: Data>(pub(crate) GGLWESwitchingKey<D>);
59
60impl<D: Data> LWEInfos for LWEToGLWESwitchingKey<D> {
61 fn base2k(&self) -> Base2K {
62 self.0.base2k()
63 }
64
65 fn k(&self) -> TorusPrecision {
66 self.0.k()
67 }
68
69 fn n(&self) -> Degree {
70 self.0.n()
71 }
72
73 fn size(&self) -> usize {
74 self.0.size()
75 }
76}
77
78impl<D: Data> GLWEInfos for LWEToGLWESwitchingKey<D> {
79 fn rank(&self) -> Rank {
80 self.rank_out()
81 }
82}
83impl<D: Data> GGLWEInfos for LWEToGLWESwitchingKey<D> {
84 fn dsize(&self) -> Dsize {
85 self.0.dsize()
86 }
87
88 fn rank_in(&self) -> Rank {
89 self.0.rank_in()
90 }
91
92 fn rank_out(&self) -> Rank {
93 self.0.rank_out()
94 }
95
96 fn dnum(&self) -> Dnum {
97 self.0.dnum()
98 }
99}
100
101impl<D: DataRef> fmt::Debug for LWEToGLWESwitchingKey<D> {
102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103 write!(f, "{self}")
104 }
105}
106
107impl<D: DataMut> FillUniform for LWEToGLWESwitchingKey<D> {
108 fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
109 self.0.fill_uniform(log_bound, source);
110 }
111}
112
113impl<D: DataRef> fmt::Display for LWEToGLWESwitchingKey<D> {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 write!(f, "(LWEToGLWESwitchingKey) {}", self.0)
116 }
117}
118
119impl<D: DataMut> ReaderFrom for LWEToGLWESwitchingKey<D> {
120 fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
121 self.0.read_from(reader)
122 }
123}
124
125impl<D: DataRef> WriterTo for LWEToGLWESwitchingKey<D> {
126 fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
127 self.0.write_to(writer)
128 }
129}
130
131impl LWEToGLWESwitchingKey<Vec<u8>> {
132 pub fn alloc<A>(infos: &A) -> Self
133 where
134 A: GGLWEInfos,
135 {
136 debug_assert_eq!(
137 infos.rank_in().0,
138 1,
139 "rank_in > 1 is not supported for LWEToGLWESwitchingKey"
140 );
141 debug_assert_eq!(
142 infos.dsize().0,
143 1,
144 "dsize > 1 is not supported for LWEToGLWESwitchingKey"
145 );
146 Self(GGLWESwitchingKey::alloc(infos))
147 }
148
149 pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self {
150 Self(GGLWESwitchingKey::alloc_with(
151 n,
152 base2k,
153 k,
154 Rank(1),
155 rank_out,
156 dnum,
157 Dsize(1),
158 ))
159 }
160
161 pub fn alloc_bytes<A>(infos: &A) -> usize
162 where
163 A: GGLWEInfos,
164 {
165 debug_assert_eq!(
166 infos.rank_in().0,
167 1,
168 "rank_in > 1 is not supported for LWEToGLWESwitchingKey"
169 );
170 debug_assert_eq!(
171 infos.dsize().0,
172 1,
173 "dsize > 1 is not supported for LWEToGLWESwitchingKey"
174 );
175 GGLWESwitchingKey::alloc_bytes(infos)
176 }
177
178 pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_out: Rank) -> usize {
179 GGLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), rank_out, dnum, Dsize(1))
180 }
181}