mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 13:16:44 +01:00
glwe packing
This commit is contained in:
@@ -6,8 +6,11 @@ use poulpy_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
GLWEAutomorphism, ScratchTakeCore,
|
GLWEAdd, GLWEAutomorphism, GLWENormalize, GLWERotate, GLWEShift, GLWESub, ScratchTakeCore,
|
||||||
layouts::{GGLWEInfos, GLWE, GLWEAlloc, GLWEInfos, GLWEToMut, GLWEToRef, LWEInfos, prepared::AutomorphismKeyPreparedToRef},
|
layouts::{
|
||||||
|
GGLWEInfos, GLWE, GLWEAlloc, GLWEInfos, GLWEToMut, GLWEToRef, LWEInfos,
|
||||||
|
prepared::{AutomorphismKeyPreparedToRef, GetAutomorphismGaloisElement},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// [GLWEPacker] enables only the fly GLWE packing
|
/// [GLWEPacker] enables only the fly GLWE packing
|
||||||
@@ -323,7 +326,14 @@ fn combine<B, M, K, BE: Backend>(
|
|||||||
|
|
||||||
pub trait GLWEPacking<BE: Backend>
|
pub trait GLWEPacking<BE: Backend>
|
||||||
where
|
where
|
||||||
Self: GLWEAutomorphism<BE> + GaloisElement + ModuleLogN,
|
Self: GLWEAutomorphism<BE>
|
||||||
|
+ GaloisElement
|
||||||
|
+ ModuleLogN
|
||||||
|
+ GLWERotate<BE>
|
||||||
|
+ GLWESub
|
||||||
|
+ GLWEShift<BE>
|
||||||
|
+ GLWEAdd
|
||||||
|
+ GLWENormalize<BE>,
|
||||||
{
|
{
|
||||||
/// Packs [x_0: GLWE(m_0), x_1: GLWE(m_1), ..., x_i: GLWE(m_i)]
|
/// Packs [x_0: GLWE(m_0), x_1: GLWE(m_1), ..., x_i: GLWE(m_i)]
|
||||||
/// to [0: GLWE(m_0 * X^x_0 + m_1 * X^x_1 + ... + m_i * X^x_i)]
|
/// to [0: GLWE(m_0 * X^x_0 + m_1 * X^x_1 + ... + m_i * X^x_i)]
|
||||||
@@ -334,8 +344,8 @@ where
|
|||||||
keys: &HashMap<i64, K>,
|
keys: &HashMap<i64, K>,
|
||||||
scratch: &mut Scratch<BE>,
|
scratch: &mut Scratch<BE>,
|
||||||
) where
|
) where
|
||||||
R: GLWEToMut,
|
R: GLWEToMut + GLWEToRef + GLWEInfos,
|
||||||
K: AutomorphismKeyPreparedToRef<BE>,
|
K: AutomorphismKeyPreparedToRef<BE> + GetAutomorphismGaloisElement,
|
||||||
Scratch<BE>: ScratchTakeCore<BE>,
|
Scratch<BE>: ScratchTakeCore<BE>,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -345,7 +355,7 @@ where
|
|||||||
|
|
||||||
let log_n: usize = self.log_n();
|
let log_n: usize = self.log_n();
|
||||||
|
|
||||||
(0..log_n - log_gap_out).for_each(|i| {
|
for i in 0..(log_n - log_gap_out){
|
||||||
let t: usize = (1 << log_n).min(1 << (log_n - 1 - i));
|
let t: usize = (1 << log_n).min(1 << (log_n - 1 - i));
|
||||||
|
|
||||||
let key: &K = if i == 0 {
|
let key: &K = if i == 0 {
|
||||||
@@ -354,7 +364,7 @@ where
|
|||||||
keys.get(&self.galois_element(1 << (i - 1))).unwrap()
|
keys.get(&self.galois_element(1 << (i - 1))).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
(0..t).for_each(|j| {
|
for j in 0..t{
|
||||||
let mut a: Option<&mut R> = cts.remove(&j);
|
let mut a: Option<&mut R> = cts.remove(&j);
|
||||||
let mut b: Option<&mut R> = cts.remove(&(j + t));
|
let mut b: Option<&mut R> = cts.remove(&(j + t));
|
||||||
|
|
||||||
@@ -365,8 +375,8 @@ where
|
|||||||
} else if let Some(b) = b {
|
} else if let Some(b) = b {
|
||||||
cts.insert(j, b);
|
cts.insert(j, b);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,10 +389,10 @@ fn pack_internal<M, A, B, K, BE: Backend>(
|
|||||||
auto_key: &K,
|
auto_key: &K,
|
||||||
scratch: &mut Scratch<BE>,
|
scratch: &mut Scratch<BE>,
|
||||||
) where
|
) where
|
||||||
M: GLWEAutomorphism<BE>,
|
M: GLWEAutomorphism<BE> + GLWERotate<BE> + GLWESub + GLWEShift<BE> + GLWEAdd + GLWENormalize<BE>,
|
||||||
A: GLWEToMut + GLWEInfos,
|
A: GLWEToMut + GLWEToRef + GLWEInfos,
|
||||||
B: GLWEToMut + GLWEInfos,
|
B: GLWEToMut + GLWEToRef + GLWEInfos,
|
||||||
K: AutomorphismKeyPreparedToRef<BE>,
|
K: AutomorphismKeyPreparedToRef<BE> + GetAutomorphismGaloisElement,
|
||||||
Scratch<BE>: ScratchTakeCore<BE>,
|
Scratch<BE>: ScratchTakeCore<BE>,
|
||||||
{
|
{
|
||||||
// Goal is to evaluate: a = a + b*X^t + phi(a - b*X^t))
|
// Goal is to evaluate: a = a + b*X^t + phi(a - b*X^t))
|
||||||
@@ -402,42 +412,42 @@ fn pack_internal<M, A, B, K, BE: Backend>(
|
|||||||
let (mut tmp_b, scratch_1) = scratch.take_glwe_ct(module, a);
|
let (mut tmp_b, scratch_1) = scratch.take_glwe_ct(module, a);
|
||||||
|
|
||||||
// a = a * X^-t
|
// a = a * X^-t
|
||||||
a.rotate_inplace(module, -t, scratch_1);
|
module.glwe_rotate_inplace(-t, a, scratch_1);
|
||||||
|
|
||||||
// tmp_b = a * X^-t - b
|
// tmp_b = a * X^-t - b
|
||||||
tmp_b.sub(module, a, b);
|
module.glwe_sub(&mut tmp_b, a, b);
|
||||||
tmp_b.rsh(module, 1, scratch_1);
|
module.glwe_rsh(1, &mut tmp_b, scratch_1);
|
||||||
|
|
||||||
// a = a * X^-t + b
|
// a = a * X^-t + b
|
||||||
a.add_inplace(module, b);
|
module.glwe_add_inplace(a, b);
|
||||||
a.rsh(module, 1, scratch_1);
|
module.glwe_rsh(1, a, scratch_1);
|
||||||
|
|
||||||
tmp_b.normalize_inplace(module, scratch_1);
|
module.glwe_normalize_inplace(&mut tmp_b, scratch_1);
|
||||||
|
|
||||||
// tmp_b = phi(a * X^-t - b)
|
// tmp_b = phi(a * X^-t - b)
|
||||||
tmp_b.automorphism_inplace(module, auto_key, scratch_1);
|
module.glwe_automorphism_inplace(&mut tmp_b, auto_key, scratch_1);
|
||||||
|
|
||||||
// a = a * X^-t + b - phi(a * X^-t - b)
|
// a = a * X^-t + b - phi(a * X^-t - b)
|
||||||
a.sub_inplace_ab(module, &tmp_b);
|
module.glwe_sub_inplace(a, &tmp_b);
|
||||||
a.normalize_inplace(module, scratch_1);
|
module.glwe_normalize_inplace(a, scratch_1);
|
||||||
|
|
||||||
// a = a + b * X^t - phi(a * X^-t - b) * X^t
|
// a = a + b * X^t - phi(a * X^-t - b) * X^t
|
||||||
// = a + b * X^t - phi(a * X^-t - b) * - phi(X^t)
|
// = a + b * X^t - phi(a * X^-t - b) * - phi(X^t)
|
||||||
// = a + b * X^t + phi(a - b * X^t)
|
// = a + b * X^t + phi(a - b * X^t)
|
||||||
a.rotate_inplace(module, t, scratch_1);
|
module.glwe_rotate_inplace(t, a, scratch_1);
|
||||||
} else {
|
} else {
|
||||||
a.rsh(module, 1, scratch);
|
module.glwe_rsh(1, a, scratch);
|
||||||
// a = a + phi(a)
|
// a = a + phi(a)
|
||||||
a.automorphism_add_inplace(module, auto_key, scratch);
|
module.glwe_automorphism_add_inplace(a, auto_key, scratch);
|
||||||
}
|
}
|
||||||
} else if let Some(b) = b.as_deref_mut() {
|
} else if let Some(b) = b.as_deref_mut() {
|
||||||
let t: i64 = 1 << (b.n().log2() - i - 1);
|
let t: i64 = 1 << (b.n().log2() - i - 1);
|
||||||
|
|
||||||
let (mut tmp_b, scratch_1) = scratch.take_glwe_ct(b);
|
let (mut tmp_b, scratch_1) = scratch.take_glwe_ct(module, b);
|
||||||
tmp_b.rotate(module, t, b);
|
module.glwe_rotate(t, &mut tmp_b, b);
|
||||||
tmp_b.rsh(module, 1, scratch_1);
|
module.glwe_rsh(1, &mut tmp_b, scratch_1);
|
||||||
|
|
||||||
// a = (b* X^t - phi(b* X^t))
|
// a = (b* X^t - phi(b* X^t))
|
||||||
b.automorphism_sub_negate(module, &tmp_b, auto_key, scratch_1);
|
module.glwe_automorphism_sub_negate(b, &tmp_b, auto_key, scratch_1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ where
|
|||||||
res.set_k(a.k().min(res.k()));
|
res.set_k(a.k().min(res.k()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_normalize_inplace<R>(&mut self, res: &mut R, scratch: &mut Scratch<BE>)
|
fn glwe_normalize_inplace<R>(&self, res: &mut R, scratch: &mut Scratch<BE>)
|
||||||
where
|
where
|
||||||
R: GLWEToMut,
|
R: GLWEToMut,
|
||||||
Scratch<BE>: ScratchTakeCore<BE>,
|
Scratch<BE>: ScratchTakeCore<BE>,
|
||||||
|
|||||||
Reference in New Issue
Block a user