poulpy_core/encryption/compressed/
gglwe_atk.rs

1use poulpy_hal::{
2    api::{
3        ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft,
4        VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxBigNormalize, VecZnxDftAllocBytes,
5        VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace,
6        VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
7    },
8    layouts::{Backend, DataMut, DataRef, Module, Scratch},
9    source::Source,
10};
11
12use crate::{
13    TakeGLWESecret, TakeGLWESecretPrepared,
14    layouts::{
15        GGLWELayoutInfos, GLWEInfos, GLWESecret, LWEInfos,
16        compressed::{GGLWEAutomorphismKeyCompressed, GGLWESwitchingKeyCompressed},
17    },
18};
19
20impl GGLWEAutomorphismKeyCompressed<Vec<u8>> {
21    pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
22    where
23        A: GGLWELayoutInfos,
24        Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + SvpPPolAllocBytes,
25    {
26        assert_eq!(module.n() as u32, infos.n());
27        GGLWESwitchingKeyCompressed::encrypt_sk_scratch_space(module, infos)
28            + GLWESecret::alloc_bytes_with(infos.n(), infos.rank_out())
29    }
30}
31
32impl<DataSelf: DataMut> GGLWEAutomorphismKeyCompressed<DataSelf> {
33    #[allow(clippy::too_many_arguments)]
34    pub fn encrypt_sk<DataSk: DataRef, B: Backend>(
35        &mut self,
36        module: &Module<B>,
37        p: i64,
38        sk: &GLWESecret<DataSk>,
39        seed_xa: [u8; 32],
40        source_xe: &mut Source,
41        scratch: &mut Scratch<B>,
42    ) where
43        Module<B>: VecZnxAutomorphism
44            + SvpPrepare<B>
45            + SvpPPolAllocBytes
46            + VecZnxSwitchRing
47            + VecZnxDftAllocBytes
48            + VecZnxBigNormalize<B>
49            + VecZnxDftApply<B>
50            + SvpApplyDftToDftInplace<B>
51            + VecZnxIdftApplyConsume<B>
52            + VecZnxNormalizeTmpBytes
53            + VecZnxFillUniform
54            + VecZnxSubInplace
55            + VecZnxAddInplace
56            + VecZnxNormalizeInplace<B>
57            + VecZnxAddNormal
58            + VecZnxNormalize<B>
59            + VecZnxSub
60            + VecZnxAddScalarInplace,
61        Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx + TakeScalarZnx + TakeGLWESecretPrepared<B>,
62    {
63        #[cfg(debug_assertions)]
64        {
65            assert_eq!(self.n(), sk.n());
66            assert_eq!(self.rank_out(), self.rank_in());
67            assert_eq!(sk.rank(), self.rank_out());
68            assert!(
69                scratch.available() >= GGLWEAutomorphismKeyCompressed::encrypt_sk_scratch_space(module, self),
70                "scratch.available(): {} < AutomorphismKey::encrypt_sk_scratch_space: {}",
71                scratch.available(),
72                GGLWEAutomorphismKeyCompressed::encrypt_sk_scratch_space(module, self)
73            )
74        }
75
76        let (mut sk_out, scratch_1) = scratch.take_glwe_secret(sk.n(), sk.rank());
77
78        {
79            (0..self.rank_out().into()).for_each(|i| {
80                module.vec_znx_automorphism(
81                    module.galois_element_inv(p),
82                    &mut sk_out.data.as_vec_znx_mut(),
83                    i,
84                    &sk.data.as_vec_znx(),
85                    i,
86                );
87            });
88        }
89
90        self.key
91            .encrypt_sk(module, sk, &sk_out, seed_xa, source_xe, scratch_1);
92
93        self.p = p;
94    }
95}