From 0e95653698f18a165e05cf36ef0f840e0e6f308f Mon Sep 17 00:00:00 2001 From: Janmajaya Mall Date: Mon, 17 Jun 2024 14:10:36 +0530 Subject: [PATCH] add shoup repre non-interactive multiparty server key eval domain --- src/bool/evaluator.rs | 11 ++-- src/bool/keys.rs | 118 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 102 insertions(+), 27 deletions(-) diff --git a/src/bool/evaluator.rs b/src/bool/evaluator.rs index 8a37404..c2ae5b3 100644 --- a/src/bool/evaluator.rs +++ b/src/bool/evaluator.rs @@ -54,7 +54,7 @@ use super::{ ThrowMeAwayKey, }; -pub struct NonInteractiveMultiPartyServerKeyShare { +pub struct SeededNonInteractiveMultiPartyServerKeyShare { /// (ak*si + e + \beta ui, ak*si + e) ni_rgsw_cts: (Vec, Vec), ui_to_s_ksk: M, @@ -67,7 +67,7 @@ pub struct NonInteractiveMultiPartyServerKeyShare { cr_seed: S, } -impl NonInteractiveMultiPartyServerKeyShare { +impl SeededNonInteractiveMultiPartyServerKeyShare { fn ui_to_s_ksk_zero_encs_for_user_i(&self, user_i: usize) -> &M { assert!(user_i != self.user_index); if user_i < self.user_index { @@ -916,7 +916,7 @@ where &self, cr_seed: &NonInteractiveMultiPartyCrs<[u8; 32]>, total_users: usize, - key_shares: &[NonInteractiveMultiPartyServerKeyShare< + key_shares: &[SeededNonInteractiveMultiPartyServerKeyShare< M, NonInteractiveMultiPartyCrs<[u8; 32]>, >], @@ -1439,7 +1439,8 @@ where self_index: usize, total_users: usize, client_key: &ThrowMeAwayKey, - ) -> NonInteractiveMultiPartyServerKeyShare> { + ) -> SeededNonInteractiveMultiPartyServerKeyShare> + { // TODO: check whether parameters support `total_users` let nttop = self.pbs_info().nttop_rlweq(); let rlwe_modop = self.pbs_info().modop_rlweq(); @@ -1556,7 +1557,7 @@ where ) }; - NonInteractiveMultiPartyServerKeyShare { + SeededNonInteractiveMultiPartyServerKeyShare { ni_rgsw_cts, ui_to_s_ksk, others_ksk_zero_encs: zero_encs_for_others, diff --git a/src/bool/keys.rs b/src/bool/keys.rs index c8a0a12..de5ffe2 100644 --- a/src/bool/keys.rs +++ b/src/bool/keys.rs @@ -930,38 +930,89 @@ impl SeededNonInteractiveMultiPartyServerKey { } } -/// Server key in evaluation domain with Shoup representations -pub(crate) struct ShoupServerKeyEvaluationDomain { - /// Rgsw cts of LWE secret elements +pub(crate) struct ShoupNonInteractiveServerKeyEvaluationDomain { + /// RGSW ciphertexts ideal lwe secret key elements under ideal rlwe secret rgsw_cts: Vec>, - /// Auto keys. Key corresponding to g^{k} is at index `k`. Key corresponding - /// to -g is at 0 - galois_keys: HashMap>, - /// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret + /// Automorphism keys under ideal rlwe secret + auto_keys: HashMap>, + /// 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>, } -/// Stores normal and shoup representation of Matrix elements (Normal, Shoup) -pub(crate) struct NormalAndShoup(M, M); +mod impl_shoup_non_interactive_server_key_eval_domain { + use itertools::Itertools; + use num_traits::{FromPrimitive, PrimInt, ToPrimitive}; -impl NormalAndShoup { - fn new_with_modulus(value: M, modulus: ::Modulus) -> Self { - let value_shoup = M::to_shoup(&value, modulus); - NormalAndShoup(value, value_shoup) + use super::*; + use crate::{backend::Modulus, pbs::PbsKey}; + + impl, R, N> + From, R, N>> + for ShoupNonInteractiveServerKeyEvaluationDomain + where + M::MatElement: FromPrimitive + ToPrimitive + PrimInt, + { + fn from( + value: NonInteractiveServerKeyEvaluationDomain, 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 AsRef for NormalAndShoup { - fn as_ref(&self) -> &M { - &self.0 + impl PbsKey for ShoupNonInteractiveServerKeyEvaluationDomain { + type AutoKey = NormalAndShoup; + type LweKskKey = M; + type RgswCt = NormalAndShoup; + + 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 WithShoupRepr for NormalAndShoup { - type M = M; - fn shoup_repr(&self) -> &Self::M { - &self.1 - } +/// Server key in evaluation domain with Shoup representations +pub(crate) struct ShoupServerKeyEvaluationDomain { + /// Rgsw cts of LWE secret elements + rgsw_cts: Vec>, + /// Auto keys. Key corresponding to g^{k} is at index `k`. Key corresponding + /// to -g is at 0 + galois_keys: HashMap>, + /// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret + lwe_ksk: M, } 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); + +impl NormalAndShoup { + fn new_with_modulus(value: M, modulus: ::Modulus) -> Self { + let value_shoup = M::to_shoup(&value, modulus); + NormalAndShoup(value, value_shoup) + } +} + +impl AsRef for NormalAndShoup { + fn as_ref(&self) -> &M { + &self.0 + } +} + +impl WithShoupRepr for NormalAndShoup { + type M = M; + fn shoup_repr(&self) -> &Self::M { + &self.1 + } +}