mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-11 16:41:29 +01:00
make enc and dec variant specific
This commit is contained in:
File diff suppressed because it is too large
Load Diff
184
src/bool/keys.rs
184
src/bool/keys.rs
@@ -10,112 +10,130 @@ use crate::{
|
||||
Decryptor, Encryptor, Matrix, MatrixEntity, MatrixMut, MultiPartyDecryptor, RowEntity, RowMut,
|
||||
};
|
||||
|
||||
use super::{parameters, BoolEvaluator, BoolParameters, CiphertextModulus};
|
||||
use super::{
|
||||
evaluator::BoolEvaluator,
|
||||
parameters::{BoolParameters, CiphertextModulus},
|
||||
};
|
||||
|
||||
trait SinglePartyClientKey {
|
||||
pub(crate) trait SinglePartyClientKey {
|
||||
type Element;
|
||||
fn sk_rlwe(&self) -> &[Self::Element];
|
||||
fn sk_lwe(&self) -> &[Self::Element];
|
||||
fn sk_rlwe(&self) -> Vec<Self::Element>;
|
||||
fn sk_lwe(&self) -> Vec<Self::Element>;
|
||||
}
|
||||
|
||||
trait InteractiveMultiPartyClientKey {
|
||||
pub(crate) trait InteractiveMultiPartyClientKey {
|
||||
type Element;
|
||||
fn sk_rlwe(&self) -> &[Self::Element];
|
||||
fn sk_lwe(&self) -> &[Self::Element];
|
||||
fn sk_rlwe(&self) -> Vec<Self::Element>;
|
||||
fn sk_lwe(&self) -> Vec<Self::Element>;
|
||||
}
|
||||
|
||||
trait NonInteractiveMultiPartyClientKey {
|
||||
pub(crate) trait NonInteractiveMultiPartyClientKey {
|
||||
type Element;
|
||||
fn sk_rlwe(&self) -> &[Self::Element];
|
||||
fn sk_u_rlwe(&self) -> &[Self::Element];
|
||||
fn sk_lwe(&self) -> &[Self::Element];
|
||||
fn sk_rlwe(&self) -> Vec<Self::Element>;
|
||||
fn sk_u_rlwe(&self) -> Vec<Self::Element>;
|
||||
fn sk_lwe(&self) -> Vec<Self::Element>;
|
||||
}
|
||||
|
||||
/// Client key with RLWE and LWE secrets
|
||||
/// Client key
|
||||
///
|
||||
/// Key is used for all parameter varians - Single party, interactive
|
||||
/// multi-party, and non-interactive multi-party. The only stored the main seed
|
||||
/// and seeds of the Rlwe/Lwe secrets are derived at puncturing the seed desired
|
||||
/// number of times.
|
||||
///
|
||||
/// ### Punctures required:
|
||||
///
|
||||
/// Puncture 1 -> Seed of RLWE secret used as main RLWE secret for
|
||||
/// single-party, interactive/non-interactive multi-party
|
||||
///
|
||||
/// Puncture 2 -> Seed of LWE secret used main LWE secret for single-party,
|
||||
/// interactive/non-interactive multi-party
|
||||
///
|
||||
/// Puncture 3 -> Seed of RLWE secret used as `u` in
|
||||
/// interactive/non-interactive multi-party.
|
||||
#[derive(Clone)]
|
||||
pub struct ClientKey {
|
||||
sk_rlwe: RlweSecret,
|
||||
sk_lwe: LweSecret,
|
||||
}
|
||||
|
||||
/// Client key with RLWE and LWE secrets
|
||||
#[derive(Clone)]
|
||||
pub struct ThrowMeAwayKey {
|
||||
sk_rlwe: RlweSecret,
|
||||
sk_u_rlwe: RlweSecret,
|
||||
sk_lwe: LweSecret,
|
||||
pub struct ClientKey<S, E> {
|
||||
seed: S,
|
||||
parameters: BoolParameters<E>,
|
||||
}
|
||||
|
||||
mod impl_ck {
|
||||
use crate::{
|
||||
random::DefaultSecureRng,
|
||||
utils::{fill_random_ternary_secret_with_hamming_weight, puncture_p_rng},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
// Client key
|
||||
impl ClientKey {
|
||||
pub(in super::super) fn new(sk_rlwe: RlweSecret, sk_lwe: LweSecret) -> Self {
|
||||
Self { sk_rlwe, sk_lwe }
|
||||
}
|
||||
|
||||
pub(in super::super) fn sk_rlwe(&self) -> &RlweSecret {
|
||||
&self.sk_rlwe
|
||||
}
|
||||
|
||||
pub(in super::super) fn sk_lwe(&self) -> &LweSecret {
|
||||
&self.sk_lwe
|
||||
impl<E> ClientKey<[u8; 32], E> {
|
||||
pub(in super::super) fn new(parameters: BoolParameters<E>) -> ClientKey<[u8; 32], E> {
|
||||
let mut rng = DefaultSecureRng::new();
|
||||
let mut seed = [0u8; 32];
|
||||
rng.fill_bytes(&mut seed);
|
||||
Self { seed, parameters }
|
||||
}
|
||||
}
|
||||
|
||||
// Client key
|
||||
impl ThrowMeAwayKey {
|
||||
pub(in super::super) fn new(
|
||||
sk_rlwe: RlweSecret,
|
||||
sk_u_rlwe: RlweSecret,
|
||||
sk_lwe: LweSecret,
|
||||
) -> Self {
|
||||
Self {
|
||||
sk_rlwe,
|
||||
sk_u_rlwe,
|
||||
sk_lwe,
|
||||
}
|
||||
}
|
||||
impl<E> SinglePartyClientKey for ClientKey<[u8; 32], E> {
|
||||
type Element = i32;
|
||||
fn sk_lwe(&self) -> Vec<Self::Element> {
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(self.seed);
|
||||
let lwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 2);
|
||||
|
||||
pub(in super::super) fn sk_rlwe(&self) -> &RlweSecret {
|
||||
&self.sk_rlwe
|
||||
let mut lwe_prng = DefaultSecureRng::new_seeded(lwe_seed);
|
||||
let mut out = vec![0i32; self.parameters.lwe_n().0];
|
||||
fill_random_ternary_secret_with_hamming_weight(
|
||||
&mut out,
|
||||
self.parameters.lwe_n().0 >> 1,
|
||||
&mut lwe_prng,
|
||||
);
|
||||
out
|
||||
}
|
||||
fn sk_rlwe(&self) -> Vec<Self::Element> {
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(self.seed);
|
||||
let rlwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 1);
|
||||
|
||||
pub(in super::super) fn sk_u_rlwe(&self) -> &RlweSecret {
|
||||
&self.sk_u_rlwe
|
||||
}
|
||||
|
||||
pub(in super::super) fn sk_lwe(&self) -> &LweSecret {
|
||||
&self.sk_lwe
|
||||
let mut rlwe_prng = DefaultSecureRng::new_seeded(rlwe_seed);
|
||||
let mut out = vec![0i32; self.parameters.rlwe_n().0];
|
||||
fill_random_ternary_secret_with_hamming_weight(
|
||||
&mut out,
|
||||
self.parameters.rlwe_n().0 >> 1,
|
||||
&mut rlwe_prng,
|
||||
);
|
||||
out
|
||||
}
|
||||
}
|
||||
|
||||
impl Encryptor<bool, Vec<u64>> for ClientKey {
|
||||
fn encrypt(&self, m: &bool) -> Vec<u64> {
|
||||
BoolEvaluator::with_local(|e| e.sk_encrypt(*m, self))
|
||||
impl<E> InteractiveMultiPartyClientKey for ClientKey<[u8; 32], E> {
|
||||
type Element = i32;
|
||||
fn sk_lwe(&self) -> Vec<Self::Element> {
|
||||
<Self as SinglePartyClientKey>::sk_lwe(&self)
|
||||
}
|
||||
fn sk_rlwe(&self) -> Vec<Self::Element> {
|
||||
<Self as SinglePartyClientKey>::sk_rlwe(&self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decryptor<bool, Vec<u64>> for ClientKey {
|
||||
fn decrypt(&self, c: &Vec<u64>) -> bool {
|
||||
BoolEvaluator::with_local(|e| e.sk_decrypt(c, self))
|
||||
impl<E> NonInteractiveMultiPartyClientKey for ClientKey<[u8; 32], E> {
|
||||
type Element = i32;
|
||||
fn sk_lwe(&self) -> Vec<Self::Element> {
|
||||
<Self as SinglePartyClientKey>::sk_lwe(&self)
|
||||
}
|
||||
}
|
||||
|
||||
impl MultiPartyDecryptor<bool, Vec<u64>> for ClientKey {
|
||||
type DecryptionShare = u64;
|
||||
|
||||
fn gen_decryption_share(&self, c: &Vec<u64>) -> Self::DecryptionShare {
|
||||
BoolEvaluator::with_local(|e| e.multi_party_decryption_share(c, &self))
|
||||
fn sk_rlwe(&self) -> Vec<Self::Element> {
|
||||
<Self as SinglePartyClientKey>::sk_rlwe(&self)
|
||||
}
|
||||
fn sk_u_rlwe(&self) -> Vec<Self::Element> {
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(self.seed);
|
||||
let rlwe_seed = puncture_p_rng::<[u8; 32], DefaultSecureRng>(&mut p_rng, 3);
|
||||
|
||||
fn aggregate_decryption_shares(
|
||||
&self,
|
||||
c: &Vec<u64>,
|
||||
shares: &[Self::DecryptionShare],
|
||||
) -> bool {
|
||||
BoolEvaluator::with_local(|e| e.multi_party_decrypt(shares, c))
|
||||
let mut rlwe_prng = DefaultSecureRng::new_seeded(rlwe_seed);
|
||||
let mut out = vec![0i32; self.parameters.rlwe_n().0];
|
||||
fill_random_ternary_secret_with_hamming_weight(
|
||||
&mut out,
|
||||
self.parameters.rlwe_n().0 >> 1,
|
||||
&mut rlwe_prng,
|
||||
);
|
||||
out
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,18 +153,6 @@ pub(super) mod impl_pk {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Rng, ModOp> Encryptor<bool, Vec<u64>> for PublicKey<Vec<Vec<u64>>, Rng, ModOp> {
|
||||
fn encrypt(&self, m: &bool) -> Vec<u64> {
|
||||
BoolEvaluator::with_local(|e| e.pk_encrypt(&self.key, *m))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Rng, ModOp> Encryptor<[bool], Vec<Vec<u64>>> for PublicKey<Vec<Vec<u64>>, Rng, ModOp> {
|
||||
fn encrypt(&self, m: &[bool]) -> Vec<Vec<u64>> {
|
||||
BoolEvaluator::with_local(|e| e.pk_encrypt_batched(&self.key, m))
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
M: MatrixMut + MatrixEntity,
|
||||
Rng: NewWithSeed
|
||||
@@ -456,8 +462,6 @@ pub(super) mod impl_server_key_eval_domain {
|
||||
use itertools::{izip, Itertools};
|
||||
|
||||
use crate::{
|
||||
backend::Modulus,
|
||||
bool::{NonInteractiveMultiPartyCrs, SeededNonInteractiveMultiPartyServerKey},
|
||||
ntt::{Ntt, NttInit},
|
||||
pbs::PbsKey,
|
||||
};
|
||||
@@ -736,7 +740,7 @@ pub(crate) struct NonInteractiveServerKeyEvaluationDomain<M, P, R, N> {
|
||||
pub(super) mod impl_non_interactive_server_key_eval_domain {
|
||||
use itertools::{izip, Itertools};
|
||||
|
||||
use crate::{bool::NonInteractiveMultiPartyCrs, random::RandomFill, Ntt, NttInit};
|
||||
use crate::{bool::evaluator::NonInteractiveMultiPartyCrs, random::RandomFill, Ntt, NttInit};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
pub(crate) mod evaluator;
|
||||
pub(crate) mod keys;
|
||||
mod keys;
|
||||
mod mp_api;
|
||||
mod ni_mp_api;
|
||||
mod noise;
|
||||
pub(crate) mod parameters;
|
||||
|
||||
pub use mp_api::*;
|
||||
pub(crate) use keys::PublicKey;
|
||||
|
||||
pub type FheBool = Vec<u64>;
|
||||
|
||||
use std::{cell::RefCell, sync::OnceLock};
|
||||
|
||||
use evaluator::*;
|
||||
use keys::*;
|
||||
use parameters::*;
|
||||
pub use mp_api::*;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::{cell::RefCell, sync::OnceLock};
|
||||
|
||||
use crate::{
|
||||
backend::{ModularOpsU64, ModulusPowerOf2},
|
||||
ntt::NttBackendU64,
|
||||
@@ -5,7 +7,7 @@ use crate::{
|
||||
utils::{Global, WithLocal},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
use super::{evaluator::*, keys::*, parameters::*};
|
||||
|
||||
thread_local! {
|
||||
static BOOL_EVALUATOR: RefCell<Option<BoolEvaluator<Vec<Vec<u64>>, NttBackendU64, ModularOpsU64<CiphertextModulus<u64>>, ModulusPowerOf2<CiphertextModulus<u64>>, ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>>>> = RefCell::new(None);
|
||||
@@ -15,6 +17,8 @@ static BOOL_SERVER_KEY: OnceLock<ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>>
|
||||
|
||||
static MULTI_PARTY_CRS: OnceLock<MultiPartyCrs<[u8; 32]>> = OnceLock::new();
|
||||
|
||||
pub type ClientKey = super::keys::ClientKey<[u8; 32], u64>;
|
||||
|
||||
pub enum ParameterSelector {
|
||||
MultiPartyLessThanOrEqualTo16,
|
||||
}
|
||||
@@ -62,7 +66,7 @@ pub fn gen_mp_keys_phase1(
|
||||
) -> CommonReferenceSeededCollectivePublicKeyShare<Vec<u64>, [u8; 32], BoolParameters<u64>> {
|
||||
let seed = MultiPartyCrs::global().public_key_share_seed::<DefaultSecureRng>();
|
||||
BoolEvaluator::with_local(|e| {
|
||||
let pk_share = e.multi_party_public_key_share(seed, &ck);
|
||||
let pk_share = e.multi_party_public_key_share(seed, ck);
|
||||
pk_share
|
||||
})
|
||||
}
|
||||
@@ -167,3 +171,91 @@ impl Global for RuntimeServerKey {
|
||||
BOOL_SERVER_KEY.get().expect("Server key not set!")
|
||||
}
|
||||
}
|
||||
|
||||
mod impl_enc_dec {
|
||||
use crate::{
|
||||
pbs::{sample_extract, PbsInfo},
|
||||
rgsw::public_key_encrypt_rlwe,
|
||||
Decryptor, Encryptor, Matrix, MatrixEntity, MultiPartyDecryptor, RowEntity,
|
||||
};
|
||||
use num_traits::Zero;
|
||||
|
||||
use super::*;
|
||||
|
||||
type Mat = Vec<Vec<u64>>;
|
||||
|
||||
impl<E> Encryptor<bool, Vec<u64>> for super::super::keys::ClientKey<[u8; 32], E> {
|
||||
fn encrypt(&self, m: &bool) -> Vec<u64> {
|
||||
BoolEvaluator::with_local(|e| e.sk_encrypt(*m, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Decryptor<bool, Vec<u64>> for super::super::keys::ClientKey<[u8; 32], E> {
|
||||
fn decrypt(&self, c: &Vec<u64>) -> bool {
|
||||
BoolEvaluator::with_local(|e| e.sk_decrypt(c, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> MultiPartyDecryptor<bool, <Mat as Matrix>::R>
|
||||
for super::super::keys::ClientKey<[u8; 32], E>
|
||||
{
|
||||
type DecryptionShare = <Mat as Matrix>::MatElement;
|
||||
|
||||
fn gen_decryption_share(&self, c: &<Mat as Matrix>::R) -> Self::DecryptionShare {
|
||||
BoolEvaluator::with_local(|e| e.multi_party_decryption_share(c, self))
|
||||
}
|
||||
|
||||
fn aggregate_decryption_shares(
|
||||
&self,
|
||||
c: &<Mat as Matrix>::R,
|
||||
shares: &[Self::DecryptionShare],
|
||||
) -> bool {
|
||||
BoolEvaluator::with_local(|e| e.multi_party_decrypt(shares, c))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Rng, ModOp> Encryptor<[bool], Mat> for PublicKey<Mat, Rng, ModOp> {
|
||||
fn encrypt(&self, m: &[bool]) -> Mat {
|
||||
BoolEvaluator::with_local(|e| {
|
||||
DefaultSecureRng::with_local_mut(|rng| {
|
||||
let parameters = e.parameters();
|
||||
let mut rlwe_out = <Mat as MatrixEntity>::zeros(2, parameters.rlwe_n().0);
|
||||
assert!(m.len() <= parameters.rlwe_n().0);
|
||||
|
||||
let mut message =
|
||||
vec![<Mat as Matrix>::MatElement::zero(); parameters.rlwe_n().0];
|
||||
m.iter().enumerate().for_each(|(i, v)| {
|
||||
if *v {
|
||||
message[i] = parameters.rlwe_q().true_el()
|
||||
} else {
|
||||
message[i] = parameters.rlwe_q().false_el()
|
||||
}
|
||||
});
|
||||
|
||||
// e.pk_encrypt_batched(self.key(), m)
|
||||
public_key_encrypt_rlwe::<_, _, _, _, i32, _>(
|
||||
&mut rlwe_out,
|
||||
self.key(),
|
||||
&message,
|
||||
e.pbs_info().modop_rlweq(),
|
||||
e.pbs_info().nttop_rlweq(),
|
||||
rng,
|
||||
);
|
||||
rlwe_out
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<Rng, ModOp> Encryptor<bool, <Mat as Matrix>::R> for PublicKey<Mat, Rng, ModOp> {
|
||||
fn encrypt(&self, m: &bool) -> <Mat as Matrix>::R {
|
||||
let m = vec![*m];
|
||||
let rlwe = self.encrypt(m.as_slice());
|
||||
BoolEvaluator::with_local(|e| {
|
||||
let mut lwe = <Mat as Matrix>::R::zeros(e.parameters().rlwe_n().0 + 1);
|
||||
sample_extract(&mut lwe, &rlwe, e.pbs_info().modop_rlweq(), 0);
|
||||
lwe
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
mod impl_enc_dec {
|
||||
use crate::{
|
||||
bool::{
|
||||
evaluator::{BoolEncoding, BoolEvaluator},
|
||||
keys::NonInteractiveMultiPartyClientKey,
|
||||
parameters::CiphertextModulus,
|
||||
},
|
||||
pbs::PbsInfo,
|
||||
random::{DefaultSecureRng, NewWithSeed},
|
||||
rgsw::secret_key_encrypt_rlwe,
|
||||
utils::{TryConvertFrom1, WithLocal},
|
||||
Encryptor, Matrix, RowEntity,
|
||||
};
|
||||
use num_traits::Zero;
|
||||
|
||||
trait SeededCiphertext<M, S> {
|
||||
fn new_with_seed(data: M, seed: S) -> Self;
|
||||
}
|
||||
|
||||
type Mat = Vec<Vec<u64>>;
|
||||
|
||||
impl<K, C> Encryptor<[bool], C> for K
|
||||
where
|
||||
K: NonInteractiveMultiPartyClientKey,
|
||||
C: SeededCiphertext<<Mat as Matrix>::R, <DefaultSecureRng as NewWithSeed>::Seed>,
|
||||
<Mat as Matrix>::R:
|
||||
TryConvertFrom1<[K::Element], CiphertextModulus<<Mat as Matrix>::MatElement>>,
|
||||
{
|
||||
fn encrypt(&self, m: &[bool]) -> C {
|
||||
BoolEvaluator::with_local(|e| {
|
||||
let parameters = e.parameters();
|
||||
assert!(m.len() <= parameters.rlwe_n().0);
|
||||
|
||||
let mut message = vec![<Mat as Matrix>::MatElement::zero(); parameters.rlwe_n().0];
|
||||
m.iter().enumerate().for_each(|(i, v)| {
|
||||
if *v {
|
||||
message[i] = parameters.rlwe_q().true_el()
|
||||
} else {
|
||||
message[i] = parameters.rlwe_q().false_el()
|
||||
}
|
||||
});
|
||||
|
||||
DefaultSecureRng::with_local_mut(|rng| {
|
||||
let mut seed = <DefaultSecureRng as NewWithSeed>::Seed::default();
|
||||
rng.fill_bytes(&mut seed);
|
||||
let mut prng = DefaultSecureRng::new_seeded(seed);
|
||||
|
||||
let mut rlwe_out =
|
||||
<<Mat as Matrix>::R as RowEntity>::zeros(parameters.rlwe_n().0);
|
||||
|
||||
secret_key_encrypt_rlwe(
|
||||
&message,
|
||||
&mut rlwe_out,
|
||||
&self.sk_u_rlwe(),
|
||||
e.pbs_info().modop_rlweq(),
|
||||
e.pbs_info().nttop_rlweq(),
|
||||
&mut prng,
|
||||
rng,
|
||||
);
|
||||
|
||||
C::new_with_seed(rlwe_out, seed)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,17 @@ mod test {
|
||||
use itertools::{izip, Itertools};
|
||||
|
||||
use crate::{
|
||||
backend::{ArithmeticOps, ModularOpsU64, Modulus, ModulusPowerOf2},
|
||||
backend::{ModularOpsU64, ModulusPowerOf2},
|
||||
bool::{
|
||||
BoolEncoding, BoolEvaluator, BooleanGates, CiphertextModulus, ClientKey, PublicKey,
|
||||
ServerKeyEvaluationDomain, ShoupServerKeyEvaluationDomain, MP_BOOL_PARAMS,
|
||||
SMALL_MP_BOOL_PARAMS,
|
||||
evaluator::{BoolEncoding, BoolEvaluator, BooleanGates},
|
||||
keys::{
|
||||
InteractiveMultiPartyClientKey, PublicKey, ServerKeyEvaluationDomain,
|
||||
ShoupServerKeyEvaluationDomain,
|
||||
},
|
||||
parameters::{CiphertextModulus, SMALL_MP_BOOL_PARAMS},
|
||||
},
|
||||
lwe::{decrypt_lwe, LweSecret},
|
||||
ntt::NttBackendU64,
|
||||
pbs::PbsInfo,
|
||||
random::DefaultSecureRng,
|
||||
rgsw::RlweSecret,
|
||||
utils::Stats,
|
||||
Ntt, Secret,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@@ -42,29 +40,26 @@ mod test {
|
||||
.collect_vec();
|
||||
|
||||
// construct ideal rlwe sk for meauring noise
|
||||
let ideal_client_key = {
|
||||
let mut ideal_rlwe_sk = vec![0i32; evaluator.parameters().rlwe_n().0];
|
||||
cks.iter().for_each(|k| {
|
||||
izip!(ideal_rlwe_sk.iter_mut(), k.sk_rlwe().values()).for_each(|(ideal_i, s_i)| {
|
||||
*ideal_i = *ideal_i + s_i;
|
||||
});
|
||||
});
|
||||
let mut ideal_lwe_sk = vec![0i32; evaluator.parameters().lwe_n().0];
|
||||
cks.iter().for_each(|k| {
|
||||
izip!(ideal_lwe_sk.iter_mut(), k.sk_lwe().values()).for_each(|(ideal_i, s_i)| {
|
||||
*ideal_i = *ideal_i + s_i;
|
||||
});
|
||||
});
|
||||
|
||||
ClientKey::new(
|
||||
RlweSecret {
|
||||
values: ideal_rlwe_sk,
|
||||
},
|
||||
LweSecret {
|
||||
values: ideal_lwe_sk,
|
||||
},
|
||||
let mut ideal_rlwe_sk = vec![0i32; evaluator.parameters().rlwe_n().0];
|
||||
cks.iter().for_each(|k| {
|
||||
izip!(
|
||||
ideal_rlwe_sk.iter_mut(),
|
||||
InteractiveMultiPartyClientKey::sk_rlwe(k)
|
||||
)
|
||||
};
|
||||
.for_each(|(ideal_i, s_i)| {
|
||||
*ideal_i = *ideal_i + s_i;
|
||||
});
|
||||
});
|
||||
let mut ideal_lwe_sk = vec![0i32; evaluator.parameters().lwe_n().0];
|
||||
cks.iter().for_each(|k| {
|
||||
izip!(
|
||||
ideal_lwe_sk.iter_mut(),
|
||||
InteractiveMultiPartyClientKey::sk_lwe(k)
|
||||
)
|
||||
.for_each(|(ideal_i, s_i)| {
|
||||
*ideal_i = *ideal_i + s_i;
|
||||
});
|
||||
});
|
||||
|
||||
// round 1
|
||||
let pk_shares = cks
|
||||
|
||||
Reference in New Issue
Block a user