crypto_bigint/modular/const_monty_form/
sqrt.rs1use core::marker::PhantomData;
2
3use super::ConstPrimeMontyParams;
4use crate::{
5 CtOption,
6 modular::{ConstMontyForm, sqrt::sqrt_montgomery_form},
7};
8
9impl<const LIMBS: usize, MOD> ConstMontyForm<MOD, LIMBS>
10where
11 MOD: ConstPrimeMontyParams<LIMBS>,
12{
13 #[must_use]
15 pub const fn sqrt(&self) -> CtOption<Self> {
16 let res = sqrt_montgomery_form(self.as_montgomery(), &MOD::PARAMS, &MOD::PRIME_PARAMS);
17 let is_some = res.is_some();
18 CtOption::new(
19 Self {
20 montgomery_form: *res.as_inner_unchecked(),
21 phantom: PhantomData,
22 },
23 is_some,
24 )
25 }
26}
27
28#[cfg(test)]
29mod tests {
30 use crate::{
31 U256, const_prime_monty_params,
32 modular::{ConstMontyForm, ConstPrimeMontyParams},
33 };
34
35 #[test]
36 fn check_sqrt() {
37 const_prime_monty_params!(
40 P256Field,
41 U256,
42 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
43 6
44 );
45 assert_eq!(P256Field::PRIME_PARAMS.s().get(), 1);
46 type ConstForm = ConstMontyForm<P256Field, { U256::LIMBS }>;
47
48 let four_monty = ConstForm::new(&U256::from(4u32));
50 assert_eq!(
51 four_monty.sqrt().expect("ensured square"),
52 ConstForm::new(&U256::from(2u32))
53 );
54
55 let generator = U256::from_u32(P256Field::PRIME_PARAMS.generator().get());
57 let gen_monty = ConstForm::new(&generator);
58 assert!(gen_monty.sqrt().is_none().to_bool_vartime());
59 }
60}