wip on plaintext ring packing

This commit is contained in:
Jean-Philippe Bossuat
2025-01-08 17:45:51 +01:00
parent c1ed2e38fa
commit 2b916b03c5
6 changed files with 106 additions and 3 deletions

View File

@@ -93,8 +93,14 @@ pub trait ScalarOperations<O> {
// Assigns -a to b. // Assigns -a to b.
fn sa_neg_into_sb<const SARANGE: u8, const REDUCE: REDUCEMOD>(&self, a: &O, b: &mut O); fn sa_neg_into_sb<const SARANGE: u8, const REDUCE: REDUCEMOD>(&self, a: &O, b: &mut O);
// Assigns a * 2^64 to a.
fn sa_prepare_montgomery_into_sa<const REDUCE: REDUCEMOD>(
&self,
a: &mut montgomery::Montgomery<O>,
);
// Assigns a * 2^64 to b. // Assigns a * 2^64 to b.
fn sa_prep_mont_into_sb<const REDUCE: REDUCEMOD>( fn sa_prepare_montgomery_into_sb<const REDUCE: REDUCEMOD>(
&self, &self,
a: &O, a: &O,
b: &mut montgomery::Montgomery<O>, b: &mut montgomery::Montgomery<O>,
@@ -252,6 +258,12 @@ pub trait VectorOperations<O> {
b: &mut [montgomery::Montgomery<O>], b: &mut [montgomery::Montgomery<O>],
); );
// vec(a) <- vec(a).
fn va_prepare_montgomery_into_va<const CHUNK: usize, const REDUCE: REDUCEMOD>(
&self,
a: &mut [montgomery::Montgomery<O>],
);
// vec(c) <- vec(a) * vec(b). // vec(c) <- vec(a) * vec(b).
fn va_mont_mul_vb_into_vc<const CHUNK: usize, const REDUCE: REDUCEMOD>( fn va_mont_mul_vb_into_vc<const CHUNK: usize, const REDUCE: REDUCEMOD>(
&self, &self,

View File

@@ -95,7 +95,12 @@ impl ScalarOperations<u64> for Prime<u64> {
} }
#[inline(always)] #[inline(always)]
fn sa_prep_mont_into_sb<const REDUCE: REDUCEMOD>(&self, a: &u64, b: &mut Montgomery<u64>) { fn sa_prepare_montgomery_into_sa<const REDUCE: REDUCEMOD>(&self, a: &mut Montgomery<u64>) {
*a = self.montgomery.prepare::<REDUCE>(*a);
}
#[inline(always)]
fn sa_prepare_montgomery_into_sb<const REDUCE: REDUCEMOD>(&self, a: &u64, b: &mut Montgomery<u64>) {
self.montgomery.prepare_assign::<REDUCE>(*a, b); self.montgomery.prepare_assign::<REDUCE>(*a, b);
} }
@@ -325,9 +330,17 @@ impl VectorOperations<u64> for Prime<u64> {
a: &[u64], a: &[u64],
b: &mut [Montgomery<u64>], b: &mut [Montgomery<u64>],
) { ) {
apply_vv!(self, Self::sa_prep_mont_into_sb::<REDUCE>, a, b, CHUNK); apply_vv!(self, Self::sa_prepare_montgomery_into_sb::<REDUCE>, a, b, CHUNK);
} }
#[inline(always)]
fn va_prepare_montgomery_into_va<const CHUNK: usize, const REDUCE: REDUCEMOD>(
&self,
a: &mut [Montgomery<u64>],
) {
apply_v!(self, Self::sa_prepare_montgomery_into_sa::<REDUCE>, a, CHUNK);
}
#[inline(always)] #[inline(always)]
fn va_mont_mul_vb_into_vc<const CHUNK: usize, const REDUCE: REDUCEMOD>( fn va_mont_mul_vb_into_vc<const CHUNK: usize, const REDUCE: REDUCEMOD>(
&self, &self,

View File

@@ -3,6 +3,7 @@ pub mod impl_u64;
use crate::dft::DFT; use crate::dft::DFT;
use crate::modulus::prime::Prime; use crate::modulus::prime::Prime;
use crate::poly::{Poly, PolyRNS}; use crate::poly::{Poly, PolyRNS};
use crate::modulus::WordOps;
use num::traits::Unsigned; use num::traits::Unsigned;
use std::sync::Arc; use std::sync::Arc;
@@ -13,6 +14,11 @@ pub struct Ring<O: Unsigned> {
} }
impl<O: Unsigned> Ring<O> { impl<O: Unsigned> Ring<O> {
pub fn log_n(&self) -> usize{
return self.n().log2();
}
pub fn n(&self) -> usize { pub fn n(&self) -> usize {
return self.n; return self.n;
} }
@@ -25,6 +31,11 @@ impl<O: Unsigned> Ring<O> {
pub struct RingRNS<O: Unsigned>(pub Vec<Arc<Ring<O>>>); pub struct RingRNS<O: Unsigned>(pub Vec<Arc<Ring<O>>>);
impl<O: Unsigned> RingRNS<O> { impl<O: Unsigned> RingRNS<O> {
pub fn log_n(&self) -> usize{
return self.n().log2();
}
pub fn n(&self) -> usize { pub fn n(&self) -> usize {
self.0[0].n() self.0[0].n()
} }

View File

@@ -3,3 +3,4 @@ pub mod rescaling_rns;
pub mod ring; pub mod ring;
pub mod ring_rns; pub mod ring_rns;
pub mod sampling; pub mod sampling;
pub mod packing;

View File

@@ -0,0 +1,60 @@
use std::collections::HashMap;
use crate::poly::Poly;
use crate::ring::Ring;
use crate::modulus::ONCE;
impl Ring<u64>{
// Generates a vector storing {X^{2^0}, X^{2^1}, .., X^{2^log_n}}.
pub fn gen_x_pow_2<const NTT: bool, const INV: bool>(&self, log_n: usize) -> Vec<Poly<u64>>{
let mut x_pow: Vec<Poly<u64>> = Vec::<Poly<u64>>::with_capacity(log_n);
(0..log_n).for_each(|i|{
let mut idx: usize = 1<<i;
if INV{
idx = self.n() - idx;
}
x_pow.push(self.new_poly());
if i == 0{
x_pow[i].0[idx] = self.modulus.montgomery.one();
self.ntt_inplace::<false>(&mut x_pow[i]);
}else{
let (left, right) = x_pow.split_at_mut(i);
self.a_mul_b_montgomery_into_c::<ONCE>(&left[i-1], &left[i-1], &mut right[0]);
}
});
if INV{
self.a_neg_into_a::<1, ONCE>(&mut x_pow[0]);
}
if !NTT{
x_pow.iter_mut().for_each(|x| self.intt_inplace::<false>(x));
}
x_pow
}
pub fn pack<const ZEROGARBAGE: bool, const NTT: bool>(&self, polys: HashMap<Poly<u64>, usize>, log_gap: usize) -> Poly<u64>{
let log_n = self.log_n();
let log_start = log_n - log_gap;
let log_end = log_n;
/*
if !ZEROGARBAGE{
if gap > 0 {
log_end -= log_gap;
}
}
*/
let n_inv = self.modulus.inv(1<<(log_end - log_start));
Poly::<u64>::default()
}
}

View File

@@ -198,6 +198,12 @@ impl Ring<u64> {
.va_neg_into_va::<CHUNK, ARANGE, REDUCE>(&mut a.0); .va_neg_into_va::<CHUNK, ARANGE, REDUCE>(&mut a.0);
} }
#[inline(always)]
pub fn a_prepare_montgomery_into_a<const REDUCE: REDUCEMOD>(&self, a: &mut Poly<Montgomery<u64>>){
debug_assert!(a.n() == self.n(), "a.n()={} != n={}", a.n(), self.n());
self.modulus.va_prepare_montgomery_into_va::<CHUNK, REDUCE>(&mut a.0);
}
#[inline(always)] #[inline(always)]
pub fn a_mul_b_montgomery_into_c<const REDUCE: REDUCEMOD>( pub fn a_mul_b_montgomery_into_c<const REDUCE: REDUCEMOD>(
&self, &self,