Botan  1.10.17
numthry.cpp
Go to the documentation of this file.
1 /*
2 * Number Theory Functions
3 * (C) 1999-2011 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/numthry.h>
9 #include <botan/reducer.h>
10 #include <botan/internal/mp_core.h>
11 #include <botan/internal/bit_ops.h>
12 #include <algorithm>
13 
14 namespace Botan {
15 
16 namespace {
17 
18 /*
19 * Miller-Rabin Primality Tester
20 */
21 class MillerRabin_Test
22  {
23  public:
24  bool is_witness(const BigInt& nonce);
25  MillerRabin_Test(const BigInt& num);
26  private:
27  BigInt n, r, n_minus_1;
28  size_t s;
29  Fixed_Exponent_Power_Mod pow_mod;
30  Modular_Reducer reducer;
31  };
32 
33 /*
34 * Miller-Rabin Test, as described in Handbook of Applied Cryptography
35 * section 4.24
36 */
37 bool MillerRabin_Test::is_witness(const BigInt& a)
38  {
39  if(a < 2 || a >= n_minus_1)
40  throw Invalid_Argument("Bad size for nonce in Miller-Rabin test");
41 
42  BigInt y = pow_mod(a);
43  if(y == 1 || y == n_minus_1)
44  return false;
45 
46  for(size_t i = 1; i != s; ++i)
47  {
48  y = reducer.square(y);
49 
50  if(y == 1) // found a non-trivial square root
51  return true;
52 
53  if(y == n_minus_1) // -1, trivial square root, so give up
54  return false;
55  }
56 
57  // If we reached here then n fails the Fermat test
58  return true;
59  }
60 
61 /*
62 * Miller-Rabin Constructor
63 */
64 MillerRabin_Test::MillerRabin_Test(const BigInt& num)
65  {
66  if(num.is_even() || num < 3)
67  throw Invalid_Argument("MillerRabin_Test: Invalid number for testing");
68 
69  n = num;
70  n_minus_1 = n - 1;
71  s = low_zero_bits(n_minus_1);
72  r = n_minus_1 >> s;
73 
74  pow_mod = Fixed_Exponent_Power_Mod(r, n);
75  reducer = Modular_Reducer(n);
76  }
77 
78 /*
79 * Miller-Rabin Iterations
80 */
81 size_t miller_rabin_test_iterations(size_t bits, size_t level)
82  {
83  struct mapping { size_t bits; size_t verify_iter; size_t check_iter; };
84 
85  static const mapping tests[] = {
86  { 50, 55, 25 },
87  { 100, 38, 22 },
88  { 160, 32, 18 },
89  { 163, 31, 17 },
90  { 168, 30, 16 },
91  { 177, 29, 16 },
92  { 181, 28, 15 },
93  { 185, 27, 15 },
94  { 190, 26, 15 },
95  { 195, 25, 14 },
96  { 201, 24, 14 },
97  { 208, 23, 14 },
98  { 215, 22, 13 },
99  { 222, 21, 13 },
100  { 231, 20, 13 },
101  { 241, 19, 12 },
102  { 252, 18, 12 },
103  { 264, 17, 12 },
104  { 278, 16, 11 },
105  { 294, 15, 10 },
106  { 313, 14, 9 },
107  { 334, 13, 8 },
108  { 360, 12, 8 },
109  { 392, 11, 7 },
110  { 430, 10, 7 },
111  { 479, 9, 6 },
112  { 542, 8, 6 },
113  { 626, 7, 5 },
114  { 746, 6, 4 },
115  { 926, 5, 3 },
116  { 1232, 4, 2 },
117  { 1853, 3, 2 },
118  { 0, 0, 0 }
119  };
120 
121  for(size_t i = 0; tests[i].bits; ++i)
122  {
123  if(bits <= tests[i].bits)
124  {
125  if(level >= 2)
126  return tests[i].verify_iter;
127  else if(level == 1)
128  return tests[i].check_iter;
129  else if(level == 0)
130  return std::max<size_t>(tests[i].check_iter / 4, 1);
131  }
132  }
133 
134  return level > 0 ? 2 : 1; // for large inputs
135  }
136 
137 }
138 
139 /*
140 * Return the number of 0 bits at the end of n
141 */
142 size_t low_zero_bits(const BigInt& n)
143  {
144  size_t low_zero = 0;
145 
146  if(n.is_positive() && n.is_nonzero())
147  {
148  for(size_t i = 0; i != n.size(); ++i)
149  {
150  word x = n[i];
151 
152  if(x)
153  {
154  low_zero += ctz(x);
155  break;
156  }
157  else
158  low_zero += BOTAN_MP_WORD_BITS;
159  }
160  }
161 
162  return low_zero;
163  }
164 
165 /*
166 * Calculate the GCD
167 */
168 BigInt gcd(const BigInt& a, const BigInt& b)
169  {
170  if(a.is_zero() || b.is_zero()) return 0;
171  if(a == 1 || b == 1) return 1;
172 
173  BigInt x = a, y = b;
175  y.set_sign(BigInt::Positive);
176  size_t shift = std::min(low_zero_bits(x), low_zero_bits(y));
177 
178  x >>= shift;
179  y >>= shift;
180 
181  while(x.is_nonzero())
182  {
183  x >>= low_zero_bits(x);
184  y >>= low_zero_bits(y);
185  if(x >= y) { x -= y; x >>= 1; }
186  else { y -= x; y >>= 1; }
187  }
188 
189  return (y << shift);
190  }
191 
192 /*
193 * Calculate the LCM
194 */
195 BigInt lcm(const BigInt& a, const BigInt& b)
196  {
197  return ((a * b) / gcd(a, b));
198  }
199 
200 namespace {
201 
202 BigInt ct_inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod)
203  {
204  if(n.is_negative() || mod.is_negative())
205  throw Invalid_Argument("ct_inverse_mod_odd_modulus: arguments must be non-negative");
206  if(mod < 3 || mod.is_even())
207  throw Invalid_Argument("Bad modulus to ct_inverse_mod_odd_modulus");
208 
209  /*
210  This uses a modular inversion algorithm designed by Niels Möller
211  and implemented in Nettle. The same algorithm was later also
212  adapted to GMP in mpn_sec_invert.
213 
214  It can be easily implemented in a way that does not depend on
215  secret branches or memory lookups, providing resistance against
216  some forms of side channel attack.
217 
218  There is also a description of the algorithm in Appendix 5 of "Fast
219  Software Polynomial Multiplication on ARM Processors using the NEON Engine"
220  by Danilo Câmara, Conrado P. L. Gouvêa, Julio López, and Ricardo
221  Dahab in LNCS 8182
222  http://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf
223 
224  Thanks to Niels for creating the algorithm, explaining some things
225  about it, and the reference to the paper.
226  */
227 
228  // todo allow this to be pre-calculated and passed in as arg
229  BigInt mp1o2 = (mod + 1) >> 1;
230 
231  const size_t mod_words = mod.sig_words();
232 
233  BigInt a = n;
234  BigInt b = mod;
235  BigInt u = 1, v = 0;
236 
237  a.grow_to(mod_words);
238  u.grow_to(mod_words);
239  v.grow_to(mod_words);
240  mp1o2.grow_to(mod_words);
241 
242  SecureVector<word>& a_w = a.get_reg();
243  SecureVector<word>& b_w = b.get_reg();
244  SecureVector<word>& u_w = u.get_reg();
245  SecureVector<word>& v_w = v.get_reg();
246 
247  // Only n.bits() + mod.bits() iterations are required, but avoid leaking the size of n
248  size_t bits = 2 * mod.bits();
249 
250  while(bits--)
251  {
252 #if 1
253  const word odd = a.is_odd();
254  a -= odd * b;
255  const word underflow = a.is_negative();
256  b += a * underflow;
257  a.set_sign(BigInt::Positive);
258 
259  a >>= 1;
260 
261  if(underflow)
262  {
263  std::swap(u, v);
264  }
265 
266  u -= odd * v;
267  u += u.is_negative() * mod;
268 
269  const word odd_u = u.is_odd();
270 
271  u >>= 1;
272  u += mp1o2 * odd_u;
273 #else
274  const word odd_a = a_w[0] & 1;
275 
276  //if(odd_a) a -= b
277  word underflow = bigint_cnd_sub(odd_a, a_w.begin(), b_w.begin(), mod_words);
278 
279  //if(underflow) { b -= a; a = abs(a); swap(u, v); }
280  bigint_cnd_add(underflow, b_w.begin(), a_w.begin(), mod_words);
281  bigint_cnd_abs(underflow, a_w.begin(), mod_words);
282  bigint_cnd_swap(underflow, u_w.begin(), v_w.begin(), mod_words);
283 
284  // a >>= 1
285  bigint_shr1(a_w.begin(), mod_words, 0, 1);
286 
287  //if(odd_a) u -= v;
288  word borrow = bigint_cnd_sub(odd_a, u_w.begin(), v_w.begin(), mod_words);
289 
290  // if(borrow) u += p
291  bigint_cnd_add(borrow, u_w.begin(), mod.data(), mod_words);
292 
293  const word odd_u = u_w[0] & 1;
294 
295  // u >>= 1
296  bigint_shr1(u_w.begin(), mod_words, 0, 1);
297 
298  //if(odd_u) u += mp1o2;
299  bigint_cnd_add(odd_u, u_w.begin(), mp1o2.data(), mod_words);
300 #endif
301  }
302 
303  if(b != 1)
304  return 0;
305 
306  return v;
307  }
308 
309 }
310 
311 /*
312 * Find the Modular Inverse
313 */
314 BigInt inverse_mod(const BigInt& n, const BigInt& mod)
315  {
316  if(mod.is_zero())
317  throw BigInt::DivideByZero();
318  if(mod.is_negative() || n.is_negative())
319  throw Invalid_Argument("inverse_mod: arguments must be non-negative");
320 
321  if(n.is_zero() || (n.is_even() && mod.is_even()))
322  return 0;
323 
324  if(mod.is_odd())
325  return ct_inverse_mod_odd_modulus(n % mod, mod);
326 
327  BigInt x = mod, y = n, u = mod, v = n;
328  BigInt A = 1, B = 0, C = 0, D = 1;
329 
330  while(u.is_nonzero())
331  {
332  size_t zero_bits = low_zero_bits(u);
333  u >>= zero_bits;
334  for(size_t i = 0; i != zero_bits; ++i)
335  {
336  if(A.is_odd() || B.is_odd())
337  { A += y; B -= x; }
338  A >>= 1; B >>= 1;
339  }
340 
341  zero_bits = low_zero_bits(v);
342  v >>= zero_bits;
343  for(size_t i = 0; i != zero_bits; ++i)
344  {
345  if(C.is_odd() || D.is_odd())
346  { C += y; D -= x; }
347  C >>= 1; D >>= 1;
348  }
349 
350  if(u >= v) { u -= v; A -= C; B -= D; }
351  else { v -= u; C -= A; D -= B; }
352  }
353 
354  if(v != 1)
355  return 0;
356 
357  while(D.is_negative()) D += mod;
358  while(D >= mod) D -= mod;
359 
360  return D;
361  }
362 
363 /*
364 * Modular Exponentiation
365 */
366 BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod)
367  {
368  Power_Mod pow_mod(mod);
369  pow_mod.set_base(base);
370  pow_mod.set_exponent(exp);
371  return pow_mod.execute();
372  }
373 
374 /*
375 * Test for primaility using Miller-Rabin
376 */
377 bool primality_test(const BigInt& n,
379  size_t level)
380  {
381  const size_t PREF_NONCE_BITS = 128;
382 
383  if(n == 2)
384  return true;
385  if(n <= 1 || n.is_even())
386  return false;
387 
388  // Fast path testing for small numbers (<= 65521)
389  if(n <= PRIMES[PRIME_TABLE_SIZE-1])
390  {
391  const word num = n.word_at(0);
392 
393  for(size_t i = 0; PRIMES[i]; ++i)
394  {
395  if(num == PRIMES[i])
396  return true;
397  if(num < PRIMES[i])
398  return false;
399  }
400 
401  return false;
402  }
403 
404  if(level > 2)
405  level = 2;
406 
407  const size_t NONCE_BITS = std::min(n.bits() - 2, PREF_NONCE_BITS);
408 
409  MillerRabin_Test mr(n);
410 
411  if(mr.is_witness(2))
412  return false;
413 
414  const size_t tests = miller_rabin_test_iterations(n.bits(), level);
415 
416  for(size_t i = 0; i != tests; ++i)
417  {
418  BigInt nonce;
419  while(nonce < 2 || nonce >= (n-1))
420  nonce.randomize(rng, NONCE_BITS);
421 
422  if(mr.is_witness(nonce))
423  return false;
424  }
425 
426  return true;
427  }
428 
429 }
const size_t PRIME_TABLE_SIZE
Definition: numthry.h:220
void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift)
Definition: mp_shift.cpp:42
size_t ctz(T n)
Definition: bit_ops.h:93
void set_exponent(const BigInt &) const
Definition: pow_mod.cpp:96
bool is_negative() const
Definition: bigint.h:245
size_t bits() const
Definition: bigint.cpp:254
BigInt gcd(const BigInt &a, const BigInt &b)
Definition: numthry.cpp:168
bool is_zero() const
Definition: bigint.h:176
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
bool is_even() const
Definition: bigint.h:158
bool is_nonzero() const
Definition: bigint.h:170
word word_at(size_t n) const
Definition: bigint.h:238
bool primality_test(const BigInt &n, RandomNumberGenerator &rng, size_t level)
Definition: numthry.cpp:377
void randomize(RandomNumberGenerator &rng, size_t bitsize=0)
Definition: big_rand.cpp:29
word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size)
Definition: mp_asm.cpp:64
void bigint_cnd_swap(word cnd, word x[], word y[], size_t size)
Definition: mp_asm.cpp:25
bool is_odd() const
Definition: bigint.h:164
size_t size() const
Definition: bigint.h:284
size_t low_zero_bits(const BigInt &n)
Definition: numthry.cpp:142
BigInt execute() const
Definition: pow_mod.cpp:109
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: numthry.cpp:314
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition: numthry.cpp:366
word bigint_cnd_add(word cnd, word x[], const word y[], size_t size)
Definition: mp_asm.cpp:42
T min(T a, T b)
Definition: ct_utils.h:127
void set_base(const BigInt &) const
Definition: pow_mod.cpp:83
const u16bit BOTAN_DLL PRIMES[]
Definition: primes.cpp:12
void swap(Botan::MemoryRegion< T > &x, Botan::MemoryRegion< T > &y)
Definition: secmem.h:438
void bigint_cnd_abs(word cnd, word x[], size_t size)
Definition: mp_asm.cpp:78
void set_sign(Sign sign)
Definition: bigint.cpp:292
BigInt lcm(const BigInt &a, const BigInt &b)
Definition: numthry.cpp:195
BigInt square(const BigInt &x) const
Definition: reducer.h:39
bool is_positive() const
Definition: bigint.h:251