arnaucube
arnaucube/phantom-zonePublic Self-hosted repository
phantom-zone/src/bool/mp_api.rs
src/bool/mp_api.rsRaw
  1use std::{cell::RefCell, sync::OnceLock};
  2
  3use crate::{
  4    backend::{ModularOpsU64, ModulusPowerOf2},
  5    ntt::NttBackendU64,
  6    random::{DefaultSecureRng, NewWithSeed},
  7    utils::{Global, WithLocal},
  8};
  9
 10use super::{evaluator::MultiPartyCrs, keys::*, parameters::*, ClientKey, ParameterSelector};
 11
 12pub type BoolEvaluator = super::evaluator::BoolEvaluator<
 13    Vec<Vec<u64>>,
 14    NttBackendU64,
 15    ModularOpsU64<CiphertextModulus<u64>>,
 16    ModulusPowerOf2<CiphertextModulus<u64>>,
 17    ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>,
 18>;
 19
 20thread_local! {
 21    static BOOL_EVALUATOR: RefCell<Option<BoolEvaluator>> = RefCell::new(None);
 22
 23}
 24static BOOL_SERVER_KEY: OnceLock<ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>> = OnceLock::new();
 25
 26static MULTI_PARTY_CRS: OnceLock<MultiPartyCrs<[u8; 32]>> = OnceLock::new();
 27
 28pub fn set_parameter_set(select: ParameterSelector) {
 29    match select {
 30        ParameterSelector::MultiPartyLessThanOrEqualTo16 => {
 31            BOOL_EVALUATOR.with_borrow_mut(|v| *v = Some(BoolEvaluator::new(SMALL_MP_BOOL_PARAMS)));
 32        }
 33        _ => {
 34            panic!("Paramerters not supported")
 35        }
 36    }
 37}
 38
 39pub fn set_mp_seed(seed: [u8; 32]) {
 40    assert!(
 41        MULTI_PARTY_CRS.set(MultiPartyCrs { seed: seed }).is_ok(),
 42        "Attempted to set MP SEED twice."
 43    )
 44}
 45
 46fn set_server_key(key: ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>) {
 47    assert!(
 48        BOOL_SERVER_KEY.set(key).is_ok(),
 49        "Attempted to set server key twice."
 50    );
 51}
 52
 53pub(crate) fn gen_keys() -> (
 54    ClientKey,
 55    SeededSinglePartyServerKey<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]>,
 56) {
 57    BoolEvaluator::with_local_mut(|e| {
 58        let ck = e.client_key();
 59        let sk = e.single_party_server_key(&ck);
 60
 61        (ck, sk)
 62    })
 63}
 64
 65pub fn gen_client_key() -> ClientKey {
 66    BoolEvaluator::with_local(|e| e.client_key())
 67}
 68
 69pub fn gen_mp_keys_phase1(
 70    ck: &ClientKey,
 71) -> CommonReferenceSeededCollectivePublicKeyShare<Vec<u64>, [u8; 32], BoolParameters<u64>> {
 72    let seed = MultiPartyCrs::global().public_key_share_seed::<DefaultSecureRng>();
 73    BoolEvaluator::with_local(|e| {
 74        let pk_share = e.multi_party_public_key_share(seed, ck);
 75        pk_share
 76    })
 77}
 78
 79pub fn gen_mp_keys_phase2<R, ModOp>(
 80    ck: &ClientKey,
 81    pk: &PublicKey<Vec<Vec<u64>>, R, ModOp>,
 82) -> CommonReferenceSeededMultiPartyServerKeyShare<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]> {
 83    let seed = MultiPartyCrs::global().server_key_share_seed::<DefaultSecureRng>();
 84    BoolEvaluator::with_local_mut(|e| {
 85        let server_key_share = e.multi_party_server_key_share(seed, pk.key(), ck);
 86        server_key_share
 87    })
 88}
 89
 90pub fn aggregate_public_key_shares(
 91    shares: &[CommonReferenceSeededCollectivePublicKeyShare<
 92        Vec<u64>,
 93        [u8; 32],
 94        BoolParameters<u64>,
 95    >],
 96) -> PublicKey<Vec<Vec<u64>>, DefaultSecureRng, ModularOpsU64<CiphertextModulus<u64>>> {
 97    PublicKey::from(shares)
 98}
 99
