mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 05:06:44 +01:00
[prime]: nth_root does not mutate prime anymore
This commit is contained in:
@@ -3,8 +3,8 @@ use math::{modulus::prime::Prime,dft::ntt::Table};
|
||||
use math::dft::DFT;
|
||||
|
||||
fn forward_inplace(c: &mut Criterion) {
|
||||
fn runner<T: DFT<u64> + 'static>(prime_instance: &mut Prime<u64>, nth_root: u64) -> Box<dyn FnMut()+ '_> {
|
||||
let ntt_table: Table<'_, u64> = Table::<u64>::new(prime_instance, nth_root);
|
||||
fn runner<T: DFT<u64> + 'static>(prime_instance: Prime<u64>, nth_root: u64) -> Box<dyn FnMut()> {
|
||||
let ntt_table: Table<u64> = Table::<u64>::new(prime_instance, nth_root);
|
||||
let mut a: Vec<u64> = vec![0; (nth_root >> 1) as usize];
|
||||
for i in 0..a.len(){
|
||||
a[i] = i as u64;
|
||||
@@ -21,7 +21,7 @@ fn forward_inplace(c: &mut Criterion) {
|
||||
|
||||
let runners = [
|
||||
("prime", {
|
||||
runner::<Table<'_, u64>>(&mut prime_instance, 1<<log_nth_root)
|
||||
runner::<Table<u64>>(prime_instance, 1<<log_nth_root)
|
||||
}),
|
||||
];
|
||||
for (name, mut runner) in runners {
|
||||
@@ -32,8 +32,8 @@ fn forward_inplace(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
fn forward_inplace_lazy(c: &mut Criterion) {
|
||||
fn runner<T: DFT<u64> + 'static>(prime_instance: &mut Prime<u64>, nth_root: u64) -> Box<dyn FnMut()+ '_> {
|
||||
let ntt_table: Table<'_, u64> = Table::<u64>::new(prime_instance, nth_root);
|
||||
fn runner<T: DFT<u64> + 'static>(prime_instance: Prime<u64>, nth_root: u64) -> Box<dyn FnMut()> {
|
||||
let ntt_table: Table<u64> = Table::<u64>::new(prime_instance, nth_root);
|
||||
let mut a: Vec<u64> = vec![0; (nth_root >> 1) as usize];
|
||||
for i in 0..a.len(){
|
||||
a[i] = i as u64;
|
||||
@@ -46,11 +46,11 @@ fn forward_inplace_lazy(c: &mut Criterion) {
|
||||
let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> = c.benchmark_group("forward_inplace_lazy");
|
||||
for log_nth_root in 11..17 {
|
||||
|
||||
let mut prime_instance: Prime<u64> = Prime::<u64>::new(0x1fffffffffe00001, 1);
|
||||
let prime_instance: Prime<u64> = Prime::<u64>::new(0x1fffffffffe00001, 1);
|
||||
|
||||
let runners = [
|
||||
("prime", {
|
||||
runner::<Table<'_, u64>>(&mut prime_instance, 1<<log_nth_root)
|
||||
runner::<Table<u64>>(prime_instance, 1<<log_nth_root)
|
||||
}),
|
||||
];
|
||||
for (name, mut runner) in runners {
|
||||
@@ -61,8 +61,8 @@ fn forward_inplace_lazy(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
fn backward_inplace(c: &mut Criterion) {
|
||||
fn runner<T: DFT<u64> + 'static>(prime_instance: &mut Prime<u64>, nth_root: u64) -> Box<dyn FnMut()+ '_> {
|
||||
let ntt_table: Table<'_, u64> = Table::<u64>::new(prime_instance, nth_root);
|
||||
fn runner<T: DFT<u64> + 'static>(prime_instance: Prime<u64>, nth_root: u64) -> Box<dyn FnMut()> {
|
||||
let ntt_table: Table<u64> = Table::<u64>::new(prime_instance, nth_root);
|
||||
let mut a: Vec<u64> = vec![0; (nth_root >> 1) as usize];
|
||||
for i in 0..a.len(){
|
||||
a[i] = i as u64;
|
||||
@@ -75,11 +75,11 @@ fn backward_inplace(c: &mut Criterion) {
|
||||
let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> = c.benchmark_group("backward_inplace");
|
||||
for log_nth_root in 11..18 {
|
||||
|
||||
let mut prime_instance: Prime<u64> = Prime::<u64>::new(0x1fffffffffe00001, 1);
|
||||
let prime_instance: Prime<u64> = Prime::<u64>::new(0x1fffffffffe00001, 1);
|
||||
|
||||
let runners = [
|
||||
("prime", {
|
||||
runner::<Table<'_, u64>>(&mut prime_instance, 1<<log_nth_root)
|
||||
runner::<Table<u64>>(prime_instance, 1<<log_nth_root)
|
||||
}),
|
||||
];
|
||||
for (name, mut runner) in runners {
|
||||
@@ -90,8 +90,8 @@ fn backward_inplace(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
fn backward_inplace_lazy(c: &mut Criterion) {
|
||||
fn runner<T: DFT<u64> + 'static>(prime_instance: &mut Prime<u64>, nth_root: u64) -> Box<dyn FnMut()+ '_> {
|
||||
let ntt_table: Table<'_, u64> = Table::<u64>::new(prime_instance, nth_root);
|
||||
fn runner<T: DFT<u64> + 'static>(prime_instance: Prime<u64>, nth_root: u64) -> Box<dyn FnMut()> {
|
||||
let ntt_table: Table<u64> = Table::<u64>::new(prime_instance, nth_root);
|
||||
let mut a: Vec<u64> = vec![0; (nth_root >> 1) as usize];
|
||||
for i in 0..a.len(){
|
||||
a[i] = i as u64;
|
||||
@@ -104,11 +104,11 @@ fn backward_inplace_lazy(c: &mut Criterion) {
|
||||
let mut b: criterion::BenchmarkGroup<'_, criterion::measurement::WallTime> = c.benchmark_group("backward_inplace_lazy");
|
||||
for log_nth_root in 11..17 {
|
||||
|
||||
let mut prime_instance: Prime<u64> = Prime::<u64>::new(0x1fffffffffe00001, 1);
|
||||
let prime_instance: Prime<u64> = Prime::<u64>::new(0x1fffffffffe00001, 1);
|
||||
|
||||
let runners = [
|
||||
("prime", {
|
||||
runner::<Table<'_, u64>>(&mut prime_instance, 1<<log_nth_root)
|
||||
runner::<Table<u64>>(prime_instance, 1<<log_nth_root)
|
||||
}),
|
||||
];
|
||||
for (name, mut runner) in runners {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
extern crate math;
|
||||
use math::ring::Ring;
|
||||
use math::modulus::prime::Prime;
|
||||
use math::dft::ntt::Table;
|
||||
|
||||
fn main() {
|
||||
// Example usage of `Prime<u64>`
|
||||
let q_base: u64 = 0x1fffffffffe00001; // Example prime base
|
||||
let q_power: u64 = 1; // Example power
|
||||
let q_power: usize = 1; // Example power
|
||||
let mut prime_instance: Prime<u64> = Prime::<u64>::new(q_base, q_power);
|
||||
|
||||
// Display the fields of `Prime` to verify
|
||||
@@ -17,7 +18,7 @@ fn main() {
|
||||
let n: u64 = 1024;
|
||||
let nth_root: u64 = n<<1;
|
||||
|
||||
let ntt_table: Table<'_, u64> = Table::<u64>::new(&mut prime_instance, nth_root);
|
||||
let ntt_table: Table<u64> = Table::<u64>::new(prime_instance, nth_root);
|
||||
|
||||
let mut a: Vec<u64> = vec![0; (nth_root >> 1) as usize];
|
||||
|
||||
@@ -35,4 +36,6 @@ fn main() {
|
||||
|
||||
println!("{:?}", a);
|
||||
|
||||
let r : Ring<u64> = Ring::<u64>::new(n as usize, q_base, q_power);
|
||||
|
||||
}
|
||||
@@ -6,8 +6,8 @@ use crate::modulus::WordOps;
|
||||
use crate::dft::DFT;
|
||||
use itertools::izip;
|
||||
|
||||
pub struct Table<'a, O>{
|
||||
prime:&'a Prime<O>,
|
||||
pub struct Table<O>{
|
||||
prime:Prime<O>,
|
||||
psi_forward_rev:Vec<Shoup<u64>>,
|
||||
psi_backward_rev: Vec<Shoup<u64>>,
|
||||
q:O,
|
||||
@@ -15,8 +15,8 @@ pub struct Table<'a, O>{
|
||||
four_q:O,
|
||||
}
|
||||
|
||||
impl<'a> Table<'a, u64> {
|
||||
pub fn new(prime: &'a mut Prime<u64>, nth_root: u64)->Self{
|
||||
impl Table< u64> {
|
||||
pub fn new(prime: Prime<u64>, nth_root: u64)->Self{
|
||||
|
||||
assert!(nth_root&(nth_root-1) == 0, "invalid argument: nth_root = {} is not a power of two", nth_root);
|
||||
|
||||
@@ -47,13 +47,15 @@ impl<'a> Table<'a, u64> {
|
||||
psi_backward_rev[i_rev] = prime.shoup.prepare(powers_backward);
|
||||
}
|
||||
|
||||
let q: u64 = prime.q();
|
||||
|
||||
Self{
|
||||
prime: prime,
|
||||
psi_forward_rev: psi_forward_rev,
|
||||
psi_backward_rev: psi_backward_rev,
|
||||
q:prime.q(),
|
||||
two_q:prime.q()<<1,
|
||||
four_q:prime.q()<<2,
|
||||
q:q,
|
||||
two_q:q<<1,
|
||||
four_q:q<<2,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +66,7 @@ impl<'a> Table<'a, u64> {
|
||||
}
|
||||
|
||||
|
||||
impl<'a> DFT<u64> for Table<'a,u64>{
|
||||
impl DFT<u64> for Table<u64>{
|
||||
fn forward_inplace(&self, a: &mut [u64]){
|
||||
self.forward_inplace(a)
|
||||
}
|
||||
@@ -82,7 +84,7 @@ impl<'a> DFT<u64> for Table<'a,u64>{
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Table<'a,u64>{
|
||||
impl Table<u64>{
|
||||
|
||||
pub fn forward_inplace_lazy(&self, a: &mut [u64]){
|
||||
self.forward_inplace_core::<true>(a);
|
||||
|
||||
@@ -9,7 +9,7 @@ impl Prime<u64>{
|
||||
/// Returns a new instance of Prime<u64>.
|
||||
/// Panics if q_base is not a prime > 2 and
|
||||
/// if q_base^q_power would overflow u64.
|
||||
pub fn new(q_base: u64, q_power: u64) -> Self{
|
||||
pub fn new(q_base: u64, q_power: usize) -> Self{
|
||||
assert!(is_prime(q_base) && q_base > 2);
|
||||
Self::new_unchecked(q_base, q_power)
|
||||
}
|
||||
@@ -17,7 +17,7 @@ impl Prime<u64>{
|
||||
/// Returns a new instance of Prime<u64>.
|
||||
/// Does not check if q_base is a prime > 2.
|
||||
/// Panics if q_base^q_power would overflow u64.
|
||||
pub fn new_unchecked(q_base: u64, q_power: u64) -> Self {
|
||||
pub fn new_unchecked(q_base: u64, q_power: usize) -> Self {
|
||||
|
||||
let mut q = q_base;
|
||||
for _i in 1..q_power{
|
||||
@@ -31,7 +31,7 @@ impl Prime<u64>{
|
||||
phi *= q_base
|
||||
}
|
||||
|
||||
Self {
|
||||
let mut prime: Prime<u64> = Self {
|
||||
q:q,
|
||||
q_base:q_base,
|
||||
q_power:q_power,
|
||||
@@ -39,7 +39,12 @@ impl Prime<u64>{
|
||||
montgomery:MontgomeryPrecomp::new(q),
|
||||
shoup:ShoupPrecomp::new(q),
|
||||
phi:phi,
|
||||
}
|
||||
};
|
||||
|
||||
prime.check_factors();
|
||||
|
||||
prime
|
||||
|
||||
}
|
||||
|
||||
pub fn q(&self) -> u64{
|
||||
@@ -50,7 +55,7 @@ impl Prime<u64>{
|
||||
self.q_base
|
||||
}
|
||||
|
||||
pub fn q_power(&self) -> u64{
|
||||
pub fn q_power(&self) -> usize{
|
||||
self.q_power
|
||||
}
|
||||
|
||||
@@ -84,9 +89,7 @@ impl Prime<u64>{
|
||||
|
||||
impl Prime<u64>{
|
||||
/// Returns the smallest nth primitive root of q_base.
|
||||
pub fn primitive_root(&mut self) -> u64{
|
||||
|
||||
self.check_factors();
|
||||
pub fn primitive_root(&self) -> u64{
|
||||
|
||||
let mut candidate: u64 = 1u64;
|
||||
let mut not_found: bool = true;
|
||||
@@ -113,7 +116,7 @@ impl Prime<u64>{
|
||||
}
|
||||
|
||||
/// Returns an nth primitive root of q = q_base^q_power in Montgomery.
|
||||
pub fn primitive_nth_root(&mut self, nth_root:u64) -> u64{
|
||||
pub fn primitive_nth_root(&self, nth_root:u64) -> u64{
|
||||
|
||||
assert!(self.q & (nth_root-1) == 1, "invalid prime: q = {} % nth_root = {} = {} != 1", self.q, nth_root, self.q & (nth_root-1));
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::modulus::montgomery::{MontgomeryPrecomp, Montgomery};
|
||||
use crate::modulus::shoup::{ShoupPrecomp};
|
||||
|
||||
use crate::modulus::montgomery::MontgomeryPrecomp;
|
||||
use crate::modulus::shoup::ShoupPrecomp;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Prime<O> {
|
||||
pub q: O, /// q_base^q_powers
|
||||
pub q_base: O,
|
||||
pub q_power: O,
|
||||
pub q_power: usize,
|
||||
pub factors: Vec<O>, /// distinct factors of q-1
|
||||
pub montgomery: MontgomeryPrecomp<O>,
|
||||
pub shoup:ShoupPrecomp<O>,
|
||||
|
||||
@@ -14,6 +14,7 @@ impl<O> Shoup<O> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct ShoupPrecomp<O>{
|
||||
pub q: O,
|
||||
pub one: Shoup<O>,
|
||||
|
||||
@@ -7,5 +7,5 @@ use crate::dft::DFT;
|
||||
pub struct Ring<O>{
|
||||
pub n:usize,
|
||||
pub modulus:Prime<O>,
|
||||
pub dft:dyn DFT<O>,
|
||||
pub dft:Box<dyn DFT<O>>,
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
pub mod automorphism;
|
||||
pub mod automorphism;
|
||||
pub mod ring;
|
||||
23
src/ring/impl_u64/ring.rs
Normal file
23
src/ring/impl_u64/ring.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use crate::ring::Ring;
|
||||
use crate::dft::ntt::Table;
|
||||
use crate::modulus::prime::Prime;
|
||||
use crate::poly::Poly;
|
||||
|
||||
impl Ring<u64>{
|
||||
pub fn new(n:usize, q_base:u64, q_power:usize) -> Self{
|
||||
let prime: Prime<u64> = Prime::<u64>::new(q_base, q_power);
|
||||
Self {
|
||||
n: n,
|
||||
modulus: prime.clone(),
|
||||
dft: Box::new(Table::<u64>::new(prime, (2 * n) as u64)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn n(&self) -> usize{
|
||||
return self.n
|
||||
}
|
||||
|
||||
pub fn new_poly(&self) -> Poly<u64>{
|
||||
Poly::<u64>::new(self.n())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user