diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/bn/bn_bpsw.c | 143 | ||||
| -rw-r--r-- | src/lib/libcrypto/bn/bn_local.h | 4 | ||||
| -rw-r--r-- | src/lib/libcrypto/bn/bn_prime.c | 16 |
3 files changed, 130 insertions, 33 deletions
diff --git a/src/lib/libcrypto/bn/bn_bpsw.c b/src/lib/libcrypto/bn/bn_bpsw.c index 9220339f19..a1acbbf1e9 100644 --- a/src/lib/libcrypto/bn/bn_bpsw.c +++ b/src/lib/libcrypto/bn/bn_bpsw.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: bn_bpsw.c,v 1.8 2022/11/26 16:08:51 tb Exp $ */ | 1 | /* $OpenBSD: bn_bpsw.c,v 1.9 2023/05/10 12:21:55 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2022 Martin Grenouilloux <martin.grenouilloux@lse.epita.fr> | 3 | * Copyright (c) 2022 Martin Grenouilloux <martin.grenouilloux@lse.epita.fr> |
| 4 | * Copyright (c) 2022 Theo Buehler <tb@openbsd.org> | 4 | * Copyright (c) 2022 Theo Buehler <tb@openbsd.org> |
| @@ -301,23 +301,103 @@ bn_strong_lucas_selfridge(int *is_prime, const BIGNUM *n, BN_CTX *ctx) | |||
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | /* | 303 | /* |
| 304 | * Miller-Rabin primality test for base 2. | 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. | ||
| 305 | */ | 318 | */ |
| 306 | 319 | ||
| 307 | static int | 320 | static int |
| 308 | bn_miller_rabin_base_2(int *is_prime, const BIGNUM *n, BN_CTX *ctx) | 321 | bn_fermat(int *is_prime, const BIGNUM *n, const BIGNUM *n_minus_one, |
| 322 | const BIGNUM *k, int s, const BIGNUM *base, BN_CTX *ctx, BN_MONT_CTX *mctx) | ||
| 309 | { | 323 | { |
| 310 | BIGNUM *n_minus_one, *k, *x; | 324 | BIGNUM *power; |
| 311 | int i, s; | ||
| 312 | int ret = 0; | 325 | int ret = 0; |
| 326 | int i; | ||
| 313 | 327 | ||
| 314 | BN_CTX_start(ctx); | 328 | BN_CTX_start(ctx); |
| 315 | 329 | ||
| 316 | if ((n_minus_one = BN_CTX_get(ctx)) == NULL) | 330 | if ((power = BN_CTX_get(ctx)) == NULL) |
| 331 | goto err; | ||
| 332 | |||
| 333 | /* Sanity check: ensure that 1 < base < n - 1. */ | ||
| 334 | if (BN_cmp(base, BN_value_one()) <= 0 || BN_cmp(base, n_minus_one) >= 0) | ||
| 335 | goto err; | ||
| 336 | |||
| 337 | if (!BN_mod_exp_mont_ct(power, base, k, n, ctx, mctx)) | ||
| 338 | goto err; | ||
| 339 | |||
| 340 | if (BN_is_one(power) || BN_cmp(power, n_minus_one) == 0) { | ||
| 341 | *is_prime = 1; | ||
| 342 | goto done; | ||
| 343 | } | ||
| 344 | |||
| 345 | /* Loop invariant: power is neither 1 nor -1 (mod n). */ | ||
| 346 | for (i = 1; i < s; i++) { | ||
| 347 | if (!BN_mod_sqr(power, power, n, ctx)) | ||
| 348 | goto err; | ||
| 349 | |||
| 350 | /* n is a pseudoprime for base. */ | ||
| 351 | if (BN_cmp(power, n_minus_one) == 0) { | ||
| 352 | *is_prime = 1; | ||
| 353 | goto done; | ||
| 354 | } | ||
| 355 | |||
| 356 | /* n is composite: there's a square root of unity != 1 or -1. */ | ||
| 357 | if (BN_is_one(power)) { | ||
| 358 | *is_prime = 0; | ||
| 359 | goto done; | ||
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | /* | ||
| 364 | * If we get here, n is definitely composite: base^(n-1) != 1. | ||
| 365 | */ | ||
| 366 | |||
| 367 | *is_prime = 0; | ||
| 368 | |||
| 369 | done: | ||
| 370 | ret = 1; | ||
| 371 | |||
| 372 | err: | ||
| 373 | BN_CTX_end(ctx); | ||
| 374 | |||
| 375 | return ret; | ||
| 376 | } | ||
| 377 | |||
| 378 | /* | ||
| 379 | * Miller-Rabin primality test for base 2 and for |rounds| of random bases. | ||
| 380 | * On success: is_prime == 0 implies n is composite - the converse is false. | ||
| 381 | */ | ||
| 382 | |||
| 383 | static int | ||
| 384 | bn_miller_rabin(int *is_prime, const BIGNUM *n, BN_CTX *ctx, size_t rounds) | ||
| 385 | { | ||
| 386 | BN_MONT_CTX *mctx = NULL; | ||
| 387 | BIGNUM *base, *k, *n_minus_one, *three; | ||
| 388 | size_t i; | ||
| 389 | int s; | ||
| 390 | int ret = 0; | ||
| 391 | |||
| 392 | BN_CTX_start(ctx); | ||
| 393 | |||
| 394 | if ((base = BN_CTX_get(ctx)) == NULL) | ||
| 317 | goto err; | 395 | goto err; |
| 318 | if ((k = BN_CTX_get(ctx)) == NULL) | 396 | if ((k = BN_CTX_get(ctx)) == NULL) |
| 319 | goto err; | 397 | goto err; |
| 320 | if ((x = BN_CTX_get(ctx)) == NULL) | 398 | if ((n_minus_one = BN_CTX_get(ctx)) == NULL) |
| 399 | goto err; | ||
| 400 | if ((three = BN_CTX_get(ctx)) == NULL) | ||
| 321 | goto err; | 401 | goto err; |
| 322 | 402 | ||
| 323 | if (BN_is_word(n, 2) || BN_is_word(n, 3)) { | 403 | if (BN_is_word(n, 2) || BN_is_word(n, 3)) { |
| @@ -344,43 +424,56 @@ bn_miller_rabin_base_2(int *is_prime, const BIGNUM *n, BN_CTX *ctx) | |||
| 344 | goto err; | 424 | goto err; |
| 345 | 425 | ||
| 346 | /* | 426 | /* |
| 347 | * If 2^k is 1 or -1 (mod n) then n is a 2-pseudoprime. | 427 | * Montgomery setup for n. |
| 348 | */ | 428 | */ |
| 349 | 429 | ||
| 350 | if (!BN_set_word(x, 2)) | 430 | if ((mctx = BN_MONT_CTX_new()) == NULL) |
| 351 | goto err; | 431 | goto err; |
| 352 | if (!BN_mod_exp_ct(x, x, k, n, ctx)) | 432 | |
| 433 | if (!BN_MONT_CTX_set(mctx, n, ctx)) | ||
| 353 | goto err; | 434 | goto err; |
| 354 | 435 | ||
| 355 | if (BN_is_one(x) || BN_cmp(x, n_minus_one) == 0) { | 436 | /* |
| 356 | *is_prime = 1; | 437 | * Perform a Miller-Rabin test for base 2 as required by BPSW. |
| 438 | */ | ||
| 439 | |||
| 440 | if (!BN_set_word(base, 2)) | ||
| 441 | goto err; | ||
| 442 | |||
| 443 | if (!bn_fermat(is_prime, n, n_minus_one, k, s, base, ctx, mctx)) | ||
| 444 | goto err; | ||
| 445 | if (!*is_prime) | ||
| 357 | goto done; | 446 | goto done; |
| 358 | } | ||
| 359 | 447 | ||
| 360 | /* | 448 | /* |
| 361 | * If 2^{2^i k} == -1 (mod n) for some 1 <= i < s, then n is a | 449 | * Perform Miller-Rabin tests with random 3 <= base < n - 1 to reduce |
| 362 | * 2-pseudoprime. | 450 | * risk of false positives in BPSW. |
| 363 | */ | 451 | */ |
| 364 | 452 | ||
| 365 | for (i = 1; i < s; i++) { | 453 | if (!BN_set_word(three, 3)) |
| 366 | if (!BN_mod_sqr(x, x, n, ctx)) | 454 | goto err; |
| 455 | |||
| 456 | for (i = 0; i < rounds; i++) { | ||
| 457 | if (!bn_rand_interval(base, three, n_minus_one)) | ||
| 367 | goto err; | 458 | goto err; |
| 368 | if (BN_cmp(x, n_minus_one) == 0) { | 459 | |
| 369 | *is_prime = 1; | 460 | if (!bn_fermat(is_prime, n, n_minus_one, k, s, base, ctx, mctx)) |
| 461 | goto err; | ||
| 462 | if (!*is_prime) | ||
| 370 | goto done; | 463 | goto done; |
| 371 | } | ||
| 372 | } | 464 | } |
| 373 | 465 | ||
| 374 | /* | 466 | /* |
| 375 | * If we got here, n is definitely composite. | 467 | * If we got here, we have a Miller-Rabin pseudoprime. |
| 376 | */ | 468 | */ |
| 377 | 469 | ||
| 378 | *is_prime = 0; | 470 | *is_prime = 1; |
| 379 | 471 | ||
| 380 | done: | 472 | done: |
| 381 | ret = 1; | 473 | ret = 1; |
| 382 | 474 | ||
| 383 | err: | 475 | err: |
| 476 | BN_MONT_CTX_free(mctx); | ||
| 384 | BN_CTX_end(ctx); | 477 | BN_CTX_end(ctx); |
| 385 | 478 | ||
| 386 | return ret; | 479 | return ret; |
| @@ -392,7 +485,7 @@ bn_miller_rabin_base_2(int *is_prime, const BIGNUM *n, BN_CTX *ctx) | |||
| 392 | */ | 485 | */ |
| 393 | 486 | ||
| 394 | int | 487 | int |
| 395 | bn_is_prime_bpsw(int *is_prime, const BIGNUM *n, BN_CTX *in_ctx) | 488 | bn_is_prime_bpsw(int *is_prime, const BIGNUM *n, BN_CTX *in_ctx, size_t rounds) |
| 396 | { | 489 | { |
| 397 | BN_CTX *ctx = NULL; | 490 | BN_CTX *ctx = NULL; |
| 398 | BN_ULONG mod; | 491 | BN_ULONG mod; |
| @@ -424,13 +517,11 @@ bn_is_prime_bpsw(int *is_prime, const BIGNUM *n, BN_CTX *in_ctx) | |||
| 424 | if (ctx == NULL) | 517 | if (ctx == NULL) |
| 425 | goto err; | 518 | goto err; |
| 426 | 519 | ||
| 427 | if (!bn_miller_rabin_base_2(is_prime, n, ctx)) | 520 | if (!bn_miller_rabin(is_prime, n, ctx, rounds)) |
| 428 | goto err; | 521 | goto err; |
| 429 | if (!*is_prime) | 522 | if (!*is_prime) |
| 430 | goto done; | 523 | goto done; |
| 431 | 524 | ||
| 432 | /* XXX - Miller-Rabin for random bases? See FIPS 186-4, Table C.1. */ | ||
| 433 | |||
| 434 | if (!bn_strong_lucas_selfridge(is_prime, n, ctx)) | 525 | if (!bn_strong_lucas_selfridge(is_prime, n, ctx)) |
| 435 | goto err; | 526 | goto err; |
| 436 | 527 | ||
diff --git a/src/lib/libcrypto/bn/bn_local.h b/src/lib/libcrypto/bn/bn_local.h index 24d91af462..78b4157d12 100644 --- a/src/lib/libcrypto/bn/bn_local.h +++ b/src/lib/libcrypto/bn/bn_local.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: bn_local.h,v 1.21 2023/04/25 17:59:41 tb Exp $ */ | 1 | /* $OpenBSD: bn_local.h,v 1.22 2023/05/10 12:21:55 tb Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -324,7 +324,7 @@ int bn_copy(BIGNUM *dst, const BIGNUM *src); | |||
| 324 | int bn_isqrt(BIGNUM *out_sqrt, int *out_perfect, const BIGNUM *n, BN_CTX *ctx); | 324 | int bn_isqrt(BIGNUM *out_sqrt, int *out_perfect, const BIGNUM *n, BN_CTX *ctx); |
| 325 | int bn_is_perfect_square(int *out_perfect, const BIGNUM *n, BN_CTX *ctx); | 325 | int bn_is_perfect_square(int *out_perfect, const BIGNUM *n, BN_CTX *ctx); |
| 326 | 326 | ||
| 327 | int bn_is_prime_bpsw(int *is_prime, const BIGNUM *n, BN_CTX *in_ctx); | 327 | int bn_is_prime_bpsw(int *is_prime, const BIGNUM *n, BN_CTX *ctx, size_t rounds); |
| 328 | 328 | ||
| 329 | __END_HIDDEN_DECLS | 329 | __END_HIDDEN_DECLS |
| 330 | #endif /* !HEADER_BN_LOCAL_H */ | 330 | #endif /* !HEADER_BN_LOCAL_H */ |
diff --git a/src/lib/libcrypto/bn/bn_prime.c b/src/lib/libcrypto/bn/bn_prime.c index c2fd0fc2e9..b8f0eb69ce 100644 --- a/src/lib/libcrypto/bn/bn_prime.c +++ b/src/lib/libcrypto/bn/bn_prime.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: bn_prime.c,v 1.31 2023/04/25 19:57:59 tb Exp $ */ | 1 | /* $OpenBSD: bn_prime.c,v 1.32 2023/05/10 12:21:55 tb Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -195,12 +195,12 @@ BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, | |||
| 195 | goto err; | 195 | goto err; |
| 196 | 196 | ||
| 197 | if (!safe) { | 197 | if (!safe) { |
| 198 | if (!bn_is_prime_bpsw(&is_prime, ret, ctx)) | 198 | if (!bn_is_prime_bpsw(&is_prime, ret, ctx, 1)) |
| 199 | goto err; | 199 | goto err; |
| 200 | if (!is_prime) | 200 | if (!is_prime) |
| 201 | goto loop; | 201 | goto loop; |
| 202 | } else { | 202 | } else { |
| 203 | if (!bn_is_prime_bpsw(&is_prime, ret, ctx)) | 203 | if (!bn_is_prime_bpsw(&is_prime, ret, ctx, 1)) |
| 204 | goto err; | 204 | goto err; |
| 205 | if (!is_prime) | 205 | if (!is_prime) |
| 206 | goto loop; | 206 | goto loop; |
| @@ -213,7 +213,7 @@ BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, | |||
| 213 | if (!BN_rshift1(p, ret)) | 213 | if (!BN_rshift1(p, ret)) |
| 214 | goto err; | 214 | goto err; |
| 215 | 215 | ||
| 216 | if (!bn_is_prime_bpsw(&is_prime, p, ctx)) | 216 | if (!bn_is_prime_bpsw(&is_prime, p, ctx, 1)) |
| 217 | goto err; | 217 | goto err; |
| 218 | if (!is_prime) | 218 | if (!is_prime) |
| 219 | goto loop; | 219 | goto loop; |
| @@ -243,8 +243,14 @@ BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, | |||
| 243 | { | 243 | { |
| 244 | int is_prime; | 244 | int is_prime; |
| 245 | 245 | ||
| 246 | if (checks < 0) | ||
| 247 | return -1; | ||
| 248 | |||
| 249 | if (checks == BN_prime_checks) | ||
| 250 | checks = BN_prime_checks_for_size(BN_num_bits(a)); | ||
| 251 | |||
| 246 | /* XXX - tickle BN_GENCB in bn_is_prime_bpsw(). */ | 252 | /* XXX - tickle BN_GENCB in bn_is_prime_bpsw(). */ |
| 247 | if (!bn_is_prime_bpsw(&is_prime, a, ctx_passed)) | 253 | if (!bn_is_prime_bpsw(&is_prime, a, ctx_passed, checks)) |
| 248 | return -1; | 254 | return -1; |
| 249 | 255 | ||
| 250 | return is_prime; | 256 | return is_prime; |
