mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-09 15:41:30 +01:00
add non-interactive multiparty server key eval domain
This commit is contained in:
File diff suppressed because it is too large
Load Diff
249
src/bool/keys.rs
249
src/bool/keys.rs
@@ -12,6 +12,25 @@ use crate::{
|
|||||||
|
|
||||||
use super::{parameters, BoolEvaluator, BoolParameters, CiphertextModulus};
|
use super::{parameters, BoolEvaluator, BoolParameters, CiphertextModulus};
|
||||||
|
|
||||||
|
trait SinglePartyClientKey {
|
||||||
|
type Element;
|
||||||
|
fn sk_rlwe(&self) -> &[Self::Element];
|
||||||
|
fn sk_lwe(&self) -> &[Self::Element];
|
||||||
|
}
|
||||||
|
|
||||||
|
trait InteractiveMultiPartyClientKey {
|
||||||
|
type Element;
|
||||||
|
fn sk_rlwe(&self) -> &[Self::Element];
|
||||||
|
fn sk_lwe(&self) -> &[Self::Element];
|
||||||
|
}
|
||||||
|
|
||||||
|
trait NonInteractiveMultiPartyClientKey {
|
||||||
|
type Element;
|
||||||
|
fn sk_rlwe(&self) -> &[Self::Element];
|
||||||
|
fn sk_u_rlwe(&self) -> &[Self::Element];
|
||||||
|
fn sk_lwe(&self) -> &[Self::Element];
|
||||||
|
}
|
||||||
|
|
||||||
/// Client key with RLWE and LWE secrets
|
/// Client key with RLWE and LWE secrets
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ClientKey {
|
pub struct ClientKey {
|
||||||
@@ -21,7 +40,7 @@ pub struct ClientKey {
|
|||||||
|
|
||||||
/// Client key with RLWE and LWE secrets
|
/// Client key with RLWE and LWE secrets
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct NonInteractiveClientKey {
|
pub struct ThrowMeAwayKey {
|
||||||
sk_rlwe: RlweSecret,
|
sk_rlwe: RlweSecret,
|
||||||
sk_u_rlwe: RlweSecret,
|
sk_u_rlwe: RlweSecret,
|
||||||
sk_lwe: LweSecret,
|
sk_lwe: LweSecret,
|
||||||
@@ -46,7 +65,7 @@ mod impl_ck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Client key
|
// Client key
|
||||||
impl NonInteractiveClientKey {
|
impl ThrowMeAwayKey {
|
||||||
pub(in super::super) fn new(
|
pub(in super::super) fn new(
|
||||||
sk_rlwe: RlweSecret,
|
sk_rlwe: RlweSecret,
|
||||||
sk_u_rlwe: RlweSecret,
|
sk_u_rlwe: RlweSecret,
|
||||||
@@ -369,7 +388,7 @@ impl<M: Matrix, S, P> SeededMultiPartyServerKey<M, S, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Seeded single party server key
|
/// Seeded single party server key
|
||||||
pub struct SeededServerKey<M: Matrix, P, S> {
|
pub struct SeededSinglePartyServerKey<M: Matrix, P, S> {
|
||||||
/// Rgsw cts of LWE secret elements
|
/// Rgsw cts of LWE secret elements
|
||||||
pub(crate) rgsw_cts: Vec<M>,
|
pub(crate) rgsw_cts: Vec<M>,
|
||||||
/// Auto keys. Key corresponding to g^{k} is at index `k`. Key corresponding
|
/// Auto keys. Key corresponding to g^{k} is at index `k`. Key corresponding
|
||||||
@@ -382,7 +401,7 @@ pub struct SeededServerKey<M: Matrix, P, S> {
|
|||||||
/// Main seed
|
/// Main seed
|
||||||
pub(crate) seed: S,
|
pub(crate) seed: S,
|
||||||
}
|
}
|
||||||
impl<M: Matrix, S> SeededServerKey<M, BoolParameters<M::MatElement>, S> {
|
impl<M: Matrix, S> SeededSinglePartyServerKey<M, BoolParameters<M::MatElement>, S> {
|
||||||
pub(super) fn from_raw(
|
pub(super) fn from_raw(
|
||||||
auto_keys: HashMap<usize, M>,
|
auto_keys: HashMap<usize, M>,
|
||||||
rgsw_cts: Vec<M>,
|
rgsw_cts: Vec<M>,
|
||||||
@@ -410,7 +429,7 @@ impl<M: Matrix, S> SeededServerKey<M, BoolParameters<M::MatElement>, S> {
|
|||||||
== (parameters.lwe_decomposition_count().0 * parameters.rlwe_n().0)
|
== (parameters.lwe_decomposition_count().0 * parameters.rlwe_n().0)
|
||||||
);
|
);
|
||||||
|
|
||||||
SeededServerKey {
|
SeededSinglePartyServerKey {
|
||||||
rgsw_cts,
|
rgsw_cts,
|
||||||
auto_keys,
|
auto_keys,
|
||||||
lwe_ksk,
|
lwe_ksk,
|
||||||
@@ -438,6 +457,7 @@ pub(super) mod impl_server_key_eval_domain {
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::Modulus,
|
backend::Modulus,
|
||||||
|
bool::{NonInteractiveMultiPartyCrs, SeededNonInteractiveMultiPartyServerKey},
|
||||||
ntt::{Ntt, NttInit},
|
ntt::{Ntt, NttInit},
|
||||||
pbs::PbsKey,
|
pbs::PbsKey,
|
||||||
};
|
};
|
||||||
@@ -455,14 +475,16 @@ pub(super) mod impl_server_key_eval_domain {
|
|||||||
R: RandomFillUniformInModulus<[M::MatElement], CiphertextModulus<M::MatElement>>
|
R: RandomFillUniformInModulus<[M::MatElement], CiphertextModulus<M::MatElement>>
|
||||||
+ NewWithSeed,
|
+ NewWithSeed,
|
||||||
N: NttInit<CiphertextModulus<M::MatElement>> + Ntt<Element = M::MatElement>,
|
N: NttInit<CiphertextModulus<M::MatElement>> + Ntt<Element = M::MatElement>,
|
||||||
> From<&SeededServerKey<M, BoolParameters<M::MatElement>, R::Seed>>
|
> From<&SeededSinglePartyServerKey<M, BoolParameters<M::MatElement>, R::Seed>>
|
||||||
for ServerKeyEvaluationDomain<M, BoolParameters<M::MatElement>, R, N>
|
for ServerKeyEvaluationDomain<M, BoolParameters<M::MatElement>, R, N>
|
||||||
where
|
where
|
||||||
<M as Matrix>::R: RowMut,
|
<M as Matrix>::R: RowMut,
|
||||||
M::MatElement: Copy,
|
M::MatElement: Copy,
|
||||||
R::Seed: Clone,
|
R::Seed: Clone,
|
||||||
{
|
{
|
||||||
fn from(value: &SeededServerKey<M, BoolParameters<M::MatElement>, R::Seed>) -> Self {
|
fn from(
|
||||||
|
value: &SeededSinglePartyServerKey<M, BoolParameters<M::MatElement>, R::Seed>,
|
||||||
|
) -> Self {
|
||||||
let mut main_prng = R::new_with_seed(value.seed.clone());
|
let mut main_prng = R::new_with_seed(value.seed.clone());
|
||||||
let parameters = &value.parameters;
|
let parameters = &value.parameters;
|
||||||
let g = parameters.g() as isize;
|
let g = parameters.g() as isize;
|
||||||
@@ -697,7 +719,218 @@ pub(super) mod impl_server_key_eval_domain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Server key in evaluation domain
|
pub(crate) struct NonInteractiveServerKeyEvaluationDomain<M, P, R, N> {
|
||||||
|
/// RGSW ciphertexts ideal lwe secret key elements under ideal rlwe secret
|
||||||
|
rgsw_cts: Vec<M>,
|
||||||
|
/// Automorphism keys under ideal rlwe secret
|
||||||
|
auto_keys: HashMap<usize, M>,
|
||||||
|
/// LWE key switching key from Q -> Q_{ks}
|
||||||
|
lwe_ksk: M,
|
||||||
|
/// Key switching key from user j to ideal secret key s. User j's ksk is at
|
||||||
|
/// j'th element
|
||||||
|
ui_to_s_ksks: Vec<M>,
|
||||||
|
parameters: P,
|
||||||
|
_phanton: PhantomData<(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 super::*;
|
||||||
|
|
||||||
|
impl<M, Rng, N>
|
||||||
|
From<
|
||||||
|
SeededNonInteractiveMultiPartyServerKey<
|
||||||
|
M,
|
||||||
|
NonInteractiveMultiPartyCrs<Rng::Seed>,
|
||||||
|
BoolParameters<M::MatElement>,
|
||||||
|
>,
|
||||||
|
> for NonInteractiveServerKeyEvaluationDomain<M, BoolParameters<M::MatElement>, Rng, N>
|
||||||
|
where
|
||||||
|
M: MatrixMut + MatrixEntity + Clone,
|
||||||
|
Rng: NewWithSeed
|
||||||
|
+ RandomFillUniformInModulus<[M::MatElement], CiphertextModulus<M::MatElement>>
|
||||||
|
+ RandomFill<<Rng as NewWithSeed>::Seed>,
|
||||||
|
N: Ntt<Element = M::MatElement> + NttInit<CiphertextModulus<M::MatElement>>,
|
||||||
|
M::R: RowMut,
|
||||||
|
M::MatElement: Copy,
|
||||||
|
Rng::Seed: Clone + Copy + Default,
|
||||||
|
{
|
||||||
|
fn from(
|
||||||
|
value: SeededNonInteractiveMultiPartyServerKey<
|
||||||
|
M,
|
||||||
|
NonInteractiveMultiPartyCrs<Rng::Seed>,
|
||||||
|
BoolParameters<M::MatElement>,
|
||||||
|
>,
|
||||||
|
) -> Self {
|
||||||
|
let rlwe_nttop = N::new(value.parameters.rlwe_q(), value.parameters.rlwe_n().0);
|
||||||
|
let ring_size = value.parameters.rlwe_n().0;
|
||||||
|
|
||||||
|
// RGSW cts
|
||||||
|
// copy over rgsw cts and send to evaluation domain
|
||||||
|
let mut rgsw_cts = value.rgsw_cts.clone();
|
||||||
|
rgsw_cts.iter_mut().for_each(|c| {
|
||||||
|
c.iter_rows_mut()
|
||||||
|
.for_each(|ri| rlwe_nttop.forward(ri.as_mut()))
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auto keys
|
||||||
|
// populate pseudo random part of auto keys. Then send auto keys to
|
||||||
|
// evaluation domain
|
||||||
|
let mut auto_keys = HashMap::new();
|
||||||
|
let auto_seed = value.cr_seed.auto_keys_cts_seed::<Rng>();
|
||||||
|
let mut auto_prng = Rng::new_with_seed(auto_seed);
|
||||||
|
let auto_element_dlogs = value.parameters.auto_element_dlogs();
|
||||||
|
let d_auto = value.parameters.auto_decomposition_count().0;
|
||||||
|
auto_element_dlogs.iter().for_each(|el| {
|
||||||
|
let auto_part_b = value
|
||||||
|
.auto_keys
|
||||||
|
.get(el)
|
||||||
|
.expect(&format!("Auto key for element g^{el} not found"));
|
||||||
|
|
||||||
|
assert!(auto_part_b.dimension() == (d_auto, ring_size));
|
||||||
|
|
||||||
|
let mut auto_ct = M::zeros(d_auto, ring_size);
|
||||||
|
|
||||||
|
// sample part A
|
||||||
|
auto_ct.iter_rows_mut().take(d_auto).for_each(|ri| {
|
||||||
|
RandomFillUniformInModulus::random_fill(
|
||||||
|
&mut auto_prng,
|
||||||
|
value.parameters.rlwe_q(),
|
||||||
|
ri.as_mut(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Copy over part B
|
||||||
|
izip!(
|
||||||
|
auto_ct.iter_rows_mut().skip(d_auto),
|
||||||
|
auto_part_b.iter_rows()
|
||||||
|
)
|
||||||
|
.for_each(|(to_ri, from_ri)| to_ri.as_mut().copy_from_slice(from_ri.as_ref()));
|
||||||
|
|
||||||
|
// send to evaluation domain
|
||||||
|
auto_ct
|
||||||
|
.iter_rows_mut()
|
||||||
|
.for_each(|r| rlwe_nttop.forward(r.as_mut()));
|
||||||
|
|
||||||
|
auto_keys.insert(*el, auto_ct);
|
||||||
|
});
|
||||||
|
|
||||||
|
// LWE ksk
|
||||||
|
// populate pseudo random part of lwe ciphertexts in ksk and copy over part b
|
||||||
|
// elements
|
||||||
|
let lwe_ksk_seed = value.cr_seed.lwe_ksk_cts_seed::<Rng>();
|
||||||
|
let mut lwe_ksk_prng = Rng::new_with_seed(lwe_ksk_seed);
|
||||||
|
let mut lwe_ksk = M::zeros(
|
||||||
|
value.parameters.lwe_decomposition_count().0 * ring_size,
|
||||||
|
value.parameters.lwe_n().0 + 1,
|
||||||
|
);
|
||||||
|
lwe_ksk.iter_rows_mut().for_each(|ri| {
|
||||||
|
// first element is resereved for part b. Only sample a_is in the rest
|
||||||
|
RandomFillUniformInModulus::random_fill(
|
||||||
|
&mut lwe_ksk_prng,
|
||||||
|
value.parameters.lwe_q(),
|
||||||
|
&mut ri.as_mut()[1..],
|
||||||
|
)
|
||||||
|
});
|
||||||
|
// copy over part bs
|
||||||
|
izip!(value.lwe_ksk.as_ref().iter(), lwe_ksk.iter_rows_mut()).for_each(
|
||||||
|
|(b_el, lwe_ct)| {
|
||||||
|
lwe_ct.as_mut()[0] = *b_el;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// u_i to s ksk
|
||||||
|
let d_uitos = value
|
||||||
|
.parameters
|
||||||
|
.non_interactive_ui_to_s_key_switch_decomposition_count()
|
||||||
|
.0;
|
||||||
|
let total_users = *value.ui_to_s_ksks_key_order.iter().max().unwrap();
|
||||||
|
let ui_to_s_ksks = (0..total_users)
|
||||||
|
.map(|user_index| {
|
||||||
|
let user_i_seed = value.cr_seed.ui_to_s_ks_seed_for_user_i::<Rng>(user_index);
|
||||||
|
let mut prng = Rng::new_with_seed(user_i_seed);
|
||||||
|
|
||||||
|
let mut ksk_ct = M::zeros(d_uitos * 2, ring_size);
|
||||||
|
|
||||||
|
ksk_ct.iter_rows_mut().take(d_uitos).for_each(|r| {
|
||||||
|
RandomFillUniformInModulus::random_fill(
|
||||||
|
&mut prng,
|
||||||
|
value.parameters.rlwe_q(),
|
||||||
|
r.as_mut(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
let incoming_ksk_partb_ref =
|
||||||
|
&value.ui_to_s_ksks[value.ui_to_s_ksks_key_order[user_index]];
|
||||||
|
assert!(ksk_ct.dimension() == (d_uitos, ring_size));
|
||||||
|
izip!(
|
||||||
|
ksk_ct.iter_rows_mut().skip(d_uitos),
|
||||||
|
incoming_ksk_partb_ref.iter_rows()
|
||||||
|
)
|
||||||
|
.for_each(|(to_ri, from_ri)| {
|
||||||
|
to_ri.as_mut().copy_from_slice(from_ri.as_ref());
|
||||||
|
});
|
||||||
|
|
||||||
|
ksk_ct
|
||||||
|
.iter_rows_mut()
|
||||||
|
.for_each(|r| rlwe_nttop.forward(r.as_mut()));
|
||||||
|
ksk_ct
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
NonInteractiveServerKeyEvaluationDomain {
|
||||||
|
rgsw_cts,
|
||||||
|
auto_keys,
|
||||||
|
lwe_ksk,
|
||||||
|
ui_to_s_ksks,
|
||||||
|
parameters: value.parameters.clone(),
|
||||||
|
_phanton: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SeededNonInteractiveMultiPartyServerKey<M: Matrix, S, P> {
|
||||||
|
/// u_i to s key switching keys in random order
|
||||||
|
ui_to_s_ksks: Vec<M>,
|
||||||
|
/// Defines order for u_i to s key switchin keys by storing the index of
|
||||||
|
/// user j's ksk in `ui_to_s_ksks` at index `j`. Find user j's u_i to s ksk
|
||||||
|
/// at `ui_to_s_ksks[ui_to_s_ksks_key_order[j]]`
|
||||||
|
ui_to_s_ksks_key_order: Vec<usize>,
|
||||||
|
/// RGSW ciphertets
|
||||||
|
rgsw_cts: Vec<M>,
|
||||||
|
auto_keys: HashMap<usize, M>,
|
||||||
|
lwe_ksk: M::R,
|
||||||
|
cr_seed: S,
|
||||||
|
parameters: P,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: Matrix, S, P> SeededNonInteractiveMultiPartyServerKey<M, S, P> {
|
||||||
|
pub(super) fn new(
|
||||||
|
ui_to_s_ksks: Vec<M>,
|
||||||
|
ui_to_s_ksks_key_order: Vec<usize>,
|
||||||
|
rgsw_cts: Vec<M>,
|
||||||
|
auto_keys: HashMap<usize, M>,
|
||||||
|
lwe_ksk: M::R,
|
||||||
|
cr_seed: S,
|
||||||
|
parameters: P,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
ui_to_s_ksks,
|
||||||
|
ui_to_s_ksks_key_order,
|
||||||
|
rgsw_cts,
|
||||||
|
auto_keys,
|
||||||
|
lwe_ksk,
|
||||||
|
cr_seed,
|
||||||
|
parameters,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Server key in evaluation domain with Shoup representations
|
||||||
pub(crate) struct ShoupServerKeyEvaluationDomain<M> {
|
pub(crate) struct ShoupServerKeyEvaluationDomain<M> {
|
||||||
/// Rgsw cts of LWE secret elements
|
/// Rgsw cts of LWE secret elements
|
||||||
rgsw_cts: Vec<NormalAndShoup<M>>,
|
rgsw_cts: Vec<NormalAndShoup<M>>,
|
||||||
|
|||||||
174
src/bool/mod.rs
174
src/bool/mod.rs
@@ -1,8 +1,12 @@
|
|||||||
pub(crate) mod evaluator;
|
pub(crate) mod evaluator;
|
||||||
pub(crate) mod keys;
|
pub(crate) mod keys;
|
||||||
pub mod noise;
|
mod mp_api;
|
||||||
|
mod ni_mp_api;
|
||||||
|
mod noise;
|
||||||
pub(crate) mod parameters;
|
pub(crate) mod parameters;
|
||||||
|
|
||||||
|
pub use mp_api::*;
|
||||||
|
|
||||||
pub type FheBool = Vec<u64>;
|
pub type FheBool = Vec<u64>;
|
||||||
|
|
||||||
use std::{cell::RefCell, sync::OnceLock};
|
use std::{cell::RefCell, sync::OnceLock};
|
||||||
@@ -10,171 +14,3 @@ use std::{cell::RefCell, sync::OnceLock};
|
|||||||
use evaluator::*;
|
use evaluator::*;
|
||||||
use keys::*;
|
use keys::*;
|
||||||
use parameters::*;
|
use parameters::*;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
backend::{ModularOpsU64, ModulusPowerOf2},
|
|
||||||
ntt::NttBackendU64,
|
|
||||||
random::{DefaultSecureRng, NewWithSeed},
|
|
||||||
utils::{Global, WithLocal},
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
static BOOL_SERVER_KEY: OnceLock<ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>> = OnceLock::new();
|
|
||||||
|
|
||||||
static MULTI_PARTY_CRS: OnceLock<MultiPartyCrs<[u8; 32]>> = OnceLock::new();
|
|
||||||
|
|
||||||
pub enum ParameterSelector {
|
|
||||||
MultiPartyLessThanOrEqualTo16,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_parameter_set(select: ParameterSelector) {
|
|
||||||
match select {
|
|
||||||
ParameterSelector::MultiPartyLessThanOrEqualTo16 => {
|
|
||||||
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(SMALL_MP_BOOL_PARAMS)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_mp_seed(seed: [u8; 32]) {
|
|
||||||
assert!(
|
|
||||||
MULTI_PARTY_CRS.set(MultiPartyCrs { seed: seed }).is_ok(),
|
|
||||||
"Attempted to set MP SEED twice."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_server_key(key: ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>) {
|
|
||||||
assert!(
|
|
||||||
BOOL_SERVER_KEY.set(key).is_ok(),
|
|
||||||
"Attempted to set server key twice."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn gen_keys() -> (
|
|
||||||
ClientKey,
|
|
||||||
SeededServerKey<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]>,
|
|
||||||
) {
|
|
||||||
BoolEvaluator::with_local_mut(|e| {
|
|
||||||
let ck = e.client_key();
|
|
||||||
let sk = e.single_party_server_key(&ck);
|
|
||||||
|
|
||||||
(ck, sk)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gen_client_key() -> ClientKey {
|
|
||||||
BoolEvaluator::with_local(|e| e.client_key())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gen_mp_keys_phase1(
|
|
||||||
ck: &ClientKey,
|
|
||||||
) -> 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);
|
|
||||||
pk_share
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gen_mp_keys_phase2<R, ModOp>(
|
|
||||||
ck: &ClientKey,
|
|
||||||
pk: &PublicKey<Vec<Vec<u64>>, R, ModOp>,
|
|
||||||
) -> CommonReferenceSeededMultiPartyServerKeyShare<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]> {
|
|
||||||
let seed = MultiPartyCrs::global().server_key_share_seed::<DefaultSecureRng>();
|
|
||||||
BoolEvaluator::with_local_mut(|e| {
|
|
||||||
let server_key_share = e.multi_party_server_key_share(seed, pk.key(), ck);
|
|
||||||
server_key_share
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn aggregate_public_key_shares(
|
|
||||||
shares: &[CommonReferenceSeededCollectivePublicKeyShare<
|
|
||||||
Vec<u64>,
|
|
||||||
[u8; 32],
|
|
||||||
BoolParameters<u64>,
|
|
||||||
>],
|
|
||||||
) -> PublicKey<Vec<Vec<u64>>, DefaultSecureRng, ModularOpsU64<CiphertextModulus<u64>>> {
|
|
||||||
PublicKey::from(shares)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn aggregate_server_key_shares(
|
|
||||||
shares: &[CommonReferenceSeededMultiPartyServerKeyShare<
|
|
||||||
Vec<Vec<u64>>,
|
|
||||||
BoolParameters<u64>,
|
|
||||||
[u8; 32],
|
|
||||||
>],
|
|
||||||
) -> SeededMultiPartyServerKey<Vec<Vec<u64>>, [u8; 32], BoolParameters<u64>> {
|
|
||||||
BoolEvaluator::with_local(|e| e.aggregate_multi_party_server_key_shares(shares))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SERVER KEY EVAL (/SHOUP) DOMAIN //
|
|
||||||
impl SeededServerKey<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]> {
|
|
||||||
pub fn set_server_key(&self) {
|
|
||||||
let eval = ServerKeyEvaluationDomain::<_, _, DefaultSecureRng, NttBackendU64>::from(self);
|
|
||||||
set_server_key(ShoupServerKeyEvaluationDomain::from(eval));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl
|
|
||||||
SeededMultiPartyServerKey<
|
|
||||||
Vec<Vec<u64>>,
|
|
||||||
<DefaultSecureRng as NewWithSeed>::Seed,
|
|
||||||
BoolParameters<u64>,
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pub fn set_server_key(&self) {
|
|
||||||
set_server_key(ShoupServerKeyEvaluationDomain::from(
|
|
||||||
ServerKeyEvaluationDomain::<_, _, DefaultSecureRng, NttBackendU64>::from(self),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MULTIPARTY CRS //
|
|
||||||
impl Global for MultiPartyCrs<[u8; 32]> {
|
|
||||||
fn global() -> &'static Self {
|
|
||||||
MULTI_PARTY_CRS
|
|
||||||
.get()
|
|
||||||
.expect("Multi Party Common Reference String not set")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// BOOL EVALUATOR //
|
|
||||||
impl WithLocal
|
|
||||||
for BoolEvaluator<
|
|
||||||
Vec<Vec<u64>>,
|
|
||||||
NttBackendU64,
|
|
||||||
ModularOpsU64<CiphertextModulus<u64>>,
|
|
||||||
ModulusPowerOf2<CiphertextModulus<u64>>,
|
|
||||||
ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>,
|
|
||||||
>
|
|
||||||
{
|
|
||||||
fn with_local<F, R>(func: F) -> R
|
|
||||||
where
|
|
||||||
F: Fn(&Self) -> R,
|
|
||||||
{
|
|
||||||
BOOL_EVALUATOR.with_borrow(|s| func(s.as_ref().expect("Parameters not set")))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_local_mut<F, R>(func: F) -> R
|
|
||||||
where
|
|
||||||
F: Fn(&mut Self) -> R,
|
|
||||||
{
|
|
||||||
BOOL_EVALUATOR.with_borrow_mut(|s| func(s.as_mut().expect("Parameters not set")))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_local_mut_mut<F, R>(func: &mut F) -> R
|
|
||||||
where
|
|
||||||
F: FnMut(&mut Self) -> R,
|
|
||||||
{
|
|
||||||
BOOL_EVALUATOR.with_borrow_mut(|s| func(s.as_mut().expect("Parameters not set")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) type RuntimeServerKey = ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>;
|
|
||||||
impl Global for RuntimeServerKey {
|
|
||||||
fn global() -> &'static Self {
|
|
||||||
BOOL_SERVER_KEY.get().expect("Server key not set!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
169
src/bool/mp_api.rs
Normal file
169
src/bool/mp_api.rs
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
use crate::{
|
||||||
|
backend::{ModularOpsU64, ModulusPowerOf2},
|
||||||
|
ntt::NttBackendU64,
|
||||||
|
random::{DefaultSecureRng, NewWithSeed},
|
||||||
|
utils::{Global, WithLocal},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
static BOOL_SERVER_KEY: OnceLock<ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>> = OnceLock::new();
|
||||||
|
|
||||||
|
static MULTI_PARTY_CRS: OnceLock<MultiPartyCrs<[u8; 32]>> = OnceLock::new();
|
||||||
|
|
||||||
|
pub enum ParameterSelector {
|
||||||
|
MultiPartyLessThanOrEqualTo16,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_parameter_set(select: ParameterSelector) {
|
||||||
|
match select {
|
||||||
|
ParameterSelector::MultiPartyLessThanOrEqualTo16 => {
|
||||||
|
BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(SMALL_MP_BOOL_PARAMS)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_mp_seed(seed: [u8; 32]) {
|
||||||
|
assert!(
|
||||||
|
MULTI_PARTY_CRS.set(MultiPartyCrs { seed: seed }).is_ok(),
|
||||||
|
"Attempted to set MP SEED twice."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_server_key(key: ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>) {
|
||||||
|
assert!(
|
||||||
|
BOOL_SERVER_KEY.set(key).is_ok(),
|
||||||
|
"Attempted to set server key twice."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn gen_keys() -> (
|
||||||
|
ClientKey,
|
||||||
|
SeededSinglePartyServerKey<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]>,
|
||||||
|
) {
|
||||||
|
BoolEvaluator::with_local_mut(|e| {
|
||||||
|
let ck = e.client_key();
|
||||||
|
let sk = e.single_party_server_key(&ck);
|
||||||
|
|
||||||
|
(ck, sk)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gen_client_key() -> ClientKey {
|
||||||
|
BoolEvaluator::with_local(|e| e.client_key())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gen_mp_keys_phase1(
|
||||||
|
ck: &ClientKey,
|
||||||
|
) -> 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);
|
||||||
|
pk_share
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gen_mp_keys_phase2<R, ModOp>(
|
||||||
|
ck: &ClientKey,
|
||||||
|
pk: &PublicKey<Vec<Vec<u64>>, R, ModOp>,
|
||||||
|
) -> CommonReferenceSeededMultiPartyServerKeyShare<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]> {
|
||||||
|
let seed = MultiPartyCrs::global().server_key_share_seed::<DefaultSecureRng>();
|
||||||
|
BoolEvaluator::with_local_mut(|e| {
|
||||||
|
let server_key_share = e.multi_party_server_key_share(seed, pk.key(), ck);
|
||||||
|
server_key_share
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn aggregate_public_key_shares(
|
||||||
|
shares: &[CommonReferenceSeededCollectivePublicKeyShare<
|
||||||
|
Vec<u64>,
|
||||||
|
[u8; 32],
|
||||||
|
BoolParameters<u64>,
|
||||||
|
>],
|
||||||
|
) -> PublicKey<Vec<Vec<u64>>, DefaultSecureRng, ModularOpsU64<CiphertextModulus<u64>>> {
|
||||||
|
PublicKey::from(shares)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn aggregate_server_key_shares(
|
||||||
|
shares: &[CommonReferenceSeededMultiPartyServerKeyShare<
|
||||||
|
Vec<Vec<u64>>,
|
||||||
|
BoolParameters<u64>,
|
||||||
|
[u8; 32],
|
||||||
|
>],
|
||||||
|
) -> SeededMultiPartyServerKey<Vec<Vec<u64>>, [u8; 32], BoolParameters<u64>> {
|
||||||
|
BoolEvaluator::with_local(|e| e.aggregate_multi_party_server_key_shares(shares))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SERVER KEY EVAL (/SHOUP) DOMAIN //
|
||||||
|
impl SeededSinglePartyServerKey<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]> {
|
||||||
|
pub fn set_server_key(&self) {
|
||||||
|
let eval = ServerKeyEvaluationDomain::<_, _, DefaultSecureRng, NttBackendU64>::from(self);
|
||||||
|
set_server_key(ShoupServerKeyEvaluationDomain::from(eval));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl
|
||||||
|
SeededMultiPartyServerKey<
|
||||||
|
Vec<Vec<u64>>,
|
||||||
|
<DefaultSecureRng as NewWithSeed>::Seed,
|
||||||
|
BoolParameters<u64>,
|
||||||
|
>
|
||||||
|
{
|
||||||
|
pub fn set_server_key(&self) {
|
||||||
|
set_server_key(ShoupServerKeyEvaluationDomain::from(
|
||||||
|
ServerKeyEvaluationDomain::<_, _, DefaultSecureRng, NttBackendU64>::from(self),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MULTIPARTY CRS //
|
||||||
|
impl Global for MultiPartyCrs<[u8; 32]> {
|
||||||
|
fn global() -> &'static Self {
|
||||||
|
MULTI_PARTY_CRS
|
||||||
|
.get()
|
||||||
|
.expect("Multi Party Common Reference String not set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BOOL EVALUATOR //
|
||||||
|
impl WithLocal
|
||||||
|
for BoolEvaluator<
|
||||||
|
Vec<Vec<u64>>,
|
||||||
|
NttBackendU64,
|
||||||
|
ModularOpsU64<CiphertextModulus<u64>>,
|
||||||
|
ModulusPowerOf2<CiphertextModulus<u64>>,
|
||||||
|
ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>,
|
||||||
|
>
|
||||||
|
{
|
||||||
|
fn with_local<F, R>(func: F) -> R
|
||||||
|
where
|
||||||
|
F: Fn(&Self) -> R,
|
||||||
|
{
|
||||||
|
BOOL_EVALUATOR.with_borrow(|s| func(s.as_ref().expect("Parameters not set")))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_local_mut<F, R>(func: F) -> R
|
||||||
|
where
|
||||||
|
F: Fn(&mut Self) -> R,
|
||||||
|
{
|
||||||
|
BOOL_EVALUATOR.with_borrow_mut(|s| func(s.as_mut().expect("Parameters not set")))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_local_mut_mut<F, R>(func: &mut F) -> R
|
||||||
|
where
|
||||||
|
F: FnMut(&mut Self) -> R,
|
||||||
|
{
|
||||||
|
BOOL_EVALUATOR.with_borrow_mut(|s| func(s.as_mut().expect("Parameters not set")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) type RuntimeServerKey = ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>;
|
||||||
|
impl Global for RuntimeServerKey {
|
||||||
|
fn global() -> &'static Self {
|
||||||
|
BOOL_SERVER_KEY.get().expect("Server key not set!")
|
||||||
|
}
|
||||||
|
}
|
||||||
0
src/bool/ni_mp_api.rs
Normal file
0
src/bool/ni_mp_api.rs
Normal file
@@ -4,9 +4,9 @@ mod test {
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::{ArithmeticOps, ModularOpsU64, Modulus, ModulusPowerOf2},
|
backend::{ArithmeticOps, ModularOpsU64, Modulus, ModulusPowerOf2},
|
||||||
bool::{
|
bool::{
|
||||||
set_parameter_set, BoolEncoding, BoolEvaluator, BooleanGates, CiphertextModulus,
|
BoolEncoding, BoolEvaluator, BooleanGates, CiphertextModulus, ClientKey, PublicKey,
|
||||||
ClientKey, PublicKey, ServerKeyEvaluationDomain, ShoupServerKeyEvaluationDomain,
|
ServerKeyEvaluationDomain, ShoupServerKeyEvaluationDomain, MP_BOOL_PARAMS,
|
||||||
MP_BOOL_PARAMS, SMALL_MP_BOOL_PARAMS,
|
SMALL_MP_BOOL_PARAMS,
|
||||||
},
|
},
|
||||||
lwe::{decrypt_lwe, LweSecret},
|
lwe::{decrypt_lwe, LweSecret},
|
||||||
ntt::NttBackendU64,
|
ntt::NttBackendU64,
|
||||||
|
|||||||
Reference in New Issue
Block a user