arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/schemes/src/tfhe/circuit_bootstrapping/key.rs
schemes/src/tfhe/circuit_bootstrapping/key.rsRaw
  1use core::layouts::{
  2    GGLWEAutomorphismKey, GGLWETensorKey, GLWECiphertext, GLWESecret, LWESecret,
  3    prepared::{GGLWEAutomorphismKeyPrepared, GGLWETensorKeyPrepared, GLWESecretPrepared, PrepareAlloc},
  4};
  5use std::{collections::HashMap, usize};
  6
  7use backend::hal::{
  8    api::{
  9        ScratchAvailable, TakeScalarZnx, TakeSvpPPol, TakeVecZnx, TakeVecZnxBig, TakeVecZnxDft, VecZnxAddScalarInplace,
 10        VecZnxAutomorphism, VecZnxSwithcDegree, VmpPMatAlloc, VmpPMatPrepare,
 11    },
 12    layouts::{Backend, Data, DataRef, Module, Scratch},
 13};
 14use sampling::source::Source;
 15
 16use core::trait_families::{
 17    GGLWEAutomorphismKeyEncryptSkFamily, GGLWETensorKeyEncryptSkFamily, GGSWEncryptSkFamily, GLWESecretPreparedModuleFamily,
 18};
 19
 20use crate::tfhe::blind_rotation::{
 21    BlindRotationAlgo, BlindRotationKey, BlindRotationKeyAlloc, BlindRotationKeyEncryptSk, BlindRotationKeyPrepared,
 22};
 23
 24pub trait CircuitBootstrappingKeyEncryptSk<B: Backend> {
 25    fn encrypt_sk<DLwe, DGlwe>(
 26        module: &Module<B>,
 27        basek: usize,
 28        sk_lwe: &LWESecret<DLwe>,
 29        sk_glwe: &GLWESecret<DGlwe>,
 30        k_brk: usize,
 31        rows_brk: usize,
 32        k_trace: usize,
 33        rows_trace: usize,
 34        k_tsk: usize,
 35        rows_tsk: usize,
 36        source_xa: &mut Source,
 37        source_xe: &mut Source,
 38        sigma: f64,
 39        scratch: &mut Scratch<B>,
 40    ) -> Self
 41    where
 42        DLwe: DataRef,
 43        DGlwe: DataRef;
 44}
 45
 46pub struct CircuitBootstrappingKey<D: Data, BRA: BlindRotationAlgo> {
 47    pub(crate) brk: BlindRotationKey<D, BRA>,
 48    pub(crate) tsk: GGLWETensorKey<Vec<u8>>,
 49    pub(crate) atk: HashMap<i64, GGLWEAutomorphismKey<Vec<u8>>>,
 50}
 51
 52impl<BRA: BlindRotationAlgo, B: Backend> CircuitBootstrappingKeyEncryptSk<B> for CircuitBootstrappingKey<Vec<u8>, BRA>
 53where
 54    BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<B>,
 55    Module<B>: GGSWEncryptSkFamily<B>
 56        + GLWESecretPreparedModuleFamily<B>
 57        + VecZnxAddScalarInplace
 58        + GGLWEAutomorphismKeyEncryptSkFamily<B>
 59        + VecZnxAutomorphism
 60        + VecZnxSwithcDegree
 61        + GGLWETensorKeyEncryptSkFamily<B>,
 62    Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx + TakeScalarZnx + TakeSvpPPol<B> + TakeVecZnxBig<B>,
 63{
 64    fn encrypt_sk<DLwe, DGlwe>(
 65        module: &Module<B>,
 66        basek: usize,
 67        sk_lwe: &LWESecret<DLwe>,
 68        sk_glwe: &GLWESecret<DGlwe>,
 69        k_brk: usize,
 70        rows_brk: usize,
 71        k_trace: usize,
 72        rows_trace: usize,
 73        k_tsk: usize,
 74        rows_tsk: usize,
 75        source_xa: &mut Source,
 76        source_xe: &mut Source,
 77        sigma: f64,
 78        scratch: &mut Scratch<B>,
 79    ) -> Self
 80    where
 81        DLwe: DataRef,
 82        DGlwe: DataRef,
 83    {
 84        let mut auto_keys: HashMap<i64, GGLWEAutomorphismKey<Vec<u8>>> = HashMap::new();
 85        let gal_els: Vec<i64> = GLWECiphertext::trace_galois_elements(&module);
 86        gal_els.iter().for_each(|gal_el| {
 87            let mut key: GGLWEAutomorphismKey<Vec<u8>> =
 88                GGLWEAutomorphismKey::alloc(sk_glwe.n(), basek, k_trace, rows_trace, 1, sk_glwe.rank());
 89            key.encrypt_sk(
 90                &module, *gal_el, &sk_glwe, source_xa, source_xe, sigma, scratch,
 91            );
 92            auto_keys.insert(*gal_el, key);
 93        });
 94
 95        let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch);
 96
 97        let mut brk: BlindRotationKey<Vec<u8>, BRA> = BlindRotationKey::<Vec<u8>, BRA>::alloc(
 98            sk_glwe.n(),
 99            sk_lwe.n(),
100            basek,
101            k_brk,
102            rows_brk,
103            sk_glwe.rank(),
104        );
105
106        brk.encrypt_sk(
107            module,
108            &sk_glwe_prepared,
109            sk_lwe,
110            source_xa,
111            source_xe,
112            sigma,
113            scratch,
114        );
115
116        let mut tsk: GGLWETensorKey<Vec<u8>> = GGLWETensorKey::alloc(sk_glwe.n(), basek, k_tsk, rows_tsk, 1, sk_glwe.rank());
117        tsk.encrypt_sk(module, &sk_glwe, source_xa, source_xe, sigma, scratch);
118
119        Self {
120            brk,
121            atk: auto_keys,
122            tsk,
123        }
124    }
125}
126
127pub struct CircuitBootstrappingKeyPrepared<D: Data, BRA: BlindRotationAlgo, B: Backend> {
128    pub(crate) brk: BlindRotationKeyPrepared<D, BRA, B>,
129    pub(crate) tsk: GGLWETensorKeyPrepared<Vec<u8>, B>,
130    pub(crate) atk: HashMap<i64, GGLWEAutomorphismKeyPrepared<Vec<u8>, B>>,
131}
132
133impl<D: DataRef, BRA: BlindRotationAlgo, B: Backend> PrepareAlloc<B, CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B>>
134    for CircuitBootstrappingKey<D, BRA>
135where
136    Module<B>: VmpPMatAlloc<B> + VmpPMatPrepare<B>,
137    BlindRotationKey<D, BRA>: PrepareAlloc<B, BlindRotationKeyPrepared<Vec<u8>, BRA, B>>,
138    GGLWETensorKey<D>: PrepareAlloc<B, GGLWETensorKeyPrepared<Vec<u8>, B>>,
139    GGLWEAutomorphismKey<D>: PrepareAlloc<B, GGLWEAutomorphismKeyPrepared<Vec<u8>, B>>,
140{
141    fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B> {
142        let brk: BlindRotationKeyPrepared<Vec<u8>, BRA, B> = self.brk.prepare_alloc(module, scratch);
143        let tsk: GGLWETensorKeyPrepared<Vec<u8>, B> = self.tsk.prepare_alloc(module, scratch);
144        let mut atk: HashMap<i64, GGLWEAutomorphismKeyPrepared<Vec<u8>, B>> = HashMap::new();
145        for (key, value) in &self.atk {
146            atk.insert(*key, value.prepare_alloc(module, scratch));
147        }
148        CircuitBootstrappingKeyPrepared { brk, tsk, atk }
149    }
150}