Botan 1.10.17
powm_mnt.cpp
Go to the documentation of this file.
1/*
2* Montgomery Exponentiation
3* (C) 1999-2010 Jack Lloyd
4*
5* Distributed under the terms of the Botan license
6*/
7
8#include <botan/internal/def_powm.h>
9#include <botan/numthry.h>
10#include <botan/internal/mp_core.h>
11
12namespace Botan {
13
14/*
15* Set the exponent
16*/
18 {
19 this->exp = exp;
20 exp_bits = exp.bits();
21 }
22
23/*
24* Set the base
25*/
27 {
28 window_bits = Power_Mod::window_bits(exp.bits(), base.bits(), hints);
29
30 g.resize((1 << window_bits));
31
32 SecureVector<word> z(2 * (mod_words + 1));
33 SecureVector<word> workspace(z.size());
34
35 g[0] = 1;
36
37 bigint_monty_mul(&z[0], z.size(),
38 g[0].data(), g[0].size(), g[0].sig_words(),
39 R2.data(), R2.size(), R2.sig_words(),
40 modulus.data(), mod_words, mod_prime,
41 &workspace[0]);
42
43 g[0].assign(&z[0], mod_words + 1);
44
45 g[1] = (base >= modulus) ? (base % modulus) : base;
46
47 bigint_monty_mul(&z[0], z.size(),
48 g[1].data(), g[1].size(), g[1].sig_words(),
49 R2.data(), R2.size(), R2.sig_words(),
50 modulus.data(), mod_words, mod_prime,
51 &workspace[0]);
52
53 g[1].assign(&z[0], mod_words + 1);
54
55 const BigInt& x = g[1];
56 const size_t x_sig = x.sig_words();
57
58 for(size_t i = 1; i != g.size(); ++i)
59 {
60 const BigInt& y = g[i-1];
61 const size_t y_sig = y.sig_words();
62
63 zeroise(z);
64 bigint_monty_mul(&z[0], z.size(),
65 x.data(), x.size(), x_sig,
66 y.data(), y.size(), y_sig,
67 modulus.data(), mod_words, mod_prime,
68 &workspace[0]);
69
70 g[i].assign(&z[0], mod_words + 1);
71 g[i].grow_to(mod_words);
72 }
73 }
74
75/*
76* Compute the result
77*/
79 {
80 const size_t exp_nibbles = (exp_bits + window_bits - 1) / window_bits;
81
82 BigInt x = R_mod;
83 SecureVector<word> z(2 * (mod_words + 1));
84 SecureVector<word> workspace(2 * (mod_words + 1));
85 SecureVector<word> e(mod_words);
86
87 for(size_t i = exp_nibbles; i > 0; --i)
88 {
89 for(size_t k = 0; k != window_bits; ++k)
90 {
91 zeroise(z);
92
93 bigint_monty_sqr(&z[0], z.size(),
94 x.data(), x.size(), x.sig_words(),
95 modulus.data(), mod_words, mod_prime,
96 &workspace[0]);
97
98 x.assign(&z[0], mod_words + 1);
99 }
100
101 const u32bit nibble = exp.get_substring(window_bits*(i-1), window_bits);
102
103 zeroise(z);
104
105 BigInt::const_time_lookup(e, g, nibble);
106
107 bigint_monty_mul(&z[0], z.size(),
108 x.data(), x.size(), x.sig_words(),
109 e.data(), e.size(), e.size(),
110 modulus.data(), mod_words, mod_prime,
111 &workspace[0]);
112
113 x.assign(&z[0], mod_words + 1);
114 }
115
116 x.get_reg().resize(2*mod_words+1);
117
118 bigint_monty_redc(&x[0], x.size(),
119 modulus.data(), mod_words, mod_prime,
120 &workspace[0]);
121
122 x.get_reg().resize(mod_words+1);
123
124 return x;
125 }
126
127/*
128* Montgomery_Exponentiator Constructor
129*/
132 {
133 // Montgomery reduction only works for positive odd moduli
134 if(!mod.is_positive() || mod.is_even())
135 throw Invalid_Argument("Montgomery_Exponentiator: invalid modulus");
136
137 window_bits = 0;
138 this->hints = hints;
139 modulus = mod;
140 exp_bits = 0;
141
142 mod_words = modulus.sig_words();
143
144 BigInt r(BigInt::Power2, mod_words * BOTAN_MP_WORD_BITS);
145 mod_prime = (((r * inverse_mod(r, mod)) - 1) / mod).word_at(0);
146
147 R_mod = r % modulus;
148
149 R2 = (R_mod * R_mod) % modulus;
150 }
151
152}
size_t sig_words() const
Definition bigint.h:290
SecureVector< word > & get_reg()
Definition bigint.h:325
size_t size() const
Definition bigint.h:284
void assign(const word x[], size_t length)
Definition bigint.h:337
const word * data() const
Definition bigint.h:317
size_t bits() const
Definition bigint.cpp:254
bool is_even() const
Definition bigint.h:158
static void const_time_lookup(SecureVector< word > &output, const std::vector< BigInt > &vec, size_t idx)
Definition bigint.cpp:382
bool is_positive() const
Definition bigint.h:251
size_t size() const
Definition secmem.h:29
void resize(size_t n)
Definition secmem.h:217
Montgomery_Exponentiator(const BigInt &, Power_Mod::Usage_Hints)
Definition powm_mnt.cpp:130
void set_exponent(const BigInt &)
Definition powm_mnt.cpp:17
void set_base(const BigInt &)
Definition powm_mnt.cpp:26
static size_t window_bits(size_t exp_bits, size_t base_bits, Power_Mod::Usage_Hints hints)
Definition pow_mod.cpp:119
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition numthry.cpp:314
void zeroise(MemoryRegion< T > &vec)
Definition secmem.h:428
void bigint_monty_redc(word z[], size_t z_size, const word p[], size_t p_size, word p_dash, word workspace[])
Definition mp_monty.cpp:21
void bigint_monty_sqr(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, const word p[], size_t p_size, word p_dash, word workspace[])
Definition mp_monty.cpp:84
std::invalid_argument Invalid_Argument
Definition exceptn.h:20
unsigned int u32bit
Definition types.h:32
void bigint_monty_mul(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, const word y[], size_t y_size, size_t y_sw, const word p[], size_t p_size, word p_dash, word workspace[])
Definition mp_monty.cpp:69