use crate::params::params::P;
pub fn freeze(a: i16) -> i8 {
let a_32 = a as i32;
let b = a_32 - (3 * ((10923 * a_32) >> 15));
let c = b - (3 * ((89_478_485 * b + 134_217_728) >> 28));
c as i8
}
pub fn round(a: &mut [i16; P]) {
a.iter_mut().for_each(|x| *x -= freeze(*x) as i16);
}
#[cfg(feature = "ntrup761")]
#[test]
fn test_round() {
use crate::poly::rq::Rq;
use crate::rng::short_random;
let mut rng = rand::rng();
let mut r3: Rq = Rq::from(short_random(&mut rng).unwrap())
.recip::<3>()
.unwrap();
fn round3(h: &mut [i16; 761]) {
let f: [i16; 761] = *h;
for i in 0..761 {
let inner = 21846i32 * (f[i] + 2295) as i32;
h[i] = (((inner + 32768) >> 16) * 3 - 2295) as i16;
}
}
let mut new_round = r3.coeffs.clone();
round3(&mut r3.coeffs);
round(&mut new_round);
assert_eq!(new_round, r3.coeffs);
}
#[cfg(feature = "ntrup761")]
#[test]
fn test_freeze() {
use rand::RngExt;
let mut rng = rand::rng();
pub fn test_freeze(a: i32) -> i8 {
let b = a - (3 * ((10923 * a) >> 15));
let c = b - (3 * ((89_478_485 * b + 134_217_728) >> 28));
c as i8
}
for _ in 0..1000 {
let r = rng.random::<i16>();
let t1 = test_freeze(r as i32);
let t2 = freeze(r);
assert_eq!(t2, t1);
}
}