From e23ee338c8668e4df8c457a15db7bfc19641e9ae Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bossuat Date: Thu, 2 Jan 2025 18:05:16 +0100 Subject: [PATCH] wip --- Cargo.toml | 22 +--- README.md | 2 +- math/Cargo.toml | 20 +++ {benches => math/benches}/ntt.rs | 0 {benches => math/benches}/operations.rs | 5 +- {examples => math/examples}/main.rs | 1 - {src => math/src}/dft.rs | 0 {src => math/src}/dft/ntt.rs | 1 + {src => math/src}/lib.rs | 2 + {src => math/src}/modulus.rs | 10 +- {src => math/src}/modulus/barrett.rs | 0 {src => math/src}/modulus/impl_u64/barrett.rs | 0 .../src}/modulus/impl_u64/generation.rs | 0 {src => math/src}/modulus/impl_u64/mod.rs | 0 .../src}/modulus/impl_u64/montgomery.rs | 0 .../src}/modulus/impl_u64/operations.rs | 17 ++- {src => math/src}/modulus/impl_u64/prime.rs | 0 {src => math/src}/modulus/montgomery.rs | 0 {src => math/src}/modulus/prime.rs | 0 math/src/poly.rs | 58 +++++++++ {src => math/src}/poly/poly.rs | 0 {src => math/src}/ring.rs | 5 +- .../src}/ring/impl_u64/automorphism.rs | 0 math/src/ring/impl_u64/mod.rs | 3 + math/src/ring/impl_u64/ring.rs | 102 ++++++++++++++++ math/src/ring/impl_u64/ring_rns.rs | 114 ++++++++++++++++++ src/poly.rs | 29 ----- src/ring/impl_u64/mod.rs | 2 - src/ring/impl_u64/ring.rs | 53 -------- 29 files changed, 331 insertions(+), 115 deletions(-) create mode 100644 math/Cargo.toml rename {benches => math/benches}/ntt.rs (100%) rename {benches => math/benches}/operations.rs (98%) rename {examples => math/examples}/main.rs (98%) rename {src => math/src}/dft.rs (100%) rename {src => math/src}/dft/ntt.rs (99%) rename {src => math/src}/lib.rs (99%) rename {src => math/src}/modulus.rs (90%) rename {src => math/src}/modulus/barrett.rs (100%) rename {src => math/src}/modulus/impl_u64/barrett.rs (100%) rename {src => math/src}/modulus/impl_u64/generation.rs (100%) rename {src => math/src}/modulus/impl_u64/mod.rs (100%) rename {src => math/src}/modulus/impl_u64/montgomery.rs (100%) rename {src => math/src}/modulus/impl_u64/operations.rs (87%) rename {src => math/src}/modulus/impl_u64/prime.rs (100%) rename {src => math/src}/modulus/montgomery.rs (100%) rename {src => math/src}/modulus/prime.rs (100%) create mode 100644 math/src/poly.rs rename {src => math/src}/poly/poly.rs (100%) rename {src => math/src}/ring.rs (79%) rename {src => math/src}/ring/impl_u64/automorphism.rs (100%) create mode 100644 math/src/ring/impl_u64/mod.rs create mode 100644 math/src/ring/impl_u64/ring.rs create mode 100644 math/src/ring/impl_u64/ring_rns.rs delete mode 100644 src/poly.rs delete mode 100644 src/ring/impl_u64/mod.rs delete mode 100644 src/ring/impl_u64/ring.rs diff --git a/Cargo.toml b/Cargo.toml index fdc7dd2..eecba5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,20 +1,2 @@ -[package] -name = "math" -version = "0.1.0" -edition = "2021" - -[dependencies] -primality-test = "0.3.0" -num-bigint = "0.4.6" -num-traits = "0.2.19" -prime_factorization = "1.0.5" -itertools = "0.13.0" -criterion = "0.5.1" - -[[bench]] -name = "ntt" -harness = false - -[[bench]] -name = "operations" -harness = false \ No newline at end of file +[workspace] +members = ["math"] \ No newline at end of file diff --git a/README.md b/README.md index 09aa116..c3a697e 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# math \ No newline at end of file +# app \ No newline at end of file diff --git a/math/Cargo.toml b/math/Cargo.toml new file mode 100644 index 0000000..fdc7dd2 --- /dev/null +++ b/math/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "math" +version = "0.1.0" +edition = "2021" + +[dependencies] +primality-test = "0.3.0" +num-bigint = "0.4.6" +num-traits = "0.2.19" +prime_factorization = "1.0.5" +itertools = "0.13.0" +criterion = "0.5.1" + +[[bench]] +name = "ntt" +harness = false + +[[bench]] +name = "operations" +harness = false \ No newline at end of file diff --git a/benches/ntt.rs b/math/benches/ntt.rs similarity index 100% rename from benches/ntt.rs rename to math/benches/ntt.rs diff --git a/benches/operations.rs b/math/benches/operations.rs similarity index 98% rename from benches/operations.rs rename to math/benches/operations.rs index 4a15e9f..b0ed1c9 100644 --- a/benches/operations.rs +++ b/math/benches/operations.rs @@ -2,9 +2,8 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use math::ring::Ring; use math::modulus::VecOperations; use math::modulus::montgomery::Montgomery; -use math::modulus::{BARRETT, ONCE}; - -const CHUNK: usize= 8; +use math::modulus::ONCE; +use math::CHUNK; fn vec_add_unary(c: &mut Criterion) { fn runner(r: Ring) -> Box { diff --git a/examples/main.rs b/math/examples/main.rs similarity index 98% rename from examples/main.rs rename to math/examples/main.rs index dd68ecb..8b932af 100644 --- a/examples/main.rs +++ b/math/examples/main.rs @@ -1,4 +1,3 @@ -extern crate math; use math::ring::Ring; use math::modulus::prime::Prime; use math::dft::ntt::Table; diff --git a/src/dft.rs b/math/src/dft.rs similarity index 100% rename from src/dft.rs rename to math/src/dft.rs diff --git a/src/dft/ntt.rs b/math/src/dft/ntt.rs similarity index 99% rename from src/dft/ntt.rs rename to math/src/dft/ntt.rs index 730f84b..f987fde 100644 --- a/src/dft/ntt.rs +++ b/math/src/dft/ntt.rs @@ -7,6 +7,7 @@ use crate::modulus::ONCE; use crate::dft::DFT; use itertools::izip; +#[allow(dead_code)] pub struct Table{ prime:Prime, psi: O, diff --git a/src/lib.rs b/math/src/lib.rs similarity index 99% rename from src/lib.rs rename to math/src/lib.rs index 1306749..3dba2fe 100644 --- a/src/lib.rs +++ b/math/src/lib.rs @@ -6,6 +6,8 @@ pub mod dft; pub mod ring; pub mod poly; +pub const CHUNK: usize= 8; + pub mod macros{ #[macro_export] diff --git a/src/modulus.rs b/math/src/modulus.rs similarity index 90% rename from src/modulus.rs rename to math/src/modulus.rs index 3f37d0c..7f1adb4 100644 --- a/src/modulus.rs +++ b/math/src/modulus.rs @@ -72,7 +72,10 @@ pub trait WordOperations{ fn word_sub_unary_assign(&self, a: &O, b: &mut O); // Assigns -a to a. - fn word_neg_assign(&self, a:&mut O); + fn word_neg_unary_assign(&self, a:&mut O); + + // Assigns -a to b. + fn word_neg_binary_assign(&self, a: &O, b:&mut O); // Assigns a * 2^64 to b. fn word_prepare_montgomery_assign(&self, a: &O, b: &mut montgomery::Montgomery); @@ -102,7 +105,10 @@ pub trait VecOperations{ fn vec_sub_unary_assign(&self, a: &[O], b: &mut [O]); // Assigns -a[i] to a[i]. - fn vec_neg_assign(&self, a: &mut [O]); + fn vec_neg_unary_assign(&self, a: &mut [O]); + + // Assigns -a[i] to a[i]. + fn vec_neg_binary_assign(&self, a: &[O], b: &mut [O]); // Assigns a * 2^64 to b. fn vec_prepare_montgomery_assign(&self, a: &[O], b: &mut [montgomery::Montgomery]); diff --git a/src/modulus/barrett.rs b/math/src/modulus/barrett.rs similarity index 100% rename from src/modulus/barrett.rs rename to math/src/modulus/barrett.rs diff --git a/src/modulus/impl_u64/barrett.rs b/math/src/modulus/impl_u64/barrett.rs similarity index 100% rename from src/modulus/impl_u64/barrett.rs rename to math/src/modulus/impl_u64/barrett.rs diff --git a/src/modulus/impl_u64/generation.rs b/math/src/modulus/impl_u64/generation.rs similarity index 100% rename from src/modulus/impl_u64/generation.rs rename to math/src/modulus/impl_u64/generation.rs diff --git a/src/modulus/impl_u64/mod.rs b/math/src/modulus/impl_u64/mod.rs similarity index 100% rename from src/modulus/impl_u64/mod.rs rename to math/src/modulus/impl_u64/mod.rs diff --git a/src/modulus/impl_u64/montgomery.rs b/math/src/modulus/impl_u64/montgomery.rs similarity index 100% rename from src/modulus/impl_u64/montgomery.rs rename to math/src/modulus/impl_u64/montgomery.rs diff --git a/src/modulus/impl_u64/operations.rs b/math/src/modulus/impl_u64/operations.rs similarity index 87% rename from src/modulus/impl_u64/operations.rs rename to math/src/modulus/impl_u64/operations.rs index a91d039..7f41c92 100644 --- a/src/modulus/impl_u64/operations.rs +++ b/math/src/modulus/impl_u64/operations.rs @@ -44,11 +44,17 @@ impl WordOperations for Prime{ } #[inline(always)] - fn word_neg_assign(&self, a: &mut u64){ + fn word_neg_unary_assign(&self, a: &mut u64){ *a = self.q.wrapping_sub(*a); self.word_reduce_assign::(a) } + #[inline(always)] + fn word_neg_binary_assign(&self, a: &u64, b: &mut u64){ + *b = self.q.wrapping_sub(*a); + self.word_reduce_assign::(b) + } + #[inline(always)] fn word_prepare_montgomery_assign(&self, a: &u64, b: &mut Montgomery){ self.montgomery.prepare_assign::(*a, b); @@ -100,8 +106,13 @@ impl VecOperations for Prime{ } #[inline(always)] - fn vec_neg_assign(&self, a: &mut [u64]){ - apply_unary!(self, Self::word_neg_assign::, a, CHUNK); + fn vec_neg_unary_assign(&self, a: &mut [u64]){ + apply_unary!(self, Self::word_neg_unary_assign::, a, CHUNK); + } + + #[inline(always)] + fn vec_neg_binary_assign(&self, a: &[u64], b: &mut [u64]){ + apply_binary!(self, Self::word_neg_binary_assign::, a, b, CHUNK); } #[inline(always)] diff --git a/src/modulus/impl_u64/prime.rs b/math/src/modulus/impl_u64/prime.rs similarity index 100% rename from src/modulus/impl_u64/prime.rs rename to math/src/modulus/impl_u64/prime.rs diff --git a/src/modulus/montgomery.rs b/math/src/modulus/montgomery.rs similarity index 100% rename from src/modulus/montgomery.rs rename to math/src/modulus/montgomery.rs diff --git a/src/modulus/prime.rs b/math/src/modulus/prime.rs similarity index 100% rename from src/modulus/prime.rs rename to math/src/modulus/prime.rs diff --git a/math/src/poly.rs b/math/src/poly.rs new file mode 100644 index 0000000..83f4f02 --- /dev/null +++ b/math/src/poly.rs @@ -0,0 +1,58 @@ +pub mod poly; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Poly(pub Vec); + +impl Polywhere + O: Default + Clone, + { + 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 n(&self) -> usize{ + return self.0.len() + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct PolyRNS(pub Vec>); + +impl PolyRNSwhere + O: Default + Clone, + { + pub fn new(n: usize) -> Self{ + Self(vec![Poly::::new(n);n]) + } + + pub fn n(&self) -> usize{ + self.0[0].n() + } + + pub fn level(&self) -> usize{ + self.0.len()-1 + } + + pub fn buffer_size(&self) -> usize{ + self.n() * (self.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); + } + } +} \ No newline at end of file diff --git a/src/poly/poly.rs b/math/src/poly/poly.rs similarity index 100% rename from src/poly/poly.rs rename to math/src/poly/poly.rs diff --git a/src/ring.rs b/math/src/ring.rs similarity index 79% rename from src/ring.rs rename to math/src/ring.rs index d26868b..8bb9a1d 100644 --- a/src/ring.rs +++ b/math/src/ring.rs @@ -8,4 +8,7 @@ pub struct Ring{ pub n:usize, pub modulus:Prime, pub dft:Box>, -} \ No newline at end of file +} + + +pub struct RingRNS(pub Vec>); \ No newline at end of file diff --git a/src/ring/impl_u64/automorphism.rs b/math/src/ring/impl_u64/automorphism.rs similarity index 100% rename from src/ring/impl_u64/automorphism.rs rename to math/src/ring/impl_u64/automorphism.rs diff --git a/math/src/ring/impl_u64/mod.rs b/math/src/ring/impl_u64/mod.rs new file mode 100644 index 0000000..8e359a7 --- /dev/null +++ b/math/src/ring/impl_u64/mod.rs @@ -0,0 +1,3 @@ +pub mod automorphism; +pub mod ring; +pub mod ring_rns; \ No newline at end of file diff --git a/math/src/ring/impl_u64/ring.rs b/math/src/ring/impl_u64/ring.rs new file mode 100644 index 0000000..728475f --- /dev/null +++ b/math/src/ring/impl_u64/ring.rs @@ -0,0 +1,102 @@ +use crate::ring::Ring; +use crate::dft::ntt::Table; +use crate::modulus::prime::Prime; +use crate::modulus::montgomery::Montgomery; +use crate::poly::Poly; +use crate::modulus::REDUCEMOD; +use crate::modulus::VecOperations; +use crate::CHUNK; + +impl Ring{ + pub fn new(n:usize, q_base:u64, q_power:usize) -> Self{ + let prime: Prime = Prime::::new(q_base, q_power); + Self { + n: n, + modulus: prime.clone(), + dft: Box::new(Table::::new(prime, (2 * n) as u64)), + } + } + + pub fn n(&self) -> usize{ + return self.n + } + + pub fn new_poly(&self) -> Poly{ + Poly::::new(self.n()) + } +} + +impl Ring{ + pub fn ntt_inplace(&self, poly: &mut Poly){ + match LAZY{ + true => self.dft.forward_inplace_lazy(&mut poly.0), + false => self.dft.forward_inplace(&mut poly.0) + } + } + + pub fn intt_inplace(&self, poly: &mut Poly){ + match LAZY{ + true => self.dft.forward_inplace_lazy(&mut poly.0), + false => self.dft.forward_inplace(&mut poly.0) + } + } + + pub fn ntt(&self, poly_in: &Poly, poly_out: &mut Poly){ + poly_out.0.copy_from_slice(&poly_in.0); + match LAZY{ + true => self.dft.backward_inplace_lazy(&mut poly_out.0), + false => self.dft.backward_inplace(&mut poly_out.0) + } + } + + pub fn intt(&self, poly_in: &Poly, poly_out: &mut Poly){ + poly_out.0.copy_from_slice(&poly_in.0); + match LAZY{ + true => self.dft.backward_inplace_lazy(&mut poly_out.0), + false => self.dft.backward_inplace(&mut poly_out.0) + } + } +} + +impl Ring{ + + #[inline(always)] + pub fn add_inplace(&self, a: &Poly, b: &mut Poly){ + self.modulus.vec_add_unary_assign::(&a.0, &mut b.0); + } + + #[inline(always)] + pub fn add(&self, a: &Poly, b: &Poly, c: &mut Poly){ + self.modulus.vec_add_binary_assign::(&a.0, &b.0, &mut c.0); + } + + #[inline(always)] + pub fn sub_inplace(&self, a: &Poly, b: &mut Poly){ + self.modulus.vec_sub_unary_assign::(&a.0, &mut b.0); + } + + #[inline(always)] + pub fn sub(&self, a: &Poly, b: &Poly, c: &mut Poly){ + self.modulus.vec_sub_binary_assign::(&a.0, &b.0, &mut c.0); + } + + #[inline(always)] + pub fn neg(&self, a: &Poly, b: &mut Poly){ + self.modulus.vec_neg_binary_assign::(&a.0, &mut b.0); + } + + #[inline(always)] + pub fn neg_inplace(&self, a: &mut Poly){ + self.modulus.vec_neg_unary_assign::(&mut a.0); + } + + #[inline(always)] + pub fn mul_montgomery_external(&self, a:&Poly>, b:&Poly, c: &mut Poly){ + self.modulus.vec_mul_montgomery_external_binary_assign::(&a.0, &b.0, &mut c.0); + } + + #[inline(always)] + pub fn mul_montgomery_external_inplace(&self, a:&Poly>, b:&mut Poly){ + self.modulus.vec_mul_montgomery_external_unary_assign::(&a.0, &mut b.0); + } +} \ No newline at end of file diff --git a/math/src/ring/impl_u64/ring_rns.rs b/math/src/ring/impl_u64/ring_rns.rs new file mode 100644 index 0000000..069038a --- /dev/null +++ b/math/src/ring/impl_u64/ring_rns.rs @@ -0,0 +1,114 @@ +use crate::ring::{Ring, RingRNS}; +use crate::poly::PolyRNS; +use crate::modulus::montgomery::Montgomery; +use crate::modulus::REDUCEMOD; + +impl RingRNS{ + pub fn new(n:usize, moduli: Vec) -> Self{ + assert!(!moduli.is_empty(), "moduli cannot be empty"); + let rings: Vec> = moduli + .into_iter() + .map(|prime: u64| Ring::new(n, prime, 1)) + .collect(); + RingRNS(rings) + } + + pub fn n(&self) -> usize{ + self.0[0].n() + } + + pub fn max_level(&self) -> usize{ + self.0.len()-1 + } +} + +impl RingRNS{ + +} + +impl RingRNS{ + + #[inline(always)] + pub fn add(&self, a: &PolyRNS, b: &PolyRNS, c: &mut PolyRNS){ + debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL); + debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n()); + debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n()); + debug_assert!(c.n() >= self.n(), "c.n()={} < n={}", c.n(), self.n()); + debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL); + debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL); + debug_assert!(c.level() >= LEVEL, "c.level()={} < LEVEL={}", c.level(), LEVEL); + self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.add::(&a.0[i], &b.0[i], &mut c.0[i])); + } + + #[inline(always)] + pub fn add_inplace(&self, a: &PolyRNS, b: &mut PolyRNS){ + debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL); + debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n()); + debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n()); + debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL); + debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL); + self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.add_inplace::(&a.0[i], &mut b.0[i])); + } + + #[inline(always)] + pub fn sub(&self, a: &PolyRNS, b: &PolyRNS, c: &mut PolyRNS){ + debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL); + debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n()); + debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n()); + debug_assert!(c.n() >= self.n(), "c.n()={} < n={}", c.n(), self.n()); + debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL); + debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL); + debug_assert!(c.level() >= LEVEL, "c.level()={} < LEVEL={}", c.level(), LEVEL); + self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.sub::(&a.0[i], &b.0[i], &mut c.0[i])); + } + + #[inline(always)] + pub fn sub_inplace(&self, a: &PolyRNS, b: &mut PolyRNS){ + debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL); + debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n()); + debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n()); + debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL); + debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL); + self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.sub_inplace::(&a.0[i], &mut b.0[i])); + } + + #[inline(always)] + pub fn neg(&self, a: &PolyRNS, b: &mut PolyRNS){ + debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL); + debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n()); + debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n()); + debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL); + debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL); + self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.neg::(&a.0[i], &mut b.0[i])); + } + + #[inline(always)] + pub fn neg_inplace(&self, a: &mut PolyRNS){ + debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL); + debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n()); + debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL); + self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.neg_inplace::(&mut a.0[i])); + } + + #[inline(always)] + pub fn mul_montgomery_external(&self, a:&PolyRNS>, b:&PolyRNS, c: &mut PolyRNS){ + debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL); + debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n()); + debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n()); + debug_assert!(c.n() >= self.n(), "c.n()={} < n={}", c.n(), self.n()); + debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL); + debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL); + debug_assert!(c.level() >= LEVEL, "c.level()={} < LEVEL={}", c.level(), LEVEL); + self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.mul_montgomery_external::(&a.0[i], &b.0[i], &mut c.0[i])); + } + + #[inline(always)] + pub fn mul_montgomery_external_inplace(&self, a:&PolyRNS>, b:&mut PolyRNS){ + debug_assert!(self.max_level() <= LEVEL, "max_level={} < LEVEL={}", self.max_level(), LEVEL); + debug_assert!(a.n() >= self.n(), "a.n()={} < n={}", a.n(), self.n()); + debug_assert!(b.n() >= self.n(), "b.n()={} < n={}", b.n(), self.n()); + debug_assert!(a.level() >= LEVEL, "a.level()={} < LEVEL={}", a.level(), LEVEL); + debug_assert!(b.level() >= LEVEL, "b.level()={} < LEVEL={}", b.level(), LEVEL); + self.0.iter().take(LEVEL + 1).enumerate().for_each(|(i, ring)| ring.mul_montgomery_external_inplace::(&a.0[i], &mut b.0[i])); + } +} \ No newline at end of file diff --git a/src/poly.rs b/src/poly.rs deleted file mode 100644 index c7cccd3..0000000 --- a/src/poly.rs +++ /dev/null @@ -1,29 +0,0 @@ -pub mod poly; - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Poly(pub Vec); - -impl Polywhere - O: Default + Clone, - { - pub fn new(n: usize) -> Self{ - Self(vec![O::default();n]) - } - - pub fn new_montgomery(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 n(&self) -> usize{ - return self.0.len() - } -} \ No newline at end of file diff --git a/src/ring/impl_u64/mod.rs b/src/ring/impl_u64/mod.rs deleted file mode 100644 index f21c8c0..0000000 --- a/src/ring/impl_u64/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod automorphism; -pub mod ring; \ No newline at end of file diff --git a/src/ring/impl_u64/ring.rs b/src/ring/impl_u64/ring.rs deleted file mode 100644 index de43a0a..0000000 --- a/src/ring/impl_u64/ring.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::ring::Ring; -use crate::dft::ntt::Table; -use crate::modulus::prime::Prime; -use crate::poly::Poly; - -impl Ring{ - pub fn new(n:usize, q_base:u64, q_power:usize) -> Self{ - let prime: Prime = Prime::::new(q_base, q_power); - Self { - n: n, - modulus: prime.clone(), - dft: Box::new(Table::::new(prime, (2 * n) as u64)), - } - } - - pub fn n(&self) -> usize{ - return self.n - } - - pub fn new_poly(&self) -> Poly{ - Poly::::new(self.n()) - } - - pub fn ntt_inplace(&self, poly: &mut Poly){ - match LAZY{ - true => self.dft.forward_inplace_lazy(&mut poly.0), - false => self.dft.forward_inplace(&mut poly.0) - } - } - - pub fn intt_inplace(&self, poly: &mut Poly){ - match LAZY{ - true => self.dft.forward_inplace_lazy(&mut poly.0), - false => self.dft.forward_inplace(&mut poly.0) - } - } - - pub fn ntt(&self, poly_in: &Poly, poly_out: &mut Poly){ - poly_out.0.copy_from_slice(&poly_in.0); - match LAZY{ - true => self.dft.backward_inplace_lazy(&mut poly_out.0), - false => self.dft.backward_inplace(&mut poly_out.0) - } - } - - pub fn intt(&self, poly_in: &Poly, poly_out: &mut Poly){ - poly_out.0.copy_from_slice(&poly_in.0); - match LAZY{ - true => self.dft.backward_inplace_lazy(&mut poly_out.0), - false => self.dft.backward_inplace(&mut poly_out.0) - } - } -} \ No newline at end of file