crypto_bigint/modular/monty_form/
pow.rs1use super::MontyForm;
4use crate::{
5 modular::pow::{multi_exponentiate_montgomery_form_array, pow_montgomery_form},
6 MultiExponentiateBoundedExp, PowBoundedExp, Uint,
7};
8
9#[cfg(feature = "alloc")]
10use {crate::modular::pow::multi_exponentiate_montgomery_form_slice, alloc::vec::Vec};
11
12impl<const LIMBS: usize> MontyForm<LIMBS> {
13 pub const fn pow<const RHS_LIMBS: usize>(
15 &self,
16 exponent: &Uint<RHS_LIMBS>,
17 ) -> MontyForm<LIMBS> {
18 self.pow_bounded_exp(exponent, Uint::<RHS_LIMBS>::BITS)
19 }
20
21 pub const fn pow_bounded_exp<const RHS_LIMBS: usize>(
27 &self,
28 exponent: &Uint<RHS_LIMBS>,
29 exponent_bits: u32,
30 ) -> Self {
31 Self {
32 montgomery_form: pow_montgomery_form(
33 &self.montgomery_form,
34 exponent,
35 exponent_bits,
36 &self.params.modulus,
37 &self.params.one,
38 self.params.mod_neg_inv,
39 ),
40 params: self.params,
41 }
42 }
43}
44
45impl<const LIMBS: usize, const RHS_LIMBS: usize> PowBoundedExp<Uint<RHS_LIMBS>>
46 for MontyForm<LIMBS>
47{
48 fn pow_bounded_exp(&self, exponent: &Uint<RHS_LIMBS>, exponent_bits: u32) -> Self {
49 self.pow_bounded_exp(exponent, exponent_bits)
50 }
51}
52
53impl<const N: usize, const LIMBS: usize, const RHS_LIMBS: usize>
54 MultiExponentiateBoundedExp<Uint<RHS_LIMBS>, [(Self, Uint<RHS_LIMBS>); N]>
55 for MontyForm<LIMBS>
56{
57 fn multi_exponentiate_bounded_exp(
58 bases_and_exponents: &[(Self, Uint<RHS_LIMBS>); N],
59 exponent_bits: u32,
60 ) -> Self {
61 assert!(N != 0, "bases_and_exponents must not be empty");
62 let params = bases_and_exponents[0].0.params;
63
64 let mut bases_and_exponents_montgomery_form =
65 [(Uint::<LIMBS>::ZERO, Uint::<RHS_LIMBS>::ZERO); N];
66
67 let mut i = 0;
68 while i < N {
69 let (base, exponent) = bases_and_exponents[i];
70 bases_and_exponents_montgomery_form[i] = (base.montgomery_form, exponent);
71 i += 1;
72 }
73
74 Self {
75 montgomery_form: multi_exponentiate_montgomery_form_array(
76 &bases_and_exponents_montgomery_form,
77 exponent_bits,
78 ¶ms.modulus,
79 ¶ms.one,
80 params.mod_neg_inv,
81 ),
82 params,
83 }
84 }
85}
86
87#[cfg(feature = "alloc")]
88impl<const LIMBS: usize, const RHS_LIMBS: usize>
89 MultiExponentiateBoundedExp<Uint<RHS_LIMBS>, [(Self, Uint<RHS_LIMBS>)]> for MontyForm<LIMBS>
90{
91 fn multi_exponentiate_bounded_exp(
92 bases_and_exponents: &[(Self, Uint<RHS_LIMBS>)],
93 exponent_bits: u32,
94 ) -> Self {
95 assert!(
96 !bases_and_exponents.is_empty(),
97 "bases_and_exponents must not be empty"
98 );
99 let params = bases_and_exponents[0].0.params;
100
101 let bases_and_exponents: Vec<(Uint<LIMBS>, Uint<RHS_LIMBS>)> = bases_and_exponents
102 .iter()
103 .map(|(base, exp)| (base.montgomery_form, *exp))
104 .collect();
105 Self {
106 montgomery_form: multi_exponentiate_montgomery_form_slice(
107 &bases_and_exponents,
108 exponent_bits,
109 ¶ms.modulus,
110 ¶ms.one,
111 params.mod_neg_inv,
112 ),
113 params,
114 }
115 }
116}