pub mod poly; use std::cmp::min; use std::cmp::PartialEq; #[derive(Clone, Debug, Eq)] pub struct Poly(pub Vec); impl Poly where O: Default + Clone + Copy, { pub fn new(n: usize) -> Self { Self(vec![O::default(); n]) } pub fn buffer_size(&self) -> usize { return self.0.len(); } pub fn from_buffer(&mut self, n: usize, buf: &mut [O]) { assert!( buf.len() >= n, "invalid buffer: buf.len()={} < n={}", buf.len(), n ); self.0 = Vec::from(&buf[..n]); } pub fn log_n(&self) -> usize { (usize::BITS - (self.n() - 1).leading_zeros()) as usize } pub fn n(&self) -> usize { self.0.len() } pub fn resize(&mut self, n: usize) { self.0.resize(n, O::default()); } pub fn set(&mut self, v: &[O]) { let size: usize = min(v.len(), self.n()); self.0[..size].copy_from_slice(&v[..size]); } pub fn fill(&mut self, v: &O) { self.0.fill(*v) } pub fn zero(&mut self) { self.fill(&O::default()) } pub fn copy_from(&mut self, other: &Poly) { if std::ptr::eq(self, other) { return; } self.resize(other.n()); self.0.copy_from_slice(&other.0) } } impl PartialEq for Poly { fn eq(&self, other: &Self) -> bool { std::ptr::eq(self, other) || (self.0 == other.0) } } impl Default for Poly { fn default() -> Self { Poly(Vec::new()) } } #[derive(Clone, Debug, Eq)] pub struct PolyRNS(pub Vec>); impl PolyRNS where O: Default + Clone + Copy, { pub fn new(n: usize, level: usize) -> Self { let mut polyrns: PolyRNS = PolyRNS::::default(); let mut buf: Vec = vec![O::default(); polyrns.buffer_size(n, level)]; polyrns.from_buffer(n, level, &mut buf[..]); polyrns } pub fn n(&self) -> usize { self.0[0].n() } pub fn log_n(&self) -> usize { self.0[0].log_n() } pub fn level(&self) -> usize { self.0.len() - 1 } pub fn buffer_size(&self, n: usize, level: usize) -> usize { n * (level + 1) } pub fn from_buffer(&mut self, n: usize, level: usize, buf: &mut [O]) { assert!( buf.len() >= n * (level + 1), "invalid buffer: buf.len()={} < n * (level+1)={}", buf.len(), level + 1 ); self.0.clear(); for chunk in buf.chunks_mut(n).take(level + 1) { let mut poly: Poly = Poly(Vec::new()); poly.from_buffer(n, chunk); self.0.push(poly); } } pub fn resize(&mut self, level: usize) { self.0.resize(level + 1, Poly::::new(self.n())); } pub fn split_at_mut(&mut self, level: usize) -> (&mut [Poly], &mut [Poly]) { self.0.split_at_mut(level) } pub fn at(&self, level: usize) -> &Poly { assert!( level <= self.level(), "invalid argument level: level={} > self.level()={}", level, self.level() ); &self.0[level] } pub fn at_mut(&mut self, level: usize) -> &mut Poly { &mut self.0[level] } pub fn fill(&mut self, v: &O) { (0..self.level() + 1).for_each(|i| self.at_mut(i).fill(v)) } pub fn zero(&mut self) { self.fill(&O::default()) } pub fn copy(&mut self, other: &PolyRNS) { if std::ptr::eq(self, other) { return; } self.resize(other.level()); self.copy_level(other.level(), other); } pub fn copy_level(&mut self, level: usize, other: &PolyRNS) { assert!( self.level() <= level, "invalid argument level: level={} > self.level()={}", level, self.level() ); assert!( other.level() <= level, "invalid argument level: level={} > other.level()={}", level, other.level() ); (0..level + 1).for_each(|i| self.at_mut(i).copy_from(other.at(i))) } } impl PartialEq for PolyRNS { fn eq(&self, other: &Self) -> bool { std::ptr::eq(self, other) && (self.0 == other.0) } } impl Default for PolyRNS { fn default() -> Self { Self { 0: Vec::new() } } }