poulpy/core/src/gglwe/automorphism_key.rs
core/src/gglwe/automorphism_key.rsRaw
1use backend::hal::{
2 api::{MatZnxAlloc, MatZnxAllocBytes},
3 layouts::{Backend, Data, DataMut, DataRef, MatZnx, Module, ReaderFrom, Scratch, VmpPMat, WriterTo},
4};
5
6use crate::{GGLWEExecLayoutFamily, GLWECiphertext, GLWESwitchingKey, GLWESwitchingKeyExec, Infos};
7
8#[derive(PartialEq, Eq)]
9pub struct AutomorphismKey<D: Data> {
10 pub(crate) key: GLWESwitchingKey<D>,
11 pub(crate) p: i64,
12}
13
14impl AutomorphismKey<Vec<u8>> {
15 pub fn alloc<B: Backend>(module: &Module<B>, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> Self
16 where
17 Module<B>: MatZnxAlloc,
18 {
19 AutomorphismKey {
20 key: GLWESwitchingKey::alloc(module, basek, k, rows, digits, rank, rank),
21 p: 0,
22 }
23 }
24
25 pub fn bytes_of<B: Backend>(module: &Module<B>, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> usize
26 where
27 Module<B>: MatZnxAllocBytes,
28 {
29 GLWESwitchingKey::<Vec<u8>>::bytes_of(module, basek, k, rows, digits, rank, rank)
30 }
31}
32
33impl<D: Data> Infos for AutomorphismKey<D> {
34 type Inner = MatZnx<D>;
35
36 fn inner(&self) -> &Self::Inner {
37 &self.key.inner()
38 }
39
40 fn basek(&self) -> usize {
41 self.key.basek()
42 }
43
44 fn k(&self) -> usize {
45 self.key.k()
46 }
47}
48
49impl<D: Data> AutomorphismKey<D> {
50 pub fn p(&self) -> i64 {
51 self.p
52 }
53
54 pub fn digits(&self) -> usize {
55 self.key.digits()
56 }
57
58 pub fn rank(&self) -> usize {
59 self.key.rank()
60 }
61
62 pub fn rank_in(&self) -> usize {
63 self.key.rank_in()
64 }
65
66 pub fn rank_out(&self) -> usize {
67 self.key.rank_out()
68 }
69}
70
71impl<D: DataRef> AutomorphismKey<D> {
72 pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
73 self.key.at(row, col)
74 }
75}
76
77impl<D: DataMut> AutomorphismKey<D> {
78 pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
79 self.key.at_mut(row, col)
80 }
81}
82
83use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
84
85impl<D: DataMut> ReaderFrom for AutomorphismKey<D> {
86 fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
87 self.p = reader.read_u64::<LittleEndian>()? as i64;
88 self.key.read_from(reader)
89 }
90}
91
92impl<D: DataRef> WriterTo for AutomorphismKey<D> {
93 fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
94 writer.write_u64::<LittleEndian>(self.p as u64)?;
95 self.key.write_to(writer)
96 }
97}
98
99#[derive(PartialEq, Eq)]
100pub struct AutomorphismKeyExec<D: Data, B: Backend> {
101 pub(crate) key: GLWESwitchingKeyExec<D, B>,
102 pub(crate) p: i64,
103}
104
105impl<B: Backend> AutomorphismKeyExec<Vec<u8>, B> {
106 pub fn alloc(module: &Module<B>, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> Self
107 where
108 Module<B>: GGLWEExecLayoutFamily<B>,
109 {
110 AutomorphismKeyExec::<Vec<u8>, B> {
111 key: GLWESwitchingKeyExec::alloc(module, basek, k, rows, digits, rank, rank),
112 p: 0,
113 }
114 }
115
116 pub fn bytes_of(module: &Module<B>, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> usize
117 where
118 Module<B>: GGLWEExecLayoutFamily<B>,
119 {
120 GLWESwitchingKeyExec::<Vec<u8>, B>::bytes_of(module, basek, k, rows, digits, rank, rank)
121 }
122
123 pub fn from<DataOther: DataRef>(module: &Module<B>, other: &AutomorphismKey<DataOther>, scratch: &mut Scratch<B>) -> Self
124 where
125 Module<B>: GGLWEExecLayoutFamily<B>,
126 {
127 let mut atk_exec: AutomorphismKeyExec<Vec<u8>, B> = Self::alloc(
128 module,
129 other.basek(),
130 other.k(),
131 other.rows(),
132 other.digits(),
133 other.rank(),
134 );
135 atk_exec.prepare(module, other, scratch);
136 atk_exec
137 }
138}
139
140impl<D: DataMut, B: Backend> AutomorphismKeyExec<D, B> {
141 pub fn prepare<DataOther>(&mut self, module: &Module<B>, other: &AutomorphismKey<DataOther>, scratch: &mut Scratch<B>)
142 where
143 DataOther: DataRef,
144 Module<B>: GGLWEExecLayoutFamily<B>,
145 {
146 self.key.prepare(module, &other.key, scratch);
147 self.p = other.p;
148 }
149}
150
151impl<D: Data, B: Backend> Infos for AutomorphismKeyExec<D, B> {
152 type Inner = VmpPMat<D, B>;
153
154 fn inner(&self) -> &Self::Inner {
155 &self.key.inner()
156 }
157
158 fn basek(&self) -> usize {
159 self.key.basek()
160 }
161
162 fn k(&self) -> usize {
163 self.key.k()
164 }
165}
166
167impl<D: Data, B: Backend> AutomorphismKeyExec<D, B> {
168 pub fn p(&self) -> i64 {
169 self.p
170 }
171
172 pub fn digits(&self) -> usize {
173 self.key.digits()
174 }
175
176 pub fn rank(&self) -> usize {
177 self.key.rank()
178 }
179
180 pub fn rank_in(&self) -> usize {
181 self.key.rank_in()
182 }
183
184 pub fn rank_out(&self) -> usize {
185 self.key.rank_out()
186 }
187}