|
|
@ -17,8 +17,14 @@ use crate::Ring; |
|
|
|
/// since if using a fixed-size array it would overflow the stack.
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct TR<R: Ring, const K: usize>(pub Vec<R>);
|
|
|
|
// TODO rm pub from Vec<R>, so that TR can not be created from a Vec with
|
|
|
|
// invalid length, since it has to be created using the `new` method.
|
|
|
|
|
|
|
|
impl<R: Ring, const K: usize> TR<R, K> {
|
|
|
|
pub fn new(v: Vec<R>) -> Self {
|
|
|
|
assert_eq!(v.len(), K);
|
|
|
|
Self(v)
|
|
|
|
}
|
|
|
|
pub fn zero() -> Self {
|
|
|
|
Self((0..K).into_iter().map(|_| R::zero()).collect())
|
|
|
|
}
|
|
|
@ -37,6 +43,20 @@ impl TR { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<const K: usize> TR<crate::torus::T64, K> {
|
|
|
|
pub fn mod_switch<const Q2: u64>(&self) -> TR<crate::torus::T64, K> {
|
|
|
|
TR(self.0.iter().map(|c_i| c_i.mod_switch::<Q2>()).collect())
|
|
|
|
}
|
|
|
|
// pub fn mod_switch(&self, Q2: u64) -> TR<crate::torus::T64, K> {
|
|
|
|
// TR(self.0.iter().map(|c_i| c_i.mod_switch(Q2)).collect())
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
impl<const N: usize, const K: usize> TR<crate::ring_torus::Tn<N>, K> {
|
|
|
|
pub fn left_rotate(&self, h: usize) -> Self {
|
|
|
|
TR(self.0.iter().map(|c_i| c_i.left_rotate(h)).collect())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<R: Ring, const K: usize> TR<R, K> {
|
|
|
|
pub fn iter(&self) -> std::slice::Iter<R> {
|
|
|
|
self.0.iter()
|
|
|
|