use crate::params::params::{Q, Q12};
use crate::math::nums::i32_mod_u14;
pub fn freeze(x: i32) -> i16 {
let r = i32_mod_u14(x + Q12 as i32, Q as u16);
r as i16 - Q12 as i16
}
pub fn recip(a1: i16) -> i16 {
let mut i = 1;
let mut ai = a1;
while i < Q - 2 {
ai = freeze((a1 as i32) * (ai as i32));
i += 1;
}
ai
}
#[cfg(test)]
mod tests_fq {
use super::*;
#[cfg(feature = "ntrup653")]
const RQ_FREEZE: i32 = 58_078;
#[cfg(feature = "ntrup761")]
const RQ_FREEZE: i32 = 58_470;
#[cfg(feature = "ntrup857")]
const RQ_FREEZE: i32 = 51_949;
#[cfg(feature = "ntrup953")]
const RQ_FREEZE: i32 = 42_319;
#[cfg(feature = "ntrup1013")]
const RQ_FREEZE: i32 = 37_402;
#[cfg(feature = "ntrup1277")]
const RQ_FREEZE: i32 = 34_069;
#[cfg(all(
not(feature = "ntrup653"),
not(feature = "ntrup761"),
not(feature = "ntrup857"),
not(feature = "ntrup953"),
not(feature = "ntrup1013"),
not(feature = "ntrup1277")
))]
const RQ_FREEZE: i32 = 34_069;
#[test]
fn test_freeze() {
fn test_freeze(a: i32) -> i16 {
let mut b = a;
let q = Q as i32;
let rq = RQ_FREEZE;
b -= q * ((228 * b) >> 20);
b -= q * ((rq * b + 134_217_728) >> 28);
b as i16
}
for n in 0..i16::MAX {
let t1 = test_freeze(n as i32);
let t2 = freeze(n as i32);
assert_eq!(t2, t1);
}
}
#[test]
fn test_recip() {
assert_eq!(recip(42), -recip(-42));
assert_eq!(recip(-42), -recip(42));
}
}