mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-07 22:51:29 +01:00
add seeded server key
This commit is contained in:
369
src/bool.rs
369
src/bool.rs
@@ -15,7 +15,7 @@ use crate::{
|
||||
decomposer::{gadget_vector, Decomposer, DefaultDecomposer, NumInfo},
|
||||
lwe::{decrypt_lwe, encrypt_lwe, lwe_key_switch, lwe_ksk_keygen, measure_noise_lwe, LweSecret},
|
||||
ntt::{Ntt, NttBackendU64, NttInit},
|
||||
random::{DefaultSecureRng, RandomGaussianDist, RandomUniformDist},
|
||||
random::{DefaultSecureRng, NewWithSeed, RandomGaussianDist, RandomUniformDist},
|
||||
rgsw::{
|
||||
decrypt_rlwe, galois_auto, galois_key_gen, generate_auto_map, rlwe_by_rgsw,
|
||||
secret_key_encrypt_rgsw, IsTrivial, RlweCiphertext, RlweSecret,
|
||||
@@ -97,19 +97,172 @@ impl ClientKey {
|
||||
// ClientKey::with_local_mut(|k| *k = key.clone())
|
||||
// }
|
||||
|
||||
struct ServerKey<M> {
|
||||
struct SeededServerKey<M: Matrix, P, S> {
|
||||
/// Rgsw cts of LWE secret elements
|
||||
rgsw_cts: Vec<M>,
|
||||
/// Auto keys
|
||||
auto_keys: HashMap<isize, M>,
|
||||
/// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret
|
||||
lwe_ksk: M::R,
|
||||
/// Parameters
|
||||
parameters: P,
|
||||
/// Main seed
|
||||
seed: S,
|
||||
}
|
||||
|
||||
impl<M: Matrix, S> SeededServerKey<M, BoolParameters<M::MatElement>, S> {
|
||||
pub(crate) fn from_raw(
|
||||
auto_keys: HashMap<isize, M>,
|
||||
rgsw_cts: Vec<M>,
|
||||
lwe_ksk: M::R,
|
||||
parameters: BoolParameters<M::MatElement>,
|
||||
seed: S,
|
||||
) -> Self {
|
||||
// sanity checks
|
||||
auto_keys
|
||||
.iter()
|
||||
.for_each(|v| assert!(v.1.dimension() == (parameters.d_rgsw, parameters.rlwe_n)));
|
||||
rgsw_cts
|
||||
.iter()
|
||||
.for_each(|v| assert!(v.dimension() == (parameters.d_rgsw * 3, parameters.rlwe_n)));
|
||||
assert!(lwe_ksk.as_ref().len() == (parameters.d_lwe * parameters.rlwe_n));
|
||||
|
||||
SeededServerKey {
|
||||
rgsw_cts,
|
||||
auto_keys,
|
||||
lwe_ksk,
|
||||
parameters,
|
||||
seed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ServerKeyEvaluationDomain<M, R, N> {
|
||||
/// Rgsw cts of LWE secret elements
|
||||
rgsw_cts: Vec<M>,
|
||||
/// Galois keys
|
||||
galois_keys: HashMap<isize, M>,
|
||||
/// LWE ksk to key switching LWE ciphertext from RLWE secret to LWE secret
|
||||
lwe_ksk: M,
|
||||
_phanton: PhantomData<(R, N)>,
|
||||
}
|
||||
|
||||
impl<
|
||||
M: MatrixMut + MatrixEntity,
|
||||
R: RandomUniformDist<[M::MatElement], Parameters = M::MatElement> + NewWithSeed,
|
||||
N: NttInit<Element = M::MatElement> + Ntt<Element = M::MatElement>,
|
||||
> From<&SeededServerKey<M, BoolParameters<M::MatElement>, R::Seed>>
|
||||
for ServerKeyEvaluationDomain<M, 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 {
|
||||
let mut main_prng = R::new_with_seed(value.seed.clone());
|
||||
|
||||
let g = value.parameters.g as isize;
|
||||
let ring_size = value.parameters.rlwe_n;
|
||||
let lwe_n = value.parameters.lwe_n;
|
||||
let d_rgsw = value.parameters.d_rgsw;
|
||||
let d_lwe = value.parameters.d_lwe;
|
||||
let rlwe_q = value.parameters.rlwe_q;
|
||||
let lwq_q = value.parameters.lwe_q;
|
||||
|
||||
let nttop = N::new(rlwe_q, ring_size);
|
||||
|
||||
// galois keys
|
||||
let mut auto_keys = HashMap::new();
|
||||
for i in [g, -g] {
|
||||
let seeded_auto_key = value.auto_keys.get(&i).unwrap();
|
||||
assert!(seeded_auto_key.dimension() == (d_rgsw, ring_size));
|
||||
|
||||
let mut data = M::zeros(d_rgsw * 2, ring_size);
|
||||
|
||||
// sample RLWE'_A(-s(X^k))
|
||||
data.iter_rows_mut().take(d_rgsw).for_each(|ri| {
|
||||
RandomUniformDist::random_fill(&mut main_prng, &rlwe_q, ri.as_mut())
|
||||
});
|
||||
|
||||
// copy over RLWE'B_(-s(X^k))
|
||||
izip!(
|
||||
data.iter_rows_mut().skip(d_rgsw),
|
||||
seeded_auto_key.iter_rows()
|
||||
)
|
||||
.for_each(|(to_ri, from_ri)| to_ri.as_mut().copy_from_slice(from_ri.as_ref()));
|
||||
|
||||
// Send to Evaluation domain
|
||||
data.iter_rows_mut()
|
||||
.for_each(|ri| nttop.forward(ri.as_mut()));
|
||||
|
||||
auto_keys.insert(i, data);
|
||||
}
|
||||
|
||||
// RGSW ciphertexts
|
||||
let rgsw_cts = value
|
||||
.rgsw_cts
|
||||
.iter()
|
||||
.map(|seeded_rgsw_si| {
|
||||
assert!(seeded_rgsw_si.dimension() == (3 * d_rgsw, ring_size));
|
||||
|
||||
let mut data = M::zeros(d_rgsw * 4, ring_size);
|
||||
|
||||
// copy over RLWE'(-sm)
|
||||
izip!(
|
||||
data.iter_rows_mut().take(d_rgsw * 2),
|
||||
seeded_rgsw_si.iter_rows().take(d_rgsw * 2)
|
||||
)
|
||||
.for_each(|(to_ri, from_ri)| to_ri.as_mut().copy_from_slice(from_ri.as_ref()));
|
||||
|
||||
// sample RLWE'_A(m)
|
||||
data.iter_rows_mut()
|
||||
.skip(2 * d_rgsw)
|
||||
.take(d_rgsw)
|
||||
.for_each(|ri| {
|
||||
RandomUniformDist::random_fill(&mut main_prng, &rlwe_q, ri.as_mut())
|
||||
});
|
||||
|
||||
// copy over RLWE'_B(m)
|
||||
izip!(
|
||||
data.iter_rows_mut().skip(d_rgsw * 3),
|
||||
seeded_rgsw_si.iter_rows().skip(d_rgsw * 2)
|
||||
)
|
||||
.for_each(|(to_ri, from_ri)| to_ri.as_mut().copy_from_slice(from_ri.as_ref()));
|
||||
|
||||
// send polynomials to evaluation domain
|
||||
data.iter_rows_mut()
|
||||
.for_each(|ri| nttop.forward(ri.as_mut()));
|
||||
|
||||
data
|
||||
})
|
||||
.collect_vec();
|
||||
|
||||
// LWE ksk
|
||||
let lwe_ksk = {
|
||||
assert!(value.lwe_ksk.as_ref().len() == d_lwe * ring_size);
|
||||
|
||||
let mut data = M::zeros(d_lwe * ring_size, lwe_n + 1);
|
||||
izip!(data.iter_rows_mut(), value.lwe_ksk.as_ref().iter()).for_each(|(lwe_i, bi)| {
|
||||
RandomUniformDist::random_fill(&mut main_prng, &lwq_q, &mut lwe_i.as_mut()[1..]);
|
||||
lwe_i.as_mut()[0] = *bi;
|
||||
});
|
||||
|
||||
data
|
||||
};
|
||||
|
||||
ServerKeyEvaluationDomain {
|
||||
rgsw_cts,
|
||||
galois_keys: auto_keys,
|
||||
lwe_ksk,
|
||||
_phanton: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME(Jay): Figure out a way for BoolEvaluator to have access to ServerKey
|
||||
// via a pointer and implement PbsKey for BoolEvaluator instead of ServerKey
|
||||
// directly
|
||||
impl<M: Matrix> PbsKey for ServerKey<M> {
|
||||
impl<M: Matrix, R, N> PbsKey for ServerKeyEvaluationDomain<M, R, N> {
|
||||
type M = M;
|
||||
fn galois_key_for_auto(&self, k: isize) -> &Self::M {
|
||||
self.galois_keys.get(&k).unwrap()
|
||||
@@ -123,6 +276,7 @@ impl<M: Matrix> PbsKey for ServerKey<M> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct BoolParameters<El> {
|
||||
rlwe_q: El,
|
||||
rlwe_logq: usize,
|
||||
@@ -170,7 +324,8 @@ where
|
||||
<M as Matrix>::R: RowMut,
|
||||
DefaultSecureRng: RandomGaussianDist<[M::MatElement], Parameters = M::MatElement>
|
||||
+ RandomGaussianDist<M::MatElement, Parameters = M::MatElement>
|
||||
+ RandomUniformDist<[M::MatElement], Parameters = M::MatElement>,
|
||||
+ RandomUniformDist<[M::MatElement], Parameters = M::MatElement>
|
||||
+ NewWithSeed,
|
||||
{
|
||||
fn new(parameters: BoolParameters<M::MatElement>) -> Self {
|
||||
//TODO(Jay): Run sanity checks for modulus values in parameters
|
||||
@@ -285,104 +440,104 @@ where
|
||||
ClientKey { sk_rlwe, sk_lwe }
|
||||
}
|
||||
|
||||
fn server_key(&self, client_key: &ClientKey) -> ServerKey<M> {
|
||||
// let sk_rlwe = &client_key.sk_rlwe;
|
||||
// let sk_lwe = &client_key.sk_lwe;
|
||||
fn server_key(
|
||||
&self,
|
||||
client_key: &ClientKey,
|
||||
) -> SeededServerKey<M, BoolParameters<M::MatElement>, [u8; 32]> {
|
||||
DefaultSecureRng::with_local_mut(|rng| {
|
||||
let mut main_seed = [0u8; 32];
|
||||
rng.fill_bytes(&mut main_seed);
|
||||
|
||||
// let d_rgsw_gadget_vec = gadget_vector(
|
||||
// self.parameters.rlwe_logq,
|
||||
// self.parameters.logb_rgsw,
|
||||
// self.parameters.d_rgsw,
|
||||
// );
|
||||
let mut main_prng = DefaultSecureRng::new_seeded(main_seed);
|
||||
|
||||
// // generate galois key -g, g
|
||||
// let mut galois_keys = HashMap::new();
|
||||
// let g = self.parameters.g as isize;
|
||||
// for i in [g, -g] {
|
||||
// let gk = DefaultSecureRng::with_local_mut(|rng| {
|
||||
// let mut ksk_out = M::zeros(self.parameters.d_rgsw * 2,
|
||||
// self.parameters.rlwe_n); galois_key_gen(
|
||||
// &mut ksk_out,
|
||||
// sk_rlwe,
|
||||
// i,
|
||||
// &d_rgsw_gadget_vec,
|
||||
// &self.rlwe_modop,
|
||||
// &self.rlwe_nttop,
|
||||
// rng,
|
||||
// );
|
||||
// ksk_out
|
||||
// });
|
||||
let sk_rlwe = &client_key.sk_rlwe;
|
||||
let sk_lwe = &client_key.sk_lwe;
|
||||
|
||||
// galois_keys.insert(i, gk);
|
||||
// }
|
||||
let d_rgsw_gadget_vec = gadget_vector(
|
||||
self.parameters.rlwe_logq,
|
||||
self.parameters.logb_rgsw,
|
||||
self.parameters.d_rgsw,
|
||||
);
|
||||
|
||||
// // generate rgsw ciphertexts RGSW(si) where si is i^th LWE secret element
|
||||
// let ring_size = self.parameters.rlwe_n;
|
||||
// let rlwe_q = self.parameters.rlwe_q;
|
||||
// let rgsw_cts = sk_lwe
|
||||
// .values()
|
||||
// .iter()
|
||||
// .map(|si| {
|
||||
// // X^{si}; assume |emebedding_factor * si| < N
|
||||
// let mut m = M::zeros(1, ring_size);
|
||||
// let si = (self.embedding_factor as i32) * si;
|
||||
// // dbg!(si);
|
||||
// if si < 0 {
|
||||
// // X^{-i} = X^{2N - i} = -X^{N-i}
|
||||
// m.set(
|
||||
// 0,
|
||||
// ring_size - (si.abs() as usize),
|
||||
// rlwe_q - M::MatElement::one(),
|
||||
// );
|
||||
// } else {
|
||||
// // X^{i}
|
||||
// m.set(0, (si.abs() as usize), M::MatElement::one());
|
||||
// }
|
||||
// self.rlwe_nttop.forward(m.get_row_mut(0));
|
||||
// generate auto keys -g, g
|
||||
let mut auto_keys = HashMap::new();
|
||||
let g = self.parameters.g as isize;
|
||||
for i in [g, -g] {
|
||||
let mut gk = M::zeros(self.parameters.d_rgsw, self.parameters.rlwe_n);
|
||||
galois_key_gen(
|
||||
&mut gk,
|
||||
sk_rlwe.values(),
|
||||
i,
|
||||
&d_rgsw_gadget_vec,
|
||||
&self.rlwe_modop,
|
||||
&self.rlwe_nttop,
|
||||
&mut main_prng,
|
||||
rng,
|
||||
);
|
||||
auto_keys.insert(i, gk);
|
||||
}
|
||||
|
||||
// let rgsw_si = DefaultSecureRng::with_local_mut(|rng| {
|
||||
// let mut rgsw_si = M::zeros(self.parameters.d_rgsw * 4,
|
||||
// ring_size); secret_key_encrypt_rgsw(
|
||||
// &mut rgsw_si,
|
||||
// &m,
|
||||
// &d_rgsw_gadget_vec,
|
||||
// sk_rlwe,
|
||||
// &self.rlwe_modop,
|
||||
// &self.rlwe_nttop,
|
||||
// rng,
|
||||
// );
|
||||
// rgsw_si
|
||||
// });
|
||||
// rgsw_si
|
||||
// })
|
||||
// .collect_vec();
|
||||
// generate rgsw ciphertexts RGSW(si) where si is i^th LWE secret element
|
||||
let ring_size = self.parameters.rlwe_n;
|
||||
let rlwe_q = self.parameters.rlwe_q;
|
||||
let rgsw_cts = sk_lwe
|
||||
.values()
|
||||
.iter()
|
||||
.map(|si| {
|
||||
// X^{si}; assume |emebedding_factor * si| < N
|
||||
let mut m = M::R::zeros(ring_size);
|
||||
let si = (self.embedding_factor as i32) * si;
|
||||
// dbg!(si);
|
||||
if si < 0 {
|
||||
// X^{-i} = X^{2N - i} = -X^{N-i}
|
||||
m.as_mut()[ring_size - (si.abs() as usize)] = rlwe_q - M::MatElement::one();
|
||||
} else {
|
||||
// X^{i}
|
||||
m.as_mut()[si.abs() as usize] = M::MatElement::one();
|
||||
}
|
||||
|
||||
// // LWE KSK from RLWE secret s -> LWE secret z
|
||||
// let d_lwe_gadget = gadget_vector(
|
||||
// self.parameters.lwe_logq,
|
||||
// self.parameters.logb_lwe,
|
||||
// self.parameters.d_lwe,
|
||||
// );
|
||||
// let mut lwe_ksk = DefaultSecureRng::with_local_mut(|rng| {
|
||||
// let mut out = M::zeros(self.parameters.d_lwe * ring_size,
|
||||
// self.parameters.lwe_n + 1); lwe_ksk_keygen(
|
||||
// &sk_rlwe.values(),
|
||||
// &sk_lwe.values(),
|
||||
// &mut out,
|
||||
// &d_lwe_gadget,
|
||||
// &self.lwe_modop,
|
||||
// rng,
|
||||
// );
|
||||
// out
|
||||
// });
|
||||
let mut rgsw_si = M::zeros(self.parameters.d_rgsw * 3, ring_size);
|
||||
secret_key_encrypt_rgsw(
|
||||
&mut rgsw_si,
|
||||
&m,
|
||||
&d_rgsw_gadget_vec,
|
||||
sk_rlwe.values(),
|
||||
&self.rlwe_modop,
|
||||
&self.rlwe_nttop,
|
||||
&mut main_prng,
|
||||
rng,
|
||||
);
|
||||
|
||||
// ServerKey {
|
||||
// rgsw_cts,
|
||||
// galois_keys,
|
||||
// lwe_ksk,
|
||||
// }
|
||||
rgsw_si
|
||||
})
|
||||
.collect_vec();
|
||||
|
||||
todo!()
|
||||
// LWE KSK from RLWE secret s -> LWE secret z
|
||||
let d_lwe_gadget = gadget_vector(
|
||||
self.parameters.lwe_logq,
|
||||
self.parameters.logb_lwe,
|
||||
self.parameters.d_lwe,
|
||||
);
|
||||
|
||||
let mut lwe_ksk = M::R::zeros(self.parameters.d_lwe * ring_size);
|
||||
lwe_ksk_keygen(
|
||||
&sk_rlwe.values(),
|
||||
&sk_lwe.values(),
|
||||
&mut lwe_ksk,
|
||||
&d_lwe_gadget,
|
||||
&self.lwe_modop,
|
||||
&mut main_prng,
|
||||
rng,
|
||||
);
|
||||
|
||||
SeededServerKey::from_raw(
|
||||
auto_keys,
|
||||
rgsw_cts,
|
||||
lwe_ksk,
|
||||
self.parameters.clone(),
|
||||
main_seed,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// TODO(Jay): Fetch client key from thread local
|
||||
@@ -434,7 +589,7 @@ where
|
||||
&self,
|
||||
c0: &M::R,
|
||||
c1: &M::R,
|
||||
server_key: &ServerKey<M>,
|
||||
server_key: &ServerKeyEvaluationDomain<M, DefaultSecureRng, NttOp>,
|
||||
scratch_lwen_plus1: &mut M::R,
|
||||
scratch_matrix_dplus2_ring: &mut M,
|
||||
) -> M::R {
|
||||
@@ -984,7 +1139,7 @@ mod tests {
|
||||
lwe_n: 493,
|
||||
d_rgsw: 3,
|
||||
logb_rgsw: 8,
|
||||
d_lwe: 2,
|
||||
d_lwe: 3,
|
||||
logb_lwe: 4,
|
||||
g: 5,
|
||||
w: 1,
|
||||
@@ -996,7 +1151,7 @@ mod tests {
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn encrypt_decrypt_works() {
|
||||
fn bool_encrypt_decrypt_works() {
|
||||
// let prime = generate_prime(32, 2 * 1024, 1 << 32);
|
||||
// dbg!(prime);
|
||||
let bool_evaluator =
|
||||
@@ -1014,18 +1169,22 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trial12() {
|
||||
// DefaultSecureRng::with_local_mut(|r| {
|
||||
// let rng = DefaultSecureRng::new_seeded([19u8; 32]);
|
||||
// *r = rng;
|
||||
// });
|
||||
fn bool_nand() {
|
||||
DefaultSecureRng::with_local_mut(|r| {
|
||||
let rng = DefaultSecureRng::new_seeded([19u8; 32]);
|
||||
*r = rng;
|
||||
});
|
||||
|
||||
let bool_evaluator =
|
||||
BoolEvaluator::<Vec<Vec<u64>>, u64, NttBackendU64, ModularOpsU64>::new(SP_BOOL_PARAMS);
|
||||
|
||||
// println!("{:?}", bool_evaluator.nand_test_vec);
|
||||
let client_key = bool_evaluator.client_key();
|
||||
let server_key = bool_evaluator.server_key(&client_key);
|
||||
let seeded_server_key = bool_evaluator.server_key(&client_key);
|
||||
let server_key_eval_domain =
|
||||
ServerKeyEvaluationDomain::<_, DefaultSecureRng, NttBackendU64>::from(
|
||||
&seeded_server_key,
|
||||
);
|
||||
|
||||
let mut scratch_lwen_plus1 = vec![0u64; bool_evaluator.parameters.lwe_n + 1];
|
||||
let mut scratch_matrix_dplus2_ring = vec![
|
||||
@@ -1037,11 +1196,11 @@ mod tests {
|
||||
let mut m1 = true;
|
||||
let mut ct0 = bool_evaluator.encrypt(m0, &client_key);
|
||||
let mut ct1 = bool_evaluator.encrypt(m1, &client_key);
|
||||
for _ in 0..100 {
|
||||
for _ in 0..1000 {
|
||||
let ct_back = bool_evaluator.nand(
|
||||
&ct0,
|
||||
&ct1,
|
||||
&server_key,
|
||||
&server_key_eval_domain,
|
||||
&mut scratch_lwen_plus1,
|
||||
&mut scratch_matrix_dplus2_ring,
|
||||
);
|
||||
|
||||
13
src/lwe.rs
13
src/lwe.rs
@@ -131,16 +131,15 @@ pub fn lwe_ksk_keygen<
|
||||
Ro: Row + RowMut + RowEntity,
|
||||
S,
|
||||
Op: VectorOps<Element = Ro::Element> + ArithmeticOps<Element = Ro::Element>,
|
||||
R: RandomGaussianDist<Ro::Element, Parameters = Ro::Element>
|
||||
+ RandomUniformDist<[Ro::Element], Parameters = Ro::Element>
|
||||
+ NewWithSeed,
|
||||
R: RandomGaussianDist<Ro::Element, Parameters = Ro::Element>,
|
||||
PR: RandomUniformDist<[Ro::Element], Parameters = Ro::Element>,
|
||||
>(
|
||||
from_lwe_sk: &[S],
|
||||
to_lwe_sk: &[S],
|
||||
ksk_out: &mut Ro,
|
||||
gadget: &[Ro::Element],
|
||||
seed: R::Seed,
|
||||
operator: &Op,
|
||||
p_rng: &mut PR,
|
||||
rng: &mut R,
|
||||
) where
|
||||
Ro: TryConvertFrom<[S], Parameters = Ro::Element>,
|
||||
@@ -156,13 +155,12 @@ pub fn lwe_ksk_keygen<
|
||||
let sk_out_m = Ro::try_convert_from(to_lwe_sk, &modulus);
|
||||
|
||||
let mut scratch = Ro::zeros(to_lwe_sk.len());
|
||||
let mut p_rng = R::new_with_seed(seed);
|
||||
|
||||
izip!(neg_sk_in_m.as_ref(), ksk_out.as_mut().chunks_mut(d)).for_each(
|
||||
|(neg_sk_in_si, d_lwes_partb)| {
|
||||
izip!(gadget.iter(), d_lwes_partb.into_iter()).for_each(|(f, lwe_b)| {
|
||||
// sample `a`
|
||||
RandomUniformDist::random_fill(&mut p_rng, &modulus, scratch.as_mut());
|
||||
RandomUniformDist::random_fill(p_rng, &modulus, scratch.as_mut());
|
||||
|
||||
// a * z
|
||||
let mut az = Ro::Element::zero();
|
||||
@@ -345,14 +343,15 @@ mod tests {
|
||||
rng.fill_bytes(&mut ksk_seed);
|
||||
let mut seeded_ksk =
|
||||
SeededLweKeySwitchingKey::empty(lwe_in_n, lwe_out_n, d_ks, ksk_seed, q);
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(ksk_seed);
|
||||
let gadget = gadget_vector(logq, logb, d_ks);
|
||||
lwe_ksk_keygen(
|
||||
&lwe_sk_in.values(),
|
||||
&lwe_sk_out.values(),
|
||||
&mut seeded_ksk.data,
|
||||
&gadget,
|
||||
seeded_ksk.seed,
|
||||
&modq_op,
|
||||
&mut p_rng,
|
||||
&mut rng,
|
||||
);
|
||||
// println!("{:?}", ksk);
|
||||
|
||||
63
src/rgsw.rs
63
src/rgsw.rs
@@ -383,9 +383,8 @@ pub(crate) fn rlwe_ksk_gen<
|
||||
Mmut: MatrixMut + MatrixEntity,
|
||||
ModOp: ArithmeticOps<Element = Mmut::MatElement> + VectorOps<Element = Mmut::MatElement>,
|
||||
NttOp: Ntt<Element = Mmut::MatElement>,
|
||||
R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement>
|
||||
+ RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>
|
||||
+ NewWithSeed,
|
||||
R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement>,
|
||||
PR: RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>,
|
||||
>(
|
||||
ksk_out: &mut Mmut,
|
||||
neg_from_s: Mmut::R,
|
||||
@@ -393,7 +392,7 @@ pub(crate) fn rlwe_ksk_gen<
|
||||
gadget_vector: &[Mmut::MatElement],
|
||||
mod_op: &ModOp,
|
||||
ntt_op: &NttOp,
|
||||
seed: R::Seed,
|
||||
p_rng: &mut PR,
|
||||
rng: &mut R,
|
||||
) where
|
||||
<Mmut as Matrix>::R: RowMut,
|
||||
@@ -409,9 +408,8 @@ pub(crate) fn rlwe_ksk_gen<
|
||||
// RLWE'_{to_s}(-from_s)
|
||||
let mut part_a = {
|
||||
let mut a = Mmut::zeros(d, ring_size);
|
||||
let mut p_rng = R::new_with_seed(seed);
|
||||
a.iter_rows_mut()
|
||||
.for_each(|ai| RandomUniformDist::random_fill(&mut p_rng, &q, ai.as_mut()));
|
||||
.for_each(|ai| RandomUniformDist::random_fill(p_rng, &q, ai.as_mut()));
|
||||
a
|
||||
};
|
||||
izip!(
|
||||
@@ -443,9 +441,8 @@ pub(crate) fn galois_key_gen<
|
||||
ModOp: ArithmeticOps<Element = Mmut::MatElement> + VectorOps<Element = Mmut::MatElement>,
|
||||
NttOp: Ntt<Element = Mmut::MatElement>,
|
||||
S,
|
||||
R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement>
|
||||
+ RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>
|
||||
+ NewWithSeed,
|
||||
R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement>,
|
||||
PR: RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>,
|
||||
>(
|
||||
ksk_out: &mut Mmut,
|
||||
s: &[S],
|
||||
@@ -453,7 +450,7 @@ pub(crate) fn galois_key_gen<
|
||||
gadget_vector: &[Mmut::MatElement],
|
||||
mod_op: &ModOp,
|
||||
ntt_op: &NttOp,
|
||||
seed: R::Seed,
|
||||
p_rng: &mut PR,
|
||||
rng: &mut R,
|
||||
) where
|
||||
<Mmut as Matrix>::R: RowMut,
|
||||
@@ -488,7 +485,7 @@ pub(crate) fn galois_key_gen<
|
||||
gadget_vector,
|
||||
mod_op,
|
||||
ntt_op,
|
||||
seed,
|
||||
p_rng,
|
||||
rng,
|
||||
);
|
||||
}
|
||||
@@ -731,8 +728,8 @@ pub(crate) fn secret_key_encrypt_rgsw<
|
||||
Mmut: MatrixMut + MatrixEntity,
|
||||
S,
|
||||
R: RandomGaussianDist<[Mmut::MatElement], Parameters = Mmut::MatElement>
|
||||
+ RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>
|
||||
+ NewWithSeed,
|
||||
+ RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>,
|
||||
PR: RandomUniformDist<[Mmut::MatElement], Parameters = Mmut::MatElement>,
|
||||
ModOp: VectorOps<Element = Mmut::MatElement>,
|
||||
NttOp: Ntt<Element = Mmut::MatElement>,
|
||||
>(
|
||||
@@ -742,13 +739,11 @@ pub(crate) fn secret_key_encrypt_rgsw<
|
||||
s: &[S],
|
||||
mod_op: &ModOp,
|
||||
ntt_op: &NttOp,
|
||||
seed: R::Seed,
|
||||
p_rng: &mut PR,
|
||||
rng: &mut R,
|
||||
) where
|
||||
<Mmut as Matrix>::R:
|
||||
RowMut + RowEntity + TryConvertFrom<[S], Parameters = Mmut::MatElement> + Debug,
|
||||
Mmut::MatElement: Copy + Debug,
|
||||
Mmut: Debug,
|
||||
<Mmut as Matrix>::R: RowMut + RowEntity + TryConvertFrom<[S], Parameters = Mmut::MatElement>,
|
||||
Mmut::MatElement: Copy,
|
||||
{
|
||||
let d = gadget_vector.len();
|
||||
let q = mod_op.modulus();
|
||||
@@ -793,10 +788,9 @@ pub(crate) fn secret_key_encrypt_rgsw<
|
||||
// RLWE(m)
|
||||
let mut a_rlwe_dash_m = {
|
||||
// polynomials of part A of RLWE'(m) are sampled from seed
|
||||
let mut p_rng = R::new_with_seed(seed);
|
||||
let mut a = Mmut::zeros(d, ring_size);
|
||||
a.iter_rows_mut()
|
||||
.for_each(|ai| RandomUniformDist::random_fill(&mut p_rng, &q, ai.as_mut()));
|
||||
.for_each(|ai| RandomUniformDist::random_fill(p_rng, &q, ai.as_mut()));
|
||||
a
|
||||
};
|
||||
|
||||
@@ -832,16 +826,15 @@ pub(crate) fn secret_key_encrypt_rlwe<
|
||||
ModOp: VectorOps<Element = Ro::Element>,
|
||||
NttOp: Ntt<Element = Ro::Element>,
|
||||
S,
|
||||
R: RandomUniformDist<[Ro::Element], Parameters = Ro::Element>
|
||||
+ RandomGaussianDist<[Ro::Element], Parameters = Ro::Element>
|
||||
+ NewWithSeed,
|
||||
R: RandomGaussianDist<[Ro::Element], Parameters = Ro::Element>,
|
||||
PR: RandomUniformDist<[Ro::Element], Parameters = Ro::Element>,
|
||||
>(
|
||||
m: &Ro,
|
||||
b_rlwe_out: &mut Ro,
|
||||
s: &[S],
|
||||
mod_op: &ModOp,
|
||||
ntt_op: &NttOp,
|
||||
seed: R::Seed,
|
||||
p_rng: &mut PR,
|
||||
rng: &mut R,
|
||||
) where
|
||||
Ro: TryConvertFrom<[S], Parameters = Ro::Element> + Debug,
|
||||
@@ -855,8 +848,7 @@ pub(crate) fn secret_key_encrypt_rlwe<
|
||||
// sample a
|
||||
let mut a = {
|
||||
let mut a = Ro::zeros(ring_size);
|
||||
let mut p_rng = R::new_with_seed(seed);
|
||||
RandomUniformDist::random_fill(&mut p_rng, &q, a.as_mut());
|
||||
RandomUniformDist::random_fill(p_rng, &q, a.as_mut());
|
||||
a
|
||||
};
|
||||
|
||||
@@ -982,7 +974,7 @@ mod tests {
|
||||
backend::{ModInit, ModularOpsU64},
|
||||
decomposer::{gadget_vector, DefaultDecomposer},
|
||||
ntt::{self, Ntt, NttBackendU64, NttInit},
|
||||
random::{DefaultSecureRng, RandomUniformDist},
|
||||
random::{DefaultSecureRng, NewWithSeed, RandomUniformDist},
|
||||
rgsw::{
|
||||
measure_noise, AutoKeyEvaluationDomain, RgswCiphertextEvaluationDomain, RlweCiphertext,
|
||||
SeededAutoKey, SeededRgswCiphertext, SeededRlweCiphertext,
|
||||
@@ -1020,6 +1012,7 @@ mod tests {
|
||||
rng.fill_bytes(&mut rlwe_seed);
|
||||
let mut seeded_rlwe_in_ct =
|
||||
SeededRlweCiphertext::<_, [u8; 32]>::empty(ring_size as usize, rlwe_seed, q);
|
||||
let mut p_rng = DefaultSecureRng::new_with_seed(rlwe_seed);
|
||||
let encoded_m = m0
|
||||
.iter()
|
||||
.map(|v| (((*v as f64) * q as f64) / (p as f64)).round() as u64)
|
||||
@@ -1030,7 +1023,7 @@ mod tests {
|
||||
s.values(),
|
||||
&mod_op,
|
||||
&ntt_op,
|
||||
seeded_rlwe_in_ct.seed,
|
||||
&mut p_rng,
|
||||
&mut rng,
|
||||
);
|
||||
let rlwe_in_ct =
|
||||
@@ -1046,7 +1039,7 @@ mod tests {
|
||||
);
|
||||
let m_back = encoded_m_back
|
||||
.iter()
|
||||
.map(|v| ((*v as f64 * p as f64) / q as f64).round() as u64)
|
||||
.map(|v| (((*v as f64 * p as f64) / q as f64).round() as u64) % p)
|
||||
.collect_vec();
|
||||
assert_eq!(m0, m_back);
|
||||
}
|
||||
@@ -1082,6 +1075,7 @@ mod tests {
|
||||
rgsw_seed,
|
||||
q,
|
||||
);
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(rgsw_seed);
|
||||
let gadget_vector = gadget_vector(logq, logb, d_rgsw);
|
||||
secret_key_encrypt_rgsw(
|
||||
&mut seeded_rgsw_ct.data,
|
||||
@@ -1090,7 +1084,7 @@ mod tests {
|
||||
s.values(),
|
||||
&mod_op,
|
||||
&ntt_op,
|
||||
seeded_rgsw_ct.seed,
|
||||
&mut p_rng,
|
||||
&mut rng,
|
||||
);
|
||||
let rgsw_ct = RgswCiphertextEvaluationDomain::<_, DefaultSecureRng, NttBackendU64>::from(
|
||||
@@ -1102,6 +1096,7 @@ mod tests {
|
||||
rng.fill_bytes(&mut rlwe_seed);
|
||||
let mut seeded_rlwe_in_ct =
|
||||
SeededRlweCiphertext::<_, [u8; 32]>::empty(ring_size as usize, rlwe_seed, q);
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(rlwe_seed);
|
||||
let encoded_m = m0
|
||||
.iter()
|
||||
.map(|v| (((*v as f64) * q as f64) / (p as f64)).round() as u64)
|
||||
@@ -1112,7 +1107,7 @@ mod tests {
|
||||
s.values(),
|
||||
&mod_op,
|
||||
&ntt_op,
|
||||
seeded_rlwe_in_ct.seed,
|
||||
&mut p_rng,
|
||||
&mut rng,
|
||||
);
|
||||
let mut rlwe_in_ct =
|
||||
@@ -1181,13 +1176,14 @@ mod tests {
|
||||
let mut seed_rlwe = [0u8; 32];
|
||||
rng.fill_bytes(&mut seed_rlwe);
|
||||
let mut seeded_rlwe_m = SeededRlweCiphertext::empty(ring_size as usize, seed_rlwe, q);
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(seed_rlwe);
|
||||
secret_key_encrypt_rlwe(
|
||||
&encoded_m,
|
||||
&mut seeded_rlwe_m.data,
|
||||
s.values(),
|
||||
&mod_op,
|
||||
&ntt_op,
|
||||
seeded_rlwe_m.seed,
|
||||
&mut p_rng,
|
||||
&mut rng,
|
||||
);
|
||||
let mut rlwe_m = RlweCiphertext::<Vec<Vec<u64>>, DefaultSecureRng>::from(&seeded_rlwe_m);
|
||||
@@ -1198,6 +1194,7 @@ mod tests {
|
||||
let mut seed_auto = [0u8; 32];
|
||||
rng.fill_bytes(&mut seed_auto);
|
||||
let mut seeded_auto_key = SeededAutoKey::empty(ring_size as usize, d_rgsw, seed_auto, q);
|
||||
let mut p_rng = DefaultSecureRng::new_seeded(seed_auto);
|
||||
let gadget_vector = gadget_vector(logq, logb, d_rgsw);
|
||||
galois_key_gen(
|
||||
&mut seeded_auto_key.data,
|
||||
@@ -1206,7 +1203,7 @@ mod tests {
|
||||
&gadget_vector,
|
||||
&mod_op,
|
||||
&ntt_op,
|
||||
seeded_auto_key.seed,
|
||||
&mut p_rng,
|
||||
&mut rng,
|
||||
);
|
||||
let auto_key =
|
||||
|
||||
Reference in New Issue
Block a user