mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 05:06:44 +01:00
Added glwe rank switch before glwe -> lwe
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
use poulpy_core::{
|
use poulpy_core::{
|
||||||
GLWEAdd, GLWECopy, GLWEDecrypt, GLWEEncryptSk, GLWENoise, GLWEPacking, GLWERotate, GLWESub, GLWETrace, LWEFromGLWE,
|
GLWEAdd, GLWECopy, GLWEDecrypt, GLWEEncryptSk, GLWEKeyswitch, GLWENoise, GLWEPacking, GLWERotate, GLWESub, GLWETrace,
|
||||||
ScratchTakeCore,
|
LWEFromGLWE, ScratchTakeCore,
|
||||||
layouts::{
|
layouts::{
|
||||||
Base2K, Degree, GGLWEInfos, GGLWEPreparedToRef, GLWE, GLWEAutomorphismKeyHelper, GLWEInfos, GLWEPlaintextLayout,
|
Base2K, Degree, GGLWEInfos, GGLWEPreparedToRef, GLWE, GLWEAutomorphismKeyHelper, GLWEInfos, GLWELayout,
|
||||||
GLWESecretPreparedToRef, GLWEToMut, GLWEToRef, GetGaloisElement, LWEInfos, LWEToMut, Rank, TorusPrecision,
|
GLWEPlaintextLayout, GLWESecretPreparedToRef, GLWEToMut, GLWEToRef, GetGaloisElement, LWEInfos, LWEToMut, Rank,
|
||||||
|
TorusPrecision,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
@@ -323,16 +324,41 @@ where
|
|||||||
impl<T: UnsignedInteger, BE: Backend> ScratchTakeBDD<T, BE> for Scratch<BE> where Self: ScratchTakeCore<BE> {}
|
impl<T: UnsignedInteger, BE: Backend> ScratchTakeBDD<T, BE> for Scratch<BE> where Self: ScratchTakeCore<BE> {}
|
||||||
|
|
||||||
impl<D: DataRef, T: UnsignedInteger> FheUint<D, T> {
|
impl<D: DataRef, T: UnsignedInteger> FheUint<D, T> {
|
||||||
pub fn get_bit_lwe<R, K, M, BE: Backend>(&self, module: &M, bit: usize, res: &mut R, ks: &K, scratch: &mut Scratch<BE>)
|
pub fn get_bit_lwe<R, KGLWE, KLWE, M, BE: Backend>(
|
||||||
where
|
&self,
|
||||||
|
module: &M,
|
||||||
|
bit: usize,
|
||||||
|
res: &mut R,
|
||||||
|
ks_glwe: Option<&KGLWE>,
|
||||||
|
ks_lwe: &KLWE,
|
||||||
|
scratch: &mut Scratch<BE>,
|
||||||
|
) where
|
||||||
R: LWEToMut,
|
R: LWEToMut,
|
||||||
K: GGLWEPreparedToRef<BE> + GGLWEInfos,
|
KGLWE: GGLWEPreparedToRef<BE> + GGLWEInfos,
|
||||||
M: ModuleLogN + LWEFromGLWE<BE> + GLWERotate<BE>,
|
KLWE: GGLWEPreparedToRef<BE> + GGLWEInfos,
|
||||||
|
M: ModuleLogN + LWEFromGLWE<BE> + GLWERotate<BE> + GLWEKeyswitch<BE>,
|
||||||
Scratch<BE>: ScratchTakeCore<BE>,
|
Scratch<BE>: ScratchTakeCore<BE>,
|
||||||
{
|
{
|
||||||
let log_gap: usize = module.log_n() - T::LOG_BITS as usize;
|
let log_gap: usize = module.log_n() - T::LOG_BITS as usize;
|
||||||
|
if let Some(ks_glwe) = ks_glwe {
|
||||||
|
let (mut res_tmp, scratch_1) = scratch.take_glwe(&GLWELayout {
|
||||||
|
n: self.n(),
|
||||||
|
base2k: ks_lwe.base2k(),
|
||||||
|
k: ks_lwe.k().min(self.k()),
|
||||||
|
rank: ks_lwe.rank_out(),
|
||||||
|
});
|
||||||
|
module.glwe_keyswitch(&mut res_tmp, self, ks_glwe, scratch_1);
|
||||||
|
res.to_mut().from_glwe(
|
||||||
|
module,
|
||||||
|
&res_tmp,
|
||||||
|
T::bit_index(bit) << log_gap,
|
||||||
|
ks_lwe,
|
||||||
|
scratch_1,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
res.to_mut()
|
res.to_mut()
|
||||||
.from_glwe(module, self, T::bit_index(bit) << log_gap, ks, scratch);
|
.from_glwe(module, self, T::bit_index(bit) << log_gap, ks_lwe, scratch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bit_glwe<R, K, M, H, BE: Backend>(&self, module: &M, bit: usize, res: &mut R, keys: &H, scratch: &mut Scratch<BE>)
|
pub fn get_bit_glwe<R, K, M, H, BE: Backend>(&self, module: &M, bit: usize, res: &mut R, keys: &H, scratch: &mut Scratch<BE>)
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ where
|
|||||||
K: BDDKeyHelper<DK, BRA, BE> + BDDKeyInfos,
|
K: BDDKeyHelper<DK, BRA, BE> + BDDKeyInfos,
|
||||||
{
|
{
|
||||||
let bit_end = bit_start + bit_count;
|
let bit_end = bit_start + bit_count;
|
||||||
let (cbt, ks) = key.get_cbt_key();
|
let (cbt, ks_glwe, ks_lwe) = key.get_cbt_key();
|
||||||
|
|
||||||
assert!(bit_end <= T::BITS as usize);
|
assert!(bit_end <= T::BITS as usize);
|
||||||
|
|
||||||
@@ -363,7 +363,14 @@ where
|
|||||||
let (mut tmp_ggsw, scratch_1) = scratch_thread.take_ggsw(ggsw_infos);
|
let (mut tmp_ggsw, scratch_1) = scratch_thread.take_ggsw(ggsw_infos);
|
||||||
let (mut tmp_lwe, scratch_2) = scratch_1.take_lwe(bits);
|
let (mut tmp_lwe, scratch_2) = scratch_1.take_lwe(bits);
|
||||||
for (local_bit, dst) in res_bits_chunk.iter_mut().enumerate() {
|
for (local_bit, dst) in res_bits_chunk.iter_mut().enumerate() {
|
||||||
bits.get_bit_lwe(self, start + local_bit, &mut tmp_lwe, ks, scratch_2);
|
bits.get_bit_lwe(
|
||||||
|
self,
|
||||||
|
start + local_bit,
|
||||||
|
&mut tmp_lwe,
|
||||||
|
ks_glwe,
|
||||||
|
ks_lwe,
|
||||||
|
scratch_2,
|
||||||
|
);
|
||||||
cbt.execute_to_constant(self, &mut tmp_ggsw, &tmp_lwe, 1, 1, scratch_2);
|
cbt.execute_to_constant(self, &mut tmp_ggsw, &tmp_lwe, 1, 1, scratch_2);
|
||||||
dst.prepare(self, &tmp_ggsw, scratch_2);
|
dst.prepare(self, &tmp_ggsw, scratch_2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,14 @@ where
|
|||||||
let (_, scratch_1) = scratch.take_ggsw(res);
|
let (_, scratch_1) = scratch.take_ggsw(res);
|
||||||
let (mut tmp_lwe, scratch_2) = scratch_1.take_lwe(bits);
|
let (mut tmp_lwe, scratch_2) = scratch_1.take_lwe(bits);
|
||||||
for (bit, dst) in res.bits.iter_mut().enumerate() {
|
for (bit, dst) in res.bits.iter_mut().enumerate() {
|
||||||
bits.get_bit_lwe(self, bit, &mut tmp_lwe, &key.ks, scratch_2);
|
bits.get_bit_lwe(
|
||||||
|
self,
|
||||||
|
bit,
|
||||||
|
&mut tmp_lwe,
|
||||||
|
key.ks_glwe.as_ref(),
|
||||||
|
&key.ks_lwe,
|
||||||
|
scratch_2,
|
||||||
|
);
|
||||||
key.cbt
|
key.cbt
|
||||||
.execute_to_constant(self, dst, &tmp_lwe, 1, 1, scratch_2);
|
.execute_to_constant(self, dst, &tmp_lwe, 1, 1, scratch_2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ use crate::tfhe::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use poulpy_core::layouts::{GGLWEInfos, GLWEAutomorphismKeyHelper, GLWEAutomorphismKeyPrepared};
|
use poulpy_core::GLWESwitchingKeyEncryptSk;
|
||||||
|
use poulpy_core::layouts::{
|
||||||
|
GGLWEInfos, GLWEAutomorphismKeyHelper, GLWEAutomorphismKeyPrepared, GLWESecret, GLWESwitchingKey, GLWESwitchingKeyLayout,
|
||||||
|
GLWESwitchingKeyPrepared,
|
||||||
|
};
|
||||||
use poulpy_core::{
|
use poulpy_core::{
|
||||||
GLWEToLWESwitchingKeyEncryptSk, GetDistribution, ScratchTakeCore,
|
GLWEToLWESwitchingKeyEncryptSk, GetDistribution, ScratchTakeCore,
|
||||||
layouts::{
|
layouts::{
|
||||||
@@ -24,13 +28,15 @@ use poulpy_hal::{
|
|||||||
|
|
||||||
pub trait BDDKeyInfos {
|
pub trait BDDKeyInfos {
|
||||||
fn cbt_infos(&self) -> CircuitBootstrappingKeyLayout;
|
fn cbt_infos(&self) -> CircuitBootstrappingKeyLayout;
|
||||||
fn ks_infos(&self) -> GLWEToLWEKeyLayout;
|
fn ks_lwe_infos(&self) -> GLWEToLWEKeyLayout;
|
||||||
|
fn ks_glwe_infos(&self) -> Option<GLWESwitchingKeyLayout>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct BDDKeyLayout {
|
pub struct BDDKeyLayout {
|
||||||
pub cbt: CircuitBootstrappingKeyLayout,
|
pub cbt: CircuitBootstrappingKeyLayout,
|
||||||
pub ks: GLWEToLWEKeyLayout,
|
pub ks_glwe: Option<GLWESwitchingKeyLayout>,
|
||||||
|
pub ks_lwe: GLWEToLWEKeyLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BDDKeyInfos for BDDKeyLayout {
|
impl BDDKeyInfos for BDDKeyLayout {
|
||||||
@@ -38,8 +44,12 @@ impl BDDKeyInfos for BDDKeyLayout {
|
|||||||
self.cbt
|
self.cbt
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ks_infos(&self) -> GLWEToLWEKeyLayout {
|
fn ks_glwe_infos(&self) -> Option<GLWESwitchingKeyLayout> {
|
||||||
self.ks
|
self.ks_glwe
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ks_lwe_infos(&self) -> GLWEToLWEKeyLayout {
|
||||||
|
self.ks_lwe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +59,8 @@ where
|
|||||||
BRA: BlindRotationAlgo,
|
BRA: BlindRotationAlgo,
|
||||||
{
|
{
|
||||||
pub(crate) cbt: CircuitBootstrappingKey<D, BRA>,
|
pub(crate) cbt: CircuitBootstrappingKey<D, BRA>,
|
||||||
pub(crate) ks: GLWEToLWEKey<D>,
|
pub(crate) ks_glwe: Option<GLWESwitchingKey<D>>,
|
||||||
|
pub(crate) ks_lwe: GLWEToLWEKey<D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<BRA: BlindRotationAlgo> BDDKey<Vec<u8>, BRA>
|
impl<BRA: BlindRotationAlgo> BDDKey<Vec<u8>, BRA>
|
||||||
@@ -60,9 +71,16 @@ where
|
|||||||
where
|
where
|
||||||
A: BDDKeyInfos,
|
A: BDDKeyInfos,
|
||||||
{
|
{
|
||||||
|
let ks_glwe: Option<GLWESwitchingKey<Vec<u8>>> = if let Some(ks_infos) = &infos.ks_glwe_infos() {
|
||||||
|
Some(GLWESwitchingKey::alloc_from_infos(ks_infos))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
cbt: CircuitBootstrappingKey::alloc_from_infos(&infos.cbt_infos()),
|
cbt: CircuitBootstrappingKey::alloc_from_infos(&infos.cbt_infos()),
|
||||||
ks: GLWEToLWEKey::alloc_from_infos(&infos.ks_infos()),
|
ks_glwe: ks_glwe,
|
||||||
|
ks_lwe: GLWEToLWEKey::alloc_from_infos(&infos.ks_lwe_infos()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,7 +106,7 @@ pub trait BDDKeyEncryptSk<BRA: BlindRotationAlgo, BE: Backend> {
|
|||||||
|
|
||||||
impl<BE: Backend, BRA: BlindRotationAlgo> BDDKeyEncryptSk<BRA, BE> for Module<BE>
|
impl<BE: Backend, BRA: BlindRotationAlgo> BDDKeyEncryptSk<BRA, BE> for Module<BE>
|
||||||
where
|
where
|
||||||
Self: CircuitBootstrappingKeyEncryptSk<BRA, BE> + GLWEToLWESwitchingKeyEncryptSk<BE>,
|
Self: CircuitBootstrappingKeyEncryptSk<BRA, BE> + GLWEToLWESwitchingKeyEncryptSk<BE> + GLWESwitchingKeyEncryptSk<BE>,
|
||||||
Scratch<BE>: ScratchTakeCore<BE>,
|
Scratch<BE>: ScratchTakeCore<BE>,
|
||||||
{
|
{
|
||||||
fn bdd_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
fn bdd_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||||
@@ -96,7 +114,7 @@ where
|
|||||||
A: BDDKeyInfos,
|
A: BDDKeyInfos,
|
||||||
{
|
{
|
||||||
self.circuit_bootstrapping_key_encrypt_sk_tmp_bytes(&infos.cbt_infos())
|
self.circuit_bootstrapping_key_encrypt_sk_tmp_bytes(&infos.cbt_infos())
|
||||||
.max(self.glwe_to_lwe_key_encrypt_sk_tmp_bytes(&infos.ks_infos()))
|
.max(self.glwe_to_lwe_key_encrypt_sk_tmp_bytes(&infos.ks_lwe_infos()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bdd_key_encrypt_sk<D, S0, S1>(
|
fn bdd_key_encrypt_sk<D, S0, S1>(
|
||||||
@@ -112,8 +130,17 @@ where
|
|||||||
S0: LWESecretToRef + GetDistribution + LWEInfos,
|
S0: LWESecretToRef + GetDistribution + LWEInfos,
|
||||||
S1: GLWESecretToRef + GetDistribution + GLWEInfos,
|
S1: GLWESecretToRef + GetDistribution + GLWEInfos,
|
||||||
{
|
{
|
||||||
res.ks
|
if let Some(key) = &mut res.ks_glwe {
|
||||||
|
let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(sk_glwe.n(), key.rank_out());
|
||||||
|
sk_out.fill_ternary_prob(0.5, source_xe);
|
||||||
|
key.encrypt_sk(self, sk_glwe, &sk_out, source_xa, source_xe, scratch);
|
||||||
|
res.ks_lwe
|
||||||
|
.encrypt_sk(self, sk_lwe, &sk_out, source_xa, source_xe, scratch);
|
||||||
|
} else {
|
||||||
|
res.ks_lwe
|
||||||
.encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
|
.encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
|
||||||
|
}
|
||||||
|
|
||||||
res.cbt
|
res.cbt
|
||||||
.encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
|
.encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
|
||||||
}
|
}
|
||||||
@@ -145,7 +172,8 @@ where
|
|||||||
BE: Backend,
|
BE: Backend,
|
||||||
{
|
{
|
||||||
pub(crate) cbt: CircuitBootstrappingKeyPrepared<D, BRA, BE>,
|
pub(crate) cbt: CircuitBootstrappingKeyPrepared<D, BRA, BE>,
|
||||||
pub(crate) ks: GLWEToLWEKeyPrepared<D, BE>,
|
pub(crate) ks_glwe: Option<GLWESwitchingKeyPrepared<D, BE>>,
|
||||||
|
pub(crate) ks_lwe: GLWEToLWEKeyPrepared<D, BE>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef, BRA: BlindRotationAlgo, BE: Backend> BDDKeyInfos for BDDKeyPrepared<D, BRA, BE> {
|
impl<D: DataRef, BRA: BlindRotationAlgo, BE: Backend> BDDKeyInfos for BDDKeyPrepared<D, BRA, BE> {
|
||||||
@@ -156,13 +184,28 @@ impl<D: DataRef, BRA: BlindRotationAlgo, BE: Backend> BDDKeyInfos for BDDKeyPrep
|
|||||||
layout_tsk: self.cbt.tsk_infos(),
|
layout_tsk: self.cbt.tsk_infos(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn ks_infos(&self) -> GLWEToLWEKeyLayout {
|
fn ks_glwe_infos(&self) -> Option<GLWESwitchingKeyLayout> {
|
||||||
|
if let Some(ks_glwe) = &self.ks_glwe {
|
||||||
|
Some(GLWESwitchingKeyLayout {
|
||||||
|
n: ks_glwe.n(),
|
||||||
|
base2k: ks_glwe.base2k(),
|
||||||
|
k: ks_glwe.k(),
|
||||||
|
rank_in: ks_glwe.rank_in(),
|
||||||
|
rank_out: ks_glwe.rank_out(),
|
||||||
|
dnum: ks_glwe.dnum(),
|
||||||
|
dsize: ks_glwe.dsize(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn ks_lwe_infos(&self) -> GLWEToLWEKeyLayout {
|
||||||
GLWEToLWEKeyLayout {
|
GLWEToLWEKeyLayout {
|
||||||
n: self.ks.n(),
|
n: self.ks_lwe.n(),
|
||||||
base2k: self.ks.base2k(),
|
base2k: self.ks_lwe.base2k(),
|
||||||
k: self.ks.k(),
|
k: self.ks_lwe.k(),
|
||||||
rank_in: self.ks.rank_in(),
|
rank_in: self.ks_lwe.rank_in(),
|
||||||
dnum: self.ks.dnum(),
|
dnum: self.ks_lwe.dnum(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,9 +230,19 @@ where
|
|||||||
where
|
where
|
||||||
A: BDDKeyInfos,
|
A: BDDKeyInfos,
|
||||||
{
|
{
|
||||||
|
let ks_glwe = if let Some(ks_glwe_infos) = &infos.ks_glwe_infos() {
|
||||||
|
Some(GLWESwitchingKeyPrepared::alloc_from_infos(
|
||||||
|
self,
|
||||||
|
ks_glwe_infos,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
BDDKeyPrepared {
|
BDDKeyPrepared {
|
||||||
cbt: CircuitBootstrappingKeyPrepared::alloc_from_infos(self, &infos.cbt_infos()),
|
cbt: CircuitBootstrappingKeyPrepared::alloc_from_infos(self, &infos.cbt_infos()),
|
||||||
ks: GLWEToLWEKeyPrepared::alloc_from_infos(self, &infos.ks_infos()),
|
ks_glwe,
|
||||||
|
ks_lwe: GLWEToLWEKeyPrepared::alloc_from_infos(self, &infos.ks_lwe_infos()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +251,7 @@ where
|
|||||||
A: BDDKeyInfos,
|
A: BDDKeyInfos,
|
||||||
{
|
{
|
||||||
self.circuit_bootstrapping_key_prepare_tmp_bytes(&infos.cbt_infos())
|
self.circuit_bootstrapping_key_prepare_tmp_bytes(&infos.cbt_infos())
|
||||||
.max(self.prepare_glwe_to_lwe_key_tmp_bytes(&infos.ks_infos()))
|
.max(self.prepare_glwe_to_lwe_key_tmp_bytes(&infos.ks_lwe_infos()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_bdd_key<DM, DR>(&self, res: &mut BDDKeyPrepared<DM, BRA, BE>, other: &BDDKey<DR, BRA>, scratch: &mut Scratch<BE>)
|
fn prepare_bdd_key<DM, DR>(&self, res: &mut BDDKeyPrepared<DM, BRA, BE>, other: &BDDKey<DR, BRA>, scratch: &mut Scratch<BE>)
|
||||||
@@ -208,7 +261,16 @@ where
|
|||||||
Scratch<BE>: ScratchTakeCore<BE>,
|
Scratch<BE>: ScratchTakeCore<BE>,
|
||||||
{
|
{
|
||||||
res.cbt.prepare(self, &other.cbt, scratch);
|
res.cbt.prepare(self, &other.cbt, scratch);
|
||||||
res.ks.prepare(self, &other.ks, scratch);
|
|
||||||
|
if let Some(key_prep) = &mut res.ks_glwe {
|
||||||
|
if let Some(other) = &other.ks_glwe {
|
||||||
|
key_prep.prepare(self, other, scratch);
|
||||||
|
} else {
|
||||||
|
panic!("incompatible keys: res has Some(ks_glwe) but other has none")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.ks_lwe.prepare(self, &other.ks_lwe, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<BRA: BlindRotationAlgo, BE: Backend> BDDKeyPreparedFactory<BRA, BE> for Module<BE> where
|
impl<BRA: BlindRotationAlgo, BE: Backend> BDDKeyPreparedFactory<BRA, BE> for Module<BE> where
|
||||||
@@ -231,9 +293,10 @@ impl<D: DataRef, BRA: BlindRotationAlgo, BE: Backend> BDDKeyHelper<D, BRA, BE> f
|
|||||||
&self,
|
&self,
|
||||||
) -> (
|
) -> (
|
||||||
&CircuitBootstrappingKeyPrepared<D, BRA, BE>,
|
&CircuitBootstrappingKeyPrepared<D, BRA, BE>,
|
||||||
|
Option<&GLWESwitchingKeyPrepared<D, BE>>,
|
||||||
&GLWEToLWEKeyPrepared<D, BE>,
|
&GLWEToLWEKeyPrepared<D, BE>,
|
||||||
) {
|
) {
|
||||||
(&self.cbt, &self.ks)
|
(&self.cbt, self.ks_glwe.as_ref(), &self.ks_lwe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,6 +305,7 @@ pub trait BDDKeyHelper<D: DataRef, BRA: BlindRotationAlgo, BE: Backend> {
|
|||||||
&self,
|
&self,
|
||||||
) -> (
|
) -> (
|
||||||
&CircuitBootstrappingKeyPrepared<D, BRA, BE>,
|
&CircuitBootstrappingKeyPrepared<D, BRA, BE>,
|
||||||
|
Option<&GLWESwitchingKeyPrepared<D, BE>>,
|
||||||
&GLWEToLWEKeyPrepared<D, BE>,
|
&GLWEToLWEKeyPrepared<D, BE>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use rand::RngCore;
|
|||||||
use crate::tfhe::{
|
use crate::tfhe::{
|
||||||
bdd_arithmetic::{
|
bdd_arithmetic::{
|
||||||
FheUintPrepared, GGSWBlindRotation,
|
FheUintPrepared, GGSWBlindRotation,
|
||||||
tests::test_suite::{TEST_BASE2K, TEST_RANK, TestContext},
|
tests::test_suite::{TEST_FHEUINT_BASE2K, TEST_RANK, TestContext},
|
||||||
},
|
},
|
||||||
blind_rotation::BlindRotationAlgo,
|
blind_rotation::BlindRotationAlgo,
|
||||||
};
|
};
|
||||||
@@ -37,7 +37,7 @@ where
|
|||||||
let module: &Module<BE> = &test_context.module;
|
let module: &Module<BE> = &test_context.module;
|
||||||
let sk_glwe_prep: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
|
let sk_glwe_prep: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
|
||||||
|
|
||||||
let base2k: Base2K = TEST_BASE2K.into();
|
let base2k: Base2K = TEST_FHEUINT_BASE2K.into();
|
||||||
let rank: Rank = TEST_RANK.into();
|
let rank: Rank = TEST_RANK.into();
|
||||||
let k_ggsw_res: TorusPrecision = TorusPrecision(39);
|
let k_ggsw_res: TorusPrecision = TorusPrecision(39);
|
||||||
let k_ggsw_apply: TorusPrecision = TorusPrecision(52);
|
let k_ggsw_apply: TorusPrecision = TorusPrecision(52);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use rand::RngCore;
|
|||||||
use crate::tfhe::{
|
use crate::tfhe::{
|
||||||
bdd_arithmetic::{
|
bdd_arithmetic::{
|
||||||
FheUintPrepared, GLWEBlindRotation,
|
FheUintPrepared, GLWEBlindRotation,
|
||||||
tests::test_suite::{TEST_BASE2K, TEST_RANK, TestContext},
|
tests::test_suite::{TEST_FHEUINT_BASE2K, TEST_RANK, TestContext},
|
||||||
},
|
},
|
||||||
blind_rotation::BlindRotationAlgo,
|
blind_rotation::BlindRotationAlgo,
|
||||||
};
|
};
|
||||||
@@ -35,7 +35,7 @@ where
|
|||||||
let module: &Module<BE> = &test_context.module;
|
let module: &Module<BE> = &test_context.module;
|
||||||
let sk_glwe_prep: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
|
let sk_glwe_prep: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
|
||||||
|
|
||||||
let base2k: Base2K = TEST_BASE2K.into();
|
let base2k: Base2K = TEST_FHEUINT_BASE2K.into();
|
||||||
let rank: Rank = TEST_RANK.into();
|
let rank: Rank = TEST_RANK.into();
|
||||||
let k_glwe: TorusPrecision = TorusPrecision(26);
|
let k_glwe: TorusPrecision = TorusPrecision(26);
|
||||||
let k_ggsw: TorusPrecision = TorusPrecision(39);
|
let k_ggsw: TorusPrecision = TorusPrecision(39);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use rand::RngCore;
|
|||||||
use crate::tfhe::{
|
use crate::tfhe::{
|
||||||
bdd_arithmetic::{
|
bdd_arithmetic::{
|
||||||
FheUintPrepared, GLWEBlinSelection,
|
FheUintPrepared, GLWEBlinSelection,
|
||||||
tests::test_suite::{TEST_BASE2K, TEST_RANK, TestContext},
|
tests::test_suite::{TEST_FHEUINT_BASE2K, TEST_RANK, TestContext},
|
||||||
},
|
},
|
||||||
blind_rotation::BlindRotationAlgo,
|
blind_rotation::BlindRotationAlgo,
|
||||||
};
|
};
|
||||||
@@ -37,7 +37,7 @@ where
|
|||||||
let module: &Module<BE> = &test_context.module;
|
let module: &Module<BE> = &test_context.module;
|
||||||
let sk_glwe_prep: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
|
let sk_glwe_prep: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
|
||||||
|
|
||||||
let base2k: Base2K = TEST_BASE2K.into();
|
let base2k: Base2K = TEST_FHEUINT_BASE2K.into();
|
||||||
let rank: Rank = TEST_RANK.into();
|
let rank: Rank = TEST_RANK.into();
|
||||||
let k_glwe: TorusPrecision = TorusPrecision(26);
|
let k_glwe: TorusPrecision = TorusPrecision(26);
|
||||||
let k_ggsw: TorusPrecision = TorusPrecision(39);
|
let k_ggsw: TorusPrecision = TorusPrecision(39);
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ use poulpy_core::{
|
|||||||
ScratchTakeCore,
|
ScratchTakeCore,
|
||||||
layouts::{
|
layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEToGGSWKeyLayout, GGSWLayout, GLWEAutomorphismKeyLayout, GLWELayout, GLWESecret,
|
Base2K, Degree, Dnum, Dsize, GGLWEToGGSWKeyLayout, GGSWLayout, GLWEAutomorphismKeyLayout, GLWELayout, GLWESecret,
|
||||||
GLWESecretPrepared, GLWESecretPreparedFactory, GLWEToLWEKeyLayout, LWESecret, Rank, TorusPrecision,
|
GLWESecretPrepared, GLWESecretPreparedFactory, GLWESwitchingKeyLayout, GLWEToLWEKeyLayout, LWESecret, Rank,
|
||||||
|
TorusPrecision,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,7 +138,11 @@ impl<BRA: BlindRotationAlgo, BE: Backend> TestContext<BRA, BE> {
|
|||||||
|
|
||||||
pub(crate) const TEST_N_GLWE: u32 = 256;
|
pub(crate) const TEST_N_GLWE: u32 = 256;
|
||||||
pub(crate) const TEST_N_LWE: u32 = 77;
|
pub(crate) const TEST_N_LWE: u32 = 77;
|
||||||
pub(crate) const TEST_BASE2K: u32 = 13;
|
pub(crate) const TEST_FHEUINT_BASE2K: u32 = 13;
|
||||||
|
pub(crate) const TEST_BRK_BASE2K: u32 = 12;
|
||||||
|
pub(crate) const TEST_ATK_BASE2K: u32 = 11;
|
||||||
|
pub(crate) const TEST_TSK_BASE2K: u32 = 10;
|
||||||
|
pub(crate) const TEST_LWE_BASE2K: u32 = 4;
|
||||||
pub(crate) const TEST_K_GLWE: u32 = 26;
|
pub(crate) const TEST_K_GLWE: u32 = 26;
|
||||||
pub(crate) const TEST_K_GGSW: u32 = 39;
|
pub(crate) const TEST_K_GGSW: u32 = 39;
|
||||||
pub(crate) const TEST_BLOCK_SIZE: u32 = 7;
|
pub(crate) const TEST_BLOCK_SIZE: u32 = 7;
|
||||||
@@ -145,14 +150,14 @@ pub(crate) const TEST_RANK: u32 = 2;
|
|||||||
|
|
||||||
pub(crate) static TEST_GLWE_INFOS: GLWELayout = GLWELayout {
|
pub(crate) static TEST_GLWE_INFOS: GLWELayout = GLWELayout {
|
||||||
n: Degree(TEST_N_GLWE),
|
n: Degree(TEST_N_GLWE),
|
||||||
base2k: Base2K(TEST_BASE2K),
|
base2k: Base2K(TEST_FHEUINT_BASE2K),
|
||||||
k: TorusPrecision(TEST_K_GLWE),
|
k: TorusPrecision(TEST_K_GLWE),
|
||||||
rank: Rank(TEST_RANK),
|
rank: Rank(TEST_RANK),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) static TEST_GGSW_INFOS: GGSWLayout = GGSWLayout {
|
pub(crate) static TEST_GGSW_INFOS: GGSWLayout = GGSWLayout {
|
||||||
n: Degree(TEST_N_GLWE),
|
n: Degree(TEST_N_GLWE),
|
||||||
base2k: Base2K(TEST_BASE2K),
|
base2k: Base2K(TEST_FHEUINT_BASE2K),
|
||||||
k: TorusPrecision(TEST_K_GGSW),
|
k: TorusPrecision(TEST_K_GGSW),
|
||||||
rank: Rank(TEST_RANK),
|
rank: Rank(TEST_RANK),
|
||||||
dnum: Dnum(2),
|
dnum: Dnum(2),
|
||||||
@@ -164,33 +169,42 @@ pub(crate) static TEST_BDD_KEY_LAYOUT: BDDKeyLayout = BDDKeyLayout {
|
|||||||
layout_brk: BlindRotationKeyLayout {
|
layout_brk: BlindRotationKeyLayout {
|
||||||
n_glwe: Degree(TEST_N_GLWE),
|
n_glwe: Degree(TEST_N_GLWE),
|
||||||
n_lwe: Degree(TEST_N_LWE),
|
n_lwe: Degree(TEST_N_LWE),
|
||||||
base2k: Base2K(TEST_BASE2K),
|
base2k: Base2K(TEST_BRK_BASE2K),
|
||||||
k: TorusPrecision(52),
|
k: TorusPrecision(52),
|
||||||
dnum: Dnum(3),
|
dnum: Dnum(4),
|
||||||
rank: Rank(TEST_RANK),
|
rank: Rank(TEST_RANK),
|
||||||
},
|
},
|
||||||
layout_atk: GLWEAutomorphismKeyLayout {
|
layout_atk: GLWEAutomorphismKeyLayout {
|
||||||
n: Degree(TEST_N_GLWE),
|
n: Degree(TEST_N_GLWE),
|
||||||
base2k: Base2K(TEST_BASE2K),
|
base2k: Base2K(TEST_ATK_BASE2K),
|
||||||
k: TorusPrecision(52),
|
k: TorusPrecision(52),
|
||||||
rank: Rank(TEST_RANK),
|
rank: Rank(TEST_RANK),
|
||||||
dnum: Dnum(3),
|
dnum: Dnum(4),
|
||||||
dsize: Dsize(1),
|
dsize: Dsize(1),
|
||||||
},
|
},
|
||||||
layout_tsk: GGLWEToGGSWKeyLayout {
|
layout_tsk: GGLWEToGGSWKeyLayout {
|
||||||
n: Degree(TEST_N_GLWE),
|
n: Degree(TEST_N_GLWE),
|
||||||
base2k: Base2K(TEST_BASE2K),
|
base2k: Base2K(TEST_TSK_BASE2K),
|
||||||
k: TorusPrecision(52),
|
k: TorusPrecision(52),
|
||||||
rank: Rank(TEST_RANK),
|
rank: Rank(TEST_RANK),
|
||||||
dnum: Dnum(3),
|
dnum: Dnum(4),
|
||||||
dsize: Dsize(1),
|
dsize: Dsize(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ks: GLWEToLWEKeyLayout {
|
ks_glwe: Some(GLWESwitchingKeyLayout {
|
||||||
n: Degree(TEST_N_GLWE),
|
n: Degree(TEST_N_GLWE),
|
||||||
base2k: Base2K(TEST_BASE2K),
|
base2k: Base2K(TEST_LWE_BASE2K),
|
||||||
k: TorusPrecision(39),
|
k: TorusPrecision(20),
|
||||||
rank_in: Rank(TEST_RANK),
|
rank_in: Rank(TEST_RANK),
|
||||||
dnum: Dnum(2),
|
rank_out: Rank(1),
|
||||||
|
dnum: Dnum(3),
|
||||||
|
dsize: Dsize(1),
|
||||||
|
}),
|
||||||
|
ks_lwe: GLWEToLWEKeyLayout {
|
||||||
|
n: Degree(TEST_N_GLWE),
|
||||||
|
base2k: Base2K(TEST_LWE_BASE2K),
|
||||||
|
k: TorusPrecision(16),
|
||||||
|
rank_in: Rank(1),
|
||||||
|
dnum: Dnum(3),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use crate::tfhe::{
|
|||||||
bdd_arithmetic::{
|
bdd_arithmetic::{
|
||||||
BDDKeyEncryptSk, BDDKeyPrepared, BDDKeyPreparedFactory, ExecuteBDDCircuit2WTo1W, FheUint, FheUintPrepare,
|
BDDKeyEncryptSk, BDDKeyPrepared, BDDKeyPreparedFactory, ExecuteBDDCircuit2WTo1W, FheUint, FheUintPrepare,
|
||||||
FheUintPrepareDebug, FheUintPreparedDebug, FheUintPreparedEncryptSk, FheUintPreparedFactory,
|
FheUintPrepareDebug, FheUintPreparedDebug, FheUintPreparedEncryptSk, FheUintPreparedFactory,
|
||||||
tests::test_suite::{TEST_BASE2K, TEST_GGSW_INFOS, TEST_GLWE_INFOS, TestContext},
|
tests::test_suite::{TEST_GGSW_INFOS, TEST_GLWE_INFOS, TestContext},
|
||||||
},
|
},
|
||||||
blind_rotation::{BlindRotationAlgo, BlindRotationKey, BlindRotationKeyFactory},
|
blind_rotation::{BlindRotationAlgo, BlindRotationKey, BlindRotationKeyFactory},
|
||||||
};
|
};
|
||||||
@@ -73,7 +73,7 @@ where
|
|||||||
c_enc_prep_debug.prepare(module, &c_enc, bdd_key_prepared, scratch_2.borrow());
|
c_enc_prep_debug.prepare(module, &c_enc, bdd_key_prepared, scratch_2.borrow());
|
||||||
|
|
||||||
let max_noise = |col_i: usize| {
|
let max_noise = |col_i: usize| {
|
||||||
let mut noise: f64 = -(ggsw_infos.size() as f64 * TEST_BASE2K as f64) + SIGMA.log2() + 2.0;
|
let mut noise: f64 = -(ggsw_infos.size() as f64 * ggsw_infos.base2k().as_usize() as f64) + SIGMA.log2() + 2.0;
|
||||||
noise += 0.5 * ggsw_infos.log_n() as f64;
|
noise += 0.5 * ggsw_infos.log_n() as f64;
|
||||||
if col_i != 0 {
|
if col_i != 0 {
|
||||||
noise += 0.5 * ggsw_infos.log_n() as f64
|
noise += 0.5 * ggsw_infos.log_n() as f64
|
||||||
@@ -87,7 +87,10 @@ where
|
|||||||
for (i, stat) in stats.iter().enumerate() {
|
for (i, stat) in stats.iter().enumerate() {
|
||||||
let noise_have: f64 = stat.std().log2();
|
let noise_have: f64 = stat.std().log2();
|
||||||
let noise_max: f64 = max_noise(col);
|
let noise_max: f64 = max_noise(col);
|
||||||
assert!(noise_have <= noise_max, "bit: {i} noise_have: {noise_have} > noise_max: {noise_max}")
|
assert!(
|
||||||
|
noise_have <= noise_max,
|
||||||
|
"bit: {i} noise_have: {noise_have} > noise_max: {noise_max}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user