crypto_bigint/uint/modular/runtime_mod/
runtime_pow.rs

1use 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    /// Raises to the `exponent` power.
11    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    /// Raises to the `exponent` power,
19    /// with `exponent_bits` representing the number of (least significant) bits
20    /// to take into account for the exponent.
21    ///
22    /// NOTE: `exponent_bits` may be leaked in the time pattern.
23    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}