mirror of
https://github.com/arnaucube/phantom-zone.git
synced 2026-01-12 00:51:29 +01:00
fix rounding in decom
This commit is contained in:
@@ -1156,8 +1156,8 @@ pub(crate) mod tests {
|
||||
let logq = 55;
|
||||
let ring_size = 1 << 11;
|
||||
let q = generate_prime(logq, ring_size as u64, 1u64 << logq).unwrap();
|
||||
let d = 12;
|
||||
let logb = 4;
|
||||
let d = 2;
|
||||
let logb = 12;
|
||||
let decomposer = DefaultDecomposer::new(q, logb, d);
|
||||
|
||||
let ntt_op = NttBackendU64::new(&q, ring_size as usize);
|
||||
@@ -1169,16 +1169,42 @@ pub(crate) mod tests {
|
||||
for _ in 0..10 {
|
||||
let mut a = vec![0u64; ring_size];
|
||||
RandomFillUniformInModulus::random_fill(&mut rng, &q, a.as_mut());
|
||||
let mut e = vec![1u64; ring_size];
|
||||
// RandomFillGaussianInModulus::random_fill(&mut rng, &q, e.as_mut());
|
||||
let mut m = vec![0u64; ring_size];
|
||||
RandomFillGaussianInModulus::random_fill(&mut rng, &q, m.as_mut());
|
||||
|
||||
let mut sk = vec![0u64; ring_size];
|
||||
RandomFillGaussianInModulus::random_fill(&mut rng, &q, sk.as_mut());
|
||||
let mut sk_eval = sk.clone();
|
||||
ntt_op.forward(sk_eval.as_mut_slice());
|
||||
|
||||
let gadget_vector = decomposer.gadget_vector();
|
||||
|
||||
// ksk (beta e)
|
||||
let mut ksk = vec![vec![0u64; ring_size]; decomposer.decomposition_count()];
|
||||
izip!(ksk.iter_rows_mut(), gadget_vector.iter()).for_each(|(row, beta)| {
|
||||
row.as_mut_slice().copy_from_slice(e.as_ref());
|
||||
mod_op.elwise_scalar_mul_mut(row.as_mut_slice(), beta);
|
||||
let mut ksk_part_b = vec![vec![0u64; ring_size]; decomposer.decomposition_count()];
|
||||
let mut ksk_part_a = vec![vec![0u64; ring_size]; decomposer.decomposition_count()];
|
||||
izip!(
|
||||
ksk_part_b.iter_rows_mut(),
|
||||
ksk_part_a.iter_rows_mut(),
|
||||
gadget_vector.iter()
|
||||
)
|
||||
.for_each(|(part_b, part_a, beta)| {
|
||||
RandomFillUniformInModulus::random_fill(&mut rng, &q, part_a.as_mut());
|
||||
|
||||
// a * s
|
||||
let mut tmp = part_a.to_vec();
|
||||
ntt_op.forward(tmp.as_mut());
|
||||
mod_op.elwise_mul_mut(tmp.as_mut(), sk_eval.as_ref());
|
||||
ntt_op.backward(tmp.as_mut());
|
||||
|
||||
// a*s + e + beta m
|
||||
RandomFillGaussianInModulus::random_fill(&mut rng, &q, part_b.as_mut());
|
||||
// println!("E: {:?}", &part_b);
|
||||
// a*s + e
|
||||
mod_op.elwise_add_mut(part_b.as_mut_slice(), tmp.as_ref());
|
||||
// a*s + e + beta m
|
||||
let mut tmp = m.to_vec();
|
||||
mod_op.elwise_scalar_mul_mut(tmp.as_mut_slice(), beta);
|
||||
mod_op.elwise_add_mut(part_b.as_mut_slice(), tmp.as_ref());
|
||||
});
|
||||
|
||||
// decompose a
|
||||
@@ -1195,35 +1221,60 @@ pub(crate) mod tests {
|
||||
|
||||
// println!("Last limb");
|
||||
|
||||
// decomp_a * ksk(beta e)
|
||||
ksk.iter_mut()
|
||||
// decomp_a * ksk(beta m)
|
||||
ksk_part_b
|
||||
.iter_mut()
|
||||
.for_each(|r| ntt_op.forward(r.as_mut_slice()));
|
||||
ksk_part_a
|
||||
.iter_mut()
|
||||
.for_each(|r| ntt_op.forward(r.as_mut_slice()));
|
||||
decomposed_a
|
||||
.iter_mut()
|
||||
.for_each(|r| ntt_op.forward(r.as_mut_slice()));
|
||||
let mut out = vec![0u64; ring_size];
|
||||
izip!(decomposed_a.iter(), ksk.iter()).for_each(|(a, b)| {
|
||||
// out += a * b
|
||||
let mut a_clone = a.clone();
|
||||
mod_op.elwise_mul_mut(a_clone.as_mut_slice(), b.as_ref());
|
||||
mod_op.elwise_add_mut(out.as_mut_slice(), a_clone.as_ref());
|
||||
});
|
||||
ntt_op.backward(out.as_mut_slice());
|
||||
let mut out = vec![vec![0u64; ring_size]; 2];
|
||||
izip!(decomposed_a.iter(), ksk_part_b.iter(), ksk_part_a.iter()).for_each(
|
||||
|(d_a, part_b, part_a)| {
|
||||
// out_a += d_a * part_a
|
||||
let mut d_a_clone = d_a.clone();
|
||||
mod_op.elwise_mul_mut(d_a_clone.as_mut_slice(), part_a.as_ref());
|
||||
mod_op.elwise_add_mut(out[0].as_mut_slice(), d_a_clone.as_ref());
|
||||
|
||||
// out_b += d_a * part_b
|
||||
let mut d_a_clone = d_a.clone();
|
||||
mod_op.elwise_mul_mut(d_a_clone.as_mut_slice(), part_b.as_ref());
|
||||
mod_op.elwise_add_mut(out[1].as_mut_slice(), d_a_clone.as_ref());
|
||||
},
|
||||
);
|
||||
out.iter_mut()
|
||||
.for_each(|r| ntt_op.backward(r.as_mut_slice()));
|
||||
|
||||
let out_back = {
|
||||
// decrypt
|
||||
// a*s
|
||||
ntt_op.forward(out[0].as_mut());
|
||||
mod_op.elwise_mul_mut(out[0].as_mut(), sk_eval.as_ref());
|
||||
ntt_op.backward(out[0].as_mut());
|
||||
|
||||
// b - a*s
|
||||
let tmp = (out[0]).clone();
|
||||
mod_op.elwise_sub_mut(out[1].as_mut(), tmp.as_ref());
|
||||
out.remove(1)
|
||||
};
|
||||
|
||||
let out_expected = {
|
||||
let mut a_clone = a.clone();
|
||||
let mut e_clone = e.clone();
|
||||
let mut m_clone = m.clone();
|
||||
|
||||
ntt_op.forward(a_clone.as_mut_slice());
|
||||
ntt_op.forward(e_clone.as_mut_slice());
|
||||
ntt_op.forward(m_clone.as_mut_slice());
|
||||
|
||||
mod_op.elwise_mul_mut(a_clone.as_mut_slice(), e_clone.as_mut_slice());
|
||||
mod_op.elwise_mul_mut(a_clone.as_mut_slice(), m_clone.as_mut_slice());
|
||||
ntt_op.backward(a_clone.as_mut_slice());
|
||||
a_clone
|
||||
};
|
||||
|
||||
let mut diff = out_expected;
|
||||
mod_op.elwise_sub_mut(diff.as_mut_slice(), out.as_ref());
|
||||
mod_op.elwise_sub_mut(diff.as_mut_slice(), out_back.as_ref());
|
||||
stats.add_more(&Vec::<i64>::try_convert_from(diff.as_ref(), &q));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user