Coverage Report

Created: 2025-03-09 06:52

/src/libressl/crypto/bn/bn_bpsw.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: bn_bpsw.c,v 1.12 2025/02/13 11:10:01 tb Exp $ */
2
/*
3
 * Copyright (c) 2022 Martin Grenouilloux <martin.grenouilloux@lse.epita.fr>
4
 * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <openssl/bn.h>
20
21
#include "bn_local.h"
22
#include "bn_prime.h"
23
24
/*
25
 * For an odd n compute a / 2 (mod n). If a is even, we can do a plain
26
 * division, otherwise calculate (a + n) / 2. Then reduce (mod n).
27
 */
28
29
static int
30
bn_div_by_two_mod_odd_n(BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
31
1.57M
{
32
1.57M
  if (!BN_is_odd(n))
33
0
    return 0;
34
35
1.57M
  if (BN_is_odd(a)) {
36
770k
    if (!BN_add(a, a, n))
37
0
      return 0;
38
770k
  }
39
1.57M
  if (!BN_rshift1(a, a))
40
0
    return 0;
41
1.57M
  if (!BN_mod_ct(a, a, n, ctx))
42
0
    return 0;
43
44
1.57M
  return 1;
45
1.57M
}
46
47
/*
48
 * Given the next binary digit of k and the current Lucas terms U and V, this
49
 * helper computes the next terms in the Lucas sequence defined as follows:
50
 *
51
 *   U' = U * V                  (mod n)
52
 *   V' = (V^2 + D * U^2) / 2    (mod n)
53
 *
54
 * If digit == 0, bn_lucas_step() returns U' and V'. If digit == 1, it returns
55
 *
56
 *   U'' = (U' + V') / 2         (mod n)
57
 *   V'' = (V' + D * U') / 2     (mod n)
58
 *
59
 * Compare with FIPS 186-4, Appendix C.3.3, step 6.
60
 */
61
62
static int
63
bn_lucas_step(BIGNUM *U, BIGNUM *V, int digit, const BIGNUM *D,
64
    const BIGNUM *n, BN_CTX *ctx)
65
788k
{
66
788k
  BIGNUM *tmp;
67
788k
  int ret = 0;
68
69
788k
  BN_CTX_start(ctx);
70
71
788k
  if ((tmp = BN_CTX_get(ctx)) == NULL)
72
0
    goto err;
73
74
  /* Calculate D * U^2 before computing U'. */
75
788k
  if (!BN_sqr(tmp, U, ctx))
76
0
    goto err;
77
788k
  if (!BN_mul(tmp, D, tmp, ctx))
78
0
    goto err;
79
80
  /* U' = U * V (mod n). */
81
788k
  if (!BN_mod_mul(U, U, V, n, ctx))
82
0
    goto err;
83
84
  /* V' = (V^2 + D * U^2) / 2 (mod n). */
85
788k
  if (!BN_sqr(V, V, ctx))
86
0
    goto err;
87
788k
  if (!BN_add(V, V, tmp))
88
0
    goto err;
89
788k
  if (!bn_div_by_two_mod_odd_n(V, n, ctx))
90
0
    goto err;
91
92
788k
  if (digit == 1) {
93
    /* Calculate D * U' before computing U''. */
94
393k
    if (!BN_mul(tmp, D, U, ctx))
95
0
      goto err;
96
97
    /* U'' = (U' + V') / 2 (mod n). */
98
393k
    if (!BN_add(U, U, V))
99
0
      goto err;
100
393k
    if (!bn_div_by_two_mod_odd_n(U, n, ctx))
101
0
      goto err;
102
103
    /* V'' = (V' + D * U') / 2 (mod n). */
104
393k
    if (!BN_add(V, V, tmp))
105
0
      goto err;
106
393k
    if (!bn_div_by_two_mod_odd_n(V, n, ctx))
107
0
      goto err;
108
393k
  }
109
110
788k
  ret = 1;
111
112
788k
 err:
113
788k
  BN_CTX_end(ctx);
114
115
788k
  return ret;
116
788k
}
117
118
/*
119
 * Compute the Lucas terms U_k, V_k, see FIPS 186-4, Appendix C.3.3, steps 4-6.
120
 */
121
122
static int
123
bn_lucas(BIGNUM *U, BIGNUM *V, const BIGNUM *k, const BIGNUM *D,
124
    const BIGNUM *n, BN_CTX *ctx)
125
1.32k
{
126
1.32k
  int digit, i;
127
1.32k
  int ret = 0;
128
129
1.32k
  if (!BN_one(U))
130
0
    goto err;
131
1.32k
  if (!BN_one(V))
132
0
    goto err;
133
134
  /*
135
   * Iterate over the digits of k from MSB to LSB. Start at digit 2
136
   * since the first digit is dealt with by setting U = 1 and V = 1.
137
   */
138
139
788k
  for (i = BN_num_bits(k) - 2; i >= 0; i--) {
140
787k
    digit = BN_is_bit_set(k, i);
141
142
787k
    if (!bn_lucas_step(U, V, digit, D, n, ctx))
143
0
      goto err;
144
787k
  }
145
146
1.32k
  ret = 1;
147
148
1.32k
 err:
149
1.32k
  return ret;
150
1.32k
}
151
152
/*
153
 * This is a stronger variant of the Lucas test in FIPS 186-4, Appendix C.3.3.
154
 * Every strong Lucas pseudoprime n is also a Lucas pseudoprime since
155
 * U_{n+1} == 0 follows from U_k == 0 or V_{k * 2^r} == 0 for 0 <= r < s.
156
 */
157
158
static int
159
bn_strong_lucas_test(int *is_pseudoprime, const BIGNUM *n, const BIGNUM *D,
160
    BN_CTX *ctx)
161
1.32k
{
162
1.32k
  BIGNUM *k, *U, *V;
163
1.32k
  int r, s;
164
1.32k
  int ret = 0;
165
166
1.32k
  BN_CTX_start(ctx);
167
168
1.32k
  if ((k = BN_CTX_get(ctx)) == NULL)
169
0
    goto err;
170
1.32k
  if ((U = BN_CTX_get(ctx)) == NULL)
171
0
    goto err;
172
1.32k
  if ((V = BN_CTX_get(ctx)) == NULL)
173
0
    goto err;
174
175
  /*
176
   * Factorize n + 1 = k * 2^s with odd k: shift away the s trailing ones
177
   * of n and set the lowest bit of the resulting number k.
178
   */
179
180
1.32k
  s = 0;
181
4.00k
  while (BN_is_bit_set(n, s))
182
2.68k
    s++;
183
1.32k
  if (!BN_rshift(k, n, s))
184
0
    goto err;
185
1.32k
  if (!BN_set_bit(k, 0))
186
0
    goto err;
187
188
  /*
189
   * Calculate the Lucas terms U_k and V_k. If either of them is zero,
190
   * then n is a strong Lucas pseudoprime.
191
   */
192
193
1.32k
  if (!bn_lucas(U, V, k, D, n, ctx))
194
0
    goto err;
195
196
1.32k
  if (BN_is_zero(U) || BN_is_zero(V)) {
197
755
    *is_pseudoprime = 1;
198
755
    goto done;
199
755
  }
200
201
  /*
202
   * Calculate the Lucas terms U_{k * 2^r}, V_{k * 2^r} for 1 <= r < s.
203
   * If any V_{k * 2^r} is zero then n is a strong Lucas pseudoprime.
204
   */
205
206
1.09k
  for (r = 1; r < s; r++) {
207
1.09k
    if (!bn_lucas_step(U, V, 0, D, n, ctx))
208
0
      goto err;
209
210
1.09k
    if (BN_is_zero(V)) {
211
567
      *is_pseudoprime = 1;
212
567
      goto done;
213
567
    }
214
1.09k
  }
215
216
  /*
217
   * If we got here, n is definitely composite.
218
   */
219
220
0
  *is_pseudoprime = 0;
221
222
1.32k
 done:
223
1.32k
  ret = 1;
224
225
1.32k
 err:
226
1.32k
  BN_CTX_end(ctx);
227
228
1.32k
  return ret;
229
1.32k
}
230
231
/*
232
 * Test n for primality using the strong Lucas test with Selfridge's Method A.
233
 * Returns 1 if n is prime or a strong Lucas-Selfridge pseudoprime.
234
 * If it returns 0 then n is definitely composite.
235
 */
236
237
static int
238
bn_strong_lucas_selfridge(int *is_pseudoprime, const BIGNUM *n, BN_CTX *ctx)
239
1.32k
{
240
1.32k
  BIGNUM *D, *two;
241
1.32k
  int is_perfect_square, jacobi_symbol, sign;
242
1.32k
  int ret = 0;
243
244
1.32k
  BN_CTX_start(ctx);
245
246
  /* If n is a perfect square, it is composite. */
247
1.32k
  if (!bn_is_perfect_square(&is_perfect_square, n, ctx))
248
0
    goto err;
249
1.32k
  if (is_perfect_square) {
250
0
    *is_pseudoprime = 0;
251
0
    goto done;
252
0
  }
253
254
  /*
255
   * Find the first D in the Selfridge sequence 5, -7, 9, -11, 13, ...
256
   * such that the Jacobi symbol (D/n) is -1.
257
   */
258
259
1.32k
  if ((D = BN_CTX_get(ctx)) == NULL)
260
0
    goto err;
261
1.32k
  if ((two = BN_CTX_get(ctx)) == NULL)
262
0
    goto err;
263
264
1.32k
  sign = 1;
265
1.32k
  if (!BN_set_word(D, 5))
266
0
    goto err;
267
1.32k
  if (!BN_set_word(two, 2))
268
0
    goto err;
269
270
3.19k
  while (1) {
271
    /* For odd n the Kronecker symbol computes the Jacobi symbol. */
272
3.19k
    if ((jacobi_symbol = BN_kronecker(D, n, ctx)) == -2)
273
0
      goto err;
274
275
    /* We found the value for D. */
276
3.19k
    if (jacobi_symbol == -1)
277
1.32k
      break;
278
279
    /* n and D have prime factors in common. */
280
1.87k
    if (jacobi_symbol == 0) {
281
0
      *is_pseudoprime = 0;
282
0
      goto done;
283
0
    }
284
285
1.87k
    sign = -sign;
286
1.87k
    if (!BN_uadd(D, D, two))
287
0
      goto err;
288
1.87k
    BN_set_negative(D, sign == -1);
289
1.87k
  }
290
291
1.32k
  if (!bn_strong_lucas_test(is_pseudoprime, n, D, ctx))
292
0
    goto err;
293
294
1.32k
 done:
295
1.32k
  ret = 1;
296
297
1.32k
 err:
298
1.32k
  BN_CTX_end(ctx);
299
300
1.32k
  return ret;
301
1.32k
}
302
303
/*
304
 * Fermat criterion in Miller-Rabin test.
305
 *
306
 * Check whether 1 < base < n - 1 witnesses that n is composite. For prime n:
307
 *
308
 *  * Fermat's little theorem: base^(n-1) = 1 (mod n).
309
 *  * The only square roots of 1 (mod n) are 1 and -1.
310
 *
311
 * Calculate base^((n-1)/2) by writing n - 1 = k * 2^s with odd k. Iteratively
312
 * compute power = (base^k)^(2^(s-1)) by successive squaring of base^k.
313
 *
314
 * If power ever reaches -1, base^(n-1) is equal to 1 and n is a pseudoprime
315
 * for base. If power reaches 1 before -1 during successive squaring, we have
316
 * an unexpected square root of 1 and n is composite. Otherwise base^(n-1) != 1,
317
 * and n is composite.
318
 */
319
320
static int
321
bn_fermat(int *is_pseudoprime, const BIGNUM *n, const BIGNUM *n_minus_one,
322
    const BIGNUM *k, int s, const BIGNUM *base, BN_CTX *ctx, BN_MONT_CTX *mctx)
323
110k
{
324
110k
  BIGNUM *power;
325
110k
  int ret = 0;
326
110k
  int i;
327
328
110k
  BN_CTX_start(ctx);
329
330
110k
  if ((power = BN_CTX_get(ctx)) == NULL)
331
0
    goto err;
332
333
  /* Sanity check: ensure that 1 < base < n - 1. */
334
110k
  if (BN_cmp(base, BN_value_one()) <= 0 || BN_cmp(base, n_minus_one) >= 0)
335
0
    goto err;
336
337
110k
  if (!BN_mod_exp_mont_ct(power, base, k, n, ctx, mctx))
338
0
    goto err;
339
340
110k
  if (BN_is_one(power) || BN_cmp(power, n_minus_one) == 0) {
341
55.4k
    *is_pseudoprime = 1;
342
55.4k
    goto done;
343
55.4k
  }
344
345
  /* Loop invariant: power is neither 1 nor -1 (mod n). */
346
121k
  for (i = 1; i < s; i++) {
347
93.0k
    if (!BN_mod_sqr(power, power, n, ctx))
348
0
      goto err;
349
350
    /* n is a pseudoprime for base. */
351
93.0k
    if (BN_cmp(power, n_minus_one) == 0) {
352
26.7k
      *is_pseudoprime = 1;
353
26.7k
      goto done;
354
26.7k
    }
355
356
    /* n is composite: there's a square root of unity != 1 or -1. */
357
66.3k
    if (BN_is_one(power)) {
358
0
      *is_pseudoprime = 0;
359
0
      goto done;
360
0
    }
361
66.3k
  }
362
363
  /*
364
   * If we get here, n is definitely composite: base^(n-1) != 1.
365
   */
366
367
28.4k
  *is_pseudoprime = 0;
368
369
110k
 done:
370
110k
  ret = 1;
371
372
110k
 err:
373
110k
  BN_CTX_end(ctx);
374
375
110k
  return ret;
376
110k
}
377
378
/*
379
 * Miller-Rabin primality test for base 2 and for |rounds| of random bases.
380
 * On success: is_pseudoprime == 0 implies that n is composite.
381
 */
382
383
static int
384
bn_miller_rabin(int *is_pseudoprime, const BIGNUM *n, BN_CTX *ctx,
385
    size_t rounds)
386
29.7k
{
387
29.7k
  BN_MONT_CTX *mctx = NULL;
388
29.7k
  BIGNUM *base, *k, *n_minus_one;
389
29.7k
  size_t i;
390
29.7k
  int s;
391
29.7k
  int ret = 0;
392
393
29.7k
  BN_CTX_start(ctx);
394
395
29.7k
  if ((base = BN_CTX_get(ctx)) == NULL)
396
0
    goto err;
397
29.7k
  if ((k = BN_CTX_get(ctx)) == NULL)
398
0
    goto err;
399
29.7k
  if ((n_minus_one = BN_CTX_get(ctx)) == NULL)
400
0
    goto err;
401
402
29.7k
  if (BN_is_word(n, 2) || BN_is_word(n, 3)) {
403
0
    *is_pseudoprime = 1;
404
0
    goto done;
405
0
  }
406
407
29.7k
  if (BN_cmp(n, BN_value_one()) <= 0 || !BN_is_odd(n)) {
408
0
    *is_pseudoprime = 0;
409
0
    goto done;
410
0
  }
411
412
29.7k
  if (!BN_sub(n_minus_one, n, BN_value_one()))
413
0
    goto err;
414
415
  /*
416
   * Factorize n - 1 = k * 2^s.
417
   */
418
419
29.7k
  s = 0;
420
95.2k
  while (!BN_is_bit_set(n_minus_one, s))
421
65.4k
    s++;
422
29.7k
  if (!BN_rshift(k, n_minus_one, s))
423
0
    goto err;
424
425
  /*
426
   * Montgomery setup for n.
427
   */
428
429
29.7k
  if ((mctx = BN_MONT_CTX_create(n, ctx)) == NULL)
430
0
    goto err;
431
432
  /*
433
   * Perform a Miller-Rabin test for base 2 as required by BPSW.
434
   */
435
436
29.7k
  if (!BN_set_word(base, 2))
437
0
    goto err;
438
439
29.7k
  if (!bn_fermat(is_pseudoprime, n, n_minus_one, k, s, base, ctx, mctx))
440
0
    goto err;
441
29.7k
  if (!*is_pseudoprime)
442
28.4k
    goto done;
443
444
  /*
445
   * Perform Miller-Rabin tests with random 3 <= base < n - 1 to reduce
446
   * risk of false positives in BPSW.
447
   */
448
449
82.2k
  for (i = 0; i < rounds; i++) {
450
80.8k
    if (!bn_rand_interval(base, 3, n_minus_one))
451
0
      goto err;
452
453
80.8k
    if (!bn_fermat(is_pseudoprime, n, n_minus_one, k, s, base, ctx,
454
80.8k
        mctx))
455
0
      goto err;
456
80.8k
    if (!*is_pseudoprime)
457
0
      goto done;
458
80.8k
  }
459
460
  /*
461
   * If we got here, we have a Miller-Rabin pseudoprime.
462
   */
463
464
1.32k
  *is_pseudoprime = 1;
465
466
29.7k
 done:
467
29.7k
  ret = 1;
468
469
29.7k
 err:
470
29.7k
  BN_MONT_CTX_free(mctx);
471
29.7k
  BN_CTX_end(ctx);
472
473
29.7k
  return ret;
474
29.7k
}
475
476
/*
477
 * The Baillie-Pomerance-Selfridge-Wagstaff algorithm combines a Miller-Rabin
478
 * test for base 2 with a Strong Lucas pseudoprime test.
479
 */
480
481
int
482
bn_is_prime_bpsw(int *is_pseudoprime, const BIGNUM *n, BN_CTX *in_ctx,
483
    size_t rounds)
484
256k
{
485
256k
  BN_CTX *ctx = NULL;
486
256k
  BN_ULONG mod;
487
256k
  int i;
488
256k
  int ret = 0;
489
490
256k
  if (BN_is_word(n, 2)) {
491
4
    *is_pseudoprime = 1;
492
4
    goto done;
493
4
  }
494
495
256k
  if (BN_cmp(n, BN_value_one()) <= 0 || !BN_is_odd(n)) {
496
142
    *is_pseudoprime = 0;
497
142
    goto done;
498
142
  }
499
500
  /* Trial divisions with the first 2048 primes. */
501
71.1M
  for (i = 0; i < NUMPRIMES; i++) {
502
71.1M
    if ((mod = BN_mod_word(n, primes[i])) == (BN_ULONG)-1)
503
0
      goto err;
504
71.1M
    if (mod == 0) {
505
226k
      *is_pseudoprime = BN_is_word(n, primes[i]);
506
226k
      goto done;
507
226k
    }
508
71.1M
  }
509
510
29.7k
  if ((ctx = in_ctx) == NULL)
511
182
    ctx = BN_CTX_new();
512
29.7k
  if (ctx == NULL)
513
0
    goto err;
514
515
29.7k
  if (!bn_miller_rabin(is_pseudoprime, n, ctx, rounds))
516
0
    goto err;
517
29.7k
  if (!*is_pseudoprime)
518
28.4k
    goto done;
519
520
1.32k
  if (!bn_strong_lucas_selfridge(is_pseudoprime, n, ctx))
521
0
    goto err;
522
523
256k
 done:
524
256k
  ret = 1;
525
526
256k
 err:
527
256k
  if (ctx != in_ctx)
528
226k
    BN_CTX_free(ctx);
529
530
256k
  return ret;
531
256k
}