arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/keyswitching/gglwe_ct.rs
poulpy-core/src/keyswitching/gglwe_ct.rsRaw
  1use poulpy_hal::layouts::{Backend, DataMut, Module, Scratch};
  2
  3use crate::{
  4    ScratchTakeCore,
  5    keyswitching::glwe_ct::GLWEKeySwitch,
  6    layouts::{
  7        AutomorphismKey, AutomorphismKeyToRef, GGLWE, GGLWEInfos, GGLWEToMut, GGLWEToRef, GLWESwitchingKey,
  8        GLWESwitchingKeyToRef,
  9        prepared::{GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToRef},
 10    },
 11};
 12
 13impl AutomorphismKey<Vec<u8>> {
 14    pub fn keyswitch_inplace_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
 15    where
 16        R: GGLWEInfos,
 17        A: GGLWEInfos,
 18        K: GGLWEInfos,
 19        M: GGLWEKeySwitch<BE>,
 20    {
 21        module.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
 22    }
 23}
 24
 25impl<DataSelf: DataMut> AutomorphismKey<DataSelf> {
 26    pub fn keyswitch<A, B, M, BE: Backend>(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch<BE>)
 27    where
 28        A: AutomorphismKeyToRef,
 29        B: GLWESwitchingKeyPreparedToRef<BE>,
 30        Scratch<BE>: ScratchTakeCore<BE>,
 31        M: GGLWEKeySwitch<BE>,
 32    {
 33        module.gglwe_keyswitch(&mut self.key.key, &a.to_ref().key.key, b, scratch);
 34    }
 35
 36    pub fn keyswitch_inplace<A, M, BE: Backend>(&mut self, module: &M, a: &A, scratch: &mut Scratch<BE>)
 37    where
 38        A: GLWESwitchingKeyPreparedToRef<BE>,
 39        Scratch<BE>: ScratchTakeCore<BE>,
 40        M: GGLWEKeySwitch<BE>,
 41    {
 42        module.gglwe_keyswitch_inplace(&mut self.key.key, a, scratch);
 43    }
 44}
 45
 46impl GLWESwitchingKey<Vec<u8>> {
 47    pub fn keyswitch_inplace_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
 48    where
 49        R: GGLWEInfos,
 50        A: GGLWEInfos,
 51        K: GGLWEInfos,
 52        M: GGLWEKeySwitch<BE>,
 53    {
 54        module.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
 55    }
 56}
 57
 58impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> {
 59    pub fn keyswitch<A, B, M, BE: Backend>(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch<BE>)
 60    where
 61        A: GLWESwitchingKeyToRef,
 62        B: GLWESwitchingKeyPreparedToRef<BE>,
 63        Scratch<BE>: ScratchTakeCore<BE>,
 64        M: GGLWEKeySwitch<BE>,
 65    {
 66        module.gglwe_keyswitch(&mut self.key, &a.to_ref().key, b, scratch);
 67    }
 68
 69    pub fn keyswitch_inplace<A, M, BE: Backend>(&mut self, module: &M, a: &A, scratch: &mut Scratch<BE>)
 70    where
 71        A: GLWESwitchingKeyPreparedToRef<BE>,
 72        Scratch<BE>: ScratchTakeCore<BE>,
 73        M: GGLWEKeySwitch<BE>,
 74    {
 75        module.gglwe_keyswitch_inplace(&mut self.key, a, scratch);
 76    }
 77}
 78
 79impl GGLWE<Vec<u8>> {
 80    pub fn keyswitch_inplace_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
 81    where
 82        R: GGLWEInfos,
 83        A: GGLWEInfos,
 84        K: GGLWEInfos,
 85        M: GGLWEKeySwitch<BE>,
 86    {
 87        module.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
 88    }
 89}
 90
 91impl<DataSelf: DataMut> GGLWE<DataSelf> {
 92    pub fn keyswitch<A, B, M, BE: Backend>(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch<BE>)
 93    where
 94        A: GGLWEToRef,
 95        B: GLWESwitchingKeyPreparedToRef<BE>,
 96        Scratch<BE>: ScratchTakeCore<BE>,
 97        M: GGLWEKeySwitch<BE>,
 98    {
 99        module.gglwe_keyswitch(self, a, b, scratch);
100    }
101
102    pub fn keyswitch_inplace<A, M, BE: Backend>(&mut self, module: &M, a: &A, scratch: &mut Scratch<BE>)
103    where
104        A: GLWESwitchingKeyPreparedToRef<BE>,
105        Scratch<BE>: ScratchTakeCore<BE>,
106        M: GGLWEKeySwitch<BE>,
107    {
108        module.gglwe_keyswitch_inplace(self, a, scratch);
109    }
110}
111
112impl<BE: Backend> GGLWEKeySwitch<BE> for Module<BE> where Self: GLWEKeySwitch<BE> {}
113
114pub trait GGLWEKeySwitch<BE: Backend>
115where
116    Self: GLWEKeySwitch<BE>,
117{
118    fn gglwe_keyswitch_tmp_bytes<R, A, K>(&self, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
119    where
120        R: GGLWEInfos,
121        A: GGLWEInfos,
122        K: GGLWEInfos,
123    {
124        self.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
125    }
126
127    fn gglwe_keyswitch<R, A, B>(&self, res: &mut R, a: &A, b: &B, scratch: &mut Scratch<BE>)
128    where
129        R: GGLWEToMut,
130        A: GGLWEToRef,
131        B: GLWESwitchingKeyPreparedToRef<BE>,
132        Scratch<BE>: ScratchTakeCore<BE>,
133    {
134        let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut();
135        let a: &GGLWE<&[u8]> = &a.to_ref();
136        let b: &GLWESwitchingKeyPrepared<&[u8], BE> = &b.to_ref();
137
138        assert_eq!(
139            res.rank_in(),
140            a.rank_in(),
141            "res input rank: {} != a input rank: {}",
142            res.rank_in(),
143            a.rank_in()
144        );
145        assert_eq!(
146            a.rank_out(),
147            b.rank_in(),
148            "res output rank: {} != b input rank: {}",
149            a.rank_out(),
150            b.rank_in()
151        );
152        assert_eq!(
153            res.rank_out(),
154            b.rank_out(),
155            "res output rank: {} != b output rank: {}",
156            res.rank_out(),
157            b.rank_out()
158        );
159        assert!(
160            res.dnum() <= a.dnum(),
161            "res.dnum()={} > a.dnum()={}",
162            res.dnum(),
163            a.dnum()
164        );
165        assert_eq!(
166            res.dsize(),
167            a.dsize(),
168            "res dsize: {} != a dsize: {}",
169            res.dsize(),
170            a.dsize()
171        );
172
173        for row in 0..res.dnum().into() {
174            for col in 0..res.rank_in().into() {
175                self.glwe_keyswitch(&mut res.at_mut(row, col), &a.at(row, col), b, scratch);
176            }
177        }
178    }
179
180    fn gglwe_keyswitch_inplace<R, A>(&self, res: &mut R, a: &A, scratch: &mut Scratch<BE>)
181    where
182        R: GGLWEToMut,
183        A: GLWESwitchingKeyPreparedToRef<BE>,
184        Scratch<BE>: ScratchTakeCore<BE>,
185    {
186        let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut();
187        let a: &GLWESwitchingKeyPrepared<&[u8], BE> = &a.to_ref();
188
189        assert_eq!(
190            res.rank_out(),
191            a.rank_out(),
192            "res output rank: {} != a output rank: {}",
193            res.rank_out(),
194            a.rank_out()
195        );
196
197        for row in 0..res.dnum().into() {
198            for col in 0..res.rank_in().into() {
199                self.glwe_keyswitch_inplace(&mut res.at_mut(row, col), a, scratch);
200            }
201        }
202    }
203}
204
205impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> {}