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, SvpApply, SvpApplyInplace, SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeSvpPPol,
 10        TakeVecZnx, TakeVecZnxBig, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism,
 11        VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftFromVecZnx, VecZnxDftToVecZnxBigConsume, VecZnxDftToVecZnxBigTmpA,
 12        VecZnxFillUniform, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace,
 13        VecZnxSwithcDegree, VmpPMatAlloc, VmpPrepare,
 14    },
 15    layouts::{Backend, Data, DataRef, Module, Scratch},
 16};
 17use sampling::source::Source;
 18
 19use crate::tfhe::blind_rotation::{
 20    BlindRotationAlgo, BlindRotationKey, BlindRotationKeyAlloc, BlindRotationKeyEncryptSk, BlindRotationKeyPrepared,
 21};
 22
 23pub trait CircuitBootstrappingKeyEncryptSk<B: Backend> {
 24    fn encrypt_sk<DLwe, DGlwe>(
 25        module: &Module<B>,
 26        basek: usize,
 27        sk_lwe: &LWESecret<DLwe>,
 28        sk_glwe: &GLWESecret<DGlwe>,
 29        k_brk: usize,
 30        rows_brk: usize,
 31        k_trace: usize,
 32        rows_trace: usize,
 33        k_tsk: usize,
 34        rows_tsk: usize,
 35        source_xa: &mut Source,
 36        source_xe: &mut Source,
 37        sigma: f64,
 38        scratch: &mut Scratch<B>,
 39    ) -> Self
 40    where
 41        DLwe: DataRef,
 42        DGlwe: DataRef;
 43}
 44
 45pub struct CircuitBootstrappingKey<D: Data, BRA: BlindRotationAlgo> {
 46    pub(crate) brk: BlindRotationKey<D, BRA>,
 47    pub(crate) tsk: GGLWETensorKey<Vec<u8>>,
 48    pub(crate) atk: HashMap<i64, GGLWEAutomorphismKey<Vec<u8>>>,
 49}
 50
 51impl<BRA: BlindRotationAlgo, B: Backend> CircuitBootstrappingKeyEncryptSk<B> for CircuitBootstrappingKey<Vec<u8>, BRA>
 52where
 53    BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<B>,
 54    Module<B>: SvpApply<B>
 55        + VecZnxDftToVecZnxBigTmpA<B>
 56        + VecZnxAddScalarInplace
 57        + VecZnxDftAllocBytes
 58        + VecZnxBigNormalize<B>
 59        + VecZnxDftFromVecZnx<B>
 60        + SvpApplyInplace<B>
 61        + VecZnxDftToVecZnxBigConsume<B>
 62        + VecZnxNormalizeTmpBytes
 63        + VecZnxFillUniform
 64        + VecZnxSubABInplace
 65        + VecZnxAddInplace
 66        + VecZnxNormalizeInplace<B>
 67        + VecZnxAddNormal
 68        + VecZnxNormalize<B>
 69        + VecZnxSub
 70        + SvpPrepare<B>
 71        + VecZnxSwithcDegree
 72        + SvpPPolAllocBytes
 73        + SvpPPolAlloc<B>
 74        + VecZnxAutomorphism,
 75    Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx + TakeScalarZnx + TakeSvpPPol<B> + TakeVecZnxBig<B>,
 76{
 77    fn encrypt_sk<DLwe, DGlwe>(
 78        module: &Module<B>,
 79        basek: usize,
 80        sk_lwe: &LWESecret<DLwe>,
 81        sk_glwe: &GLWESecret<DGlwe>,
 82        k_brk: usize,
 83        rows_brk: usize,
 84        k_trace: usize,
 85        rows_trace: usize,
 86        k_tsk: usize,
 87        rows_tsk: usize,
 88        source_xa: &mut Source,
 89        source_xe: &mut Source,
 90        sigma: f64,
 91        scratch: &mut Scratch<B>,
 92    ) -> Self
 93    where
 94        DLwe: DataRef,
 95        DGlwe: DataRef,
 96        Module<B>:,
 97    {
 98        let mut auto_keys: HashMap<i64, GGLWEAutomorphismKey<Vec<u8>>> = HashMap::new();
 99        let gal_els: Vec<i64> = GLWECiphertext::trace_galois_elements(&module);
100        gal_els.iter().for_each(|gal_el| {
101            let mut key: GGLWEAutomorphismKey<Vec<u8>> =
102                GGLWEAutomorphismKey::alloc(sk_glwe.n(), basek, k_trace, rows_trace, 1, sk_glwe.rank());
103            key.encrypt_sk(
104                &module, *gal_el, &sk_glwe, source_xa, source_xe, sigma, scratch,
105            );
106            auto_keys.insert(*gal_el, key);
107        });
108
109        let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch);
110
111        let mut brk: BlindRotationKey<Vec<u8>, BRA> = BlindRotationKey::<Vec<u8>, BRA>::alloc(
112            sk_glwe.n(),
113            sk_lwe.n(),
114            basek,
115            k_brk,
116            rows_brk,
117            sk_glwe.rank(),
118        );
119
120        brk.encrypt_sk(
121            module,
122            &sk_glwe_prepared,
123            sk_lwe,
124            source_xa,
125            source_xe,
126            sigma,
127            scratch,
128        );
129
130        let mut tsk: GGLWETensorKey<Vec<u8>> = GGLWETensorKey::alloc(sk_glwe.n(), basek, k_tsk, rows_tsk, 1, sk_glwe.rank());
131        tsk.encrypt_sk(module, &sk_glwe, source_xa, source_xe, sigma, scratch);
132
133        Self {
134            brk,
135            atk: auto_keys,
136            tsk,
137        }
138    }
139}
140
141pub struct CircuitBootstrappingKeyPrepared<D: Data, BRA: BlindRotationAlgo, B: Backend> {
142    pub(crate) brk: BlindRotationKeyPrepared<D, BRA, B>,
143    pub(crate) tsk: GGLWETensorKeyPrepared<Vec<u8>, B>,
144    pub(crate) atk: HashMap<i64, GGLWEAutomorphismKeyPrepared<Vec<u8>, B>>,
145}
146
147impl<D: DataRef, BRA: BlindRotationAlgo, B: Backend> PrepareAlloc<B, CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B>>
148    for CircuitBootstrappingKey<D, BRA>
149where
150    Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
151    BlindRotationKey<D, BRA>: PrepareAlloc<B, BlindRotationKeyPrepared<Vec<u8>, BRA, B>>,
152    GGLWETensorKey<D>: PrepareAlloc<B, GGLWETensorKeyPrepared<Vec<u8>, B>>,
153    GGLWEAutomorphismKey<D>: PrepareAlloc<B, GGLWEAutomorphismKeyPrepared<Vec<u8>, B>>,
154{
155    fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B> {
156        let brk: BlindRotationKeyPrepared<Vec<u8>, BRA, B> = self.brk.prepare_alloc(module, scratch);
157        let tsk: GGLWETensorKeyPrepared<Vec<u8>, B> = self.tsk.prepare_alloc(module, scratch);
158        let mut atk: HashMap<i64, GGLWEAutomorphismKeyPrepared<Vec<u8>, B>> = HashMap::new();
159        for (key, value) in &self.atk {
160            atk.insert(*key, value.prepare_alloc(module, scratch));
161        }
162        CircuitBootstrappingKeyPrepared { brk, tsk, atk }
163    }
164}