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