mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-09 15:41:30 +01:00
impl user facing Encryptor, Decrytor, KeySwitch, SampleExtract for FheBools
This commit is contained in:
@@ -229,7 +229,7 @@ mod impl_bool_frontend {
|
|||||||
mod common_mp_enc_dec {
|
mod common_mp_enc_dec {
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use super::BoolEvaluator;
|
use super::{impl_bool_frontend::FheBool, BoolEvaluator};
|
||||||
use crate::{
|
use crate::{
|
||||||
pbs::{sample_extract, PbsInfo},
|
pbs::{sample_extract, PbsInfo},
|
||||||
utils::WithLocal,
|
utils::WithLocal,
|
||||||
@@ -238,6 +238,84 @@ mod common_mp_enc_dec {
|
|||||||
|
|
||||||
type Mat = Vec<Vec<u64>>;
|
type Mat = Vec<Vec<u64>>;
|
||||||
|
|
||||||
|
/// `Self` stores batch of boolean ciphertexts as collection of `unseeded RLWE ciphertexts` encrypted under the ideal RLWE secret key of the protocol.
|
||||||
|
///
|
||||||
|
/// Bool ciphertext at `index` can be extracted from the coefficient at `index %
|
||||||
|
/// N` of `index / N`th RLWE ciphertext.
|
||||||
|
pub(crate) struct BatchedFheBools<C> {
|
||||||
|
data: Vec<C>,
|
||||||
|
count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> BatchedFheBools<C> {
|
||||||
|
pub(crate) fn new(data: Vec<C>, count: usize) -> Self {
|
||||||
|
Self { data, count }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn data(&self) -> &[C] {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn count(&self) -> usize {
|
||||||
|
self.count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: Matrix> SampleExtractor<FheBool<M::R>> for BatchedFheBools<M>
|
||||||
|
where
|
||||||
|
M: SampleExtractor<M::R>,
|
||||||
|
{
|
||||||
|
fn extract_all(&self) -> Vec<FheBool<M::R>> {
|
||||||
|
if self.data.len() > 0 {
|
||||||
|
let ring_size = self.data[0].dimension().0;
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
let mut out = Vec::with_capacity(self.count);
|
||||||
|
|
||||||
|
while index < self.count {
|
||||||
|
let row = index % ring_size;
|
||||||
|
let col = index / ring_size;
|
||||||
|
out.push(FheBool {
|
||||||
|
data: SampleExtractor::extract_at(&self.data[col], row),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn extract_at(&self, index: usize) -> FheBool<M::R> {
|
||||||
|
assert!(self.count > index);
|
||||||
|
|
||||||
|
let ring_size = self.data[0].dimension().0;
|
||||||
|
let row = index % ring_size;
|
||||||
|
let col = index / ring_size;
|
||||||
|
|
||||||
|
FheBool {
|
||||||
|
data: SampleExtractor::extract_at(&self.data[col], row),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_many(&self, how_many: usize) -> Vec<FheBool<M::R>> {
|
||||||
|
assert!(self.count >= how_many);
|
||||||
|
let ring_size = self.data[0].dimension().0;
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
let mut out = Vec::with_capacity(self.count);
|
||||||
|
|
||||||
|
while index < how_many {
|
||||||
|
let row = index % ring_size;
|
||||||
|
let col = index / ring_size;
|
||||||
|
out.push(FheBool {
|
||||||
|
data: SampleExtractor::extract_at(&self.data[col], row),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SampleExtractor<<Mat as Matrix>::R> for Mat {
|
impl SampleExtractor<<Mat as Matrix>::R> for Mat {
|
||||||
/// Sample extract coefficient at `index` as a LWE ciphertext from RLWE
|
/// Sample extract coefficient at `index` as a LWE ciphertext from RLWE
|
||||||
/// ciphertext `Self`
|
/// ciphertext `Self`
|
||||||
|
|||||||
@@ -179,38 +179,37 @@ impl Global for RuntimeServerKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `Self::data` stores collection of seeded RLWE ciphertexts encrypted unser user j's RLWE secret `u_j`.
|
||||||
|
pub(crate) struct NonInteractiveSeededFheBools<C, S> {
|
||||||
|
data: Vec<C>,
|
||||||
|
seed: S,
|
||||||
|
count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
/// Batch of bool ciphertexts stored as vector of RLWE ciphertext under user j's
|
/// Batch of bool ciphertexts stored as vector of RLWE ciphertext under user j's
|
||||||
/// RLWE secret `u_j`
|
/// RLWE secret `u_j`
|
||||||
///
|
///
|
||||||
/// To use the bool ciphertexts in multi-party protocol first key switch the
|
/// To use the bool ciphertexts in multi-party protocol first key switch the
|
||||||
/// ciphertexts from u_j to ideal RLWE secret `s` with
|
/// ciphertexts from u_j to ideal RLWE secret `s` with
|
||||||
/// `self.key_switch(user_id)` where `user_id` is user j's id. Key switch
|
/// `self.key_switch(user_id)` where `user_id` is user j's id. Key switch
|
||||||
/// returns `BatchedFheBools` that stored key vector of key switched RLWE
|
/// returns `BatchedFheBools` which stores vector of key switched RLWE
|
||||||
/// ciphertext.
|
/// ciphertext.
|
||||||
pub struct NonInteractiveBatchedFheBools<C> {
|
pub struct NonInteractiveBatchedFheBools<C> {
|
||||||
data: Vec<C>,
|
data: Vec<C>,
|
||||||
}
|
count: usize,
|
||||||
|
|
||||||
/// Batch of Bool cipphertexts stored as vector of RLWE ciphertexts under the
|
|
||||||
/// ideal RLWE secret key `s` of the protocol
|
|
||||||
///
|
|
||||||
/// Bool ciphertext at `index` can be extracted from the coefficient at `index %
|
|
||||||
/// N` of `index / N`th RLWE ciphertext.
|
|
||||||
///
|
|
||||||
/// To extract bool ciphertext at `index` as LWE ciphertext use
|
|
||||||
/// `self.extract(index)`
|
|
||||||
pub struct BatchedFheBools<C> {
|
|
||||||
pub(in super::super) data: Vec<C>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Non interactive multi-party specfic encryptor decryptor routines
|
/// Non interactive multi-party specfic encryptor decryptor routines
|
||||||
mod impl_enc_dec {
|
mod impl_enc_dec {
|
||||||
use crate::{
|
use crate::{
|
||||||
bool::{evaluator::BoolEncoding, keys::NonInteractiveMultiPartyClientKey},
|
bool::{
|
||||||
|
common_mp_enc_dec::BatchedFheBools, evaluator::BoolEncoding,
|
||||||
|
keys::NonInteractiveMultiPartyClientKey,
|
||||||
|
},
|
||||||
multi_party::{
|
multi_party::{
|
||||||
multi_party_aggregate_decryption_shares_and_decrypt, multi_party_decryption_share,
|
multi_party_aggregate_decryption_shares_and_decrypt, multi_party_decryption_share,
|
||||||
},
|
},
|
||||||
pbs::{sample_extract, PbsInfo, WithShoupRepr},
|
pbs::{PbsInfo, WithShoupRepr},
|
||||||
random::{NewWithSeed, RandomFillUniformInModulus},
|
random::{NewWithSeed, RandomFillUniformInModulus},
|
||||||
rgsw::{rlwe_key_switch, seeded_secret_key_encrypt_rlwe},
|
rgsw::{rlwe_key_switch, seeded_secret_key_encrypt_rlwe},
|
||||||
utils::TryConvertFrom1,
|
utils::TryConvertFrom1,
|
||||||
@@ -224,82 +223,23 @@ mod impl_enc_dec {
|
|||||||
|
|
||||||
type Mat = Vec<Vec<u64>>;
|
type Mat = Vec<Vec<u64>>;
|
||||||
|
|
||||||
// Implement `extract` to extract Bool LWE ciphertext at `index` from
|
impl<C, S> NonInteractiveSeededFheBools<C, S> {
|
||||||
// `BatchedFheBools`
|
/// Unseed `Self`'s collection of RLWE ciphertexts into `NonInteractiveBatchedFheBools`
|
||||||
impl<C: MatrixMut<MatElement = u64>> BatchedFheBools<C>
|
pub fn unseed<M>(&self) -> NonInteractiveBatchedFheBools<M>
|
||||||
where
|
where
|
||||||
C::R: RowEntity + RowMut,
|
NonInteractiveBatchedFheBools<M>: for<'a> From<&'a Self>,
|
||||||
{
|
{
|
||||||
pub fn extract(&self, index: usize) -> C::R {
|
NonInteractiveBatchedFheBools::from(self)
|
||||||
BoolEvaluator::with_local(|e| {
|
|
||||||
let ring_size = e.parameters().rlwe_n().0;
|
|
||||||
let ct_index = index / ring_size;
|
|
||||||
let coeff_index = index % ring_size;
|
|
||||||
let mut lwe_out = C::R::zeros(e.parameters().rlwe_n().0 + 1);
|
|
||||||
sample_extract(
|
|
||||||
&mut lwe_out,
|
|
||||||
&self.data[ct_index],
|
|
||||||
e.pbs_info().modop_rlweq(),
|
|
||||||
coeff_index,
|
|
||||||
);
|
|
||||||
lwe_out
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: MatrixEntity + MatrixMut<MatElement = u64>> From<&(Vec<M::R>, [u8; 32])>
|
impl<C, S> From<NonInteractiveSeededFheBools<C, S>> for (Vec<C>, S) {
|
||||||
for NonInteractiveBatchedFheBools<M>
|
fn from(value: NonInteractiveSeededFheBools<C, S>) -> Self {
|
||||||
where
|
(value.data, value.seed)
|
||||||
<M as Matrix>::R: RowMut,
|
|
||||||
{
|
|
||||||
/// Derive `NonInteractiveBatchedFheBools` from a vector seeded RLWE
|
|
||||||
/// ciphertexts (Vec<RLWE>, Seed)
|
|
||||||
///
|
|
||||||
/// Unseed the RLWE ciphertexts and store them as vector RLWE
|
|
||||||
/// ciphertexts in `NonInteractiveBatchedFheBools`
|
|
||||||
fn from(value: &(Vec<M::R>, [u8; 32])) -> Self {
|
|
||||||
BoolEvaluator::with_local(|e| {
|
|
||||||
let parameters = e.parameters();
|
|
||||||
let ring_size = parameters.rlwe_n().0;
|
|
||||||
let rlwe_q = parameters.rlwe_q();
|
|
||||||
|
|
||||||
let mut prng = DefaultSecureRng::new_seeded(value.1);
|
|
||||||
let rlwes = value
|
|
||||||
.0
|
|
||||||
.iter()
|
|
||||||
.map(|partb| {
|
|
||||||
let mut rlwe = M::zeros(2, ring_size);
|
|
||||||
|
|
||||||
// sample A
|
|
||||||
RandomFillUniformInModulus::random_fill(
|
|
||||||
&mut prng,
|
|
||||||
rlwe_q,
|
|
||||||
rlwe.get_row_mut(0),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Copy over B
|
|
||||||
rlwe.get_row_mut(1).copy_from_slice(partb.as_ref());
|
|
||||||
|
|
||||||
rlwe
|
|
||||||
})
|
|
||||||
.collect_vec();
|
|
||||||
Self { data: rlwes }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K> Encryptor<[bool], NonInteractiveBatchedFheBools<Mat>> for K
|
impl<K> Encryptor<[bool], NonInteractiveSeededFheBools<<Mat as Matrix>::R, [u8; 32]>> for K
|
||||||
where
|
|
||||||
K: Encryptor<[bool], (Mat, [u8; 32])>,
|
|
||||||
{
|
|
||||||
/// Encrypt a vector bool of arbitrary length as vector of unseeded RLWE
|
|
||||||
/// ciphertexts in `NonInteractiveBatchedFheBools`
|
|
||||||
fn encrypt(&self, m: &[bool]) -> NonInteractiveBatchedFheBools<Mat> {
|
|
||||||
NonInteractiveBatchedFheBools::from(&K::encrypt(&self, m))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K> Encryptor<[bool], (Vec<<Mat as Matrix>::R>, [u8; 32])> for K
|
|
||||||
where
|
where
|
||||||
K: NonInteractiveMultiPartyClientKey,
|
K: NonInteractiveMultiPartyClientKey,
|
||||||
<Mat as Matrix>::R:
|
<Mat as Matrix>::R:
|
||||||
@@ -307,7 +247,10 @@ mod impl_enc_dec {
|
|||||||
{
|
{
|
||||||
/// Encrypt a vector of bool of arbitrary length as vector of seeded
|
/// Encrypt a vector of bool of arbitrary length as vector of seeded
|
||||||
/// RLWE ciphertexts and returns (Vec<RLWE>, Seed)
|
/// RLWE ciphertexts and returns (Vec<RLWE>, Seed)
|
||||||
fn encrypt(&self, m: &[bool]) -> (Mat, [u8; 32]) {
|
fn encrypt(
|
||||||
|
&self,
|
||||||
|
m: &[bool],
|
||||||
|
) -> NonInteractiveSeededFheBools<<Mat as Matrix>::R, [u8; 32]> {
|
||||||
BoolEvaluator::with_local(|e| {
|
BoolEvaluator::with_local(|e| {
|
||||||
DefaultSecureRng::with_local_mut(|rng| {
|
DefaultSecureRng::with_local_mut(|rng| {
|
||||||
let parameters = e.parameters();
|
let parameters = e.parameters();
|
||||||
@@ -356,46 +299,57 @@ mod impl_enc_dec {
|
|||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
(rlwes, seed)
|
NonInteractiveSeededFheBools {
|
||||||
|
data: rlwes,
|
||||||
|
seed,
|
||||||
|
count: m.len(),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K> MultiPartyDecryptor<bool, <Mat as Matrix>::R> for K
|
impl<M: MatrixEntity + MatrixMut<MatElement = u64>>
|
||||||
|
From<&NonInteractiveSeededFheBools<<Mat as Matrix>::R, [u8; 32]>>
|
||||||
|
for NonInteractiveBatchedFheBools<M>
|
||||||
where
|
where
|
||||||
K: NonInteractiveMultiPartyClientKey,
|
<M as Matrix>::R: RowMut,
|
||||||
<Mat as Matrix>::R:
|
|
||||||
TryConvertFrom1<[K::Element], CiphertextModulus<<Mat as Matrix>::MatElement>>,
|
|
||||||
{
|
{
|
||||||
type DecryptionShare = <Mat as Matrix>::MatElement;
|
/// Derive `NonInteractiveBatchedFheBools` from a vector seeded RLWE
|
||||||
|
/// ciphertexts (Vec<RLWE>, Seed)
|
||||||
fn gen_decryption_share(&self, c: &<Mat as Matrix>::R) -> Self::DecryptionShare {
|
///
|
||||||
|
/// Unseed the RLWE ciphertexts and store them as vector RLWE
|
||||||
|
/// ciphertexts in `NonInteractiveBatchedFheBools`
|
||||||
|
fn from(value: &NonInteractiveSeededFheBools<<Mat as Matrix>::R, [u8; 32]>) -> Self {
|
||||||
BoolEvaluator::with_local(|e| {
|
BoolEvaluator::with_local(|e| {
|
||||||
DefaultSecureRng::with_local_mut(|rng| {
|
let parameters = e.parameters();
|
||||||
multi_party_decryption_share(
|
let ring_size = parameters.rlwe_n().0;
|
||||||
c,
|
let rlwe_q = parameters.rlwe_q();
|
||||||
self.sk_rlwe().as_slice(),
|
|
||||||
e.pbs_info().modop_rlweq(),
|
|
||||||
rng,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn aggregate_decryption_shares(
|
let mut prng = DefaultSecureRng::new_seeded(value.seed);
|
||||||
&self,
|
let rlwes = value
|
||||||
c: &<Mat as Matrix>::R,
|
.data
|
||||||
shares: &[Self::DecryptionShare],
|
.iter()
|
||||||
) -> bool {
|
.map(|partb| {
|
||||||
BoolEvaluator::with_local(|e| {
|
let mut rlwe = M::zeros(2, ring_size);
|
||||||
let noisy_m = multi_party_aggregate_decryption_shares_and_decrypt(
|
|
||||||
c,
|
|
||||||
shares,
|
|
||||||
e.pbs_info().modop_rlweq(),
|
|
||||||
);
|
|
||||||
|
|
||||||
e.pbs_info().rlwe_q().decode(noisy_m)
|
// sample A
|
||||||
|
RandomFillUniformInModulus::random_fill(
|
||||||
|
&mut prng,
|
||||||
|
rlwe_q,
|
||||||
|
rlwe.get_row_mut(0),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy over B
|
||||||
|
rlwe.get_row_mut(1).copy_from_slice(partb.as_ref());
|
||||||
|
|
||||||
|
rlwe
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
Self {
|
||||||
|
data: rlwes,
|
||||||
|
count: value.count,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,7 +397,45 @@ mod impl_enc_dec {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|c| c.key_switch(user_id))
|
.map(|c| c.key_switch(user_id))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
BatchedFheBools { data }
|
BatchedFheBools::new(data, self.count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K> MultiPartyDecryptor<bool, <Mat as Matrix>::R> for K
|
||||||
|
where
|
||||||
|
K: NonInteractiveMultiPartyClientKey,
|
||||||
|
<Mat as Matrix>::R:
|
||||||
|
TryConvertFrom1<[K::Element], CiphertextModulus<<Mat as Matrix>::MatElement>>,
|
||||||
|
{
|
||||||
|
type DecryptionShare = <Mat as Matrix>::MatElement;
|
||||||
|
|
||||||
|
fn gen_decryption_share(&self, c: &<Mat as Matrix>::R) -> Self::DecryptionShare {
|
||||||
|
BoolEvaluator::with_local(|e| {
|
||||||
|
DefaultSecureRng::with_local_mut(|rng| {
|
||||||
|
multi_party_decryption_share(
|
||||||
|
c,
|
||||||
|
self.sk_rlwe().as_slice(),
|
||||||
|
e.pbs_info().modop_rlweq(),
|
||||||
|
rng,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aggregate_decryption_shares(
|
||||||
|
&self,
|
||||||
|
c: &<Mat as Matrix>::R,
|
||||||
|
shares: &[Self::DecryptionShare],
|
||||||
|
) -> bool {
|
||||||
|
BoolEvaluator::with_local(|e| {
|
||||||
|
let noisy_m = multi_party_aggregate_decryption_shares_and_decrypt(
|
||||||
|
c,
|
||||||
|
shares,
|
||||||
|
e.pbs_info().modop_rlweq(),
|
||||||
|
);
|
||||||
|
|
||||||
|
e.pbs_info().rlwe_q().decode(noisy_m)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -615,7 +615,6 @@ mod tests {
|
|||||||
NonInteractiveServerKeyEvaluationDomain,
|
NonInteractiveServerKeyEvaluationDomain,
|
||||||
},
|
},
|
||||||
print_noise::collect_server_key_stats,
|
print_noise::collect_server_key_stats,
|
||||||
NonInteractiveBatchedFheBools,
|
|
||||||
},
|
},
|
||||||
gen_client_key, gen_server_key_share,
|
gen_client_key, gen_server_key_share,
|
||||||
parameters::CiphertextModulus,
|
parameters::CiphertextModulus,
|
||||||
@@ -624,7 +623,7 @@ mod tests {
|
|||||||
utils::{tests::Stats, Global, WithLocal},
|
utils::{tests::Stats, Global, WithLocal},
|
||||||
BoolEvaluator, BooleanGates, DefaultDecomposer, Encoder, Encryptor, KeySwitchWithId,
|
BoolEvaluator, BooleanGates, DefaultDecomposer, Encoder, Encryptor, KeySwitchWithId,
|
||||||
ModInit, ModularOpsU64, MultiPartyDecryptor, NttBackendU64, ParameterSelector,
|
ModInit, ModularOpsU64, MultiPartyDecryptor, NttBackendU64, ParameterSelector,
|
||||||
RuntimeServerKey,
|
RuntimeServerKey, SampleExtractor,
|
||||||
};
|
};
|
||||||
|
|
||||||
set_parameter_set(ParameterSelector::NonInteractiveLTE8Party);
|
set_parameter_set(ParameterSelector::NonInteractiveLTE8Party);
|
||||||
@@ -654,14 +653,20 @@ mod tests {
|
|||||||
let mut m1 = true;
|
let mut m1 = true;
|
||||||
|
|
||||||
let mut ct0 = {
|
let mut ct0 = {
|
||||||
let ct: NonInteractiveBatchedFheBools<_> = cks[0].encrypt(vec![m0].as_slice());
|
cks[0]
|
||||||
let ct = ct.key_switch(0);
|
.encrypt(vec![m0].as_slice())
|
||||||
ct.extract(0)
|
.unseed::<Vec<Vec<u64>>>()
|
||||||
|
.key_switch(0)
|
||||||
|
.extract_at(0)
|
||||||
|
.data
|
||||||
};
|
};
|
||||||
let mut ct1 = {
|
let mut ct1 = {
|
||||||
let ct: NonInteractiveBatchedFheBools<_> = cks[1].encrypt(vec![m1].as_slice());
|
cks[1]
|
||||||
let ct = ct.key_switch(1);
|
.encrypt(vec![m1].as_slice())
|
||||||
ct.extract(0)
|
.unseed::<Vec<Vec<u64>>>()
|
||||||
|
.key_switch(1)
|
||||||
|
.extract_at(0)
|
||||||
|
.data
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut stats = Stats::new();
|
let mut stats = Stats::new();
|
||||||
@@ -830,7 +835,7 @@ mod tests {
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
aggregate_server_key_shares,
|
aggregate_server_key_shares,
|
||||||
bool::{keys::tests::ideal_sk_rlwe, ni_mp_api::NonInteractiveBatchedFheBools},
|
bool::keys::tests::ideal_sk_rlwe,
|
||||||
gen_client_key, gen_server_key_share,
|
gen_client_key, gen_server_key_share,
|
||||||
rgsw::decrypt_rlwe,
|
rgsw::decrypt_rlwe,
|
||||||
set_common_reference_seed, set_parameter_set,
|
set_common_reference_seed, set_parameter_set,
|
||||||
@@ -862,8 +867,11 @@ mod tests {
|
|||||||
let m = (0..parameters.rlwe_n().0)
|
let m = (0..parameters.rlwe_n().0)
|
||||||
.map(|_| thread_rng().gen_bool(0.5))
|
.map(|_| thread_rng().gen_bool(0.5))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
let ct: NonInteractiveBatchedFheBools<_> = cks[0].encrypt(m.as_slice());
|
let ct = cks[0]
|
||||||
let ct = ct.key_switch(0);
|
.encrypt(m.as_slice())
|
||||||
|
.unseed::<Vec<Vec<u64>>>()
|
||||||
|
.key_switch(0);
|
||||||
|
assert!(ct.data().len() == 1);
|
||||||
|
|
||||||
let ideal_rlwe_sk = ideal_sk_rlwe(&cks);
|
let ideal_rlwe_sk = ideal_sk_rlwe(&cks);
|
||||||
|
|
||||||
@@ -874,7 +882,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut m_out = vec![0u64; parameters.rlwe_n().0];
|
let mut m_out = vec![0u64; parameters.rlwe_n().0];
|
||||||
decrypt_rlwe(
|
decrypt_rlwe(
|
||||||
&ct.data[0],
|
&ct.data()[0],
|
||||||
&ideal_rlwe_sk,
|
&ideal_rlwe_sk,
|
||||||
&mut m_out,
|
&mut m_out,
|
||||||
&nttop,
|
&nttop,
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ pub trait Matrix: AsRef<[Self::R]> {
|
|||||||
type MatElement;
|
type MatElement;
|
||||||
type R: Row<Element = Self::MatElement>;
|
type R: Row<Element = Self::MatElement>;
|
||||||
|
|
||||||
|
/// (Rows, Cols)
|
||||||
fn dimension(&self) -> (usize, usize);
|
fn dimension(&self) -> (usize, usize);
|
||||||
|
|
||||||
fn get_row(&self, row_idx: usize) -> impl Iterator<Item = &Self::MatElement> {
|
fn get_row(&self, row_idx: usize) -> impl Iterator<Item = &Self::MatElement> {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ impl<M: MatrixEntity + MatrixMut<MatElement = u64>> From<&SeededBatchedFheUint8<
|
|||||||
where
|
where
|
||||||
<M as Matrix>::R: RowMut,
|
<M as Matrix>::R: RowMut,
|
||||||
{
|
{
|
||||||
/// Unseeds collection of seeded RLWE ciphertext in SeededBatchedFheUint8
|
/// Unseeds collection of seeded RLWE ciphertext in `SeededBatchedFheUint8`
|
||||||
/// and returns as `Self`
|
/// and returns as `Self`
|
||||||
fn from(value: &SeededBatchedFheUint8<M::R, [u8; 32]>) -> Self {
|
fn from(value: &SeededBatchedFheUint8<M::R, [u8; 32]>) -> Self {
|
||||||
BoolEvaluator::with_local(|e| {
|
BoolEvaluator::with_local(|e| {
|
||||||
@@ -237,9 +237,10 @@ pub struct SeededBatchedFheUint8<C, S> {
|
|||||||
count: usize,
|
count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "non_interactive_mp")]
|
||||||
impl<K, C, S> Encryptor<[u8], SeededBatchedFheUint8<C, S>> for K
|
impl<K, C, S> Encryptor<[u8], SeededBatchedFheUint8<C, S>> for K
|
||||||
where
|
where
|
||||||
K: Encryptor<[bool], (Vec<C>, S)>,
|
K: Encryptor<[bool], crate::NonInteractiveSeededFheBools<C, S>>,
|
||||||
{
|
{
|
||||||
/// Encrypt a slice of u8s of arbitray length packed into collection of
|
/// Encrypt a slice of u8s of arbitray length packed into collection of
|
||||||
/// seeded RLWE ciphertexts and return `SeededBatchedFheUint8`
|
/// seeded RLWE ciphertexts and return `SeededBatchedFheUint8`
|
||||||
@@ -249,7 +250,7 @@ where
|
|||||||
.iter()
|
.iter()
|
||||||
.flat_map(|v| (0..8).into_iter().map(|i| (((*v) >> i) & 1) == 1))
|
.flat_map(|v| (0..8).into_iter().map(|i| (((*v) >> i) & 1) == 1))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
let (cts, seed) = K::encrypt(&self, &bool_m);
|
let (cts, seed): (Vec<C>, S) = K::encrypt(&self, &bool_m).into();
|
||||||
SeededBatchedFheUint8 {
|
SeededBatchedFheUint8 {
|
||||||
data: cts,
|
data: cts,
|
||||||
seed,
|
seed,
|
||||||
|
|||||||
Reference in New Issue
Block a user