malachite_base/num/arithmetic/mod_square.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::num::arithmetic::traits::{
10 ModPow, ModPowAssign, ModPowPrecomputed, ModPowPrecomputedAssign, ModSquare, ModSquareAssign,
11 ModSquarePrecomputed, ModSquarePrecomputedAssign,
12};
13
14macro_rules! impl_mod_square {
15 ($t:ident) => {
16 impl ModSquare for $t {
17 type Output = $t;
18
19 /// Squares a number modulo another number $m$. The input must be already reduced modulo
20 /// $m$.
21 ///
22 /// $f(x, m) = y$, where $x, y < m$ and $x^2 \equiv y \mod m$.
23 ///
24 /// # Worst-case complexity
25 /// Constant time and additional memory.
26 ///
27 /// # Panics
28 /// Panics if `self` is greater than or equal to `m`.
29 ///
30 /// # Examples
31 /// See [here](super::mod_square#mod_square).
32 #[inline]
33 fn mod_square(self, m: $t) -> $t {
34 self.mod_pow(2, m)
35 }
36 }
37
38 impl ModSquareAssign for $t {
39 /// Squares a number modulo another number $m$, in place. The input must be already
40 /// reduced modulo $m$.
41 ///
42 /// $x \gets y$, where $x, y < m$ and $x^2 \equiv y \mod m$.
43 ///
44 /// # Worst-case complexity
45 /// Constant time and additional memory.
46 ///
47 /// # Panics
48 /// Panics if `self` is greater than or equal to `m`.
49 ///
50 /// # Examples
51 /// See [here](super::mod_square#mod_square_assign).
52 #[inline]
53 fn mod_square_assign(&mut self, m: $t) {
54 self.mod_pow_assign(2, m);
55 }
56 }
57
58 impl ModSquarePrecomputed<u64, $t> for $t {
59 /// Squares a number modulo another number $m$. The input must be already reduced modulo
60 /// $m$.
61 ///
62 /// Some precomputed data is provided; this speeds up computations involving several
63 /// modular squarings with the same modulus. The precomputed data should be obtained
64 /// using [`precompute_mod_pow_data`](super::traits::ModPowPrecomputed).
65 ///
66 /// # Worst-case complexity
67 /// Constant time and additional memory.
68 ///
69 /// # Panics
70 /// Panics if `self` is greater than or equal to `m`.
71 ///
72 /// # Examples
73 /// See [here](super::mod_square#mod_square_precomputed).
74 #[inline]
75 fn mod_square_precomputed(self, m: $t, data: &Self::Data) -> Self::Output {
76 self.mod_pow_precomputed(2, m, data)
77 }
78 }
79
80 impl ModSquarePrecomputedAssign<u64, $t> for $t {
81 /// Squares a number modulo another number $m$, in place. The input must be already
82 /// reduced modulo $m$.
83 ///
84 /// Some precomputed data is provided; this speeds up computations involving several
85 /// modular squarings with the same modulus. The precomputed data should be obtained
86 /// using [`precompute_mod_pow_data`](super::traits::ModPowPrecomputed).
87 ///
88 /// # Worst-case complexity
89 /// Constant time and additional memory.
90 ///
91 /// # Panics
92 /// Panics if `self` is greater than or equal to `m`.
93 ///
94 /// # Examples
95 /// See [here](super::mod_square#mod_square_precomputed_assign).
96 #[inline]
97 fn mod_square_precomputed_assign(&mut self, m: $t, data: &Self::Data) {
98 self.mod_pow_precomputed_assign(2, m, data);
99 }
100 }
101 };
102}
103apply_to_unsigneds!(impl_mod_square);