arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-schemes/src/tfhe/blind_rotation/key.rs
poulpy-schemes/src/tfhe/blind_rotation/key.rsRaw
  1use poulpy_hal::{
  2    layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, Reset, Scratch, WriterTo},
  3    source::Source,
  4};
  5
  6use std::{fmt, marker::PhantomData};
  7
  8use poulpy_core::{
  9    Distribution,
 10    layouts::{GGSWCiphertext, Infos, LWESecret, prepared::GLWESecretPrepared},
 11};
 12
 13use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
 14
 15use crate::tfhe::blind_rotation::BlindRotationAlgo;
 16
 17pub trait BlindRotationKeyAlloc {
 18    fn alloc(n_gglwe: usize, n_lwe: usize, basek: usize, k: usize, rows: usize, rank: usize) -> Self;
 19}
 20
 21pub trait BlindRotationKeyEncryptSk<B: Backend> {
 22    #[allow(clippy::too_many_arguments)]
 23    fn encrypt_sk<DataSkGLWE, DataSkLWE>(
 24        &mut self,
 25        module: &Module<B>,
 26        sk_glwe: &GLWESecretPrepared<DataSkGLWE, B>,
 27        sk_lwe: &LWESecret<DataSkLWE>,
 28        source_xa: &mut Source,
 29        source_xe: &mut Source,
 30        scratch: &mut Scratch<B>,
 31    ) where
 32        DataSkGLWE: DataRef,
 33        DataSkLWE: DataRef;
 34}
 35
 36#[derive(Clone)]
 37pub struct BlindRotationKey<D: Data, BRT: BlindRotationAlgo> {
 38    pub(crate) keys: Vec<GGSWCiphertext<D>>,
 39    pub(crate) dist: Distribution,
 40    pub(crate) _phantom: PhantomData<BRT>,
 41}
 42
 43impl<D: DataRef, BRT: BlindRotationAlgo> fmt::Debug for BlindRotationKey<D, BRT> {
 44    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 45        write!(f, "{}", self)
 46    }
 47}
 48
 49impl<D: Data, BRT: BlindRotationAlgo> PartialEq for BlindRotationKey<D, BRT> {
 50    fn eq(&self, other: &Self) -> bool {
 51        if self.keys.len() != other.keys.len() {
 52            return false;
 53        }
 54        for (a, b) in self.keys.iter().zip(other.keys.iter()) {
 55            if a != b {
 56                return false;
 57            }
 58        }
 59
 60        self.dist == other.dist && self._phantom == other._phantom
 61    }
 62}
 63
 64impl<D: Data, BRT: BlindRotationAlgo> Eq for BlindRotationKey<D, BRT> {}
 65
 66impl<D: DataRef, BRT: BlindRotationAlgo> fmt::Display for BlindRotationKey<D, BRT> {
 67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 68        for (i, key) in self.keys.iter().enumerate() {
 69            write!(f, "key[{}]: {}", i, key)?;
 70        }
 71        writeln!(f, "{:?}", self.dist)
 72    }
 73}
 74
 75impl<D: DataMut, BRT: BlindRotationAlgo> Reset for BlindRotationKey<D, BRT> {
 76    fn reset(&mut self) {
 77        self.keys.iter_mut().for_each(|key| key.reset());
 78        self.dist = Distribution::NONE;
 79    }
 80}
 81
 82impl<D: DataMut, BRT: BlindRotationAlgo> FillUniform for BlindRotationKey<D, BRT> {
 83    fn fill_uniform(&mut self, source: &mut Source) {
 84        self.keys
 85            .iter_mut()
 86            .for_each(|key| key.fill_uniform(source));
 87    }
 88}
 89
 90impl<D: DataMut, BRT: BlindRotationAlgo> ReaderFrom for BlindRotationKey<D, BRT> {
 91    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
 92        match Distribution::read_from(reader) {
 93            Ok(dist) => self.dist = dist,
 94            Err(e) => return Err(e),
 95        }
 96        let len: usize = reader.read_u64::<LittleEndian>()? as usize;
 97        if self.keys.len() != len {
 98            return Err(std::io::Error::new(
 99                std::io::ErrorKind::InvalidData,
100                format!("self.keys.len()={} != read len={}", self.keys.len(), len),
101            ));
102        }
103        for key in &mut self.keys {
104            key.read_from(reader)?;
105        }
106        Ok(())
107    }
108}
109
110impl<D: DataRef, BRT: BlindRotationAlgo> WriterTo for BlindRotationKey<D, BRT> {
111    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
112        match self.dist.write_to(writer) {
113            Ok(()) => {}
114            Err(e) => return Err(e),
115        }
116        writer.write_u64::<LittleEndian>(self.keys.len() as u64)?;
117        for key in &self.keys {
118            key.write_to(writer)?;
119        }
120        Ok(())
121    }
122}
123
124impl<D: DataRef, BRT: BlindRotationAlgo> BlindRotationKey<D, BRT> {
125    #[allow(dead_code)]
126    pub(crate) fn n(&self) -> usize {
127        self.keys[0].n()
128    }
129
130    #[allow(dead_code)]
131    pub(crate) fn rows(&self) -> usize {
132        self.keys[0].rows()
133    }
134
135    #[allow(dead_code)]
136    pub(crate) fn k(&self) -> usize {
137        self.keys[0].k()
138    }
139
140    #[allow(dead_code)]
141    pub(crate) fn size(&self) -> usize {
142        self.keys[0].size()
143    }
144
145    #[allow(dead_code)]
146    pub(crate) fn rank(&self) -> usize {
147        self.keys[0].rank()
148    }
149
150    pub(crate) fn basek(&self) -> usize {
151        self.keys[0].basek()
152    }
153
154    #[allow(dead_code)]
155    pub(crate) fn block_size(&self) -> usize {
156        match self.dist {
157            Distribution::BinaryBlock(value) => value,
158            _ => 1,
159        }
160    }
161}