Skip to content

Commit

Permalink
adds ntt and vec tests
Browse files Browse the repository at this point in the history
todo: fix compress to modify buffer
  • Loading branch information
supinie committed Apr 15, 2024
1 parent f98c1c5 commit bda2406
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 55 deletions.
9 changes: 4 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@
unused_lifetimes,
unused_qualifications
)]
// pedantic
#![no_std]
#![allow(clippy::needless_range_loop)]
// #![allow(clippy::needless_range_loop)]

mod errors;
mod field_operations;
Expand All @@ -36,11 +35,11 @@ mod vectors;
mod tests {
// mod buffer;
mod field_operations;
// mod indcpa;
// mod indcpa;
// mod matrix;
// mod ntt;
mod ntt;
mod params;
mod polynomials;
// mod sample;
// mod vectors;
mod vectors;
}
4 changes: 2 additions & 2 deletions src/polynomials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ impl Poly<Normalised> {
// poly will not be normalised
// Example:
// ```
// let read_result = read_msg_to_poly(msg_buf);
// let read_result = Poly::read_msg(msg_buf);
// ```
pub(crate) fn read_msg(msg: &[u8]) -> Result<Poly<Unreduced>, PackingError> {
if msg.len() == SYMBYTES {
Expand All @@ -409,7 +409,7 @@ impl Poly<Normalised> {
// output poly is normalised
// Example:
// ```
// let decompress_result = decompress_to_poly(buf, k);
// let decompress_result = Poly::decompress(buf, k);
// ```
pub(crate) fn decompress(buf: &[u8], sec_level: &SecurityLevel) -> Result<Self, PackingError> {
if buf.len() != sec_level.poly_compressed_bytes() {
Expand Down
3 changes: 2 additions & 1 deletion src/polynomials/ntt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ impl<S: State + Reduced + Copy> Poly<S> {
impl<S: State + Copy> Poly<S> {
// In inverse NTT, with montgomery reduction
// Assumes that all coefficients are bounded in absolute value by q.
// Output coefficients are bounded in absolute value q.
// If so, output coefficients are bounded in absolute value q.
// If the input is in montgomery or regular form, then so is the output.
// coefficients must be bounded in absolute value by 3713.
// Example:
// ```
// let new_poly = poly.inv_ntt();
Expand Down
25 changes: 25 additions & 0 deletions src/tests/ntt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#![allow(warnings)]
#[cfg(test)]

pub(in crate::tests) mod ntt_tests {
use crate::{
polynomials::*,
params::*,
tests::polynomials::poly_tests::*,
};
use proptest::prelude::*;

proptest! {
#[test]
fn ntt_tests(poly in new_poly()) {
let output_1 = poly.normalise().ntt();
let output_2 = poly.mont_form().ntt();
let output_3 = poly.barrett_reduce().ntt();
}

#[test]
fn inv_ntt_test(poly in new_ntt_poly()) {
let output = poly.inv_ntt();
}
}
}
102 changes: 55 additions & 47 deletions src/tests/polynomials.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(warnings)]
#[cfg(test)]

mod poly_tests {
pub(in crate::tests) mod poly_tests {
use crate::{
polynomials::*,
params::*,
Expand All @@ -10,13 +10,39 @@ mod poly_tests {
use proptest::prelude::*;

pub(in crate::tests) fn new_limited_poly_array() -> impl Strategy<Value = [i16; N]> {
prop::array::uniform(-(Q as i16)..(Q as i16))
prop::array::uniform(-(i16::MAX / 2)..(i16::MAX / 2)) // pick i16::MAX / 2, which should be plenty more
// than Q whilst ensuring no overflows (we know
// they can happen)
}

pub(in crate::tests) fn new_poly_array() -> impl Strategy<Value = [i16; N]> {
prop::array::uniform(i16::MIN..i16::MAX)
}

prop_compose! {
pub(in crate::tests) fn new_poly()
(coeffs in new_poly_array())
-> Poly<Unreduced> {
Poly::from_arr(&coeffs)
}
}

prop_compose! {
pub(in crate::tests) fn new_limited_poly()
(coeffs in new_limited_poly_array())
-> Poly<Unreduced> {
Poly::from_arr(&coeffs)
}
}

prop_compose! {
pub(in crate::tests) fn new_ntt_poly()
(coeffs in prop::array::uniform(-(3713i16)..(3713i16)))
-> Poly<Unreduced> {
Poly::from_arr(&coeffs)
}
}

#[test]
fn new_test() {
let poly = Poly::new();
Expand All @@ -30,86 +56,68 @@ mod poly_tests {

#[test]
fn add_test(
a in new_limited_poly_array(),
b in new_limited_poly_array()
a in new_limited_poly(),
b in new_limited_poly()
) {
let poly_a = Poly::from_arr(&a);
let poly_b = Poly::from_arr(&b);

let outout = poly_a.add(&poly_b);
let outout = a.add(&b);
}

#[test]
fn sub_test(
a in new_limited_poly_array(),
b in new_limited_poly_array()
a in new_limited_poly(),
b in new_limited_poly()
) {
let poly_a = Poly::from_arr(&a);
let poly_b = Poly::from_arr(&b);

let outout = poly_a.sub(&poly_b);
let outout = a.sub(&b);
}

#[test]
fn barrett_reduce_test(a in new_poly_array()) {
let poly = Poly::from_arr(&a);

fn barrett_reduce_test(poly in new_poly()) {
let output = poly.barrett_reduce();
}

#[test]
fn mont_form_test(a in new_poly_array()) {
let poly = Poly::from_arr(&a);

fn mont_form_test(poly in new_poly()) {
let output = poly.mont_form();
}

#[test]
fn normalise_test(a in new_poly_array()) {
let poly = Poly::from_arr(&a);

fn normalise_test(poly in new_poly()) {
let output = poly.normalise();
}

#[test]
fn pointwise_mul_test(
a in new_poly_array(),
b in new_poly_array()
a in new_poly(),
b in new_poly()
) {
let poly_a = Poly::from_arr(&a).normalise();
let poly_b = Poly::from_arr(&b).normalise();

let outout = poly_a.pointwise_mul(&poly_b);
let outout = a.normalise().pointwise_mul(&b.normalise());
}

#[test]
fn pack_test(a in new_poly_array()) {
let poly = Poly::from_arr(&a).normalise();

let output = poly.pack();
fn pack_test(poly in new_poly()) {
let output = poly.normalise().pack();
}

#[test]
fn write_msg_test(a in new_poly_array()) {
let poly = Poly::from_arr(&a).normalise();
let msg = poly.write_msg().unwrap();
fn write_msg_test(poly in new_poly()) {
let msg = poly.normalise().write_msg().unwrap();
}

#[test]
fn compress_test(
a in new_poly_array(),
poly in new_poly(),
sec_level in sec_level_strategy()
) {
let mut buf = [0u8; 160]; // max poly_compressed_bytes
let poly = Poly::from_arr(&a).normalise();

let result = poly.compress(&mut buf[..sec_level.poly_compressed_bytes()], &sec_level).unwrap();
let result = poly
.normalise()
.compress(&mut buf[..sec_level.poly_compressed_bytes()], &sec_level)
.unwrap();
}

#[test]
fn unpack_test(a in new_poly_array()) {
let poly = Poly::from_arr(&a).normalise();
let buf = poly.pack();
fn unpack_test(poly in new_poly()) {
let buf = poly.normalise().pack();

let unpacked = Poly::unpack(&buf).unwrap();
}
Expand All @@ -121,13 +129,13 @@ mod poly_tests {

#[test]
fn decompress_test(
a in new_poly_array(),
poly in new_poly(),
sec_level in sec_level_strategy()
) {
let mut buf = [0u8; 160]; // max poly_compressed_bytes
let poly = Poly::from_arr(&a).normalise();

let _ = poly.compress(&mut buf[..sec_level.poly_compressed_bytes()], &sec_level);
let _ = poly
.normalise()
.compress(&mut buf[..sec_level.poly_compressed_bytes()], &sec_level);

let decompressed_poly = Poly::decompress(&buf[..sec_level.poly_compressed_bytes()], &sec_level).unwrap();
}
Expand Down
116 changes: 116 additions & 0 deletions src/tests/vectors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#![allow(warnings)]
#[cfg(test)]

mod vec_tests {
use crate::{
vectors::*,
polynomials::*,
params::*,
tests::polynomials::poly_tests::{
new_poly,
new_limited_poly,
new_ntt_poly,
},
tests::params::params_tests::sec_level_strategy,
};
use proptest::prelude::*;
use tinyvec::ArrayVec;

prop_compose! {
pub(in crate::tests) fn new_poly_vec()
(sec_level in 2..=4usize, poly_1 in new_poly(), poly_2 in new_poly(), poly_3 in new_poly(), poly_4 in new_poly())
-> PolyVec<Unreduced> {
PolyVec::from(ArrayVec::<[Poly<Unreduced>; 4]>::from_array_len([poly_1, poly_2, poly_3, poly_4], sec_level)).unwrap()
}
}

prop_compose! {
// restrict sec_level here so that we can ensure two polyvecs are the same sec_level
pub(in crate::tests) fn new_limited_poly_vec(sec_level: usize)
(poly_1 in new_limited_poly(), poly_2 in new_limited_poly(), poly_3 in new_limited_poly(), poly_4 in new_limited_poly())
-> PolyVec<Unreduced> {
PolyVec::from(ArrayVec::<[Poly<Unreduced>; 4]>::from_array_len([poly_1, poly_2, poly_3, poly_4], sec_level)).unwrap()
}
}

prop_compose! {
// restrict sec_level here so that we can ensure two polyvecs are the same sec_level
pub(in crate::tests) fn new_ntt_poly_vec(sec_level: usize)
(poly_1 in new_ntt_poly(), poly_2 in new_ntt_poly(), poly_3 in new_ntt_poly(), poly_4 in new_ntt_poly())
-> PolyVec<Unreduced> {
PolyVec::from(ArrayVec::<[Poly<Unreduced>; 4]>::from_array_len([poly_1, poly_2, poly_3, poly_4], sec_level)).unwrap()
}
}

#[test]
#[should_panic]
fn from_test() {
// new should be empty so will fail
let err_result = PolyVec::from(ArrayVec::<[Poly<Unreduced>; 4]>::new()).unwrap();
}

proptest! {
#[test]
fn sec_level_test(poly_vec in new_poly_vec()) {
let sec_level = poly_vec.sec_level();
}

#[test]
fn polynomials_test(poly_vec in new_poly_vec()) {
let polys = poly_vec.polynomials();
}

#[test]
fn add_test(a in new_limited_poly_vec(4), b in new_limited_poly_vec(4)) {
let poly_vec = a.add(&b).unwrap();
}

#[test]
#[should_panic]
fn add_test_different_sec_levels(a in new_limited_poly_vec(2), b in new_limited_poly_vec(3)) {
let poly_vec = a.add(&b).unwrap();
}

#[test]
fn barrett_reduce_test(poly_vec in new_poly_vec()) {
let output = poly_vec.barrett_reduce();
}

#[test]
fn normalise_test(poly_vec in new_poly_vec()) {
let output = poly_vec.normalise();
}

#[test]
fn inv_ntt_test(poly_vec in new_ntt_poly_vec(4)) {
let output = poly_vec.inv_ntt();
}

#[test]
fn ntt_test(poly_vec in new_poly_vec()) {
let output = poly_vec.normalise().ntt();
}

#[test]
fn new_test(sec_level in sec_level_strategy()) {
let output = PolyVec::new(sec_level.k());
}

#[test]
fn pack_test(poly_vec in new_poly_vec()) {
let mut buf = [0u8; 4 * POLYBYTES]; // max buf length needed
let k: usize = poly_vec.sec_level().k().into();

let output = poly_vec.normalise().pack(&mut buf[..k * POLYBYTES]).unwrap();
}

#[test]
fn compress_test(poly_vec in new_poly_vec()) {
let mut buf = [0u8; 4 * 352]; // max poly_vec_compressed_bytes
let end = poly_vec.sec_level().poly_vec_compressed_bytes();

let output = poly_vec.normalise().compress(&mut buf[..end]).unwrap();
assert_eq!(buf, [100u8; 4 * 352]);
}
}
}
1 change: 1 addition & 0 deletions src/vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ impl PolyVec<Normalised> {
let _ = buf
.chunks_mut(self.sec_level().poly_compressed_bytes())
.zip(self.polynomials.iter())
// This is applying it to the buf_chunk not the buf
.map(|(buf_chunk, poly)| poly.compress(buf_chunk, &self.sec_level()));

Ok(())
Expand Down

0 comments on commit bda2406

Please sign in to comment.