use crate::JacobiSymbol;
use super::{ConstMontyForm, ConstMontyParams};
impl<MOD: ConstMontyParams<LIMBS>, const LIMBS: usize> ConstMontyForm<MOD, LIMBS> {
#[must_use]
pub const fn jacobi_symbol(&self) -> JacobiSymbol {
self.retrieve().jacobi_symbol(MOD::PARAMS.modulus())
}
#[must_use]
pub const fn jacobi_symbol_vartime(&self) -> JacobiSymbol {
self.retrieve().jacobi_symbol_vartime(MOD::PARAMS.modulus())
}
}
#[cfg(test)]
mod tests {
use crate::{
JacobiSymbol, U256, const_monty_form, const_monty_params,
modular::const_monty_form::ConstMontyParams,
};
const_monty_params!(
Modulus,
U256,
"2523648240000001BA344D80000000086121000000000013A700000000000013"
);
const_monty_form!(Fe, Modulus);
#[test]
fn jacobi_quad_residue() {
let x =
U256::from_be_hex("14BFAE46F4026E97C7A3FCD889B379A5F025719911C994A594FC6C5092AC58B1");
let x_mod = Fe::new(&x);
let jac = x_mod.jacobi_symbol();
let jac_vartime = x_mod.jacobi_symbol_vartime();
assert_eq!(jac, JacobiSymbol::One);
assert_eq!(jac, jac_vartime);
}
#[test]
fn jacobi_quad_nonresidue() {
let x =
U256::from_be_hex("1D2EFB21D283A2DDE77004B9DE9A9624F7B15CEEF055CD02E9EF1A9F1B76F253");
let x_mod = Fe::new(&x);
let jac = x_mod.jacobi_symbol();
let jac_vartime = x_mod.jacobi_symbol_vartime();
assert_eq!(jac, JacobiSymbol::MinusOne);
assert_eq!(jac, jac_vartime);
}
}