Browse Source

add non-interactive multiparty server key eval domain

par-agg-key-shares
Janmajaya Mall 10 months ago
parent
commit
6aabfbfd71
6 changed files with 1025 additions and 585 deletions
  1. +607
    -405
      src/bool/evaluator.rs
  2. +241
    -8
      src/bool/keys.rs
  3. +5
    -169
      src/bool/mod.rs
  4. +169
    -0
      src/bool/mp_api.rs
  5. +0
    -0
      src/bool/ni_mp_api.rs
  6. +3
    -3
      src/bool/noise.rs

+ 607
- 405
src/bool/evaluator.rs
File diff suppressed because it is too large
View File


+ 241
- 8
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 SeededMultiPartyServerKey {
}
/// 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 {
/// 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 SeededServerKey, 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>>,

+ 5
- 169
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
- 0
src/bool/mp_api.rs

@ -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
- 0
src/bool/ni_mp_api.rs


+ 3
- 3
src/bool/noise.rs

@ -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,

Loading…
Cancel
Save