Browse Source

non-interactive RGSW ct works with different bases

par-agg-key-shares
Janmajaya Mall 9 months ago
parent
commit
89f5dbc461
4 changed files with 571 additions and 475 deletions
  1. +510
    -454
      src/bool/evaluator.rs
  2. +59
    -19
      src/bool/keys.rs
  3. +1
    -1
      src/bool/parameters.rs
  4. +1
    -1
      src/bool/print_noise.rs

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


+ 59
- 19
src/bool/keys.rs

@ -907,10 +907,12 @@ pub(super) mod impl_non_interactive_server_key_eval_domain {
.parameters .parameters
.non_interactive_ui_to_s_key_switch_decomposition_count() .non_interactive_ui_to_s_key_switch_decomposition_count()
.0; .0;
let total_users = *value.ui_to_s_ksks_key_order.iter().max().unwrap();
let ui_to_s_ksks = (0..total_users + 1)
.map(|user_index| {
let user_i_seed = value.cr_seed.ui_to_s_ks_seed_for_user_i::<Rng>(user_index);
let ui_to_s_ksks = value
.ui_to_s_ksks
.iter()
.enumerate()
.map(|(user_id, incoming_ksk_partb)| {
let user_i_seed = value.cr_seed.ui_to_s_ks_seed_for_user_i::<Rng>(user_id);
let mut prng = Rng::new_with_seed(user_i_seed); let mut prng = Rng::new_with_seed(user_i_seed);
let mut ksk_ct = M::zeros(d_uitos * 2, ring_size); let mut ksk_ct = M::zeros(d_uitos * 2, ring_size);
@ -923,12 +925,10 @@ pub(super) mod impl_non_interactive_server_key_eval_domain {
); );
}); });
let incoming_ksk_partb_ref =
&value.ui_to_s_ksks[value.ui_to_s_ksks_key_order[user_index]];
assert!(incoming_ksk_partb_ref.dimension() == (d_uitos, ring_size));
assert!(incoming_ksk_partb.dimension() == (d_uitos, ring_size));
izip!( izip!(
ksk_ct.iter_rows_mut().skip(d_uitos), ksk_ct.iter_rows_mut().skip(d_uitos),
incoming_ksk_partb_ref.iter_rows()
incoming_ksk_partb.iter_rows()
) )
.for_each(|(to_ri, from_ri)| { .for_each(|(to_ri, from_ri)| {
to_ri.as_mut().copy_from_slice(from_ri.as_ref()); to_ri.as_mut().copy_from_slice(from_ri.as_ref());
@ -970,12 +970,9 @@ pub(super) mod impl_non_interactive_server_key_eval_domain {
} }
pub struct SeededNonInteractiveMultiPartyServerKey<M: Matrix, S, P> { pub struct SeededNonInteractiveMultiPartyServerKey<M: Matrix, S, P> {
/// u_i to s key switching keys in random order
/// u_i to s key switching keys in random order. Key switchin key for user j
/// is stored at j^th index
ui_to_s_ksks: Vec<M>, 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 ciphertets
rgsw_cts: Vec<M>, rgsw_cts: Vec<M>,
auto_keys: HashMap<usize, M>, auto_keys: HashMap<usize, M>,
@ -987,7 +984,7 @@ pub struct SeededNonInteractiveMultiPartyServerKey {
impl<M: Matrix, S, P> SeededNonInteractiveMultiPartyServerKey<M, S, P> { impl<M: Matrix, S, P> SeededNonInteractiveMultiPartyServerKey<M, S, P> {
pub(super) fn new( pub(super) fn new(
ui_to_s_ksks: Vec<M>, ui_to_s_ksks: Vec<M>,
ui_to_s_ksks_key_order: Vec<usize>,
rgsw_cts: Vec<M>, rgsw_cts: Vec<M>,
auto_keys: HashMap<usize, M>, auto_keys: HashMap<usize, M>,
lwe_ksk: M::R, lwe_ksk: M::R,
@ -996,7 +993,7 @@ impl SeededNonInteractiveMultiPartyServerKey {
) -> Self { ) -> Self {
Self { Self {
ui_to_s_ksks, ui_to_s_ksks,
ui_to_s_ksks_key_order,
rgsw_cts, rgsw_cts,
auto_keys, auto_keys,
lwe_ksk, lwe_ksk,
@ -1203,10 +1200,14 @@ pub struct CommonReferenceSeededNonInteractiveMultiPartyServerKeyShare
lwe_ksk_share: M::R, lwe_ksk_share: M::R,
user_index: usize, user_index: usize,
total_users: usize,
lwe_n: usize,
cr_seed: S, cr_seed: S,
} }
mod impl_common_ref_non_interactive_multi_party_server_share { mod impl_common_ref_non_interactive_multi_party_server_share {
use crate::evaluator::interactive_mult_party_user_id_lwe_segment;
use super::*; use super::*;
impl<M: Matrix, S> CommonReferenceSeededNonInteractiveMultiPartyServerKeyShare<M, S> { impl<M: Matrix, S> CommonReferenceSeededNonInteractiveMultiPartyServerKeyShare<M, S> {
@ -1219,6 +1220,8 @@ mod impl_common_ref_non_interactive_multi_party_server_share {
auto_keys_share: HashMap<usize, M>, auto_keys_share: HashMap<usize, M>,
lwe_ksk_share: M::R, lwe_ksk_share: M::R,
user_index: usize, user_index: usize,
total_users: usize,
lwe_n: usize,
cr_seed: S, cr_seed: S,
) -> Self { ) -> Self {
Self { Self {
@ -1230,12 +1233,49 @@ mod impl_common_ref_non_interactive_multi_party_server_share {
auto_keys_share, auto_keys_share,
lwe_ksk_share, lwe_ksk_share,
user_index, user_index,
total_users,
lwe_n,
cr_seed, cr_seed,
} }
} }
pub(in super::super) fn ni_rgsw_cts(&self) -> &(Vec<M>, Vec<M>) {
&self.ni_rgsw_cts
pub(in super::super) fn ni_rgsw_cts_for_self_leader_lwe_index(
&self,
lwe_index: usize,
) -> &M {
let self_segment = interactive_mult_party_user_id_lwe_segment(
self.user_index,
self.total_users,
self.lwe_n,
);
assert!(lwe_index >= self_segment.0 && lwe_index < self_segment.1);
&self.self_leader_ni_rgsw_cts[lwe_index - self_segment.0]
}
pub(in super::super) fn ni_rgsw_cts_for_self_not_leader_lwe_index(
&self,
lwe_index: usize,
) -> &M {
let self_segment = interactive_mult_party_user_id_lwe_segment(
self.user_index,
self.total_users,
self.lwe_n,
);
// Non-interactive RGSW cts when self is not leader are stored in
// sorted-order. For ex, if self is the leader for indices (5, 6]
// then self stores NI-RGSW cts for rest of indices like [0, 1, 2,
// 3, 4, 6, 7, 8, 9]
assert!(lwe_index < self.lwe_n);
assert!(lwe_index < self_segment.0 || lwe_index >= self_segment.1);
if lwe_index < self_segment.0 {
&self.not_self_leader_ni_rgsw_cts[lwe_index]
} else {
&self.not_self_leader_ni_rgsw_cts[lwe_index - (self_segment.1 - self_segment.0)]
}
}
pub(in super::super) fn ni_rgsw_zero_enc_for_lwe_index(&self, lwe_index: usize) -> &M {
&self.ni_rgsw_zero_encs[lwe_index]
} }
pub(in super::super) fn ui_to_s_ksk(&self) -> &M { pub(in super::super) fn ui_to_s_ksk(&self) -> &M {
@ -1257,9 +1297,9 @@ mod impl_common_ref_non_interactive_multi_party_server_share {
pub(in super::super) fn ui_to_s_ksk_zero_encs_for_user_i(&self, user_i: usize) -> &M { pub(in super::super) fn ui_to_s_ksk_zero_encs_for_user_i(&self, user_i: usize) -> &M {
assert!(user_i != self.user_index); assert!(user_i != self.user_index);
if user_i < self.user_index { if user_i < self.user_index {
&self.others_ksk_zero_encs[user_i]
&self.ksk_zero_encs_for_others[user_i]
} else { } else {
&self.others_ksk_zero_encs[user_i - 1]
&self.ksk_zero_encs_for_others[user_i - 1]
} }
} }
} }

+ 1
- 1
src/bool/parameters.rs

@ -518,7 +518,7 @@ pub(crate) const NI_2P: BoolParameters = BoolParameters:: {
lwe_decomposer_params: (DecompostionLogBase(4), DecompositionCount(5)), lwe_decomposer_params: (DecompostionLogBase(4), DecompositionCount(5)),
rlrg_decomposer_params: ( rlrg_decomposer_params: (
DecompostionLogBase(11), DecompostionLogBase(11),
(DecompositionCount(2), DecompositionCount(1)),
(DecompositionCount(4), DecompositionCount(3)),
), ),
rgrg_decomposer_params: Some(( rgrg_decomposer_params: Some((
DecompostionLogBase(11), DecompostionLogBase(11),

+ 1
- 1
src/bool/print_noise.rs

@ -314,7 +314,7 @@ where
// LWE key switches LWE_in = LWE_{Q_ks,N, s}(m) = (b, a_0, ... a_N) -> LWE_out = // LWE key switches LWE_in = LWE_{Q_ks,N, s}(m) = (b, a_0, ... a_N) -> LWE_out =
// LWE_{Q_{ks}, n, z}(m) = (b', a'_0, ..., a'n) // LWE_{Q_{ks}, n, z}(m) = (b', a'_0, ..., a'n)
// If LWE_in = (0, a = {a_0, ..., a_N}), then LWE_out = LWE(-a \cdot s_{rlwe}) // If LWE_in = (0, a = {a_0, ..., a_N}), then LWE_out = LWE(-a \cdot s_{rlwe})
for _ in 0..1000 {
for _ in 0..10 {
let mut lwe_in = M::R::zeros(rlwe_n + 1); let mut lwe_in = M::R::zeros(rlwe_n + 1);
RandomFillUniformInModulus::random_fill(&mut rng, lwe_q, &mut lwe_in.as_mut()[1..]); RandomFillUniformInModulus::random_fill(&mut rng, lwe_q, &mut lwe_in.as_mut()[1..]);

Loading…
Cancel
Save