Browse Source

add shoup repre non-interactive multiparty server key eval domain

par-agg-key-shares
Janmajaya Mall 11 months ago
parent
commit
0e95653698
2 changed files with 102 additions and 27 deletions
  1. +6
    -5
      src/bool/evaluator.rs
  2. +96
    -22
      src/bool/keys.rs

+ 6
- 5
src/bool/evaluator.rs

@ -54,7 +54,7 @@ use super::{
ThrowMeAwayKey, ThrowMeAwayKey,
}; };
pub struct NonInteractiveMultiPartyServerKeyShare<M: Matrix, S> {
pub struct SeededNonInteractiveMultiPartyServerKeyShare<M: Matrix, S> {
/// (ak*si + e + \beta ui, ak*si + e) /// (ak*si + e + \beta ui, ak*si + e)
ni_rgsw_cts: (Vec<M>, Vec<M>), ni_rgsw_cts: (Vec<M>, Vec<M>),
ui_to_s_ksk: M, ui_to_s_ksk: M,
@ -67,7 +67,7 @@ pub struct NonInteractiveMultiPartyServerKeyShare {
cr_seed: S, cr_seed: S,
} }
impl<M: Matrix, S> NonInteractiveMultiPartyServerKeyShare<M, S> {
impl<M: Matrix, S> SeededNonInteractiveMultiPartyServerKeyShare<M, S> {
fn ui_to_s_ksk_zero_encs_for_user_i(&self, user_i: usize) -> &M { 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 {
@ -916,7 +916,7 @@ where
&self, &self,
cr_seed: &NonInteractiveMultiPartyCrs<[u8; 32]>, cr_seed: &NonInteractiveMultiPartyCrs<[u8; 32]>,
total_users: usize, total_users: usize,
key_shares: &[NonInteractiveMultiPartyServerKeyShare<
key_shares: &[SeededNonInteractiveMultiPartyServerKeyShare<
M, M,
NonInteractiveMultiPartyCrs<[u8; 32]>, NonInteractiveMultiPartyCrs<[u8; 32]>,
>], >],
@ -1439,7 +1439,8 @@ where
self_index: usize, self_index: usize,
total_users: usize, total_users: usize,
client_key: &ThrowMeAwayKey, client_key: &ThrowMeAwayKey,
) -> NonInteractiveMultiPartyServerKeyShare<M, NonInteractiveMultiPartyCrs<[u8; 32]>> {
) -> SeededNonInteractiveMultiPartyServerKeyShare<M, NonInteractiveMultiPartyCrs<[u8; 32]>>
{
// TODO: check whether parameters support `total_users` // TODO: check whether parameters support `total_users`
let nttop = self.pbs_info().nttop_rlweq(); let nttop = self.pbs_info().nttop_rlweq();
let rlwe_modop = self.pbs_info().modop_rlweq(); let rlwe_modop = self.pbs_info().modop_rlweq();
@ -1556,7 +1557,7 @@ where
) )
}; };
NonInteractiveMultiPartyServerKeyShare {
SeededNonInteractiveMultiPartyServerKeyShare {
ni_rgsw_cts, ni_rgsw_cts,
ui_to_s_ksk, ui_to_s_ksk,
others_ksk_zero_encs: zero_encs_for_others, others_ksk_zero_encs: zero_encs_for_others,

+ 96
- 22
src/bool/keys.rs

@ -930,38 +930,89 @@ impl SeededNonInteractiveMultiPartyServerKey {
} }
} }
/// Server key in evaluation domain with Shoup representations
pub(crate) struct ShoupServerKeyEvaluationDomain<M> {
/// Rgsw cts of LWE secret elements
pub(crate) struct ShoupNonInteractiveServerKeyEvaluationDomain<M> {
/// RGSW ciphertexts ideal lwe secret key elements under ideal rlwe secret
rgsw_cts: Vec<NormalAndShoup<M>>, rgsw_cts: Vec<NormalAndShoup<M>>,
/// Auto keys. Key corresponding to g^{k} is at index `k`. Key corresponding
/// to -g is at 0
galois_keys: HashMap<usize, NormalAndShoup<M>>,
/// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret
/// Automorphism keys under ideal rlwe secret
auto_keys: HashMap<usize, NormalAndShoup<M>>,
/// LWE key switching key from Q -> Q_{ks}
lwe_ksk: M, 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<NormalAndShoup<M>>,
} }
/// Stores normal and shoup representation of Matrix elements (Normal, Shoup)
pub(crate) struct NormalAndShoup<M>(M, M);
mod impl_shoup_non_interactive_server_key_eval_domain {
use itertools::Itertools;
use num_traits::{FromPrimitive, PrimInt, ToPrimitive};
impl<M: ToShoup> NormalAndShoup<M> {
fn new_with_modulus(value: M, modulus: <M as ToShoup>::Modulus) -> Self {
let value_shoup = M::to_shoup(&value, modulus);
NormalAndShoup(value, value_shoup)
use super::*;
use crate::{backend::Modulus, pbs::PbsKey};
impl<M: Matrix + ToShoup<Modulus = M::MatElement>, R, N>
From<NonInteractiveServerKeyEvaluationDomain<M, BoolParameters<M::MatElement>, R, N>>
for ShoupNonInteractiveServerKeyEvaluationDomain<M>
where
M::MatElement: FromPrimitive + ToPrimitive + PrimInt,
{
fn from(
value: NonInteractiveServerKeyEvaluationDomain<M, BoolParameters<M::MatElement>, R, N>,
) -> Self {
let rlwe_q = value.parameters.rlwe_q().q().unwrap();
let rgsw_cts = value
.rgsw_cts
.into_iter()
.map(|m| NormalAndShoup::new_with_modulus(m, rlwe_q))
.collect_vec();
let mut auto_keys = HashMap::new();
value.auto_keys.into_iter().for_each(|(k, v)| {
auto_keys.insert(k, NormalAndShoup::new_with_modulus(v, rlwe_q));
});
let ui_to_s_ksks = value
.ui_to_s_ksks
.into_iter()
.map(|m| NormalAndShoup::new_with_modulus(m, rlwe_q))
.collect_vec();
Self {
rgsw_cts,
auto_keys,
lwe_ksk: value.lwe_ksk,
ui_to_s_ksks,
}
}
} }
}
impl<M> AsRef<M> for NormalAndShoup<M> {
fn as_ref(&self) -> &M {
&self.0
impl<M: Matrix> PbsKey for ShoupNonInteractiveServerKeyEvaluationDomain<M> {
type AutoKey = NormalAndShoup<M>;
type LweKskKey = M;
type RgswCt = NormalAndShoup<M>;
fn galois_key_for_auto(&self, k: usize) -> &Self::AutoKey {
self.auto_keys.get(&k).unwrap()
}
fn rgsw_ct_lwe_si(&self, si: usize) -> &Self::RgswCt {
&self.rgsw_cts[si]
}
fn lwe_ksk(&self) -> &Self::LweKskKey {
&self.lwe_ksk
}
} }
} }
impl<M> WithShoupRepr for NormalAndShoup<M> {
type M = M;
fn shoup_repr(&self) -> &Self::M {
&self.1
}
/// Server key in evaluation domain with Shoup representations
pub(crate) struct ShoupServerKeyEvaluationDomain<M> {
/// Rgsw cts of LWE secret elements
rgsw_cts: Vec<NormalAndShoup<M>>,
/// Auto keys. Key corresponding to g^{k} is at index `k`. Key corresponding
/// to -g is at 0
galois_keys: HashMap<usize, NormalAndShoup<M>>,
/// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret
lwe_ksk: M,
} }
mod shoup_server_key_eval_domain { mod shoup_server_key_eval_domain {
@ -1018,3 +1069,26 @@ mod shoup_server_key_eval_domain {
} }
} }
} }
/// Stores normal and shoup representation of Matrix elements (Normal, Shoup)
pub(crate) struct NormalAndShoup<M>(M, M);
impl<M: ToShoup> NormalAndShoup<M> {
fn new_with_modulus(value: M, modulus: <M as ToShoup>::Modulus) -> Self {
let value_shoup = M::to_shoup(&value, modulus);
NormalAndShoup(value, value_shoup)
}
}
impl<M> AsRef<M> for NormalAndShoup<M> {
fn as_ref(&self) -> &M {
&self.0
}
}
impl<M> WithShoupRepr for NormalAndShoup<M> {
type M = M;
fn shoup_repr(&self) -> &Self::M {
&self.1
}
}

Loading…
Cancel
Save