crypto_bigint/int/
sqrt.rs1use super::Int;
4use crate::{CheckedSquareRoot, CtOption};
5
6impl<const LIMBS: usize> Int<LIMBS> {
7 #[must_use]
10 pub fn checked_sqrt(&self) -> CtOption<Self> {
11 self.as_uint()
12 .checked_sqrt()
13 .map(|rt| Self::new(rt.limbs))
14 .filter_by(self.is_negative().not())
15 }
16
17 #[must_use]
22 pub fn checked_sqrt_vartime(&self) -> Option<Self> {
23 if self.is_negative().not().to_bool_vartime() {
24 self.as_uint()
25 .checked_sqrt_vartime()
26 .map(|rt| Self::new(rt.limbs))
27 } else {
28 None
29 }
30 }
31}
32
33impl<const LIMBS: usize> CheckedSquareRoot for Int<LIMBS> {
34 type Output = Self;
35
36 fn checked_sqrt(&self) -> CtOption<Self::Output> {
37 self.checked_sqrt()
38 }
39
40 fn checked_sqrt_vartime(&self) -> Option<Self::Output> {
41 self.checked_sqrt_vartime()
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use crate::{CheckedSquareRoot, I256};
48
49 #[test]
50 fn square_root_expected() {
51 let tests = [
52 (I256::ZERO, Some(I256::ZERO)),
53 (I256::ONE, Some(I256::ONE)),
54 (I256::MINUS_ONE, None),
55 (I256::from_i8(4), Some(I256::from_i8(2))),
56 ];
57 for (case, expect) in tests {
58 assert_eq!(CheckedSquareRoot::checked_sqrt(&case).into_option(), expect);
59 assert_eq!(CheckedSquareRoot::checked_sqrt_vartime(&case), expect);
60 }
61 }
62}