100pub fn aggregate_server_key_shares(
101    shares: &[CommonReferenceSeededMultiPartyServerKeyShare<
102        Vec<Vec<u64>>,
103        BoolParameters<u64>,
104        [u8; 32],
105    >],
106) -> SeededMultiPartyServerKey<Vec<Vec<u64>>, [u8; 32], BoolParameters<u64>> {
107    BoolEvaluator::with_local(|e| e.aggregate_multi_party_server_key_shares(shares))
108}
109
110// SERVER KEY EVAL (/SHOUP) DOMAIN //
111impl SeededSinglePartyServerKey<Vec<Vec<u64>>, BoolParameters<u64>, [u8; 32]> {
112    pub fn set_server_key(&self) {
113        let eval = ServerKeyEvaluationDomain::<_, _, DefaultSecureRng, NttBackendU64>::from(self);
114        set_server_key(ShoupServerKeyEvaluationDomain::from(eval));
115    }
116}
117
118impl
119    SeededMultiPartyServerKey<
120        Vec<Vec<u64>>,
121        <DefaultSecureRng as NewWithSeed>::Seed,
122        BoolParameters<u64>,
123    >
124{
125    pub fn set_server_key(&self) {
126        set_server_key(ShoupServerKeyEvaluationDomain::from(
127            ServerKeyEvaluationDomain::<_, _, DefaultSecureRng, NttBackendU64>::from(self),
128        ))
129    }
130}
131
132//  MULTIPARTY CRS  //
133impl Global for MultiPartyCrs<[u8; 32]> {
134    fn global() -> &'static Self {
135        MULTI_PARTY_CRS
136            .get()
137            .expect("Multi Party Common Reference String not set")
138    }
139}
140
141// BOOL EVALUATOR //
142impl WithLocal for BoolEvaluator {
143    fn with_local<F, R>(func: F) -> R
144    where
145        F: Fn(&Self) -> R,
146    {
147        BOOL_EVALUATOR.with_borrow(|s| func(s.as_ref().expect("Parameters not set")))
148    }
149
150    fn with_local_mut<F, R>(func: F) -> R
151    where
152        F: Fn(&mut Self) -> R,
153    {
154        BOOL_EVALUATOR.with_borrow_mut(|s| func(s.as_mut().expect("Parameters not set")))
155    }
156
157    fn with_local_mut_mut<F, R>(func: &mut F) -> R
158    where
159        F: FnMut(&mut Self) -> R,
160    {
161        BOOL_EVALUATOR.with_borrow_mut(|s| func(s.as_mut().expect("Parameters not set")))
162    }
163}
164
165pub(crate) type RuntimeServerKey = ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>;
166impl Global for RuntimeServerKey {
167    fn global() -> &'static Self {
168        BOOL_SERVER_KEY.get().expect("Server key not set!")
169    }
170}
171
172mod impl_enc_dec {
173    use crate::{
174        bool::evaluator::BoolEncoding,
175        pbs::{sample_extract, PbsInfo},
176        rgsw::public_key_encrypt_rlwe,
177        Encryptor, Matrix, MatrixEntity, MultiPartyDecryptor, RowEntity,
178    };
179    use itertools::Itertools;
180    use num_traits::{ToPrimitive, Zero};
181
182    use super::*;
183
184    type Mat = Vec<Vec<u64>>;
185
186    impl<Rng, ModOp> Encryptor<[bool], Vec<Mat>> for PublicKey<Mat, Rng, ModOp> {
187        fn encrypt(&self, m: &[bool]) -> Vec<Mat> {
188            BoolEvaluator::with_local(|e| {
189                DefaultSecureRng::with_local_mut(|rng| {
190                    let parameters = e.parameters();
191                    let ring_size = parameters.rlwe_n().0;
192
193                    let rlwe_count = ((m.len() as f64 / ring_size as f64).ceil())
194                        .to_usize()
195                        .unwrap();
196
197                    // encrypt `m` into ceil(len(m)/N) RLWE ciphertexts
198                    let rlwes = (0..rlwe_count)
199                        .map(|index| {
200                            let mut message = vec![<Mat as Matrix>::MatElement::zero(); ring_size];
201                            m[(index * ring_size)..std::cmp::min(m.len(), (index + 1) * ring_size)]
202                                .iter()
203                                .enumerate()
204                                .for_each(|(i, v)| {
205                                    if *v {
206                                        message[i] = parameters.rlwe_q().true_el()
207                                    } else {
208                                        message[i] = parameters.rlwe_q().false_el()
209                                    }
210                                });
211
212                            // encrypt message
213                            let mut rlwe_out =
214                                <Mat as MatrixEntity>::zeros(2, parameters.rlwe_n().0);
215
216                            public_key_encrypt_rlwe::<_, _, _, _, i32, _>(
217                                &mut rlwe_out,
218                                self.key(),
219                                &message,
220                                e.pbs_info().modop_rlweq(),
221                                e.pbs_info().nttop_rlweq(),
222                                rng,
223                            );
224
225                            rlwe_out
226                        })
227                        .collect_vec();
228                    rlwes
229                })
230            })
231        }
232    }
233
234    impl<Rng, ModOp> Encryptor<bool, <Mat as Matrix>::R> for PublicKey<Mat, Rng, ModOp> {
235        fn encrypt(&self, m: &bool) -> <Mat as Matrix>::R {
236            let m = vec![*m];
237            let rlwe = &self.encrypt(m.as_slice())[0];
238            BoolEvaluator::with_local(|e| {
239                let mut lwe = <Mat as Matrix>::R::zeros(e.parameters().rlwe_n().0 + 1);
240                sample_extract(&mut lwe, rlwe, e.pbs_info().modop_rlweq(), 0);
241                lwe
242            })
243        }
244    }
245}