diff --git a/poulpy-core/src/layouts/gglwe_ksk.rs b/poulpy-core/src/layouts/gglwe_ksk.rs index e8a8b92..7b74193 100644 --- a/poulpy-core/src/layouts/gglwe_ksk.rs +++ b/poulpy-core/src/layouts/gglwe_ksk.rs @@ -67,6 +67,36 @@ pub struct GLWESwitchingKey { pub(crate) sk_out_n: usize, // Degree of sk_out } +pub(crate) trait GLWESwitchingKeySetMetaData { + fn set_sk_in_n(&mut self, sk_in_n: usize); + fn set_sk_out_n(&mut self, sk_out_n: usize); +} + +impl GLWESwitchingKeySetMetaData for GLWESwitchingKey { + fn set_sk_in_n(&mut self, sk_in_n: usize) { + self.sk_in_n = sk_in_n + } + + fn set_sk_out_n(&mut self, sk_out_n: usize) { + self.sk_out_n = sk_out_n + } +} + +pub(crate) trait GLWESwtichingKeyGetMetaData { + fn sk_in_n(&self) -> usize; + fn sk_out_n(&self) -> usize; +} + +impl GLWESwtichingKeyGetMetaData for GLWESwitchingKey { + fn sk_in_n(&self) -> usize { + self.sk_in_n + } + + fn sk_out_n(&self) -> usize { + self.sk_out_n + } +} + impl LWEInfos for GLWESwitchingKey { fn n(&self) -> Degree { self.key.n() diff --git a/poulpy-core/src/layouts/lwe_ksk.rs b/poulpy-core/src/layouts/lwe_ksk.rs index 8f4a2ed..2d4ba31 100644 --- a/poulpy-core/src/layouts/lwe_ksk.rs +++ b/poulpy-core/src/layouts/lwe_ksk.rs @@ -193,11 +193,11 @@ impl WriterTo for LWESwitchingKey { } } -pub trait LWEToLWEKeyToRef { +pub trait LWESwitchingKeyToRef { fn to_ref(&self) -> LWESwitchingKey<&[u8]>; } -impl LWEToLWEKeyToRef for LWESwitchingKey +impl LWESwitchingKeyToRef for LWESwitchingKey where GLWESwitchingKey: GLWESwitchingKeyToRef, { @@ -206,11 +206,11 @@ where } } -pub trait LWEToLWEKeyToMut { +pub trait LWESwitchingKeyToMut { fn to_mut(&mut self) -> LWESwitchingKey<&mut [u8]>; } -impl LWEToLWEKeyToMut for LWESwitchingKey +impl LWESwitchingKeyToMut for LWESwitchingKey where GLWESwitchingKey: GLWESwitchingKeyToMut, { diff --git a/poulpy-core/src/layouts/prepared/gglwe_atk.rs b/poulpy-core/src/layouts/prepared/gglwe_atk.rs index 2eda4e1..32dd177 100644 --- a/poulpy-core/src/layouts/prepared/gglwe_atk.rs +++ b/poulpy-core/src/layouts/prepared/gglwe_atk.rs @@ -1,12 +1,11 @@ -use poulpy_hal::{ - api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare}, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, -}; +use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}; use crate::layouts::{ AutomorphismKeyToRef, Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision, prepared::{ - GLWESwitchingKeyPrepareTmpBytes, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef, + GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepareTmpBytes, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedAlloc, + GLWESwitchingKeyPreparedAllocBytes, GLWESwitchingKeyPreparedAllocBytesFromInfos, GLWESwitchingKeyPreparedAllocFromInfos, + GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef, }, }; @@ -16,12 +15,6 @@ pub struct AutomorphismKeyPrepared { pub(crate) p: i64, } -impl AutomorphismKeyPrepared { - pub fn p(&self) -> i64 { - self.p - } -} - impl LWEInfos for AutomorphismKeyPrepared { fn n(&self) -> Degree { self.key.n() @@ -40,11 +33,21 @@ impl LWEInfos for AutomorphismKeyPrepared { } } -pub trait SetP { +pub trait GetAutomorphismGaloisElement { + fn p(&self) -> i64; +} + +impl GetAutomorphismGaloisElement for AutomorphismKeyPrepared { + fn p(&self) -> i64 { + self.p + } +} + +pub trait SetAutomorphismGaloisElement { fn set_p(&mut self, p: i64); } -impl SetP for AutomorphismKeyPrepared { +impl SetAutomorphismGaloisElement for AutomorphismKeyPrepared { fn set_p(&mut self, p: i64) { self.p = p } @@ -74,56 +77,146 @@ impl GGLWEInfos for AutomorphismKeyPrepared { } } -impl AutomorphismKeyPrepared, B> { - pub fn alloc(module: &Module, infos: &A) -> Self +pub trait AutomorphismKeyPreparedAlloc { + fn automorphism_key_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + rank: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> AutomorphismKeyPrepared, B>; +} + +impl AutomorphismKeyPreparedAlloc for Module +where + Module: GLWESwitchingKeyPreparedAlloc, +{ + fn automorphism_key_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + rank: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> AutomorphismKeyPrepared, B> { + AutomorphismKeyPrepared::, B> { + key: self.glwe_switching_key_prepared_alloc(base2k, k, rank, rank, dnum, dsize), + p: 0, + } + } +} + +pub trait AutomorphismKeyPreparedAllocFromInfos { + fn automorphism_key_prepared_alloc_from_infos(&self, infos: &A) -> AutomorphismKeyPrepared, B> + where + A: GGLWEInfos; +} + +impl AutomorphismKeyPreparedAllocFromInfos for Module +where + Module: GLWESwitchingKeyPreparedAllocFromInfos, +{ + fn automorphism_key_prepared_alloc_from_infos(&self, infos: &A) -> AutomorphismKeyPrepared, B> + where + A: GGLWEInfos, + { + assert_eq!( + infos.rank_in(), + infos.rank_out(), + "rank_in != rank_out is not supported for AutomorphismKeyPrepared" + ); + AutomorphismKeyPrepared { + key: self.glwe_switching_key_prepared_alloc_from_infos(infos), + p: 0, + } + } +} + +pub trait AutomorphismKeyPreparedAllocBytes { + fn automorphism_key_prepared_alloc_bytes( + &self, + base2k: Base2K, + k: TorusPrecision, + rank: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> usize; +} + +impl AutomorphismKeyPreparedAllocBytes for Module +where + Module: GLWESwitchingKeyPreparedAllocBytes, +{ + fn automorphism_key_prepared_alloc_bytes( + &self, + base2k: Base2K, + k: TorusPrecision, + rank: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> usize { + self.glwe_switching_key_prepared_alloc_bytes(base2k, k, rank, rank, dnum, dsize) + } +} + +pub trait AutomorphismKeyPreparedAllocBytesFromInfos { + fn automorphism_key_prepared_alloc_bytes_from_infos(&self, infos: &A) -> usize + where + A: GGLWEInfos; +} + +impl AutomorphismKeyPreparedAllocBytesFromInfos for Module +where + Module: GLWESwitchingKeyPreparedAllocBytesFromInfos, +{ + fn automorphism_key_prepared_alloc_bytes_from_infos(&self, infos: &A) -> usize where A: GGLWEInfos, - Module: VmpPMatAlloc, { assert_eq!( infos.rank_in(), infos.rank_out(), "rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared" ); - AutomorphismKeyPrepared::, B> { - key: GLWESwitchingKeyPrepared::alloc(module, infos), - p: 0, - } + self.glwe_switching_key_prepared_alloc_bytes_from_infos(infos) + } +} + +impl AutomorphismKeyPrepared, B> { + pub fn alloc_from_infos(module: &Module, infos: &A) -> Self + where + A: GGLWEInfos, + Module: AutomorphismKeyPreparedAllocFromInfos, + { + module.automorphism_key_prepared_alloc_from_infos(infos) } pub fn alloc_with(module: &Module, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self where - Module: VmpPMatAlloc, + Module: AutomorphismKeyPreparedAlloc, { - AutomorphismKeyPrepared { - key: GLWESwitchingKeyPrepared::alloc_with(module, base2k, k, rank, rank, dnum, dsize), - p: 0, - } + module.automorphism_key_prepared_alloc(base2k, k, rank, dnum, dsize) } pub fn alloc_bytes(module: &Module, infos: &A) -> usize where A: GGLWEInfos, - Module: VmpPMatAllocBytes, + Module: AutomorphismKeyPreparedAllocBytesFromInfos, { - assert_eq!( - infos.rank_in(), - infos.rank_out(), - "rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared" - ); - GLWESwitchingKeyPrepared::alloc_bytes(module, infos) + module.automorphism_key_prepared_alloc_bytes_from_infos(infos) } pub fn alloc_bytes_with(module: &Module, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize where - Module: VmpPMatAllocBytes, + Module: AutomorphismKeyPreparedAllocBytes, { - GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank, rank, dnum, dsize) + module.automorphism_key_prepared_alloc_bytes(base2k, k, rank, dnum, dsize) } } pub trait AutomorphismKeyPrepareTmpBytes { - fn automorphism_key_prepare_tmp_bytes(&self, infos: &A) + fn automorphism_key_prepare_tmp_bytes(&self, infos: &A) -> usize where A: GGLWEInfos; } @@ -132,7 +225,7 @@ impl AutomorphismKeyPrepareTmpBytes for Module where Module: GLWESwitchingKeyPrepareTmpBytes, { - fn automorphism_key_prepare_tmp_bytes(&self, infos: &A) + fn automorphism_key_prepare_tmp_bytes(&self, infos: &A) -> usize where A: GGLWEInfos, { @@ -145,45 +238,28 @@ impl AutomorphismKeyPrepared { where Module: AutomorphismKeyPrepareTmpBytes, { - module.automorphism_key_prepare_tmp_bytes(self); + module.automorphism_key_prepare_tmp_bytes(self) } } pub trait AutomorphismKeyPrepare { - fn automorphism_key_prepare(&self, res: &R, other: &O, scratch: &Scratch) + fn automorphism_key_prepare(&self, res: &mut R, other: &O, scratch: &mut Scratch) where - R: AutomorphismKeyPreparedToMut, - O: AutomorphismKeyToRef; + R: AutomorphismKeyPreparedToMut + SetAutomorphismGaloisElement, + O: AutomorphismKeyToRef + GetAutomorphismGaloisElement; } -impl AutomorphismKeyPrepare for Module { - fn automorphism_key_prepare(&self, res: &R, other: &O, scratch: &Scratch) - where - R: AutomorphismKeyPreparedToMut, - O: AutomorphismKeyToRef, - { - self.key.prepare(self, &other.to_ref().key, scratch); - self.p = other.p; - } -} - -pub trait AutomorphismKeyPrepareAlloc { - fn automorphism_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) -> AutomorphismKeyPrepared, B> - where - O: AutomorphismKeyToRef; -} - -impl AutomorphismKeyPrepareAlloc for Module +impl AutomorphismKeyPrepare for Module where - Module: VmpPMatAlloc + VmpPrepare, + Module: GLWESwitchingKeyPrepare, { - fn automorphism_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) -> AutomorphismKeyPrepared, B> + fn automorphism_key_prepare(&self, res: &mut R, other: &O, scratch: &mut Scratch) where - O: AutomorphismKeyToRef, + R: AutomorphismKeyPreparedToMut + SetAutomorphismGaloisElement, + O: AutomorphismKeyToRef + GetAutomorphismGaloisElement, { - let mut atk_prepared: AutomorphismKeyPrepared, B> = AutomorphismKeyPrepared::alloc(self, &other.to_ref()); - atk_prepared.prepare(self, &other.to_ref(), scratch); - atk_prepared + self.glwe_switching_prepare(&mut res.to_mut().key, &other.to_ref().key, scratch); + res.set_p(other.p()); } } diff --git a/poulpy-core/src/layouts/prepared/gglwe_ct.rs b/poulpy-core/src/layouts/prepared/gglwe_ct.rs index a19fd92..077ad7c 100644 --- a/poulpy-core/src/layouts/prepared/gglwe_ct.rs +++ b/poulpy-core/src/layouts/prepared/gglwe_ct.rs @@ -160,15 +160,70 @@ impl GGLWEPreparedBuilder { } } -impl GGLWEPrepared, B> { - pub fn alloc(module: &Module, infos: &A) -> Self +pub trait GGLWEPreparedAlloc { + fn gglwe_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + rank_out: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> GGLWEPrepared, B>; +} + +impl GGLWEPreparedAlloc for Module +where + Module: VmpPMatAlloc, +{ + fn gglwe_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + rank_out: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> GGLWEPrepared, B> { + let size: usize = k.0.div_ceil(base2k.0) as usize; + debug_assert!( + size as u32 > dsize.0, + "invalid gglwe: ceil(k/base2k): {size} <= dsize: {}", + dsize.0 + ); + + assert!( + dnum.0 * dsize.0 <= size as u32, + "invalid gglwe: dnum: {} * dsize:{} > ceil(k/base2k): {size}", + dnum.0, + dsize.0, + ); + + GGLWEPrepared { + data: self.vmp_pmat_alloc(dnum.into(), rank_in.into(), (rank_out + 1).into(), size), + k, + base2k, + dsize, + } + } +} + +pub trait GGLWEPreparedAllocFromInfos { + fn gglwe_prepared_alloc_from_infos(&self, infos: &A) -> GGLWEPrepared, B> + where + A: GGLWEInfos; +} + +impl GGLWEPreparedAllocFromInfos for Module +where + Module: GGLWEPreparedAlloc, +{ + fn gglwe_prepared_alloc_from_infos(&self, infos: &A) -> GGLWEPrepared, B> where A: GGLWEInfos, - Module: VmpPMatAlloc, { - debug_assert_eq!(module.n(), infos.n().0 as usize, "module.n() != infos.n()"); - Self::alloc_with( - module, + assert_eq!(self.n() as u32, infos.n(), "module.n() != infos.n()"); + self.gglwe_prepared_alloc( infos.base2k(), infos.k(), infos.rank_in(), @@ -177,8 +232,87 @@ impl GGLWEPrepared, B> { infos.dsize(), ) } +} - pub fn alloc_with( +pub trait GGLWEPreparedAllocBytes { + fn gglwe_prepared_alloc_bytes( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + rank_out: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> usize; +} + +impl GGLWEPreparedAllocBytes for Module +where + Module: VmpPMatAllocBytes, +{ + fn gglwe_prepared_alloc_bytes( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + rank_out: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> usize { + let size: usize = k.0.div_ceil(base2k.0) as usize; + debug_assert!( + size as u32 > dsize.0, + "invalid gglwe: ceil(k/base2k): {size} <= dsize: {}", + dsize.0 + ); + + assert!( + dnum.0 * dsize.0 <= size as u32, + "invalid gglwe: dnum: {} * dsize:{} > ceil(k/base2k): {size}", + dnum.0, + dsize.0, + ); + + self.vmp_pmat_alloc_bytes(dnum.into(), rank_in.into(), (rank_out + 1).into(), size) + } +} + +pub trait GGLWEPreparedAllocBytesFromInfos { + fn gglwe_prepared_alloc_bytes_from_infos(&self, infos: &A) -> usize + where + A: GGLWEInfos; +} + +impl GGLWEPreparedAllocBytesFromInfos for Module +where + Module: GGLWEPreparedAllocBytes, +{ + fn gglwe_prepared_alloc_bytes_from_infos(&self, infos: &A) -> usize + where + A: GGLWEInfos, + { + assert_eq!(self.n() as u32, infos.n(), "module.n() != infos.n()"); + self.gglwe_prepared_alloc_bytes( + infos.base2k(), + infos.k(), + infos.rank_in(), + infos.rank_out(), + infos.dnum(), + infos.dsize(), + ) + } +} + +impl GGLWEPrepared, B> { + pub fn alloc_from_infos(module: &Module, infos: &A) -> Self + where + A: GGLWEInfos, + Module: GGLWEPreparedAllocFromInfos, + { + module.gglwe_prepared_alloc_from_infos(infos) + } + + pub fn alloc( module: &Module, base2k: Base2K, k: TorusPrecision, @@ -188,48 +322,20 @@ impl GGLWEPrepared, B> { dsize: Dsize, ) -> Self where - Module: VmpPMatAlloc, + Module: GGLWEPreparedAlloc, { - let size: usize = k.0.div_ceil(base2k.0) as usize; - debug_assert!( - size as u32 > dsize.0, - "invalid gglwe: ceil(k/base2k): {size} <= dsize: {}", - dsize.0 - ); - - assert!( - dnum.0 * dsize.0 <= size as u32, - "invalid gglwe: dnum: {} * dsize:{} > ceil(k/base2k): {size}", - dnum.0, - dsize.0, - ); - - Self { - data: module.vmp_pmat_alloc(dnum.into(), rank_in.into(), (rank_out + 1).into(), size), - k, - base2k, - dsize, - } + module.gglwe_prepared_alloc(base2k, k, rank_in, rank_out, dnum, dsize) } - pub fn alloc_bytes(module: &Module, infos: &A) -> usize + pub fn alloc_bytes_from_infos(module: &Module, infos: &A) -> usize where A: GGLWEInfos, - Module: VmpPMatAllocBytes, + Module: GGLWEPreparedAllocBytesFromInfos, { - debug_assert_eq!(module.n(), infos.n().0 as usize, "module.n() != infos.n()"); - Self::alloc_bytes_with( - module, - infos.base2k(), - infos.k(), - infos.rank_in(), - infos.rank_out(), - infos.dnum(), - infos.dsize(), - ) + module.gglwe_prepared_alloc_bytes_from_infos(infos) } - pub fn alloc_bytes_with( + pub fn alloc_bytes( module: &Module, base2k: Base2K, k: TorusPrecision, @@ -239,23 +345,9 @@ impl GGLWEPrepared, B> { dsize: Dsize, ) -> usize where - Module: VmpPMatAllocBytes, + Module: GGLWEPreparedAllocBytes, { - let size: usize = k.0.div_ceil(base2k.0) as usize; - debug_assert!( - size as u32 > dsize.0, - "invalid gglwe: ceil(k/base2k): {size} <= dsize: {}", - dsize.0 - ); - - assert!( - dnum.0 * dsize.0 <= size as u32, - "invalid gglwe: dnum: {} * dsize:{} > ceil(k/base2k): {size}", - dnum.0, - dsize.0, - ); - - module.vmp_pmat_alloc_bytes(dnum.into(), rank_in.into(), (rank_out + 1).into(), size) + module.gglwe_prepared_alloc_bytes(base2k, k, rank_in, rank_out, dnum, dsize) } } @@ -283,7 +375,7 @@ where } impl GGLWEPrepared, B> { - pub fn prepare_tmp_bytes(&self, module: &Module) + pub fn prepare_tmp_bytes(&self, module: &Module) -> usize where Module: GGLWEPrepareTmpBytes, { @@ -307,7 +399,7 @@ where R: GGLWEPreparedToMut, O: GGLWEToRef, { - let mut res: GGLWEPrepared<&mut [u8], B> = self.to_mut(); + let mut res: GGLWEPrepared<&mut [u8], B> = res.to_mut(); let other: GGLWE<&[u8]> = other.to_ref(); assert_eq!(res.n(), self.n() as u32); @@ -332,30 +424,6 @@ where } } -pub trait GGLWEPrepareAlloc { - fn gglwe_prepare_alloc(&self, other: &O, scratch: &mut Scratch) -> GGLWEPrepared, B>; -} - -impl GGLWEPrepareAlloc for Module -where - Module: VmpPMatAlloc + VmpPrepare, -{ - fn gglwe_prepare_alloc(&self, other: &O, scratch: &mut Scratch) -> GGLWEPrepared, B> { - let mut ct_prepared: GGLWEPrepared, B> = GGLWEPrepared::alloc(self, &other.to_ref()); - ct_prepared.prepare(self, &other.to_ref(), scratch); - ct_prepared - } -} - -impl GGLWE { - fn prepare_alloc(&self, module: &Module, scratch: &Scratch) -> GGLWEPrepared, B> - where - Module: GGLWEPrepareAlloc, - { - module.gglwe_prepare_alloc(self, scratch) - } -} - pub trait GGLWEPreparedToMut { fn to_mut(&mut self) -> GGLWEPrepared<&mut [u8], B>; } diff --git a/poulpy-core/src/layouts/prepared/gglwe_ksk.rs b/poulpy-core/src/layouts/prepared/gglwe_ksk.rs index 7f2f887..7f3aa97 100644 --- a/poulpy-core/src/layouts/prepared/gglwe_ksk.rs +++ b/poulpy-core/src/layouts/prepared/gglwe_ksk.rs @@ -1,11 +1,12 @@ -use poulpy_hal::{ - api::{VmpPMatAlloc, VmpPMatAllocBytes}, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, -}; +use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}; use crate::layouts::{ - Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision, - prepared::{GGLWEPrepare, GGLWEPrepareTmpBytes, GGLWEPrepared, GGLWEPreparedToMut, GGLWEPreparedToRef}, + Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKeySetMetaData, GLWESwitchingKeyToRef, + GLWESwtichingKeyGetMetaData, LWEInfos, Rank, TorusPrecision, + prepared::{ + GGLWEPrepare, GGLWEPrepareTmpBytes, GGLWEPrepared, GGLWEPreparedAlloc, GGLWEPreparedAllocBytes, + GGLWEPreparedAllocBytesFromInfos, GGLWEPreparedAllocFromInfos, GGLWEPreparedToMut, GGLWEPreparedToRef, + }, }; #[derive(PartialEq, Eq)] @@ -15,18 +16,23 @@ pub struct GLWESwitchingKeyPrepared { pub(crate) sk_out_n: usize, // Degree of sk_out } -pub(crate) trait GLWESwitchingKeyPreparedSetMetaData { - fn set_sk_in_n(&mut self, sk_in_n: usize); - fn set_sk_out_n(&mut self, sk_out_n: usize); -} - -impl GLWESwitchingKeyPreparedSetMetaData for GLWESwitchingKeyPrepared { +impl GLWESwitchingKeySetMetaData for GLWESwitchingKeyPrepared { fn set_sk_in_n(&mut self, sk_in_n: usize) { self.sk_in_n = sk_in_n } fn set_sk_out_n(&mut self, sk_out_n: usize) { - self.sk_out_n = self.sk_out_n + self.sk_out_n = sk_out_n + } +} + +impl GLWESwtichingKeyGetMetaData for GLWESwitchingKeyPrepared { + fn sk_in_n(&self) -> usize { + self.sk_in_n + } + + fn sk_out_n(&self) -> usize { + self.sk_out_n } } @@ -72,21 +78,118 @@ impl GGLWEInfos for GLWESwitchingKeyPrepared { } } -impl GLWESwitchingKeyPrepared, B> { - pub fn alloc(module: &Module, infos: &A) -> Self - where - A: GGLWEInfos, - Module: VmpPMatAlloc, - { - debug_assert_eq!(module.n() as u32, infos.n(), "module.n() != infos.n()"); +pub trait GLWESwitchingKeyPreparedAlloc { + fn glwe_switching_key_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + rank_out: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> GLWESwitchingKeyPrepared, B>; +} + +impl GLWESwitchingKeyPreparedAlloc for Module +where + Module: GGLWEPreparedAlloc, +{ + fn glwe_switching_key_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + rank_out: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> GLWESwitchingKeyPrepared, B> { GLWESwitchingKeyPrepared::, B> { - key: GGLWEPrepared::alloc(module, infos), + key: self.gglwe_prepared_alloc(base2k, k, rank_in, rank_out, dnum, dsize), sk_in_n: 0, sk_out_n: 0, } } +} - pub fn alloc_with( +pub trait GLWESwitchingKeyPreparedAllocFromInfos { + fn glwe_switching_key_prepared_alloc_from_infos(&self, infos: &A) -> GLWESwitchingKeyPrepared, B> + where + A: GGLWEInfos; +} + +impl GLWESwitchingKeyPreparedAllocFromInfos for Module +where + Module: GGLWEPreparedAllocFromInfos, +{ + fn glwe_switching_key_prepared_alloc_from_infos(&self, infos: &A) -> GLWESwitchingKeyPrepared, B> + where + A: GGLWEInfos, + { + GLWESwitchingKeyPrepared::, B> { + key: self.gglwe_prepared_alloc_from_infos(infos), + sk_in_n: 0, + sk_out_n: 0, + } + } +} + +pub trait GLWESwitchingKeyPreparedAllocBytes { + fn glwe_switching_key_prepared_alloc_bytes( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + rank_out: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> usize; +} + +impl GLWESwitchingKeyPreparedAllocBytes for Module +where + Module: GGLWEPreparedAllocBytes, +{ + fn glwe_switching_key_prepared_alloc_bytes( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + rank_out: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> usize { + self.gglwe_prepared_alloc_bytes(base2k, k, rank_in, rank_out, dnum, dsize) + } +} + +pub trait GLWESwitchingKeyPreparedAllocBytesFromInfos { + fn glwe_switching_key_prepared_alloc_bytes_from_infos(&self, infos: &A) -> usize + where + A: GGLWEInfos; +} + +impl GLWESwitchingKeyPreparedAllocBytesFromInfos for Module +where + Module: GGLWEPreparedAllocBytesFromInfos, +{ + fn glwe_switching_key_prepared_alloc_bytes_from_infos(&self, infos: &A) -> usize + where + A: GGLWEInfos, + { + self.gglwe_prepared_alloc_bytes_from_infos(infos) + } +} + +impl GLWESwitchingKeyPrepared, B> { + pub fn alloc_from_infos(module: &Module, infos: &A) -> Self + where + A: GGLWEInfos, + Module: GLWESwitchingKeyPreparedAllocFromInfos, + { + module.glwe_switching_key_prepared_alloc_from_infos(infos) + } + + pub fn alloc( module: &Module, base2k: Base2K, k: TorusPrecision, @@ -96,25 +199,20 @@ impl GLWESwitchingKeyPrepared, B> { dsize: Dsize, ) -> Self where - Module: VmpPMatAlloc, + Module: GLWESwitchingKeyPreparedAlloc, { - GLWESwitchingKeyPrepared::, B> { - key: GGLWEPrepared::alloc_with(module, base2k, k, rank_in, rank_out, dnum, dsize), - sk_in_n: 0, - sk_out_n: 0, - } + module.glwe_switching_key_prepared_alloc(base2k, k, rank_in, rank_out, dnum, dsize) } - pub fn alloc_bytes(module: &Module, infos: &A) -> usize + pub fn alloc_bytes_from_infos(module: &Module, infos: &A) -> usize where A: GGLWEInfos, - Module: VmpPMatAllocBytes, + Module: GLWESwitchingKeyPreparedAllocBytesFromInfos, { - debug_assert_eq!(module.n() as u32, infos.n(), "module.n() != infos.n()"); - GGLWEPrepared::alloc_bytes(module, infos) + module.glwe_switching_key_prepared_alloc_bytes_from_infos(infos) } - pub fn alloc_bytes_with( + pub fn alloc_bytes( module: &Module, base2k: Base2K, k: TorusPrecision, @@ -124,9 +222,9 @@ impl GLWESwitchingKeyPrepared, B> { dsize: Dsize, ) -> usize where - Module: VmpPMatAllocBytes, + Module: GLWESwitchingKeyPreparedAllocBytes, { - GGLWEPrepared::alloc_bytes_with(module, base2k, k, rank_in, rank_out, dnum, dsize) + module.glwe_switching_key_prepared_alloc_bytes(base2k, k, rank_in, rank_out, dnum, dsize) } } @@ -158,66 +256,37 @@ where } pub trait GLWESwitchingKeyPrepare { - fn glwe_switching_prepare(&self, res: &R, other: &O, scratch: &mut Scratch) + fn glwe_switching_prepare(&self, res: &mut R, other: &O, scratch: &mut Scratch) where - R: GLWESwitchingKeyPreparedToMut + GLWESwitchingKeyPreparedSetMetaData, - O: GLWESwitchingKeyToRef; + R: GLWESwitchingKeyPreparedToMut + GLWESwitchingKeySetMetaData, + O: GLWESwitchingKeyToRef + GLWESwtichingKeyGetMetaData; } impl GLWESwitchingKeyPrepare for Module where Module: GGLWEPrepare, { - fn glwe_switching_prepare(&self, res: &R, other: &O, scratch: &mut Scratch) + fn glwe_switching_prepare(&self, res: &mut R, other: &O, scratch: &mut Scratch) where - R: GLWESwitchingKeyPreparedToMut + GLWESwitchingKeyPreparedSetMetaData, - O: GLWESwitchingKeyToRef, + R: GLWESwitchingKeyPreparedToMut + GLWESwitchingKeySetMetaData, + O: GLWESwitchingKeyToRef + GLWESwtichingKeyGetMetaData, { - self.gglwe_prepare(&res.to_mut(), other, scratch); - res.set_sk_in_n(other.sk_in_n); - res.set_sk_out_n(other.sk_out_n); + self.gglwe_prepare(&mut res.to_mut().key, &other.to_ref().key, scratch); + res.set_sk_in_n(other.sk_in_n()); + res.set_sk_out_n(other.sk_out_n()); } } impl GLWESwitchingKeyPrepared { pub fn prepare(&mut self, module: &Module, other: &O, scratch: &mut Scratch) where - O: GLWESwitchingKeyToRef, + O: GLWESwitchingKeyToRef + GLWESwtichingKeyGetMetaData, Module: GLWESwitchingKeyPrepare, { module.glwe_switching_prepare(self, other, scratch); } } -pub trait GLWESwitchingKeyPrepareAlloc { - fn glwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) - where - O: GLWESwitchingKeyToRef; -} - -impl GLWESwitchingKeyPrepareAlloc for Module -where - Module: GLWESwitchingKeyPrepare, -{ - fn glwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) - where - O: GLWESwitchingKeyToRef, - { - let mut ct_prepared: GLWESwitchingKeyPrepared, B> = GLWESwitchingKeyPrepared::alloc(self, self); - self.glwe_switching_prepare(&mut ct_prepared, other, scratch); - ct_prepared - } -} - -impl GLWESwitchingKey { - pub fn prepare_alloc(&self, module: &Module, scratch: &mut Scratch) -> GLWESwitchingKeyPrepared, B> - where - Module: GLWESwitchingKeyPrepareAlloc, - { - module.glwe_switching_key_prepare_alloc(self, scratch); - } -} - pub trait GLWESwitchingKeyPreparedToMut { fn to_mut(&mut self) -> GLWESwitchingKeyPrepared<&mut [u8], B>; } diff --git a/poulpy-core/src/layouts/prepared/gglwe_tsk.rs b/poulpy-core/src/layouts/prepared/gglwe_tsk.rs index eed6ff2..c6cfc90 100644 --- a/poulpy-core/src/layouts/prepared/gglwe_tsk.rs +++ b/poulpy-core/src/layouts/prepared/gglwe_tsk.rs @@ -87,7 +87,7 @@ impl TensorKeyPrepared, B> { let mut keys: Vec, B>> = Vec::new(); let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1); (0..pairs).for_each(|_| { - keys.push(GLWESwitchingKeyPrepared::alloc_with( + keys.push(GLWESwitchingKeyPrepared::alloc( module, base2k, k, @@ -113,7 +113,7 @@ impl TensorKeyPrepared, B> { let rank_out: usize = infos.rank_out().into(); let pairs: usize = (((rank_out + 1) * rank_out) >> 1).max(1); pairs - * GLWESwitchingKeyPrepared::alloc_bytes_with( + * GLWESwitchingKeyPrepared::alloc_bytes( module, infos.base2k(), infos.k(), @@ -129,7 +129,7 @@ impl TensorKeyPrepared, B> { Module: VmpPMatAllocBytes, { let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize; - pairs * GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank, dnum, dsize) + pairs * GLWESwitchingKeyPrepared::alloc_bytes(module, base2k, k, Rank(1), rank, dnum, dsize) } } diff --git a/poulpy-core/src/layouts/prepared/glwe_to_lwe_ksk.rs b/poulpy-core/src/layouts/prepared/glwe_to_lwe_ksk.rs index cea8b41..e2a8fdc 100644 --- a/poulpy-core/src/layouts/prepared/glwe_to_lwe_ksk.rs +++ b/poulpy-core/src/layouts/prepared/glwe_to_lwe_ksk.rs @@ -1,11 +1,15 @@ use poulpy_hal::{ - api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare}, + api::{VmpPMatAlloc, VmpPMatAllocBytes}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, }; use crate::layouts::{ - Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWESwitchingKey, LWEInfos, Rank, TorusPrecision, - prepared::GLWESwitchingKeyPrepared, + Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWESwitchingKeyToMut, GLWEToLWESwitchingKeyToRef, LWEInfos, Rank, + TorusPrecision, + prepared::{ + GLWESecretPrepareTmpBytes, GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, + GLWESwitchingKeyPreparedToRef, + }, }; #[derive(PartialEq, Eq)] @@ -69,14 +73,14 @@ impl GLWEToLWESwitchingKeyPrepared, B> { 1, "dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared" ); - Self(GLWESwitchingKeyPrepared::alloc(module, infos)) + Self(GLWESwitchingKeyPrepared::alloc_from_infos(module, infos)) } pub fn alloc_with(module: &Module, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self where Module: VmpPMatAlloc, { - Self(GLWESwitchingKeyPrepared::alloc_with( + Self(GLWESwitchingKeyPrepared::alloc( module, base2k, k, @@ -102,42 +106,117 @@ impl GLWEToLWESwitchingKeyPrepared, B> { 1, "dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared" ); - GLWESwitchingKeyPrepared::alloc_bytes(module, infos) + GLWESwitchingKeyPrepared::alloc_bytes_from_infos(module, infos) } pub fn alloc_bytes_with(module: &Module, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize where Module: VmpPMatAllocBytes, { - GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank_in, Rank(1), dnum, Dsize(1)) + GLWESwitchingKeyPrepared::alloc_bytes(module, base2k, k, rank_in, Rank(1), dnum, Dsize(1)) } } -impl PrepareScratchSpace for GLWEToLWESwitchingKeyPrepared, B> +pub trait GLWEToLWESwitchingKeyPrepareTmpBytes { + fn glwe_to_lwe_switching_key_prepare_tmp_bytes(&self, infos: &A) + where + A: GGLWEInfos; +} + +impl GLWEToLWESwitchingKeyPrepareTmpBytes for Module where - GLWESwitchingKeyPrepared, B>: PrepareScratchSpace, + Module: GLWEToLWESwitchingKeyPrepareTmpBytes, { - fn prepare_scratch_space(module: &Module, infos: &A) -> usize { - GLWESwitchingKeyPrepared::prepare_scratch_space(module, infos) + fn glwe_to_lwe_switching_key_prepare_tmp_bytes(&self, infos: &A) + where + A: GGLWEInfos, + { + self.glwe_to_lwe_switching_key_prepare_tmp_bytes(infos); } } -impl PrepareAlloc, B>> for GLWEToLWESwitchingKey -where - Module: VmpPrepare + VmpPMatAlloc, -{ - fn prepare_alloc(&self, module: &Module, scratch: &mut Scratch) -> GLWEToLWESwitchingKeyPrepared, B> { - let mut ksk_prepared: GLWEToLWESwitchingKeyPrepared, B> = GLWEToLWESwitchingKeyPrepared::alloc(module, self); - ksk_prepared.prepare(module, self, scratch); - ksk_prepared +impl GLWEToLWESwitchingKeyPrepared, B> { + pub fn prepare_tmp_bytes(&self, module: &Module, infos: &A) + where + A: GLWEInfos, + Module: GLWEToLWESwitchingKeyPrepareTmpBytes, + { + module.glwe_secret_prepare_tmp_bytes(infos); } } -impl Prepare> for GLWEToLWESwitchingKeyPrepared +pub trait GLWEToLWESwitchingKeyPrepare { + fn glwe_to_lwe_switching_key_prepare(&self, res: &mut R, other: &O, scratch: &Scratch) + where + R: GLWEToLWESwitchingKeyPreparedToMut, + O: GLWEToLWESwitchingKeyToRef; +} + +impl GLWEToLWESwitchingKeyPrepare for Module where - Module: VmpPrepare, + Module: GLWESwitchingKeyPrepare, { - fn prepare(&mut self, module: &Module, other: &GLWEToLWESwitchingKey, scratch: &mut Scratch) { - self.0.prepare(module, &other.0, scratch); + fn glwe_to_lwe_switching_key_prepare(&self, res: &mut R, other: &O, scratch: &Scratch) + where + R: GLWEToLWESwitchingKeyPreparedToMut, + O: GLWEToLWESwitchingKeyToRef, + { + self.glwe_switching_prepare(&mut res.to_mut().0, other, scratch); + } +} + +impl GLWEToLWESwitchingKeyPrepared { + fn prepare(&mut self, module: &Module, other: &O, scratch: &Scratch) + where + O: GLWEToLWESwitchingKeyToRef, + Module: GLWEToLWESwitchingKeyPrepare, + { + module.glwe_to_lwe_switching_key_prepare(self, other, scratch); + } +} + +pub trait GLWEToLWESwitchingKeyPrepareAlloc { + fn glwe_to_lwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) + where + O: GLWEToLWESwitchingKeyToRef; +} + +impl GLWEToLWESwitchingKeyPrepareAlloc for Module +where + Module: GLWEToLWESwitchingKeyPrepare, +{ + fn glwe_to_lwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) + where + O: GLWEToLWESwitchingKeyToRef, + { + let mut ct_prep: GLWEToLWESwitchingKeyPrepared, B> = GLWEToLWESwitchingKeyPrepared::alloc(self, &other.to_ref()); + self.glwe_to_lwe_switching_key_prepare(&mut ct_prep, other, scratch); + ct_prep + } +} + +pub trait GLWEToLWESwitchingKeyPreparedToRef { + fn to_ref(&self) -> GLWEToLWESwitchingKeyPrepared<&[u8], B>; +} + +impl GLWEToLWESwitchingKeyPreparedToRef for GLWEToLWESwitchingKeyPrepared +where + GLWESwitchingKeyPrepared: GLWESwitchingKeyPreparedToRef, +{ + fn to_ref(&self) -> GLWEToLWESwitchingKeyPrepared<&[u8], B> { + GLWEToLWESwitchingKeyPrepared(self.0.to_ref()) + } +} + +pub trait GLWEToLWESwitchingKeyPreparedToMut { + fn to_mut(&mut self) -> GLWEToLWESwitchingKeyPrepared<&mut [u8], B>; +} + +impl GLWEToLWESwitchingKeyPreparedToMut for GLWEToLWESwitchingKeyPrepared +where + GLWESwitchingKeyPrepared: GLWESwitchingKeyPreparedToMut, +{ + fn to_mut(&mut self) -> GLWEToLWESwitchingKeyPrepared<&mut [u8], B> { + GLWEToLWESwitchingKeyPrepared(self.0.to_mut()) } } diff --git a/poulpy-core/src/layouts/prepared/lwe_ksk.rs b/poulpy-core/src/layouts/prepared/lwe_ksk.rs index 8e21f23..cf5f31b 100644 --- a/poulpy-core/src/layouts/prepared/lwe_ksk.rs +++ b/poulpy-core/src/layouts/prepared/lwe_ksk.rs @@ -1,11 +1,11 @@ use poulpy_hal::{ - api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare}, + api::{VmpPMatAlloc, VmpPMatAllocBytes}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, }; use crate::layouts::{ - Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKey, Rank, TorusPrecision, - prepared::GLWESwitchingKeyPrepared, + Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKeyToRef, Rank, TorusPrecision, + prepared::{GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef}, }; #[derive(PartialEq, Eq)] @@ -73,14 +73,14 @@ impl LWESwitchingKeyPrepared, B> { 1, "rank_out > 1 is not supported for LWESwitchingKey" ); - Self(GLWESwitchingKeyPrepared::alloc(module, infos)) + Self(GLWESwitchingKeyPrepared::alloc_from_infos(module, infos)) } pub fn alloc_with(module: &Module, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self where Module: VmpPMatAlloc, { - Self(GLWESwitchingKeyPrepared::alloc_with( + Self(GLWESwitchingKeyPrepared::alloc( module, base2k, k, @@ -111,42 +111,117 @@ impl LWESwitchingKeyPrepared, B> { 1, "rank_out > 1 is not supported for LWESwitchingKey" ); - GLWESwitchingKeyPrepared::alloc_bytes(module, infos) + GLWESwitchingKeyPrepared::alloc_bytes_from_infos(module, infos) } pub fn alloc_bytes_with(module: &Module, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize where Module: VmpPMatAllocBytes, { - GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1)) + GLWESwitchingKeyPrepared::alloc_bytes(module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1)) } } -impl PrepareScratchSpace for LWESwitchingKeyPrepared, B> +pub trait LWESwitchingKeyPrepareTmpBytes { + fn lwe_switching_key_prepare_tmp_bytes(&self, infos: &A) + where + A: GGLWEInfos; +} + +impl LWESwitchingKeyPrepareTmpBytes for Module where - GLWESwitchingKeyPrepared, B>: PrepareScratchSpace, + Module: LWESwitchingKeyPrepareTmpBytes, { - fn prepare_scratch_space(module: &Module, infos: &A) -> usize { - GLWESwitchingKeyPrepared::prepare_scratch_space(module, infos) + fn lwe_switching_key_prepare_tmp_bytes(&self, infos: &A) + where + A: GGLWEInfos, + { + self.lwe_switching_key_prepare_tmp_bytes(infos); } } -impl PrepareAlloc, B>> for LWESwitchingKey -where - Module: VmpPrepare + VmpPMatAlloc, -{ - fn prepare_alloc(&self, module: &Module, scratch: &mut Scratch) -> LWESwitchingKeyPrepared, B> { - let mut ksk_prepared: LWESwitchingKeyPrepared, B> = LWESwitchingKeyPrepared::alloc(module, self); - ksk_prepared.prepare(module, self, scratch); - ksk_prepared +impl LWESwitchingKeyPrepared, B> { + pub fn prepare_tmp_bytes(&self, module: &Module, infos: &A) + where + A: GLWEInfos, + Module: LWESwitchingKeyPrepareTmpBytes, + { + module.glwe_secret_prepare_tmp_bytes(infos); } } -impl Prepare> for LWESwitchingKeyPrepared +pub trait LWESwitchingKeyPrepare { + fn lwe_switching_key_prepare(&self, res: &mut R, other: &O, scratch: &Scratch) + where + R: LWESwitchingKeyPreparedToMut, + O: LWESwitchingKeyToRef; +} + +impl LWESwitchingKeyPrepare for Module where - Module: VmpPrepare, + Module: GLWESwitchingKeyPrepare, { - fn prepare(&mut self, module: &Module, other: &LWESwitchingKey, scratch: &mut Scratch) { - self.0.prepare(module, &other.0, scratch); + fn lwe_switching_key_prepare(&self, res: &mut R, other: &O, scratch: &Scratch) + where + R: LWESwitchingKeyPreparedToMut, + O: LWESwitchingKeyToRef, + { + self.glwe_switching_prepare(&mut res.to_mut().0, other, scratch); + } +} + +impl LWESwitchingKeyPrepared { + fn prepare(&mut self, module: &Module, other: &O, scratch: &Scratch) + where + O: LWESwitchingKeyToRef, + Module: LWESwitchingKeyPrepare, + { + module.lwe_switching_key_prepare(self, other, scratch); + } +} + +pub trait LWESwitchingKeyPrepareAlloc { + fn lwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) + where + O: LWESwitchingKeyToRef; +} + +impl LWESwitchingKeyPrepareAlloc for Module +where + Module: LWESwitchingKeyPrepare, +{ + fn lwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) + where + O: LWESwitchingKeyToRef, + { + let mut ct_prep: LWESwitchingKeyPrepared, B> = LWESwitchingKeyPrepared::alloc(self, &other.to_ref()); + self.lwe_switching_key_prepare(&mut ct_prep, other, scratch); + ct_prep + } +} + +pub trait LWESwitchingKeyPreparedToRef { + fn to_ref(&self) -> LWESwitchingKeyPrepared<&[u8], B>; +} + +impl LWESwitchingKeyPreparedToRef for LWESwitchingKeyPrepared +where + GLWESwitchingKeyPrepared: GLWESwitchingKeyPreparedToRef, +{ + fn to_ref(&self) -> LWESwitchingKeyPrepared<&[u8], B> { + LWESwitchingKeyPrepared(self.0.to_ref()) + } +} + +pub trait LWESwitchingKeyPreparedToMut { + fn to_mut(&mut self) -> LWESwitchingKeyPrepared<&mut [u8], B>; +} + +impl LWESwitchingKeyPreparedToMut for LWESwitchingKeyPrepared +where + GLWESwitchingKeyPrepared: GLWESwitchingKeyPreparedToMut, +{ + fn to_mut(&mut self) -> LWESwitchingKeyPrepared<&mut [u8], B> { + LWESwitchingKeyPrepared(self.0.to_mut()) } } diff --git a/poulpy-core/src/layouts/prepared/lwe_to_glwe_ksk.rs b/poulpy-core/src/layouts/prepared/lwe_to_glwe_ksk.rs index 253c8cc..954553a 100644 --- a/poulpy-core/src/layouts/prepared/lwe_to_glwe_ksk.rs +++ b/poulpy-core/src/layouts/prepared/lwe_to_glwe_ksk.rs @@ -1,11 +1,11 @@ use poulpy_hal::{ - api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare}, + api::{VmpPMatAlloc, VmpPMatAllocBytes}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, }; use crate::layouts::{ - Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKey, Rank, TorusPrecision, - prepared::GLWESwitchingKeyPrepared, + Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKeyToRef, Rank, TorusPrecision, + prepared::{GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef}, }; /// A special [GLWESwitchingKey] required to for the conversion from [LWECiphertext] to [GLWECiphertext]. @@ -70,14 +70,14 @@ impl LWEToGLWESwitchingKeyPrepared, B> { 1, "dsize > 1 is not supported for LWEToGLWESwitchingKey" ); - Self(GLWESwitchingKeyPrepared::alloc(module, infos)) + Self(GLWESwitchingKeyPrepared::alloc_from_infos(module, infos)) } pub fn alloc_with(module: &Module, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self where Module: VmpPMatAlloc, { - Self(GLWESwitchingKeyPrepared::alloc_with( + Self(GLWESwitchingKeyPrepared::alloc( module, base2k, k, @@ -103,42 +103,117 @@ impl LWEToGLWESwitchingKeyPrepared, B> { 1, "dsize > 1 is not supported for LWEToGLWESwitchingKey" ); - GLWESwitchingKeyPrepared::alloc_bytes(module, infos) + GLWESwitchingKeyPrepared::alloc_bytes_from_infos(module, infos) } pub fn alloc_bytes_with(module: &Module, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_out: Rank) -> usize where Module: VmpPMatAllocBytes, { - GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank_out, dnum, Dsize(1)) + GLWESwitchingKeyPrepared::alloc_bytes(module, base2k, k, Rank(1), rank_out, dnum, Dsize(1)) } } -impl PrepareScratchSpace for LWEToGLWESwitchingKeyPrepared, B> +pub trait LWEToGLWESwitchingKeyPrepareTmpBytes { + fn lwe_to_glwe_switching_key_prepare_tmp_bytes(&self, infos: &A) + where + A: GGLWEInfos; +} + +impl LWEToGLWESwitchingKeyPrepareTmpBytes for Module where - GLWESwitchingKeyPrepared, B>: PrepareScratchSpace, + Module: LWEToGLWESwitchingKeyPrepareTmpBytes, { - fn prepare_scratch_space(module: &Module, infos: &A) -> usize { - GLWESwitchingKeyPrepared::prepare_scratch_space(module, infos) + fn lwe_to_glwe_switching_key_prepare_tmp_bytes(&self, infos: &A) + where + A: GGLWEInfos, + { + self.lwe_to_glwe_switching_key_prepare_tmp_bytes(infos); } } -impl PrepareAlloc, B>> for LWEToGLWESwitchingKey -where - Module: VmpPrepare + VmpPMatAlloc, -{ - fn prepare_alloc(&self, module: &Module, scratch: &mut Scratch) -> LWEToGLWESwitchingKeyPrepared, B> { - let mut ksk_prepared: LWEToGLWESwitchingKeyPrepared, B> = LWEToGLWESwitchingKeyPrepared::alloc(module, self); - ksk_prepared.prepare(module, self, scratch); - ksk_prepared +impl LWEToGLWESwitchingKeyPrepared, B> { + pub fn prepare_tmp_bytes(&self, module: &Module, infos: &A) + where + A: GLWEInfos, + Module: LWEToGLWESwitchingKeyPrepareTmpBytes, + { + module.glwe_secret_prepare_tmp_bytes(infos); } } -impl Prepare> for LWEToGLWESwitchingKeyPrepared +pub trait LWEToGLWESwitchingKeyPrepare { + fn lwe_to_glwe_switching_key_prepare(&self, res: &mut R, other: &O, scratch: &Scratch) + where + R: LWEToGLWESwitchingKeyPreparedToMut, + O: LWEToGLWESwitchingKeyToRef; +} + +impl LWEToGLWESwitchingKeyPrepare for Module where - Module: VmpPrepare, + Module: GLWESwitchingKeyPrepare, { - fn prepare(&mut self, module: &Module, other: &LWEToGLWESwitchingKey, scratch: &mut Scratch) { - self.0.prepare(module, &other.0, scratch); + fn lwe_to_glwe_switching_key_prepare(&self, res: &mut R, other: &O, scratch: &Scratch) + where + R: LWEToGLWESwitchingKeyPreparedToMut, + O: LWEToGLWESwitchingKeyToRef, + { + self.glwe_switching_prepare(&mut res.to_mut().0, other, scratch); + } +} + +impl LWEToGLWESwitchingKeyPrepared { + fn prepare(&mut self, module: &Module, other: &O, scratch: &Scratch) + where + O: LWEToGLWESwitchingKeyToRef, + Module: LWEToGLWESwitchingKeyPrepare, + { + module.lwe_to_glwe_switching_key_prepare(self, other, scratch); + } +} + +pub trait LWEToGLWESwitchingKeyPrepareAlloc { + fn lwe_to_glwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) + where + O: LWEToGLWESwitchingKeyToRef; +} + +impl LWEToGLWESwitchingKeyPrepareAlloc for Module +where + Module: LWEToGLWESwitchingKeyPrepare, +{ + fn lwe_to_glwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) + where + O: LWEToGLWESwitchingKeyToRef, + { + let mut ct_prep: LWEToGLWESwitchingKeyPrepared, B> = LWEToGLWESwitchingKeyPrepared::alloc(self, &other.to_ref()); + self.lwe_to_glwe_switching_key_prepare(&mut ct_prep, other, scratch); + ct_prep + } +} + +pub trait LWEToGLWESwitchingKeyPreparedToRef { + fn to_ref(&self) -> LWEToGLWESwitchingKeyPrepared<&[u8], B>; +} + +impl LWEToGLWESwitchingKeyPreparedToRef for LWEToGLWESwitchingKeyPrepared +where + GLWESwitchingKeyPrepared: GLWESwitchingKeyPreparedToRef, +{ + fn to_ref(&self) -> LWEToGLWESwitchingKeyPrepared<&[u8], B> { + LWEToGLWESwitchingKeyPrepared(self.0.to_ref()) + } +} + +pub trait LWEToGLWESwitchingKeyPreparedToMut { + fn to_mut(&mut self) -> LWEToGLWESwitchingKeyPrepared<&mut [u8], B>; +} + +impl LWEToGLWESwitchingKeyPreparedToMut for LWEToGLWESwitchingKeyPrepared +where + GLWESwitchingKeyPrepared: GLWESwitchingKeyPreparedToMut, +{ + fn to_mut(&mut self) -> LWEToGLWESwitchingKeyPrepared<&mut [u8], B> { + LWEToGLWESwitchingKeyPrepared(self.0.to_mut()) } } diff --git a/poulpy-core/src/tests/test_suite/automorphism/gglwe_atk.rs b/poulpy-core/src/tests/test_suite/automorphism/gglwe_atk.rs index 34fccab..b388e1c 100644 --- a/poulpy-core/src/tests/test_suite/automorphism/gglwe_atk.rs +++ b/poulpy-core/src/tests/test_suite/automorphism/gglwe_atk.rs @@ -154,7 +154,7 @@ where ); let mut auto_key_apply_prepared: AutomorphismKeyPrepared, B> = - AutomorphismKeyPrepared::alloc(module, &auto_key_apply_infos); + AutomorphismKeyPrepared::alloc_from_infos(module, &auto_key_apply_infos); auto_key_apply_prepared.prepare(module, &auto_key_apply, scratch.borrow()); @@ -348,7 +348,7 @@ where ); let mut auto_key_apply_prepared: AutomorphismKeyPrepared, B> = - AutomorphismKeyPrepared::alloc(module, &auto_key_apply_layout); + AutomorphismKeyPrepared::alloc_from_infos(module, &auto_key_apply_layout); auto_key_apply_prepared.prepare(module, &auto_key_apply, scratch.borrow()); diff --git a/poulpy-core/src/tests/test_suite/automorphism/ggsw_ct.rs b/poulpy-core/src/tests/test_suite/automorphism/ggsw_ct.rs index 8d34288..5b066a1 100644 --- a/poulpy-core/src/tests/test_suite/automorphism/ggsw_ct.rs +++ b/poulpy-core/src/tests/test_suite/automorphism/ggsw_ct.rs @@ -179,7 +179,7 @@ where ); let mut auto_key_prepared: AutomorphismKeyPrepared, B> = - AutomorphismKeyPrepared::alloc(module, &auto_key_layout); + AutomorphismKeyPrepared::alloc_from_infos(module, &auto_key_layout); auto_key_prepared.prepare(module, &auto_key, scratch.borrow()); let mut tsk_prepared: TensorKeyPrepared, B> = TensorKeyPrepared::alloc(module, &tensor_key_layout); @@ -359,7 +359,7 @@ where ); let mut auto_key_prepared: AutomorphismKeyPrepared, B> = - AutomorphismKeyPrepared::alloc(module, &auto_key_layout); + AutomorphismKeyPrepared::alloc_from_infos(module, &auto_key_layout); auto_key_prepared.prepare(module, &auto_key, scratch.borrow()); let mut tsk_prepared: TensorKeyPrepared, B> = TensorKeyPrepared::alloc(module, &tensor_key_layout); diff --git a/poulpy-core/src/tests/test_suite/automorphism/glwe_ct.rs b/poulpy-core/src/tests/test_suite/automorphism/glwe_ct.rs index a15b2c1..5affb70 100644 --- a/poulpy-core/src/tests/test_suite/automorphism/glwe_ct.rs +++ b/poulpy-core/src/tests/test_suite/automorphism/glwe_ct.rs @@ -141,7 +141,7 @@ where ); let mut autokey_prepared: AutomorphismKeyPrepared, B> = - AutomorphismKeyPrepared::alloc(module, &autokey_infos); + AutomorphismKeyPrepared::alloc_from_infos(module, &autokey_infos); autokey_prepared.prepare(module, &autokey, scratch.borrow()); ct_out.automorphism(module, &ct_in, &autokey_prepared, scratch.borrow()); @@ -274,7 +274,8 @@ where scratch.borrow(), ); - let mut autokey_prepared: AutomorphismKeyPrepared, B> = AutomorphismKeyPrepared::alloc(module, &autokey); + let mut autokey_prepared: AutomorphismKeyPrepared, B> = + AutomorphismKeyPrepared::alloc_from_infos(module, &autokey); autokey_prepared.prepare(module, &autokey, scratch.borrow()); ct.automorphism_inplace(module, &autokey_prepared, scratch.borrow());