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};
|
||||
|
||||
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
|
||||
#[derive(Clone)]
|
||||
pub struct ClientKey {
|
||||
@@ -21,7 +40,7 @@ pub struct ClientKey {
|
||||
|
||||
/// Client key with RLWE and LWE secrets
|
||||
#[derive(Clone)]
|
||||
pub struct NonInteractiveClientKey {
|
||||
pub struct ThrowMeAwayKey {
|
||||
sk_rlwe: RlweSecret,
|
||||
sk_u_rlwe: RlweSecret,
|
||||
sk_lwe: LweSecret,
|
||||
@@ -46,7 +65,7 @@ mod impl_ck {
|
||||
}
|
||||
|
||||
// Client key
|
||||
impl NonInteractiveClientKey {
|
||||
impl ThrowMeAwayKey {
|
||||
pub(in super::super) fn new(
|
||||
sk_rlwe: RlweSecret,
|
||||
sk_u_rlwe: RlweSecret,
|
||||
@@ -369,7 +388,7 @@ impl<M: Matrix, S, P> SeededMultiPartyServerKey<M, S, P> {
|
||||
}
|
||||
|
||||
/// 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
|
||||
pub(crate) rgsw_cts: Vec<M>,
|
||||
/// 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
|
||||
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(
|
||||
auto_keys: HashMap<usize, 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)
|
||||
);
|
||||
|
||||
SeededServerKey {
|
||||
SeededSinglePartyServerKey {
|
||||
rgsw_cts,
|
||||
auto_keys,
|
||||
lwe_ksk,
|
||||
@@ -438,6 +457,7 @@ pub(super) mod impl_server_key_eval_domain {
|
||||
|
||||
use crate::{
|
||||
backend::Modulus,
|
||||
bool::{NonInteractiveMultiPartyCrs, SeededNonInteractiveMultiPartyServerKey},
|
||||
ntt::{Ntt, NttInit},
|
||||
pbs::PbsKey,
|
||||
};
|
||||
@@ -455,14 +475,16 @@ pub(super) mod impl_server_key_eval_domain {
|
||||
R: RandomFillUniformInModulus<[M::MatElement], CiphertextModulus<M::MatElement>>
|
||||
+ NewWithSeed,
|
||||
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>
|
||||
where
|
||||
<M as Matrix>::R: RowMut,
|
||||
M::MatElement: Copy,
|
||||
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 parameters = &value.parameters;
|
||||
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> {
|
||||
/// Rgsw cts of LWE secret elements
|
||||
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 keys;
|
||||
pub mod noise;
|
||||
mod mp_api;
|
||||
mod ni_mp_api;
|
||||
mod noise;
|
||||
pub(crate) mod parameters;
|
||||
|
||||
pub use mp_api::*;
|
||||
|
||||
pub type FheBool = Vec<u64>;
|
||||
|
||||
use std::{cell::RefCell, sync::OnceLock};
|
||||
@@ -10,171 +14,3 @@ use std::{cell::RefCell, sync::OnceLock};
|
||||
use evaluator::*;
|
||||
use keys::*;
|
||||
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::{
|
||||
backend::{ArithmeticOps, ModularOpsU64, Modulus, ModulusPowerOf2},
|
||||
bool::{
|
||||
set_parameter_set, BoolEncoding, BoolEvaluator, BooleanGates, CiphertextModulus,
|
||||
ClientKey, PublicKey, ServerKeyEvaluationDomain, ShoupServerKeyEvaluationDomain,
|
||||
MP_BOOL_PARAMS, SMALL_MP_BOOL_PARAMS,
|
||||
BoolEncoding, BoolEvaluator, BooleanGates, CiphertextModulus, ClientKey, PublicKey,
|
||||
ServerKeyEvaluationDomain, ShoupServerKeyEvaluationDomain, MP_BOOL_PARAMS,
|
||||
SMALL_MP_BOOL_PARAMS,
|
||||
},
|
||||
lwe::{decrypt_lwe, LweSecret},
|
||||
ntt::NttBackendU64,
|
||||
|
||||
Reference in New Issue
Block a user