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