compiling CBT but failing tests

This commit is contained in:
Pro7ech
2025-10-22 10:00:32 +02:00
parent 0926913001
commit 706ecf3d07
50 changed files with 967 additions and 1060 deletions

View File

@@ -2,107 +2,46 @@ use std::hint::black_box;
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use poulpy_backend::{FFT64Avx, FFT64Ref, FFT64Spqlios};
use poulpy_core::layouts::{
AutomorphismKeyLayout, Dsize, GGSW, GGSWLayout, GLWESecret, LWE, LWELayout, LWESecret, TensorKeyLayout,
prepared::PrepareAlloc,
use poulpy_core::{
GGSWNoise, GLWEDecrypt, GLWEEncryptSk, GLWEExternalProduct, LWEEncryptSk, ScratchTakeCore,
layouts::{
Dsize, GGSW, GGSWLayout, GGSWPreparedFactory, GLWEAutomorphismKeyLayout, GLWESecret, GLWESecretPreparedFactory,
GLWETensorKeyLayout, LWE, LWELayout, LWESecret,
},
};
use poulpy_hal::{
api::{
ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc,
SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism,
VecZnxAutomorphismInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigAlloc, VecZnxBigAutomorphismInplace,
VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxBigSubSmallNegateInplace, VecZnxCopy,
VecZnxDftAddInplace, VecZnxDftAlloc, VecZnxDftApply, VecZnxDftBytesOf, VecZnxDftCopy, VecZnxFillUniform,
VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNegateInplace, VecZnxNormalize, VecZnxNormalizeInplace,
VecZnxNormalizeTmpBytes, VecZnxRotate, VecZnxRotateInplace, VecZnxRotateInplaceTmpBytes, VecZnxRshInplace, VecZnxSub,
VecZnxSubInplace, VecZnxSwitchRing, VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPMatAlloc,
VmpPrepare, ZnAddNormal, ZnFillUniform, ZnNormalizeInplace,
},
layouts::{Backend, Module, ScratchOwned},
oep::{
ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeMatZnxImpl, TakeScalarZnxImpl, TakeSliceImpl,
TakeSvpPPolImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxDftSliceImpl, TakeVecZnxImpl, TakeVecZnxSliceImpl,
},
api::{ModuleN, ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxRotateInplace},
layouts::{Backend, Module, Scratch, ScratchOwned},
source::Source,
};
use poulpy_schemes::tfhe::{
blind_rotation::{
BlincRotationExecute, BlindRotationAlgo, BlindRotationKey, BlindRotationKeyAlloc, BlindRotationKeyEncryptSk,
BlindRotationKeyInfos, BlindRotationKeyLayout, BlindRotationKeyPrepared, CGGI,
BlindRotationAlgo, BlindRotationKey, BlindRotationKeyFactory, BlindRotationKeyInfos, BlindRotationKeyLayout, CGGI,
},
circuit_bootstrapping::{
CircuitBootstrappingKey, CircuitBootstrappingKeyEncryptSk, CircuitBootstrappingKeyLayout,
CircuitBootstrappingKeyPrepared, CirtuitBootstrappingExecute,
CircuitBootstrappingKeyPrepared, CircuitBootstrappingKeyPreparedFactory, CirtuitBootstrappingExecute,
},
};
pub fn benc_circuit_bootstrapping<B: Backend, BRA: BlindRotationAlgo>(c: &mut Criterion, label: &str)
pub fn benc_circuit_bootstrapping<BE: Backend, BRA: BlindRotationAlgo>(c: &mut Criterion, label: &str)
where
Module<B>: ModuleNew<B>
+ VecZnxFillUniform
+ VecZnxAddNormal
+ VecZnxNormalizeInplace<B>
+ VecZnxDftBytesOf
+ VecZnxBigNormalize<B>
+ VecZnxDftApply<B>
+ SvpApplyDftToDftInplace<B>
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalize<B>
+ VecZnxSub
+ VecZnxAddScalarInplace
+ VecZnxAutomorphism
+ VecZnxSwitchRing
+ VecZnxBigBytesOf
+ VecZnxIdftApplyTmpA<B>
+ SvpApplyDftToDft<B>
+ VecZnxBigAddInplace<B>
+ VecZnxBigAddSmallInplace<B>
+ VecZnxBigAlloc<B>
+ VecZnxDftAlloc<B>
+ VecZnxBigNormalizeTmpBytes
+ VmpPMatAlloc<B>
+ VmpPrepare<B>
+ SvpPrepare<B>
+ SvpPPolAlloc<B>
+ VmpApplyDftToDftTmpBytes
+ VmpApplyDftToDft<B>
+ VmpApplyDftToDftAdd<B>
+ SvpPPolBytesOf
+ VecZnxRotateInplace<B>
+ VecZnxBigAutomorphismInplace<B>
+ VecZnxRshInplace<B>
+ VecZnxDftCopy<B>
+ VecZnxNegateInplace
+ VecZnxCopy
+ VecZnxAutomorphismInplace<B>
+ VecZnxBigSubSmallNegateInplace<B>
+ VecZnxRotateInplaceTmpBytes
+ VecZnxBigBytesOf
+ VecZnxDftAddInplace<B>
+ VecZnxRotate
+ ZnFillUniform
+ ZnAddNormal
+ ZnNormalizeInplace<B>,
ScratchOwned<B>: ScratchOwnedAlloc<B> + ScratchOwnedBorrow<B>,
B: Backend
+ ScratchOwnedAllocImpl<B>
+ ScratchOwnedBorrowImpl<B>
+ TakeVecZnxDftImpl<B>
+ ScratchAvailableImpl<B>
+ TakeVecZnxImpl<B>
+ TakeScalarZnxImpl<B>
+ TakeSvpPPolImpl<B>
+ TakeVecZnxBigImpl<B>
+ TakeVecZnxDftSliceImpl<B>
+ TakeMatZnxImpl<B>
+ TakeVecZnxSliceImpl<B>
+ TakeSliceImpl<B>,
BlindRotationKey<Vec<u8>, BRA>: PrepareAlloc<B, BlindRotationKeyPrepared<Vec<u8>, BRA, B>>,
BlindRotationKeyPrepared<Vec<u8>, BRA, B>: BlincRotationExecute<B>,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<B>,
Module<BE>: ModuleNew<BE>
+ ModuleN
+ GLWESecretPreparedFactory<BE>
+ GLWEExternalProduct<BE>
+ GLWEDecrypt<BE>
+ LWEEncryptSk<BE>
+ CircuitBootstrappingKeyEncryptSk<BRA, BE>
+ CircuitBootstrappingKeyPreparedFactory<BRA, BE>
+ CirtuitBootstrappingExecute<BRA, BE>
+ GGSWPreparedFactory<BE>
+ GGSWNoise<BE>
+ GLWEEncryptSk<BE>
+ VecZnxRotateInplace<BE>,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>, // TODO find a way to remove this bound or move it to CBT KEY
ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
let group_name: String = format!("circuit_bootstrapping::{label}");
@@ -118,81 +57,33 @@ where
cbt_infos: CircuitBootstrappingKeyLayout,
}
fn runner<B: Backend, BRA: BlindRotationAlgo>(params: &Params) -> impl FnMut()
fn runner<BE: Backend, BRA: BlindRotationAlgo>(params: &Params) -> impl FnMut()
where
Module<B>: ModuleNew<B>
+ VecZnxFillUniform
+ VecZnxAddNormal
+ VecZnxNormalizeInplace<B>
+ VecZnxDftBytesOf
+ VecZnxBigNormalize<B>
+ VecZnxDftApply<B>
+ SvpApplyDftToDftInplace<B>
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalize<B>
+ VecZnxSub
+ VecZnxAddScalarInplace
+ VecZnxAutomorphism
+ VecZnxSwitchRing
+ VecZnxBigBytesOf
+ VecZnxIdftApplyTmpA<B>
+ SvpApplyDftToDft<B>
+ VecZnxBigAddInplace<B>
+ VecZnxBigAddSmallInplace<B>
+ VecZnxBigAlloc<B>
+ VecZnxDftAlloc<B>
+ VecZnxBigNormalizeTmpBytes
+ VmpPMatAlloc<B>
+ VmpPrepare<B>
+ SvpPrepare<B>
+ SvpPPolAlloc<B>
+ VmpApplyDftToDftTmpBytes
+ VmpApplyDftToDft<B>
+ VmpApplyDftToDftAdd<B>
+ SvpPPolBytesOf
+ VecZnxRotateInplace<B>
+ VecZnxBigAutomorphismInplace<B>
+ VecZnxRshInplace<B>
+ VecZnxDftCopy<B>
+ VecZnxNegateInplace
+ VecZnxCopy
+ VecZnxAutomorphismInplace<B>
+ VecZnxBigSubSmallNegateInplace<B>
+ VecZnxRotateInplaceTmpBytes
+ VecZnxBigBytesOf
+ VecZnxDftAddInplace<B>
+ VecZnxRotate
+ ZnFillUniform
+ ZnAddNormal
+ ZnNormalizeInplace<B>,
B: Backend
+ ScratchOwnedAllocImpl<B>
+ ScratchOwnedBorrowImpl<B>
+ TakeVecZnxDftImpl<B>
+ ScratchAvailableImpl<B>
+ TakeVecZnxImpl<B>
+ TakeScalarZnxImpl<B>
+ TakeSvpPPolImpl<B>
+ TakeVecZnxBigImpl<B>
+ TakeVecZnxDftSliceImpl<B>
+ TakeMatZnxImpl<B>
+ TakeVecZnxSliceImpl<B>
+ TakeSliceImpl<B>,
BlindRotationKey<Vec<u8>, BRA>: PrepareAlloc<B, BlindRotationKeyPrepared<Vec<u8>, BRA, B>>,
BlindRotationKeyPrepared<Vec<u8>, BRA, B>: BlincRotationExecute<B>,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<B>,
Module<BE>: ModuleNew<BE>
+ ModuleN
+ GLWESecretPreparedFactory<BE>
+ GLWEExternalProduct<BE>
+ GLWEDecrypt<BE>
+ LWEEncryptSk<BE>
+ CircuitBootstrappingKeyEncryptSk<BRA, BE>
+ CircuitBootstrappingKeyPreparedFactory<BRA, BE>
+ CirtuitBootstrappingExecute<BRA, BE>
+ GGSWPreparedFactory<BE>
+ GGSWNoise<BE>
+ GLWEEncryptSk<BE>
+ VecZnxRotateInplace<BE>,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>, /* TODO find a way to remove this bound or move it to CBT KEY */
ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
// Scratch space (4MB)
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(1 << 22);
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let n_glwe: poulpy_core::layouts::Degree = params.cbt_infos.layout_brk.n_glwe();
let n_lwe: poulpy_core::layouts::Degree = params.cbt_infos.layout_brk.n_lwe();
let rank: poulpy_core::layouts::Rank = params.cbt_infos.layout_brk.rank;
let module: Module<B> = Module::<B>::new(n_glwe.as_u32() as u64);
let module: Module<BE> = Module::<BE>::new(n_glwe.as_u32() as u64);
let mut source_xs: Source = Source::new([1u8; 32]);
let mut source_xa: Source = Source::new([1u8; 32]);
@@ -208,19 +99,20 @@ where
let ct_lwe: LWE<Vec<u8>> = LWE::alloc_from_infos(&params.lwe_infos);
// Circuit bootstrapping evaluation key
let cbt_key: CircuitBootstrappingKey<Vec<u8>, BRA> = CircuitBootstrappingKey::encrypt_sk(
let mut cbt_key: CircuitBootstrappingKey<Vec<u8>, BRA> = CircuitBootstrappingKey::alloc_from_infos(&params.cbt_infos);
cbt_key.encrypt_sk(
&module,
&sk_lwe,
&sk_glwe,
&params.cbt_infos,
&mut source_xa,
&mut source_xe,
scratch.borrow(),
);
let mut res: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&params.ggsw_infos);
let cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B> = cbt_key.prepare_alloc(&module, scratch.borrow());
let mut cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, BE> =
CircuitBootstrappingKeyPrepared::alloc_from_infos(&module, &params.cbt_infos);
cbt_prepared.prepare(&module, &cbt_key, scratch.borrow());
move || {
cbt_prepared.execute_to_constant(
&module,
@@ -261,7 +153,7 @@ where
dnum: 3_u32.into(),
rank: 2_u32.into(),
},
layout_atk: AutomorphismKeyLayout {
layout_atk: GLWEAutomorphismKeyLayout {
n: 1024_u32.into(),
base2k: 13_u32.into(),
k: 52_u32.into(),
@@ -269,7 +161,7 @@ where
dsize: Dsize(1),
rank: 2_u32.into(),
},
layout_tsk: TensorKeyLayout {
layout_tsk: GLWETensorKeyLayout {
n: 1024_u32.into(),
base2k: 13_u32.into(),
k: 52_u32.into(),
@@ -280,7 +172,7 @@ where
},
}] {
let id: BenchmarkId = BenchmarkId::from_parameter(params.name.clone());
let mut runner = runner::<B, BRA>(&params);
let mut runner = runner::<BE, BRA>(&params);
group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
}

View File

@@ -1,9 +1,9 @@
use poulpy_core::{
GLWEOperations,
GLWENormalize,
layouts::{
AutomorphismKeyLayout, GGSW, GGSWLayout, GLWE, GLWELayout, GLWEPlaintext, GLWESecret, LWE, LWEInfos, LWELayout,
LWEPlaintext, LWESecret, TensorKeyLayout,
prepared::{GGSWPrepared, GLWESecretPrepared, PrepareAlloc},
GGSW, GGSWLayout, GLWE, GLWEAutomorphismKeyLayout, GLWELayout, GLWEPlaintext, GLWESecret, GLWETensorKeyLayout, LWE,
LWEInfos, LWELayout, LWEPlaintext, LWESecret,
prepared::{GGSWPrepared, GLWESecretPrepared},
},
};
use std::time::Instant;
@@ -22,10 +22,7 @@ use poulpy_hal::{
use poulpy_schemes::tfhe::{
blind_rotation::{BlindRotationKeyLayout, CGGI},
circuit_bootstrapping::{
CircuitBootstrappingKey, CircuitBootstrappingKeyEncryptSk, CircuitBootstrappingKeyLayout,
CircuitBootstrappingKeyPrepared, CirtuitBootstrappingExecute,
},
circuit_bootstrapping::{CircuitBootstrappingKey, CircuitBootstrappingKeyLayout, CircuitBootstrappingKeyPrepared},
};
fn main() {
@@ -89,7 +86,7 @@ fn main() {
dnum: rows_brk.into(),
rank: rank.into(),
},
layout_atk: AutomorphismKeyLayout {
layout_atk: GLWEAutomorphismKeyLayout {
n: n_glwe.into(),
base2k: base2k.into(),
k: k_trace.into(),
@@ -97,7 +94,7 @@ fn main() {
dsize: 1_u32.into(),
rank: rank.into(),
},
layout_tsk: TensorKeyLayout {
layout_tsk: GLWETensorKeyLayout {
n: n_glwe.into(),
base2k: base2k.into(),
k: k_tsk.into(),
@@ -145,7 +142,8 @@ fn main() {
// sk_glwe.fill_zero();
// GLWE secret prepared (opaque backend dependant write only struct)
let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, BackendImpl> = sk_glwe.prepare_alloc(&module, scratch.borrow());
let mut sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, BackendImpl> = GLWESecretPrepared::alloc(&module, rank.into());
sk_glwe_prepared.prepare(&module, &sk_glwe);
// Plaintext value to circuit bootstrap
let data: i64 = 1 % (1 << k_lwe_pt);
@@ -175,23 +173,26 @@ fn main() {
let now: Instant = Instant::now();
// Circuit bootstrapping evaluation key
let cbt_key: CircuitBootstrappingKey<Vec<u8>, CGGI> = CircuitBootstrappingKey::encrypt_sk(
let mut cbt_key: CircuitBootstrappingKey<Vec<u8>, CGGI> = CircuitBootstrappingKey::alloc_from_infos(&cbt_infos);
cbt_key.encrypt_sk(
&module,
&sk_lwe,
&sk_glwe,
&cbt_infos,
&mut source_xa,
&mut source_xe,
scratch.borrow(),
);
println!("CBT-KGEN: {} ms", now.elapsed().as_millis());
// Output GGSW
let mut res: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&ggsw_infos);
// Circuit bootstrapping key prepared (opaque backend dependant write only struct)
let cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, CGGI, BackendImpl> =
cbt_key.prepare_alloc(&module, scratch.borrow());
let mut cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, CGGI, BackendImpl> =
CircuitBootstrappingKeyPrepared::alloc_from_infos(&module, &cbt_infos);
cbt_prepared.prepare(&module, &cbt_key, scratch.borrow());
// Apply circuit bootstrapping: LWE(data * 2^{- (k_lwe_pt + 2)}) -> GGSW(data)
let now: Instant = Instant::now();
@@ -234,7 +235,7 @@ fn main() {
.for_each(|(x, y)| *y = (x % (1 << (k_glwe_pt - 1))) as i64 - (1 << (k_glwe_pt - 2)));
pt_glwe.encode_vec_i64(&data_vec, (k_lwe_pt + 2).into());
pt_glwe.normalize_inplace(&module, scratch.borrow());
module.glwe_normalize_inplace(&mut pt_glwe, scratch.borrow());
println!("{}", pt_glwe);
@@ -249,7 +250,8 @@ fn main() {
);
// Prepare GGSW output of circuit bootstrapping (opaque backend dependant write only struct)
let res_prepared: GGSWPrepared<Vec<u8>, BackendImpl> = res.prepare_alloc(&module, scratch.borrow());
let mut res_prepared: GGSWPrepared<Vec<u8>, BackendImpl> = GGSWPrepared::alloc_from_infos(&module, &res);
res_prepared.prepare(&module, &res, scratch.borrow());
// Apply GLWE x GGSW
ct_glwe.external_product_inplace(&module, &res_prepared, scratch.borrow());

View File

@@ -29,7 +29,7 @@ impl<D: DataRef> BlindRotationKeyFactory<CGGI> for BlindRotationKey<D, CGGI> {
}
}
impl<BE: Backend> BlindRotationKeyEncryptSk<BE, CGGI> for Module<BE>
impl<BE: Backend> BlindRotationKeyEncryptSk<CGGI, BE> for Module<BE>
where
Self: GGSWEncryptSk<BE>,
Scratch<BE>: ScratchTakeCore<BE>,

View File

@@ -15,7 +15,7 @@ use crate::tfhe::blind_rotation::{
utils::set_xai_plus_y,
};
impl<BE: Backend> BlindRotationKeyPreparedFactory<BE, CGGI> for Module<BE>
impl<BE: Backend> BlindRotationKeyPreparedFactory<CGGI, BE> for Module<BE>
where
Self: GGSWPreparedFactory<BE> + SvpPPolAlloc<BE> + SvpPrepare<BE>,
{

View File

@@ -10,7 +10,7 @@ use poulpy_core::{
use crate::tfhe::blind_rotation::{BlindRotationAlgo, BlindRotationKey};
pub trait BlindRotationKeyEncryptSk<B: Backend, BRA: BlindRotationAlgo> {
pub trait BlindRotationKeyEncryptSk<BRA: BlindRotationAlgo, B: Backend> {
fn blind_rotation_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGSWInfos;
@@ -43,7 +43,7 @@ impl<D: DataMut, BRA: BlindRotationAlgo> BlindRotationKey<D, BRA> {
S0: GLWESecretPreparedToRef<BE> + GLWEInfos,
S1: LWESecretToRef + LWEInfos + GetDistribution,
Scratch<BE>: ScratchTakeCore<BE>,
M: BlindRotationKeyEncryptSk<BE, BRA>,
M: BlindRotationKeyEncryptSk<BRA, BE>,
{
module.blind_rotation_key_encrypt_sk(self, sk_glwe, sk_lwe, source_xa, source_xe, scratch);
}
@@ -53,7 +53,7 @@ impl<BRA: BlindRotationAlgo> BlindRotationKey<Vec<u8>, BRA> {
pub fn encrypt_sk_tmp_bytes<A, M, BE: Backend>(module: &M, infos: &A) -> usize
where
A: GGSWInfos,
M: BlindRotationKeyEncryptSk<BE, BRA>,
M: BlindRotationKeyEncryptSk<BRA, BE>,
{
module.blind_rotation_key_encrypt_sk_tmp_bytes(infos)
}

View File

@@ -3,13 +3,13 @@ use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Scratch, SvpPPol};
use std::marker::PhantomData;
use poulpy_core::{
Distribution, ScratchTakeCore,
Distribution,
layouts::{Base2K, Degree, Dnum, Dsize, GGSWInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision, prepared::GGSWPrepared},
};
use crate::tfhe::blind_rotation::{BlindRotationAlgo, BlindRotationKey, BlindRotationKeyInfos};
pub trait BlindRotationKeyPreparedFactory<BE: Backend, BRA: BlindRotationAlgo> {
pub trait BlindRotationKeyPreparedFactory<BRA: BlindRotationAlgo, BE: Backend> {
fn blind_rotation_key_prepared_alloc<A>(&self, infos: &A) -> BlindRotationKeyPrepared<Vec<u8>, BRA, BE>
where
A: BlindRotationKeyInfos;
@@ -21,27 +21,23 @@ pub trait BlindRotationKeyPreparedFactory<BE: Backend, BRA: BlindRotationAlgo> {
scratch: &mut Scratch<BE>,
) where
DM: DataMut,
DR: DataRef,
Scratch<BE>: ScratchTakeCore<BE>;
DR: DataRef;
}
impl<BE: Backend, BRA: BlindRotationAlgo> BlindRotationKeyPrepared<Vec<u8>, BRA, BE> {
pub fn alloc<A, M>(module: &M, infos: &A) -> Self
where
A: BlindRotationKeyInfos,
M: BlindRotationKeyPreparedFactory<BE, BRA>,
M: BlindRotationKeyPreparedFactory<BRA, BE>,
{
module.blind_rotation_key_prepared_alloc(infos)
}
}
impl<D: DataMut, BRA: BlindRotationAlgo, BE: Backend> BlindRotationKeyPrepared<D, BRA, BE>
where
Scratch<BE>: ScratchTakeCore<BE>,
{
impl<D: DataMut, BRA: BlindRotationAlgo, BE: Backend> BlindRotationKeyPrepared<D, BRA, BE> {
pub fn prepare<DR: DataRef, M>(&mut self, module: &M, other: &BlindRotationKey<DR, BRA>, scratch: &mut Scratch<BE>)
where
M: BlindRotationKeyPreparedFactory<BE, BRA>,
M: BlindRotationKeyPreparedFactory<BRA, BE>,
{
module.blind_rotation_key_prepare(self, other, scratch);
}

View File

@@ -24,14 +24,13 @@ pub fn test_blind_rotation<BRA: BlindRotationAlgo, M, BE: Backend>(
block_size: usize,
extension_factor: usize,
) where
M: BlindRotationKeyEncryptSk<BE, BRA>
+ BlindRotationKeyPreparedFactory<BE, BRA>
M: BlindRotationKeyEncryptSk<BRA, BE>
+ BlindRotationKeyPreparedFactory<BRA, BE>
+ BlindRotationExecute<BRA, BE>
+ GLWESecretPreparedFactory<BE>
+ BlindRotationExecute<BRA, BE>
+ LWEEncryptSk<BE>
+ LookupTableFactory
+ GLWEDecrypt<BE>,
+ GLWESecretPreparedFactory<BE>
+ GLWEDecrypt<BE>
+ LWEEncryptSk<BE>,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>,
ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
Scratch<BE>: ScratchTakeCore<BE>,

View File

@@ -1,185 +1,182 @@
use std::collections::HashMap;
use poulpy_hal::{
api::{
ScratchAvailable, TakeMatZnx, TakeSlice, TakeVecZnx, TakeVecZnxBig, TakeVecZnxDft, TakeVecZnxDftSlice, TakeVecZnxSlice,
VecZnxAddInplace, VecZnxAutomorphismInplace, VecZnxBigAddSmallInplace, VecZnxBigAutomorphismInplace, VecZnxBigBytesOf,
VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxBigSubSmallNegateInplace, VecZnxCopy, VecZnxDftAddInplace,
VecZnxDftApply, VecZnxDftBytesOf, VecZnxDftCopy, VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNegateInplace,
VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxRotate, VecZnxRotateInplace,
VecZnxRotateInplaceTmpBytes, VecZnxRshInplace, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, VmpApplyDftToDft,
VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes,
},
layouts::{Backend, DataMut, DataRef, Module, Scratch, ToOwnedDeep},
oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl},
api::{ModuleLogN, ModuleN, ScratchOwnedAlloc, ScratchOwnedBorrow},
layouts::{Backend, DataRef, Module, Scratch, ScratchOwned, ToOwnedDeep},
};
use poulpy_core::{
GLWEOperations, TakeGGLWE, TakeGLWE,
layouts::{Dsize, GGLWELayout, GGSWInfos, GLWEInfos, LWEInfos},
GGSWFromGGLWE, GLWEPacking, GLWETrace, ScratchTakeCore,
layouts::{Dsize, GGLWELayout, GGSWInfos, GGSWToMut, GLWEInfos, GLWEToMut, GLWEToRef, LWEInfos, LWEToRef},
};
use poulpy_core::glwe_packing;
use poulpy_core::layouts::{GGSW, GLWE, LWE, prepared::GLWEAutomorphismKeyPrepared};
use crate::tfhe::{
blind_rotation::{
BlincRotationExecute, BlindRotationAlgo, BlindRotationKeyPrepared, LookUpTable, LookUpTableRotationDirection,
BlindRotationAlgo, BlindRotationExecute, LookUpTableLayout, LookUpTableRotationDirection, LookupTable, LookupTableFactory,
},
circuit_bootstrapping::{CircuitBootstrappingKeyPrepared, CirtuitBootstrappingExecute},
circuit_bootstrapping::CircuitBootstrappingKeyPrepared,
};
impl<D: DataRef, BRA: BlindRotationAlgo, B> CirtuitBootstrappingExecute<B> for CircuitBootstrappingKeyPrepared<D, BRA, B>
where
Module<B>: VecZnxRotateInplace<B>
+ VecZnxNormalizeInplace<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxSwitchRing
+ VecZnxBigAutomorphismInplace<B>
+ VecZnxRshInplace<B>
+ VecZnxDftCopy<B>
+ VecZnxIdftApplyTmpA<B>
+ VecZnxSub
+ VecZnxAddInplace
+ VecZnxNegateInplace
+ VecZnxCopy
+ VecZnxSubInplace
+ VecZnxDftBytesOf
+ VmpApplyDftToDftTmpBytes
+ VecZnxBigNormalizeTmpBytes
+ VmpApplyDftToDft<B>
+ VmpApplyDftToDftAdd<B>
+ VecZnxDftApply<B>
+ VecZnxIdftApplyConsume<B>
+ VecZnxBigAddSmallInplace<B>
+ VecZnxBigNormalize<B>
+ VecZnxAutomorphismInplace<B>
+ VecZnxBigSubSmallNegateInplace<B>
+ VecZnxRotateInplaceTmpBytes
+ VecZnxBigBytesOf
+ VecZnxDftAddInplace<B>
+ VecZnxRotate
+ VecZnxNormalize<B>,
B: Backend + ScratchOwnedAllocImpl<B> + ScratchOwnedBorrowImpl<B>,
Scratch<B>: TakeVecZnx
+ TakeVecZnxDftSlice<B>
+ TakeVecZnxBig<B>
+ TakeVecZnxDft<B>
+ TakeMatZnx
+ ScratchAvailable
+ TakeVecZnxSlice
+ TakeSlice,
BlindRotationKeyPrepared<D, BRA, B>: BlincRotationExecute<B>,
{
fn execute_to_constant<DM: DataMut, DR: DataRef>(
pub trait CirtuitBootstrappingExecute<BRA: BlindRotationAlgo, BE: Backend> {
fn circuit_bootstrapping_execute_to_constant<R, L, D>(
&self,
module: &Module<B>,
res: &mut GGSW<DM>,
lwe: &LWE<DR>,
res: &mut R,
lwe: &L,
key: &CircuitBootstrappingKeyPrepared<D, BRA, BE>,
log_domain: usize,
extension_factor: usize,
scratch: &mut Scratch<B>,
) {
scratch: &mut Scratch<BE>,
) where
R: GGSWToMut + GGSWInfos,
L: LWEToRef + LWEInfos,
D: DataRef;
#[allow(clippy::too_many_arguments)]
fn circuit_bootstrapping_execute_to_exponent<R, L, D>(
&self,
log_gap_out: usize,
res: &mut R,
lwe: &L,
key: &CircuitBootstrappingKeyPrepared<D, BRA, BE>,
log_domain: usize,
extension_factor: usize,
scratch: &mut Scratch<BE>,
) where
R: GGSWToMut + GGSWInfos,
L: LWEToRef + LWEInfos,
D: DataRef;
}
impl<D: DataRef, BRA: BlindRotationAlgo, BE: Backend> CircuitBootstrappingKeyPrepared<D, BRA, BE> {
pub fn execute_to_constant<M, L, R>(
&self,
module: &M,
res: &mut R,
lwe: &L,
log_domain: usize,
extension_factor: usize,
scratch: &mut Scratch<BE>,
) where
M: CirtuitBootstrappingExecute<BRA, BE>,
R: GGSWToMut + GGSWInfos,
L: LWEToRef + LWEInfos,
{
module.circuit_bootstrapping_execute_to_constant(res, lwe, self, log_domain, extension_factor, scratch);
}
pub fn execute_to_exponent<R, L, M>(
&self,
module: &M,
log_gap_out: usize,
res: &mut R,
lwe: &L,
log_domain: usize,
extension_factor: usize,
scratch: &mut Scratch<BE>,
) where
M: CirtuitBootstrappingExecute<BRA, BE>,
R: GGSWToMut + GGSWInfos,
L: LWEToRef + LWEInfos,
{
module.circuit_bootstrapping_execute_to_exponent(
log_gap_out,
res,
lwe,
self,
log_domain,
extension_factor,
scratch,
);
}
}
impl<BRA: BlindRotationAlgo, BE: Backend> CirtuitBootstrappingExecute<BRA, BE> for Module<BE>
where
Self: ModuleN + LookupTableFactory + BlindRotationExecute<BRA, BE> + GLWETrace<BE> + GLWEPacking<BE> + GGSWFromGGLWE<BE>,
ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
fn circuit_bootstrapping_execute_to_constant<R, L, D>(
&self,
res: &mut R,
lwe: &L,
key: &CircuitBootstrappingKeyPrepared<D, BRA, BE>,
log_domain: usize,
extension_factor: usize,
scratch: &mut Scratch<BE>,
) where
R: GGSWToMut + GGSWInfos,
L: LWEToRef + LWEInfos,
D: DataRef,
{
circuit_bootstrap_core(
false,
module,
self,
0,
res,
lwe,
log_domain,
extension_factor,
self,
key,
scratch,
);
}
fn execute_to_exponent<DM: DataMut, DR: DataRef>(
fn circuit_bootstrapping_execute_to_exponent<R, L, D>(
&self,
module: &Module<B>,
log_gap_out: usize,
res: &mut GGSW<DM>,
lwe: &LWE<DR>,
res: &mut R,
lwe: &L,
key: &CircuitBootstrappingKeyPrepared<D, BRA, BE>,
log_domain: usize,
extension_factor: usize,
scratch: &mut Scratch<B>,
) {
scratch: &mut Scratch<BE>,
) where
R: GGSWToMut + GGSWInfos,
L: LWEToRef + LWEInfos,
D: DataRef,
{
circuit_bootstrap_core(
true,
module,
self,
log_gap_out,
res,
lwe,
log_domain,
extension_factor,
self,
key,
scratch,
);
}
}
#[allow(clippy::too_many_arguments)]
pub fn circuit_bootstrap_core<DRes, DLwe, DBrk, BRA: BlindRotationAlgo, B>(
pub fn circuit_bootstrap_core<R, L, D, M, BRA: BlindRotationAlgo, BE: Backend>(
to_exponent: bool,
module: &Module<B>,
module: &M,
log_gap_out: usize,
res: &mut GGSW<DRes>,
lwe: &LWE<DLwe>,
res: &mut R,
lwe: &L,
log_domain: usize,
extension_factor: usize,
key: &CircuitBootstrappingKeyPrepared<DBrk, BRA, B>,
scratch: &mut Scratch<B>,
key: &CircuitBootstrappingKeyPrepared<D, BRA, BE>,
scratch: &mut Scratch<BE>,
) where
DRes: DataMut,
DLwe: DataRef,
DBrk: DataRef,
Module<B>: VecZnxRotateInplace<B>
+ VecZnxNormalizeInplace<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxSwitchRing
+ VecZnxBigAutomorphismInplace<B>
+ VecZnxRshInplace<B>
+ VecZnxDftCopy<B>
+ VecZnxIdftApplyTmpA<B>
+ VecZnxSub
+ VecZnxAddInplace
+ VecZnxNegateInplace
+ VecZnxCopy
+ VecZnxSubInplace
+ VecZnxDftBytesOf
+ VmpApplyDftToDftTmpBytes
+ VecZnxBigNormalizeTmpBytes
+ VmpApplyDftToDft<B>
+ VmpApplyDftToDftAdd<B>
+ VecZnxDftApply<B>
+ VecZnxIdftApplyConsume<B>
+ VecZnxBigAddSmallInplace<B>
+ VecZnxBigNormalize<B>
+ VecZnxAutomorphismInplace<B>
+ VecZnxBigSubSmallNegateInplace<B>
+ VecZnxBigBytesOf
+ VecZnxDftAddInplace<B>
+ VecZnxRotateInplaceTmpBytes
+ VecZnxRotate
+ VecZnxNormalize<B>,
B: Backend + ScratchOwnedAllocImpl<B> + ScratchOwnedBorrowImpl<B>,
Scratch<B>: TakeVecZnxDftSlice<B>
+ TakeVecZnxBig<B>
+ TakeVecZnxDft<B>
+ TakeVecZnx
+ ScratchAvailable
+ TakeVecZnxSlice
+ TakeMatZnx
+ TakeSlice,
BlindRotationKeyPrepared<DBrk, BRA, B>: BlincRotationExecute<B>,
R: GGSWToMut,
L: LWEToRef,
D: DataRef,
M: ModuleN + LookupTableFactory + BlindRotationExecute<BRA, BE> + GLWETrace<BE> + GLWEPacking<BE> + GGSWFromGGLWE<BE>,
ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
#[cfg(debug_assertions)]
{
use poulpy_core::layouts::LWEInfos;
let res: &mut GGSW<&mut [u8]> = &mut res.to_mut();
let lwe: &LWE<&[u8]> = &lwe.to_ref();
assert_eq!(res.n(), key.brk.n());
assert_eq!(lwe.base2k(), key.brk.base2k());
assert_eq!(res.base2k(), key.brk.base2k());
}
assert_eq!(res.n(), key.brk.n());
assert_eq!(lwe.base2k(), key.brk.base2k());
assert_eq!(res.base2k(), key.brk.base2k());
let n: usize = res.n().into();
let base2k: usize = res.base2k().into();
@@ -203,8 +200,15 @@ pub fn circuit_bootstrap_core<DRes, DLwe, DBrk, BRA: BlindRotationAlgo, B>(
});
}
let lut_infos: LookUpTableLayout = LookUpTableLayout {
n: module.n().into(),
extension_factor,
k: (base2k * dnum).into(),
base2k: base2k.into(),
};
// Lut precision, basically must be able to hold the decomposition power basis of the GGSW
let mut lut: LookUpTable = LookUpTable::alloc(module, base2k, base2k * dnum, extension_factor);
let mut lut: LookupTable = LookupTable::alloc(&lut_infos);
lut.set(module, &f, base2k * dnum);
if to_exponent {
@@ -212,7 +216,7 @@ pub fn circuit_bootstrap_core<DRes, DLwe, DBrk, BRA: BlindRotationAlgo, B>(
}
// TODO: separate GGSW k from output of blind rotation k
let (mut res_glwe, scratch_1) = scratch.take_glwe_ct(res);
let (mut res_glwe, scratch_1) = scratch.take_glwe(res);
let gglwe_infos: GGLWELayout = GGLWELayout {
n: n.into(),
@@ -252,7 +256,7 @@ pub fn circuit_bootstrap_core<DRes, DLwe, DBrk, BRA: BlindRotationAlgo, B>(
}
if i < dnum {
res_glwe.rotate_inplace(module, -(gap as i64), scratch_2);
module.glwe_rotate_inplace(-(gap as i64), &mut res_glwe, scratch_2);
}
});
@@ -261,46 +265,24 @@ pub fn circuit_bootstrap_core<DRes, DLwe, DBrk, BRA: BlindRotationAlgo, B>(
}
#[allow(clippy::too_many_arguments)]
fn post_process<DataRes, DataA, B: Backend>(
module: &Module<B>,
res: &mut GLWE<DataRes>,
a: &GLWE<DataA>,
fn post_process<R, A, M, BE: Backend>(
module: &M,
res: &mut R,
a: &A,
log_gap_in: usize,
log_gap_out: usize,
log_domain: usize,
auto_keys: &HashMap<i64, GLWEAutomorphismKeyPrepared<Vec<u8>, B>>,
scratch: &mut Scratch<B>,
auto_keys: &HashMap<i64, GLWEAutomorphismKeyPrepared<Vec<u8>, BE>>,
scratch: &mut Scratch<BE>,
) where
DataRes: DataMut,
DataA: DataRef,
Module<B>: VecZnxRotateInplace<B>
+ VecZnxNormalizeInplace<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxSwitchRing
+ VecZnxBigAutomorphismInplace<B>
+ VecZnxRshInplace<B>
+ VecZnxDftCopy<B>
+ VecZnxIdftApplyTmpA<B>
+ VecZnxSub
+ VecZnxAddInplace
+ VecZnxNegateInplace
+ VecZnxCopy
+ VecZnxSubInplace
+ VecZnxDftBytesOf
+ VmpApplyDftToDftTmpBytes
+ VecZnxBigNormalizeTmpBytes
+ VmpApplyDftToDft<B>
+ VmpApplyDftToDftAdd<B>
+ VecZnxDftApply<B>
+ VecZnxIdftApplyConsume<B>
+ VecZnxBigAddSmallInplace<B>
+ VecZnxBigNormalize<B>
+ VecZnxAutomorphismInplace<B>
+ VecZnxBigSubSmallNegateInplace<B>
+ VecZnxRotate
+ VecZnxNormalize<B>,
Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx,
R: GLWEToMut,
A: GLWEToRef,
M: ModuleLogN + GLWETrace<BE> + GLWEPacking<BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
let a: &GLWE<&[u8]> = &a.to_ref();
let log_n: usize = module.log_n();
let mut cts: HashMap<usize, &mut GLWE<Vec<u8>>> = HashMap::new();
@@ -326,7 +308,7 @@ fn post_process<DataRes, DataA, B: Backend>(
for i in 0..steps {
if i != 0 {
res.rotate_inplace(module, -(1 << log_gap_in), scratch);
module.glwe_rotate_inplace(-(1 << log_gap_in), res, scratch);
}
cts_vec.push(res.to_owned_deep());
}
@@ -335,7 +317,8 @@ fn post_process<DataRes, DataA, B: Backend>(
cts.insert(i * (1 << log_gap_out), ct);
}
glwe_packing(module, &mut cts, log_gap_out, auto_keys, scratch);
module.glwe_pack(&mut cts, log_gap_out, auto_keys, scratch);
let packed: &mut GLWE<Vec<u8>> = cts.remove(&0).unwrap();
res.trace(
module,

View File

@@ -1,41 +1,38 @@
use poulpy_core::layouts::{
AutomorphismKey, AutomorphismKeyLayout, GGLWEInfos, GGSWInfos, GLWE, GLWEInfos, GLWESecret, LWEInfos, LWESecret, TensorKey,
TensorKeyLayout,
prepared::{GLWEAutomorphismKeyPrepared, GLWESecretPrepared, TensorKeyPrepared},
use poulpy_core::{
GLWEAutomorphismKeyEncryptSk, GLWETensorKeyEncryptSk, GetDistribution, ScratchTakeCore,
layouts::{
GGLWEInfos, GGSWInfos, GLWEAutomorphismKey, GLWEAutomorphismKeyLayout, GLWEInfos, GLWESecretPreparedFactory,
GLWESecretToRef, GLWETensorKey, GLWETensorKeyLayout, LWEInfos, LWESecretToRef, prepared::GLWESecretPrepared,
},
trace_galois_elements,
};
use std::collections::HashMap;
use poulpy_hal::{
api::{
ScratchAvailable, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace,
VecZnxAutomorphism, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume,
VecZnxIdftApplyTmpA, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
VecZnxSwitchRing, VmpPMatAlloc, VmpPrepare,
},
layouts::{Backend, Data, DataRef, Module, Scratch},
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch},
source::Source,
};
use crate::tfhe::blind_rotation::{
BlindRotationAlgo, BlindRotationKey, BlindRotationKeyAlloc, BlindRotationKeyEncryptSk, BlindRotationKeyInfos,
BlindRotationKeyLayout, BlindRotationKeyPrepared,
BlindRotationAlgo, BlindRotationKey, BlindRotationKeyEncryptSk, BlindRotationKeyFactory, BlindRotationKeyInfos,
BlindRotationKeyLayout,
};
pub trait CircuitBootstrappingKeyInfos {
fn brk_infos(&self) -> BlindRotationKeyLayout;
fn atk_infos(&self) -> AutomorphismKeyLayout;
fn tsk_infos(&self) -> TensorKeyLayout;
fn atk_infos(&self) -> GLWEAutomorphismKeyLayout;
fn tsk_infos(&self) -> GLWETensorKeyLayout;
}
#[derive(Debug, Clone, Copy)]
pub struct CircuitBootstrappingKeyLayout {
pub layout_brk: BlindRotationKeyLayout,
pub layout_atk: AutomorphismKeyLayout,
pub layout_tsk: TensorKeyLayout,
pub layout_atk: GLWEAutomorphismKeyLayout,
pub layout_tsk: GLWETensorKeyLayout,
}
impl CircuitBootstrappingKeyInfos for CircuitBootstrappingKeyLayout {
fn atk_infos(&self) -> AutomorphismKeyLayout {
fn atk_infos(&self) -> GLWEAutomorphismKeyLayout {
self.layout_atk
}
@@ -43,96 +40,114 @@ impl CircuitBootstrappingKeyInfos for CircuitBootstrappingKeyLayout {
self.layout_brk
}
fn tsk_infos(&self) -> TensorKeyLayout {
fn tsk_infos(&self) -> GLWETensorKeyLayout {
self.layout_tsk
}
}
pub trait CircuitBootstrappingKeyEncryptSk<B: Backend> {
pub trait CircuitBootstrappingKeyEncryptSk<BRA: BlindRotationAlgo, BE: Backend> {
#[allow(clippy::too_many_arguments)]
fn encrypt_sk<DLwe, DGlwe, INFOS>(
module: &Module<B>,
sk_lwe: &LWESecret<DLwe>,
sk_glwe: &GLWESecret<DGlwe>,
cbt_infos: &INFOS,
fn circuit_bootstrapping_key_encrypt_sk<D, S0, S1>(
&self,
res: &mut CircuitBootstrappingKey<D, BRA>,
sk_lwe: &S0,
sk_glwe: &S1,
source_xa: &mut Source,
source_xe: &mut Source,
scratch: &mut Scratch<B>,
) -> Self
scratch: &mut Scratch<BE>,
) where
D: DataMut,
S0: LWESecretToRef + GetDistribution + LWEInfos,
S1: GLWESecretToRef + GLWEInfos + GetDistribution;
}
impl<BRA: BlindRotationAlgo> CircuitBootstrappingKey<Vec<u8>, BRA> {
pub fn alloc_from_infos<A>(infos: &A) -> Self
where
INFOS: CircuitBootstrappingKeyInfos,
DLwe: DataRef,
DGlwe: DataRef;
A: CircuitBootstrappingKeyInfos,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>,
{
let atk_infos: &GLWEAutomorphismKeyLayout = &infos.atk_infos();
let brk_infos: &BlindRotationKeyLayout = &infos.brk_infos();
let trk_infos: &GLWETensorKeyLayout = &infos.tsk_infos();
let gal_els: Vec<i64> = trace_galois_elements(atk_infos.log_n(), 2 * atk_infos.n().as_usize() as i64);
Self {
brk: <BlindRotationKey<Vec<u8>, BRA> as BlindRotationKeyFactory<BRA>>::blind_rotation_key_alloc(brk_infos),
atk: gal_els
.iter()
.map(|&gal_el| {
let key = GLWEAutomorphismKey::alloc_from_infos(atk_infos);
(gal_el, key)
})
.collect(),
tsk: GLWETensorKey::alloc_from_infos(trk_infos),
}
}
}
pub struct CircuitBootstrappingKey<D: Data, BRA: BlindRotationAlgo> {
pub(crate) brk: BlindRotationKey<D, BRA>,
pub(crate) tsk: TensorKey<Vec<u8>>,
pub(crate) atk: HashMap<i64, AutomorphismKey<Vec<u8>>>,
pub(crate) tsk: GLWETensorKey<Vec<u8>>,
pub(crate) atk: HashMap<i64, GLWEAutomorphismKey<Vec<u8>>>,
}
impl<BRA: BlindRotationAlgo, B: Backend> CircuitBootstrappingKeyEncryptSk<B> for CircuitBootstrappingKey<Vec<u8>, BRA>
where
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<B>,
Module<B>: SvpApplyDftToDft<B>
+ VecZnxIdftApplyTmpA<B>
+ VecZnxAddScalarInplace
+ VecZnxDftBytesOf
+ VecZnxBigNormalize<B>
+ VecZnxDftApply<B>
+ SvpApplyDftToDftInplace<B>
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
+ VecZnxNormalize<B>
+ VecZnxSub
+ SvpPrepare<B>
+ VecZnxSwitchRing
+ SvpPPolBytesOf
+ SvpPPolAlloc<B>
+ VecZnxAutomorphism,
Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx + TakeScalarZnx + TakeSvpPPol<B> + TakeVecZnxBig<B>,
{
fn encrypt_sk<DLwe, DGlwe, INFOS>(
module: &Module<B>,
sk_lwe: &LWESecret<DLwe>,
sk_glwe: &GLWESecret<DGlwe>,
cbt_infos: &INFOS,
impl<D: DataMut, BRA: BlindRotationAlgo> CircuitBootstrappingKey<D, BRA> {
pub fn encrypt_sk<M, S0, S1, BE: Backend>(
&mut self,
module: &M,
sk_lwe: &S0,
sk_glwe: &S1,
source_xa: &mut Source,
source_xe: &mut Source,
scratch: &mut Scratch<B>,
) -> Self
where
INFOS: CircuitBootstrappingKeyInfos,
DLwe: DataRef,
DGlwe: DataRef,
scratch: &mut Scratch<BE>,
) where
S0: LWESecretToRef + GetDistribution + LWEInfos,
S1: GLWESecretToRef + GLWEInfos + GetDistribution,
M: CircuitBootstrappingKeyEncryptSk<BRA, BE>,
{
assert_eq!(sk_lwe.n(), cbt_infos.brk_infos().n_lwe());
assert_eq!(sk_glwe.n(), cbt_infos.brk_infos().n_glwe());
assert_eq!(sk_glwe.n(), cbt_infos.atk_infos().n());
assert_eq!(sk_glwe.n(), cbt_infos.tsk_infos().n());
module.circuit_bootstrapping_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
}
}
let atk_infos: AutomorphismKeyLayout = cbt_infos.atk_infos();
let brk_infos: BlindRotationKeyLayout = cbt_infos.brk_infos();
let trk_infos: TensorKeyLayout = cbt_infos.tsk_infos();
impl<BRA: BlindRotationAlgo, BE: Backend> CircuitBootstrappingKeyEncryptSk<BRA, BE> for Module<BE>
where
Self: GLWETensorKeyEncryptSk<BE>
+ BlindRotationKeyEncryptSk<BRA, BE>
+ GLWEAutomorphismKeyEncryptSk<BE>
+ GLWESecretPreparedFactory<BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
fn circuit_bootstrapping_key_encrypt_sk<D, S0, S1>(
&self,
res: &mut CircuitBootstrappingKey<D, BRA>,
sk_lwe: &S0,
sk_glwe: &S1,
source_xa: &mut Source,
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
D: DataMut,
S0: LWESecretToRef + GetDistribution + LWEInfos,
S1: GLWESecretToRef + GLWEInfos + GetDistribution,
{
let brk_infos: &BlindRotationKeyLayout = &res.brk_infos();
let atk_infos: &GLWEAutomorphismKeyLayout = &res.atk_infos();
let tsk_infos: &GLWETensorKeyLayout = &res.tsk_infos();
let mut auto_keys: HashMap<i64, AutomorphismKey<Vec<u8>>> = HashMap::new();
let gal_els: Vec<i64> = GLWE::trace_galois_elements(module);
gal_els.iter().for_each(|gal_el| {
let mut key: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&atk_infos);
key.encrypt_sk(module, *gal_el, sk_glwe, source_xa, source_xe, scratch);
auto_keys.insert(*gal_el, key);
});
assert_eq!(sk_lwe.n(), brk_infos.n_lwe());
assert_eq!(sk_glwe.n(), brk_infos.n_glwe());
assert_eq!(sk_glwe.n(), atk_infos.n());
assert_eq!(sk_glwe.n(), tsk_infos.n());
let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch);
for (p, atk) in res.atk.iter_mut() {
atk.encrypt_sk(self, *p, sk_glwe, source_xa, source_xe, scratch);
}
let mut brk: BlindRotationKey<Vec<u8>, BRA> = BlindRotationKey::<Vec<u8>, BRA>::alloc(&brk_infos);
brk.encrypt_sk(
module,
let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(self, brk_infos.rank());
res.brk.encrypt_sk(
self,
&sk_glwe_prepared,
sk_lwe,
source_xa,
@@ -140,27 +155,15 @@ where
scratch,
);
let mut tsk: TensorKey<Vec<u8>> = TensorKey::alloc_from_infos(&trk_infos);
tsk.encrypt_sk(module, sk_glwe, source_xa, source_xe, scratch);
Self {
brk,
atk: auto_keys,
tsk,
}
res.tsk
.encrypt_sk(self, sk_glwe, source_xa, source_xe, scratch);
}
}
pub struct CircuitBootstrappingKeyPrepared<D: Data, BRA: BlindRotationAlgo, B: Backend> {
pub(crate) brk: BlindRotationKeyPrepared<D, BRA, B>,
pub(crate) tsk: TensorKeyPrepared<Vec<u8>, B>,
pub(crate) atk: HashMap<i64, GLWEAutomorphismKeyPrepared<Vec<u8>, B>>,
}
impl<D: DataRef, BRA: BlindRotationAlgo, B: Backend> CircuitBootstrappingKeyInfos for CircuitBootstrappingKeyPrepared<D, BRA, B> {
fn atk_infos(&self) -> AutomorphismKeyLayout {
impl<D: DataRef, BRA: BlindRotationAlgo> CircuitBootstrappingKeyInfos for CircuitBootstrappingKey<D, BRA> {
fn atk_infos(&self) -> GLWEAutomorphismKeyLayout {
let (_, atk) = self.atk.iter().next().expect("atk is empty");
AutomorphismKeyLayout {
GLWEAutomorphismKeyLayout {
n: atk.n(),
base2k: atk.base2k(),
k: atk.k(),
@@ -181,8 +184,8 @@ impl<D: DataRef, BRA: BlindRotationAlgo, B: Backend> CircuitBootstrappingKeyInfo
}
}
fn tsk_infos(&self) -> TensorKeyLayout {
TensorKeyLayout {
fn tsk_infos(&self) -> GLWETensorKeyLayout {
GLWETensorKeyLayout {
n: self.tsk.n(),
base2k: self.tsk.base2k(),
k: self.tsk.k(),
@@ -192,22 +195,3 @@ impl<D: DataRef, BRA: BlindRotationAlgo, B: Backend> CircuitBootstrappingKeyInfo
}
}
}
impl<D: DataRef, BRA: BlindRotationAlgo, B: Backend> PrepareAlloc<B, CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B>>
for CircuitBootstrappingKey<D, BRA>
where
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
BlindRotationKey<D, BRA>: PrepareAlloc<B, BlindRotationKeyPrepared<Vec<u8>, BRA, B>>,
TensorKey<D>: PrepareAlloc<B, TensorKeyPrepared<Vec<u8>, B>>,
AutomorphismKey<D>: PrepareAlloc<B, GLWEAutomorphismKeyPrepared<Vec<u8>, B>>,
{
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B> {
let brk: BlindRotationKeyPrepared<Vec<u8>, BRA, B> = self.brk.prepare_alloc(module, scratch);
let tsk: TensorKeyPrepared<Vec<u8>, B> = self.tsk.prepare_alloc(module, scratch);
let mut atk: HashMap<i64, GLWEAutomorphismKeyPrepared<Vec<u8>, B>> = HashMap::new();
for (key, value) in &self.atk {
atk.insert(*key, value.prepare_alloc(module, scratch));
}
CircuitBootstrappingKeyPrepared { brk, tsk, atk }
}
}

View File

@@ -0,0 +1,13 @@
use std::collections::HashMap;
use poulpy_core::layouts::{GLWEAutomorphismKeyCompressed, GLWETensorKeyCompressed};
use poulpy_hal::layouts::Data;
use crate::tfhe::blind_rotation::{BlindRotationAlgo, BlindRotationKeyCompressed};
#[allow(dead_code)]
pub struct CircuitBootstrappingKey<D: Data, BRA: BlindRotationAlgo> {
pub(crate) brk: BlindRotationKeyCompressed<D, BRA>,
pub(crate) tsk: GLWETensorKeyCompressed<Vec<u8>>,
pub(crate) atk: HashMap<i64, GLWEAutomorphismKeyCompressed<Vec<u8>>>,
}

View File

@@ -0,0 +1,136 @@
use poulpy_core::{
layouts::{
GGLWEInfos, GGSWInfos, GLWEAutomorphismKeyLayout, GLWEAutomorphismKeyPreparedFactory, GLWEInfos, GLWETensorKeyLayout,
GLWETensorKeyPreparedFactory, LWEInfos,
prepared::{GLWEAutomorphismKeyPrepared, GLWETensorKeyPrepared},
},
trace_galois_elements,
};
use std::collections::HashMap;
use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch};
use crate::tfhe::{
blind_rotation::{
BlindRotationAlgo, BlindRotationKeyInfos, BlindRotationKeyLayout, BlindRotationKeyPrepared,
BlindRotationKeyPreparedFactory,
},
circuit_bootstrapping::{CircuitBootstrappingKey, CircuitBootstrappingKeyInfos},
};
impl<BRA: BlindRotationAlgo, BE: Backend> CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, BE> {
pub fn alloc_from_infos<A, M>(module: &M, infos: &A) -> CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, BE>
where
A: CircuitBootstrappingKeyInfos,
M: CircuitBootstrappingKeyPreparedFactory<BRA, BE>,
{
module.circuit_bootstrapping_key_prepared_alloc_from_infos(infos)
}
}
impl<D: DataMut, BRA: BlindRotationAlgo, BE: Backend> CircuitBootstrappingKeyPrepared<D, BRA, BE> {
pub fn prepare<DR, M>(&mut self, module: &M, other: &CircuitBootstrappingKey<DR, BRA>, scratch: &mut Scratch<BE>)
where
DR: DataRef,
M: CircuitBootstrappingKeyPreparedFactory<BRA, BE>,
{
module.circuit_bootstrapping_key_prepare(self, other, scratch);
}
}
impl<BE: Backend, BRA: BlindRotationAlgo> CircuitBootstrappingKeyPreparedFactory<BRA, BE> for Module<BE> where
Self: Sized
+ BlindRotationKeyPreparedFactory<BRA, BE>
+ GLWETensorKeyPreparedFactory<BE>
+ GLWEAutomorphismKeyPreparedFactory<BE>
{
}
pub trait CircuitBootstrappingKeyPreparedFactory<BRA: BlindRotationAlgo, BE: Backend>
where
Self: Sized
+ BlindRotationKeyPreparedFactory<BRA, BE>
+ GLWETensorKeyPreparedFactory<BE>
+ GLWEAutomorphismKeyPreparedFactory<BE>,
{
fn circuit_bootstrapping_key_prepared_alloc_from_infos<A>(
&self,
infos: &A,
) -> CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, BE>
where
A: CircuitBootstrappingKeyInfos,
{
let atk_infos: &GLWEAutomorphismKeyLayout = &infos.atk_infos();
let gal_els: Vec<i64> = trace_galois_elements(atk_infos.log_n(), 2 * atk_infos.n().as_usize() as i64);
CircuitBootstrappingKeyPrepared {
brk: BlindRotationKeyPrepared::alloc(self, &infos.brk_infos()),
tsk: GLWETensorKeyPrepared::alloc_from_infos(self, &infos.tsk_infos()),
atk: gal_els
.iter()
.map(|&gal_el| {
let key = GLWEAutomorphismKeyPrepared::alloc_from_infos(self, atk_infos);
(gal_el, key)
})
.collect(),
}
}
fn circuit_bootstrapping_key_prepare<DM, DR>(
&self,
res: &mut CircuitBootstrappingKeyPrepared<DM, BRA, BE>,
other: &CircuitBootstrappingKey<DR, BRA>,
scratch: &mut Scratch<BE>,
) where
DM: DataMut,
DR: DataRef,
{
res.brk.prepare(self, &other.brk, scratch);
res.tsk.prepare(self, &other.tsk, scratch);
for (k, a) in res.atk.iter_mut() {
a.prepare(self, other.atk.get(k).unwrap(), scratch);
}
}
}
pub struct CircuitBootstrappingKeyPrepared<D: Data, BRA: BlindRotationAlgo, B: Backend> {
pub(crate) brk: BlindRotationKeyPrepared<D, BRA, B>,
pub(crate) tsk: GLWETensorKeyPrepared<Vec<u8>, B>,
pub(crate) atk: HashMap<i64, GLWEAutomorphismKeyPrepared<Vec<u8>, B>>,
}
impl<D: DataRef, BRA: BlindRotationAlgo, B: Backend> CircuitBootstrappingKeyInfos for CircuitBootstrappingKeyPrepared<D, BRA, B> {
fn atk_infos(&self) -> GLWEAutomorphismKeyLayout {
let (_, atk) = self.atk.iter().next().expect("atk is empty");
GLWEAutomorphismKeyLayout {
n: atk.n(),
base2k: atk.base2k(),
k: atk.k(),
dnum: atk.dnum(),
dsize: atk.dsize(),
rank: atk.rank(),
}
}
fn brk_infos(&self) -> BlindRotationKeyLayout {
BlindRotationKeyLayout {
n_glwe: self.brk.n_glwe(),
n_lwe: self.brk.n_lwe(),
base2k: self.brk.base2k(),
k: self.brk.k(),
dnum: self.brk.dnum(),
rank: self.brk.rank(),
}
}
fn tsk_infos(&self) -> GLWETensorKeyLayout {
GLWETensorKeyLayout {
n: self.tsk.n(),
base2k: self.tsk.base2k(),
k: self.tsk.k(),
dnum: self.tsk.dnum(),
dsize: self.tsk.dsize(),
rank: self.tsk.rank(),
}
}
}

View File

@@ -1,36 +1,12 @@
mod circuit;
mod key;
mod key_compressed;
mod key_prepared;
//[cfg(tests)]
//pub mod tests;
#[cfg(test)]
pub mod tests;
pub use circuit::*;
pub use key::*;
use poulpy_core::layouts::{GGSW, LWE};
use poulpy_hal::layouts::{Backend, DataMut, DataRef, Module, Scratch};
pub trait CirtuitBootstrappingExecute<B: Backend> {
fn execute_to_constant<DM: DataMut, DR: DataRef>(
&self,
module: &Module<B>,
res: &mut GGSW<DM>,
lwe: &LWE<DR>,
log_domain: usize,
extension_factor: usize,
scratch: &mut Scratch<B>,
);
#[allow(clippy::too_many_arguments)]
fn execute_to_exponent<DM: DataMut, DR: DataRef>(
&self,
module: &Module<B>,
log_gap_out: usize,
res: &mut GGSW<DM>,
lwe: &LWE<DR>,
log_domain: usize,
extension_factor: usize,
scratch: &mut Scratch<B>,
);
}
// pub use key_compressed::*;
pub use key_prepared::*;

View File

@@ -1,108 +1,49 @@
use std::time::Instant;
use poulpy_hal::{
api::{
ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf,
SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxAutomorphismInplace,
VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigAlloc, VecZnxBigAutomorphismInplace, VecZnxBigBytesOf,
VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxBigSubSmallNegateInplace, VecZnxCopy, VecZnxDftAddInplace,
VecZnxDftAlloc, VecZnxDftApply, VecZnxDftBytesOf, VecZnxDftCopy, VecZnxFillUniform, VecZnxIdftApplyConsume,
VecZnxIdftApplyTmpA, VecZnxNegateInplace, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxRotate,
VecZnxRotateInplace, VecZnxRotateInplaceTmpBytes, VecZnxRshInplace, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPMatAlloc, VmpPrepare, ZnAddNormal, ZnFillUniform,
ZnNormalizeInplace,
},
layouts::{Backend, Module, ScalarZnx, ScratchOwned, ZnxView, ZnxViewMut},
oep::{
ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeMatZnxImpl, TakeScalarZnxImpl, TakeSliceImpl,
TakeSvpPPolImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxDftSliceImpl, TakeVecZnxImpl, TakeVecZnxSliceImpl,
},
api::{ModuleN, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxRotateInplace},
layouts::{Backend, ScalarZnx, Scratch, ScratchOwned, ZnxView, ZnxViewMut},
source::Source,
};
use crate::tfhe::{
blind_rotation::{
BlincRotationExecute, BlindRotationAlgo, BlindRotationKey, BlindRotationKeyAlloc, BlindRotationKeyEncryptSk,
BlindRotationKeyLayout, BlindRotationKeyPrepared,
},
blind_rotation::{BlindRotationAlgo, BlindRotationKey, BlindRotationKeyFactory, BlindRotationKeyLayout},
circuit_bootstrapping::{
CircuitBootstrappingKey, CircuitBootstrappingKeyEncryptSk, CircuitBootstrappingKeyLayout,
CircuitBootstrappingKeyPrepared, CirtuitBootstrappingExecute,
CircuitBootstrappingKeyPrepared, CircuitBootstrappingKeyPreparedFactory, CirtuitBootstrappingExecute,
},
};
use poulpy_core::layouts::{AutomorphismKeyLayout, Dsize, GGSWLayout, LWELayout, TensorKeyLayout, prepared::PrepareAlloc};
use poulpy_core::{
GGSWNoise, GLWEDecrypt, GLWEEncryptSk, GLWEExternalProduct, LWEEncryptSk, ScratchTakeCore,
layouts::{
Dsize, GGSWLayout, GGSWPreparedFactory, GLWEAutomorphismKeyLayout, GLWESecretPreparedFactory, GLWETensorKeyLayout,
LWELayout,
},
};
use poulpy_core::layouts::{
GGSW, GLWE, GLWEPlaintext, GLWESecret, LWE, LWEPlaintext, LWESecret,
prepared::{GGSWPrepared, GLWESecretPrepared},
};
pub fn test_circuit_bootstrapping_to_exponent<B, BRA: BlindRotationAlgo>(module: &Module<B>)
pub fn test_circuit_bootstrapping_to_exponent<BE: Backend, M, BRA: BlindRotationAlgo>(module: &M)
where
Module<B>: VecZnxFillUniform
+ VecZnxAddNormal
+ VecZnxNormalizeInplace<B>
+ VecZnxDftBytesOf
+ VecZnxBigNormalize<B>
+ VecZnxDftApply<B>
+ SvpApplyDftToDftInplace<B>
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalize<B>
+ VecZnxSub
+ VecZnxAddScalarInplace
+ VecZnxAutomorphism
+ VecZnxSwitchRing
+ VecZnxBigBytesOf
+ VecZnxIdftApplyTmpA<B>
+ SvpApplyDftToDft<B>
+ VecZnxBigAddInplace<B>
+ VecZnxBigAddSmallInplace<B>
+ VecZnxBigAlloc<B>
+ VecZnxDftAlloc<B>
+ VecZnxBigNormalizeTmpBytes
+ VmpPMatAlloc<B>
+ VmpPrepare<B>
+ SvpPrepare<B>
+ SvpPPolAlloc<B>
+ VmpApplyDftToDftTmpBytes
+ VmpApplyDftToDft<B>
+ VmpApplyDftToDftAdd<B>
+ SvpPPolBytesOf
+ VecZnxRotateInplace<B>
+ VecZnxBigAutomorphismInplace<B>
+ VecZnxRshInplace<B>
+ VecZnxDftCopy<B>
+ VecZnxNegateInplace
+ VecZnxCopy
+ VecZnxAutomorphismInplace<B>
+ VecZnxBigSubSmallNegateInplace<B>
+ VecZnxRotateInplaceTmpBytes
+ VecZnxBigBytesOf
+ VecZnxDftAddInplace<B>
+ VecZnxRotate
+ ZnFillUniform
+ ZnAddNormal
+ ZnNormalizeInplace<B>,
B: Backend
+ ScratchOwnedAllocImpl<B>
+ ScratchOwnedBorrowImpl<B>
+ TakeVecZnxDftImpl<B>
+ ScratchAvailableImpl<B>
+ TakeVecZnxImpl<B>
+ TakeScalarZnxImpl<B>
+ TakeSvpPPolImpl<B>
+ TakeVecZnxBigImpl<B>
+ TakeVecZnxDftSliceImpl<B>
+ TakeMatZnxImpl<B>
+ TakeVecZnxSliceImpl<B>
+ TakeSliceImpl<B>,
BlindRotationKey<Vec<u8>, BRA>: PrepareAlloc<B, BlindRotationKeyPrepared<Vec<u8>, BRA, B>>,
BlindRotationKeyPrepared<Vec<u8>, BRA, B>: BlincRotationExecute<B>,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<B>,
M: ModuleN
+ GLWESecretPreparedFactory<BE>
+ GLWEExternalProduct<BE>
+ GLWEDecrypt<BE>
+ LWEEncryptSk<BE>
+ CircuitBootstrappingKeyEncryptSk<BRA, BE>
+ CircuitBootstrappingKeyPreparedFactory<BRA, BE>
+ CirtuitBootstrappingExecute<BRA, BE>
+ GGSWPreparedFactory<BE>
+ GGSWNoise<BE>
+ GLWEEncryptSk<BE>
+ VecZnxRotateInplace<BE>,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>, // TODO find a way to remove this bound or move it to CBT KEY
ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
let n_glwe: usize = module.n();
let base2k: usize = 17;
@@ -141,7 +82,7 @@ where
dnum: rows_brk.into(),
rank: rank.into(),
},
layout_atk: AutomorphismKeyLayout {
layout_atk: GLWEAutomorphismKeyLayout {
n: n_glwe.into(),
base2k: base2k.into(),
k: k_atk.into(),
@@ -149,7 +90,7 @@ where
rank: rank.into(),
dsize: Dsize(1),
},
layout_tsk: TensorKeyLayout {
layout_tsk: GLWETensorKeyLayout {
n: n_glwe.into(),
base2k: base2k.into(),
k: k_tsk.into(),
@@ -168,7 +109,7 @@ where
rank: rank.into(),
};
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(1 << 23);
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 23);
let mut source_xs: Source = Source::new([1u8; 32]);
let mut source_xa: Source = Source::new([1u8; 32]);
@@ -180,7 +121,8 @@ where
let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc(n_glwe.into(), rank.into());
sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch.borrow());
let mut sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank.into());
sk_glwe_prepared.prepare(module, &sk_glwe);
let data: i64 = 1;
@@ -193,22 +135,27 @@ where
ct_lwe.encrypt_sk(module, &pt_lwe, &sk_lwe, &mut source_xa, &mut source_xe);
let now: Instant = Instant::now();
let cbt_key: CircuitBootstrappingKey<Vec<u8>, BRA> = CircuitBootstrappingKey::encrypt_sk(
let mut cbt_key: CircuitBootstrappingKey<Vec<u8>, BRA> = CircuitBootstrappingKey::alloc_from_infos(&cbt_infos);
println!("CBT-ALLOC: {} ms", now.elapsed().as_millis());
let now: Instant = Instant::now();
cbt_key.encrypt_sk(
module,
&sk_lwe,
&sk_glwe,
&cbt_infos,
&mut source_xa,
&mut source_xe,
scratch.borrow(),
);
println!("CBT-KGEN: {} ms", now.elapsed().as_millis());
println!("CBT-ENCRYPT: {} ms", now.elapsed().as_millis());
let mut res: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&ggsw_infos);
let log_gap_out = 1;
let cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B> = cbt_key.prepare_alloc(module, scratch.borrow());
let mut cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, BE> =
CircuitBootstrappingKeyPrepared::alloc_from_infos(module, &cbt_infos);
cbt_prepared.prepare(module, &cbt_key, scratch.borrow());
let now: Instant = Instant::now();
cbt_prepared.execute_to_exponent(
@@ -247,7 +194,8 @@ where
scratch.borrow(),
);
let res_prepared: GGSWPrepared<Vec<u8>, B> = res.prepare_alloc(module, scratch.borrow());
let mut res_prepared: GGSWPrepared<Vec<u8>, BE> = GGSWPrepared::alloc_from_infos(module, &res);
res_prepared.prepare(module, &res, scratch.borrow());
ct_glwe.external_product_inplace(module, &res_prepared, scratch.borrow());
@@ -260,71 +208,23 @@ where
assert_eq!(pt_res.data.at(0, 0), pt_want);
}
pub fn test_circuit_bootstrapping_to_constant<B, BRA: BlindRotationAlgo>(module: &Module<B>)
pub fn test_circuit_bootstrapping_to_constant<BE: Backend, M, BRA: BlindRotationAlgo>(module: &M)
where
Module<B>: VecZnxFillUniform
+ VecZnxAddNormal
+ VecZnxNormalizeInplace<B>
+ VecZnxDftBytesOf
+ VecZnxBigNormalize<B>
+ VecZnxDftApply<B>
+ SvpApplyDftToDftInplace<B>
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalize<B>
+ VecZnxSub
+ VecZnxAddScalarInplace
+ VecZnxAutomorphism
+ VecZnxSwitchRing
+ VecZnxBigBytesOf
+ VecZnxIdftApplyTmpA<B>
+ SvpApplyDftToDft<B>
+ VecZnxBigAddInplace<B>
+ VecZnxBigAddSmallInplace<B>
+ VecZnxBigAlloc<B>
+ VecZnxDftAlloc<B>
+ VecZnxBigNormalizeTmpBytes
+ VmpPMatAlloc<B>
+ VmpPrepare<B>
+ SvpPrepare<B>
+ SvpPPolAlloc<B>
+ VmpApplyDftToDftTmpBytes
+ VmpApplyDftToDft<B>
+ VmpApplyDftToDftAdd<B>
+ SvpPPolBytesOf
+ VecZnxRotateInplace<B>
+ VecZnxBigAutomorphismInplace<B>
+ VecZnxRotateInplaceTmpBytes
+ VecZnxRshInplace<B>
+ VecZnxDftCopy<B>
+ VecZnxNegateInplace
+ VecZnxCopy
+ VecZnxAutomorphismInplace<B>
+ VecZnxBigSubSmallNegateInplace<B>
+ VecZnxBigBytesOf
+ VecZnxDftAddInplace<B>
+ VecZnxRotate
+ ZnFillUniform
+ ZnAddNormal
+ ZnNormalizeInplace<B>,
B: Backend
+ ScratchOwnedAllocImpl<B>
+ ScratchOwnedBorrowImpl<B>
+ TakeVecZnxDftImpl<B>
+ ScratchAvailableImpl<B>
+ TakeVecZnxImpl<B>
+ TakeScalarZnxImpl<B>
+ TakeSvpPPolImpl<B>
+ TakeVecZnxBigImpl<B>
+ TakeVecZnxDftSliceImpl<B>
+ TakeMatZnxImpl<B>
+ TakeVecZnxSliceImpl<B>
+ TakeSliceImpl<B>,
BlindRotationKey<Vec<u8>, BRA>: PrepareAlloc<B, BlindRotationKeyPrepared<Vec<u8>, BRA, B>>,
BlindRotationKeyPrepared<Vec<u8>, BRA, B>: BlincRotationExecute<B>,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<B>,
M: ModuleN
+ GLWESecretPreparedFactory<BE>
+ GLWEExternalProduct<BE>
+ GLWEDecrypt<BE>
+ LWEEncryptSk<BE>
+ CircuitBootstrappingKeyEncryptSk<BRA, BE>
+ CircuitBootstrappingKeyPreparedFactory<BRA, BE>
+ CirtuitBootstrappingExecute<BRA, BE>
+ GGSWPreparedFactory<BE>
+ GGSWNoise<BE>
+ GLWEEncryptSk<BE>
+ VecZnxRotateInplace<BE>,
BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>, // TODO find a way to remove this bound or move it to CBT KEY
ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
let n_glwe: usize = module.n();
let base2k: usize = 14;
@@ -363,7 +263,7 @@ where
dnum: rows_brk.into(),
rank: rank.into(),
},
layout_atk: AutomorphismKeyLayout {
layout_atk: GLWEAutomorphismKeyLayout {
n: n_glwe.into(),
base2k: base2k.into(),
k: k_atk.into(),
@@ -371,7 +271,7 @@ where
rank: rank.into(),
dsize: Dsize(1),
},
layout_tsk: TensorKeyLayout {
layout_tsk: GLWETensorKeyLayout {
n: n_glwe.into(),
base2k: base2k.into(),
k: k_tsk.into(),
@@ -390,7 +290,7 @@ where
rank: rank.into(),
};
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(1 << 23);
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 23);
let mut source_xs: Source = Source::new([1u8; 32]);
let mut source_xa: Source = Source::new([1u8; 32]);
@@ -402,7 +302,8 @@ where
let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc(n_glwe.into(), rank.into());
sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch.borrow());
let mut sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank.into());
sk_glwe_prepared.prepare(module, &sk_glwe);
let data: i64 = 1;
@@ -415,20 +316,25 @@ where
ct_lwe.encrypt_sk(module, &pt_lwe, &sk_lwe, &mut source_xa, &mut source_xe);
let now: Instant = Instant::now();
let cbt_key: CircuitBootstrappingKey<Vec<u8>, BRA> = CircuitBootstrappingKey::encrypt_sk(
let mut cbt_key: CircuitBootstrappingKey<Vec<u8>, BRA> = CircuitBootstrappingKey::alloc_from_infos(&cbt_infos);
println!("CBT-ALLOC: {} ms", now.elapsed().as_millis());
let now: Instant = Instant::now();
cbt_key.encrypt_sk(
module,
&sk_lwe,
&sk_glwe,
&cbt_infos,
&mut source_xa,
&mut source_xe,
scratch.borrow(),
);
println!("CBT-KGEN: {} ms", now.elapsed().as_millis());
println!("CBT-ENCRYPT: {} ms", now.elapsed().as_millis());
let mut res: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&ggsw_infos);
let cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B> = cbt_key.prepare_alloc(module, scratch.borrow());
let mut cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, BE> =
CircuitBootstrappingKeyPrepared::alloc_from_infos(module, &cbt_infos);
cbt_prepared.prepare(module, &cbt_key, scratch.borrow());
let now: Instant = Instant::now();
cbt_prepared.execute_to_constant(
@@ -460,7 +366,8 @@ where
scratch.borrow(),
);
let res_prepared: GGSWPrepared<Vec<u8>, B> = res.prepare_alloc(module, scratch.borrow());
let mut res_prepared: GGSWPrepared<Vec<u8>, BE> = GGSWPrepared::alloc_from_infos(module, &res);
res_prepared.prepare(module, &res, scratch.borrow());
ct_glwe.external_product_inplace(module, &res_prepared, scratch.borrow());

View File

@@ -0,0 +1,21 @@
use poulpy_backend::cpu_fft64_ref::FFT64Ref;
use poulpy_hal::{api::ModuleNew, layouts::Module};
use crate::tfhe::{
blind_rotation::CGGI,
circuit_bootstrapping::tests::circuit_bootstrapping::{
test_circuit_bootstrapping_to_constant, test_circuit_bootstrapping_to_exponent,
},
};
#[test]
fn test_to_constant_cggi() {
let module: Module<FFT64Ref> = Module::<FFT64Ref>::new(256);
test_circuit_bootstrapping_to_constant::<FFT64Ref, _, CGGI>(&module);
}
#[test]
fn test_to_exponent_cggi() {
let module: Module<FFT64Ref> = Module::<FFT64Ref>::new(256);
test_circuit_bootstrapping_to_exponent::<FFT64Ref, _, CGGI>(&module);
}

View File

@@ -1,21 +0,0 @@
use poulpy_backend::cpu_spqlios::FFT64Spqlios;
use poulpy_hal::{api::ModuleNew, layouts::Module};
use crate::tfhe::{
blind_rotation::CGGI,
circuit_bootstrapping::tests::circuit_bootstrapping::{
test_circuit_bootstrapping_to_constant, test_circuit_bootstrapping_to_exponent,
},
};
#[test]
fn test_to_constant() {
let module: Module<FFT64Spqlios> = Module::<FFT64Spqlios>::new(256);
test_circuit_bootstrapping_to_constant::<FFT64Spqlios, CGGI>(&module);
}
#[test]
fn test_to_exponent() {
let module: Module<FFT64Spqlios> = Module::<FFT64Spqlios>::new(256);
test_circuit_bootstrapping_to_exponent::<FFT64Spqlios, CGGI>(&module);
}

View File

@@ -1,3 +1,3 @@
pub mod circuit_bootstrapping;
mod implementation;
mod fft64;

View File

@@ -1,3 +1,3 @@
// pub mod bdd_arithmetic;
pub mod blind_rotation;
//pub mod circuit_bootstrapping;
pub mod circuit_bootstrapping;