arnaucube
arnaucube/poulpyPublic Self-hosted repository
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}