use poulpy_hal::layouts::{Backend, DataMut, Module, Scratch}; use crate::{ ScratchTakeCore, keyswitching::glwe_ct::GLWEKeyswitch, layouts::{ AutomorphismKey, AutomorphismKeyToRef, GGLWE, GGLWEInfos, GGLWEToMut, GGLWEToRef, GLWESwitchingKey, GLWESwitchingKeyToRef, prepared::{GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToRef}, }, }; impl AutomorphismKey> { pub fn keyswitch_inplace_tmp_bytes(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize where R: GGLWEInfos, A: GGLWEInfos, K: GGLWEInfos, M: GGLWEKeyswitch, { module.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos) } } impl AutomorphismKey { pub fn keyswitch(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch) where A: AutomorphismKeyToRef, B: GLWESwitchingKeyPreparedToRef, Scratch: ScratchTakeCore, M: GGLWEKeyswitch, { module.gglwe_keyswitch(&mut self.key.key, &a.to_ref().key.key, b, scratch); } pub fn keyswitch_inplace(&mut self, module: &M, a: &A, scratch: &mut Scratch) where A: GLWESwitchingKeyPreparedToRef, Scratch: ScratchTakeCore, M: GGLWEKeyswitch, { module.gglwe_keyswitch_inplace(&mut self.key.key, a, scratch); } } impl GLWESwitchingKey> { pub fn keyswitch_inplace_tmp_bytes(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize where R: GGLWEInfos, A: GGLWEInfos, K: GGLWEInfos, M: GGLWEKeyswitch, { module.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos) } } impl GLWESwitchingKey { pub fn keyswitch(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch) where A: GLWESwitchingKeyToRef, B: GLWESwitchingKeyPreparedToRef, Scratch: ScratchTakeCore, M: GGLWEKeyswitch, { module.gglwe_keyswitch(&mut self.key, &a.to_ref().key, b, scratch); } pub fn keyswitch_inplace(&mut self, module: &M, a: &A, scratch: &mut Scratch) where A: GLWESwitchingKeyPreparedToRef, Scratch: ScratchTakeCore, M: GGLWEKeyswitch, { module.gglwe_keyswitch_inplace(&mut self.key, a, scratch); } } impl GGLWE> { pub fn keyswitch_inplace_tmp_bytes(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize where R: GGLWEInfos, A: GGLWEInfos, K: GGLWEInfos, M: GGLWEKeyswitch, { module.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos) } } impl GGLWE { pub fn keyswitch(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch) where A: GGLWEToRef, B: GLWESwitchingKeyPreparedToRef, Scratch: ScratchTakeCore, M: GGLWEKeyswitch, { module.gglwe_keyswitch(self, a, b, scratch); } pub fn keyswitch_inplace(&mut self, module: &M, a: &A, scratch: &mut Scratch) where A: GLWESwitchingKeyPreparedToRef, Scratch: ScratchTakeCore, M: GGLWEKeyswitch, { module.gglwe_keyswitch_inplace(self, a, scratch); } } impl GGLWEKeyswitch for Module where Self: GLWEKeyswitch {} pub trait GGLWEKeyswitch where Self: GLWEKeyswitch, { fn gglwe_keyswitch_tmp_bytes(&self, res_infos: &R, a_infos: &A, key_infos: &K) -> usize where R: GGLWEInfos, A: GGLWEInfos, K: GGLWEInfos, { self.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos) } fn gglwe_keyswitch(&self, res: &mut R, a: &A, b: &B, scratch: &mut Scratch) where R: GGLWEToMut, A: GGLWEToRef, B: GLWESwitchingKeyPreparedToRef, Scratch: ScratchTakeCore, { let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut(); let a: &GGLWE<&[u8]> = &a.to_ref(); let b: &GLWESwitchingKeyPrepared<&[u8], BE> = &b.to_ref(); assert_eq!( res.rank_in(), a.rank_in(), "res input rank: {} != a input rank: {}", res.rank_in(), a.rank_in() ); assert_eq!( a.rank_out(), b.rank_in(), "res output rank: {} != b input rank: {}", a.rank_out(), b.rank_in() ); assert_eq!( res.rank_out(), b.rank_out(), "res output rank: {} != b output rank: {}", res.rank_out(), b.rank_out() ); assert!( res.dnum() <= a.dnum(), "res.dnum()={} > a.dnum()={}", res.dnum(), a.dnum() ); assert_eq!( res.dsize(), a.dsize(), "res dsize: {} != a dsize: {}", res.dsize(), a.dsize() ); for row in 0..res.dnum().into() { for col in 0..res.rank_in().into() { self.glwe_keyswitch(&mut res.at_mut(row, col), &a.at(row, col), b, scratch); } } } fn gglwe_keyswitch_inplace(&self, res: &mut R, a: &A, scratch: &mut Scratch) where R: GGLWEToMut, A: GLWESwitchingKeyPreparedToRef, Scratch: ScratchTakeCore, { let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut(); let a: &GLWESwitchingKeyPrepared<&[u8], BE> = &a.to_ref(); assert_eq!( res.rank_out(), a.rank_out(), "res output rank: {} != a output rank: {}", res.rank_out(), a.rank_out() ); for row in 0..res.dnum().into() { for col in 0..res.rank_in().into() { self.glwe_keyswitch_inplace(&mut res.at_mut(row, col), a, scratch); } } } } impl GLWESwitchingKey {}