arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/encryption/gglwe_atk.rs
poulpy-core/src/encryption/gglwe_atk.rsRaw
  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, Module, Scratch},
  9    source::Source,
 10};
 11
 12use crate::{
 13    TakeGLWESecret, TakeGLWESecretPrepared,
 14    layouts::{
 15        GGLWEAutomorphismKey, GGLWEAutomorphismKeyToMut, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, GLWESecret, GLWESecretToRef,
 16        LWEInfos,
 17    },
 18};
 19
 20impl GGLWEAutomorphismKey<Vec<u8>> {
 21    pub fn encrypt_sk_scratch_space<BE: Backend, A>(module: &Module<BE>, infos: &A) -> usize
 22    where
 23        A: GGLWEInfos,
 24        Module<BE>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
 25    {
 26        assert_eq!(
 27            infos.rank_in(),
 28            infos.rank_out(),
 29            "rank_in != rank_out is not supported for GGLWEAutomorphismKey"
 30        );
 31        GGLWESwitchingKey::encrypt_sk_scratch_space(module, infos) + GLWESecret::alloc_bytes(&infos.glwe_layout())
 32    }
 33
 34    pub fn encrypt_pk_scratch_space<BE: Backend, A>(module: &Module<BE>, _infos: &A) -> usize
 35    where
 36        A: GGLWEInfos,
 37    {
 38        assert_eq!(
 39            _infos.rank_in(),
 40            _infos.rank_out(),
 41            "rank_in != rank_out is not supported for GGLWEAutomorphismKey"
 42        );
 43        GGLWESwitchingKey::encrypt_pk_scratch_space(module, _infos)
 44    }
 45}
 46
 47pub trait GGLWEAutomorphismKeyEncryptSk<BE: Backend> {
 48    fn gglwe_automorphism_key_encrypt_sk<A, B>(
 49        &self,
 50        res: &mut A,
 51        p: i64,
 52        sk: &B,
 53        source_xa: &mut Source,
 54        source_xe: &mut Source,
 55        scratch: &mut Scratch<BE>,
 56    ) where
 57        A: GGLWEAutomorphismKeyToMut,
 58        B: GLWESecretToRef;
 59}
 60
 61impl<DM: DataMut> GGLWEAutomorphismKey<DM>
 62where
 63    Self: GGLWEAutomorphismKeyToMut,
 64{
 65    pub fn encrypt_sk<S, BE: Backend>(
 66        &mut self,
 67        module: &Module<BE>,
 68        p: i64,
 69        sk: &S,
 70        source_xa: &mut Source,
 71        source_xe: &mut Source,
 72        scratch: &mut Scratch<BE>,
 73    ) where
 74        S: GLWESecretToRef,
 75        Module<BE>: GGLWEAutomorphismKeyEncryptSk<BE>,
 76    {
 77        module.gglwe_automorphism_key_encrypt_sk(self, p, sk, source_xa, source_xe, scratch);
 78    }
 79}
 80
 81impl<BE: Backend> GGLWEAutomorphismKeyEncryptSk<BE> for Module<BE>
 82where
 83    Module<BE>: VecZnxAddScalarInplace
 84        + VecZnxDftAllocBytes
 85        + VecZnxBigNormalize<BE>
 86        + VecZnxDftApply<BE>
 87        + SvpApplyDftToDftInplace<BE>
 88        + VecZnxIdftApplyConsume<BE>
 89        + VecZnxNormalizeTmpBytes
 90        + VecZnxFillUniform
 91        + VecZnxSubInplace
 92        + VecZnxAddInplace
 93        + VecZnxNormalizeInplace<BE>
 94        + VecZnxAddNormal
 95        + VecZnxNormalize<BE>
 96        + VecZnxSub
 97        + SvpPrepare<BE>
 98        + VecZnxSwitchRing
 99        + SvpPPolAllocBytes
100        + VecZnxAutomorphism,
101    Scratch<BE>: TakeVecZnxDft<BE> + ScratchAvailable + TakeVecZnx + TakeScalarZnx + TakeGLWESecretPrepared<BE>,
102{
103    fn gglwe_automorphism_key_encrypt_sk<A, B>(
104        &self,
105        res: &mut A,
106        p: i64,
107        sk: &B,
108        source_xa: &mut Source,
109        source_xe: &mut Source,
110        scratch: &mut Scratch<BE>,
111    ) where
112        A: GGLWEAutomorphismKeyToMut,
113        B: GLWESecretToRef,
114    {
115        let res: &mut GGLWEAutomorphismKey<&mut [u8]> = &mut res.to_mut();
116        let sk: &GLWESecret<&[u8]> = &sk.to_ref();
117
118        #[cfg(debug_assertions)]
119        {
120            use crate::layouts::{GLWEInfos, LWEInfos};
121
122            assert_eq!(res.n(), sk.n());
123            assert_eq!(res.rank_out(), res.rank_in());
124            assert_eq!(sk.rank(), res.rank_out());
125            assert!(
126                scratch.available() >= GGLWEAutomorphismKey::encrypt_sk_scratch_space(self, res),
127                "scratch.available(): {} < AutomorphismKey::encrypt_sk_scratch_space: {:?}",
128                scratch.available(),
129                GGLWEAutomorphismKey::encrypt_sk_scratch_space(self, res)
130            )
131        }
132
133        let (mut sk_out, scratch_1) = scratch.take_glwe_secret(sk.n(), sk.rank());
134
135        {
136            (0..res.rank_out().into()).for_each(|i| {
137                self.vec_znx_automorphism(
138                    self.galois_element_inv(p),
139                    &mut sk_out.data.as_vec_znx_mut(),
140                    i,
141                    &sk.data.as_vec_znx(),
142                    i,
143                );
144            });
145        }
146
147        res.key
148            .encrypt_sk(self, sk, &sk_out, source_xa, source_xe, scratch_1);
149
150        res.p = p;
151    }
152}