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