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