1*050d837aStb /* $OpenBSD: bn_prime.c,v 1.34 2023/07/20 06:26:27 tb Exp $ */
25b37fcf3Sryker /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
35b37fcf3Sryker * All rights reserved.
45b37fcf3Sryker *
55b37fcf3Sryker * This package is an SSL implementation written
65b37fcf3Sryker * by Eric Young (eay@cryptsoft.com).
75b37fcf3Sryker * The implementation was written so as to conform with Netscapes SSL.
85b37fcf3Sryker *
95b37fcf3Sryker * This library is free for commercial and non-commercial use as long as
105b37fcf3Sryker * the following conditions are aheared to. The following conditions
115b37fcf3Sryker * apply to all code found in this distribution, be it the RC4, RSA,
125b37fcf3Sryker * lhash, DES, etc., code; not just the SSL code. The SSL documentation
135b37fcf3Sryker * included with this distribution is covered by the same copyright terms
145b37fcf3Sryker * except that the holder is Tim Hudson (tjh@cryptsoft.com).
155b37fcf3Sryker *
165b37fcf3Sryker * Copyright remains Eric Young's, and as such any Copyright notices in
175b37fcf3Sryker * the code are not to be removed.
185b37fcf3Sryker * If this package is used in a product, Eric Young should be given attribution
195b37fcf3Sryker * as the author of the parts of the library used.
205b37fcf3Sryker * This can be in the form of a textual message at program startup or
215b37fcf3Sryker * in documentation (online or textual) provided with the package.
225b37fcf3Sryker *
235b37fcf3Sryker * Redistribution and use in source and binary forms, with or without
245b37fcf3Sryker * modification, are permitted provided that the following conditions
255b37fcf3Sryker * are met:
265b37fcf3Sryker * 1. Redistributions of source code must retain the copyright
275b37fcf3Sryker * notice, this list of conditions and the following disclaimer.
285b37fcf3Sryker * 2. Redistributions in binary form must reproduce the above copyright
295b37fcf3Sryker * notice, this list of conditions and the following disclaimer in the
305b37fcf3Sryker * documentation and/or other materials provided with the distribution.
315b37fcf3Sryker * 3. All advertising materials mentioning features or use of this software
325b37fcf3Sryker * must display the following acknowledgement:
335b37fcf3Sryker * "This product includes cryptographic software written by
345b37fcf3Sryker * Eric Young (eay@cryptsoft.com)"
355b37fcf3Sryker * The word 'cryptographic' can be left out if the rouines from the library
365b37fcf3Sryker * being used are not cryptographic related :-).
375b37fcf3Sryker * 4. If you include any Windows specific code (or a derivative thereof) from
385b37fcf3Sryker * the apps directory (application code) you must include an acknowledgement:
395b37fcf3Sryker * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
405b37fcf3Sryker *
415b37fcf3Sryker * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
425b37fcf3Sryker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
435b37fcf3Sryker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
445b37fcf3Sryker * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
455b37fcf3Sryker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
465b37fcf3Sryker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
475b37fcf3Sryker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
485b37fcf3Sryker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
495b37fcf3Sryker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
505b37fcf3Sryker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
515b37fcf3Sryker * SUCH DAMAGE.
525b37fcf3Sryker *
535b37fcf3Sryker * The licence and distribution terms for any publically available version or
545b37fcf3Sryker * derivative of this code cannot be changed. i.e. this code cannot simply be
555b37fcf3Sryker * copied and put under another distribution licence
565b37fcf3Sryker * [including the GNU Public Licence.]
575b37fcf3Sryker */
58ba5406e9Sbeck /* ====================================================================
59da347917Sbeck * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60ba5406e9Sbeck *
61ba5406e9Sbeck * Redistribution and use in source and binary forms, with or without
62ba5406e9Sbeck * modification, are permitted provided that the following conditions
63ba5406e9Sbeck * are met:
64ba5406e9Sbeck *
65ba5406e9Sbeck * 1. Redistributions of source code must retain the above copyright
66ba5406e9Sbeck * notice, this list of conditions and the following disclaimer.
67ba5406e9Sbeck *
68ba5406e9Sbeck * 2. Redistributions in binary form must reproduce the above copyright
69ba5406e9Sbeck * notice, this list of conditions and the following disclaimer in
70ba5406e9Sbeck * the documentation and/or other materials provided with the
71ba5406e9Sbeck * distribution.
72ba5406e9Sbeck *
73ba5406e9Sbeck * 3. All advertising materials mentioning features or use of this
74ba5406e9Sbeck * software must display the following acknowledgment:
75ba5406e9Sbeck * "This product includes software developed by the OpenSSL Project
76ba5406e9Sbeck * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77ba5406e9Sbeck *
78ba5406e9Sbeck * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79ba5406e9Sbeck * endorse or promote products derived from this software without
80ba5406e9Sbeck * prior written permission. For written permission, please contact
81ba5406e9Sbeck * openssl-core@openssl.org.
82ba5406e9Sbeck *
83ba5406e9Sbeck * 5. Products derived from this software may not be called "OpenSSL"
84ba5406e9Sbeck * nor may "OpenSSL" appear in their names without prior written
85ba5406e9Sbeck * permission of the OpenSSL Project.
86ba5406e9Sbeck *
87ba5406e9Sbeck * 6. Redistributions of any form whatsoever must retain the following
88ba5406e9Sbeck * acknowledgment:
89ba5406e9Sbeck * "This product includes software developed by the OpenSSL Project
90ba5406e9Sbeck * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91ba5406e9Sbeck *
92ba5406e9Sbeck * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93ba5406e9Sbeck * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94ba5406e9Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95ba5406e9Sbeck * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96ba5406e9Sbeck * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97ba5406e9Sbeck * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98ba5406e9Sbeck * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99ba5406e9Sbeck * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100ba5406e9Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101ba5406e9Sbeck * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102ba5406e9Sbeck * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103ba5406e9Sbeck * OF THE POSSIBILITY OF SUCH DAMAGE.
104ba5406e9Sbeck * ====================================================================
105ba5406e9Sbeck *
106ba5406e9Sbeck * This product includes cryptographic software written by Eric Young
107ba5406e9Sbeck * (eay@cryptsoft.com). This product includes software written by Tim
108ba5406e9Sbeck * Hudson (tjh@cryptsoft.com).
109ba5406e9Sbeck *
110ba5406e9Sbeck */
1115b37fcf3Sryker
1125b37fcf3Sryker #include <stdio.h>
1135b37fcf3Sryker #include <time.h>
114b6ab114eSjsing
115e123f381Smiod #include <openssl/err.h>
116e123f381Smiod
117c9675a23Stb #include "bn_local.h"
118b6ab114eSjsing
119ba5406e9Sbeck /* The quick sieve algorithm approach to weeding out primes is
1205b37fcf3Sryker * Philip Zimmermann's, as implemented in PGP. I have had a read of
1215b37fcf3Sryker * his comments and implemented my own version.
1225b37fcf3Sryker */
1235b37fcf3Sryker #include "bn_prime.h"
1245b37fcf3Sryker
1255b37fcf3Sryker static int probable_prime(BIGNUM *rnd, int bits);
1265b37fcf3Sryker static int probable_prime_dh(BIGNUM *rnd, int bits,
127da347917Sbeck const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
128ba5406e9Sbeck static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
129da347917Sbeck const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
130ba5406e9Sbeck
1312bd9bb84Sjsing int
BN_GENCB_call(BN_GENCB * cb,int a,int b)1322bd9bb84Sjsing BN_GENCB_call(BN_GENCB *cb, int a, int b)
1335b37fcf3Sryker {
1344fcf65c5Sdjm /* No callback means continue */
1352bd9bb84Sjsing if (!cb)
1362bd9bb84Sjsing return 1;
1372bd9bb84Sjsing switch (cb->ver) {
1384fcf65c5Sdjm case 1:
1394fcf65c5Sdjm /* Deprecated-style callbacks */
1404fcf65c5Sdjm if (!cb->cb.cb_1)
1414fcf65c5Sdjm return 1;
1424fcf65c5Sdjm cb->cb.cb_1(a, b, cb->arg);
1434fcf65c5Sdjm return 1;
1444fcf65c5Sdjm case 2:
1454fcf65c5Sdjm /* New-style callbacks */
1464fcf65c5Sdjm return cb->cb.cb_2(a, b, cb);
1474fcf65c5Sdjm default:
1484fcf65c5Sdjm break;
1494fcf65c5Sdjm }
1504fcf65c5Sdjm /* Unrecognised callback type */
1514fcf65c5Sdjm return 0;
1524fcf65c5Sdjm }
153ca1d80d6Sbeck LCRYPTO_ALIAS(BN_GENCB_call);
1544fcf65c5Sdjm
1552bd9bb84Sjsing int
BN_generate_prime_ex(BIGNUM * ret,int bits,int safe,const BIGNUM * add,const BIGNUM * rem,BN_GENCB * cb)1562bd9bb84Sjsing BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
1572bd9bb84Sjsing const BIGNUM *rem, BN_GENCB *cb)
1584fcf65c5Sdjm {
1595b37fcf3Sryker BN_CTX *ctx;
1609d12f35aStb BIGNUM *p;
1619d12f35aStb int is_prime;
1629d12f35aStb int loops = 0;
1639d12f35aStb int found = 0;
164e123f381Smiod
165e123f381Smiod if (bits < 2 || (bits == 2 && safe)) {
166e123f381Smiod /*
167e123f381Smiod * There are no prime numbers smaller than 2, and the smallest
168e123f381Smiod * safe prime (7) spans three bits.
169e123f381Smiod */
1705067ae9fSbeck BNerror(BN_R_BITS_TOO_SMALL);
171e123f381Smiod return 0;
172e123f381Smiod }
1735b37fcf3Sryker
174d99b4544Stb if ((ctx = BN_CTX_new()) == NULL)
1752bd9bb84Sjsing goto err;
1764fcf65c5Sdjm BN_CTX_start(ctx);
1779d12f35aStb if ((p = BN_CTX_get(ctx)) == NULL)
1782bd9bb84Sjsing goto err;
179e123f381Smiod
1805b37fcf3Sryker loop:
1819d12f35aStb /* Make a random number and set the top and bottom bits. */
1822bd9bb84Sjsing if (add == NULL) {
1832bd9bb84Sjsing if (!probable_prime(ret, bits))
1842bd9bb84Sjsing goto err;
1852bd9bb84Sjsing } else {
1862bd9bb84Sjsing if (safe) {
1874fcf65c5Sdjm if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
1885b37fcf3Sryker goto err;
1892bd9bb84Sjsing } else {
1904fcf65c5Sdjm if (!probable_prime_dh(ret, bits, add, rem, ctx))
1915b37fcf3Sryker goto err;
1925b37fcf3Sryker }
1935b37fcf3Sryker }
194d99b4544Stb
195d99b4544Stb if (!BN_GENCB_call(cb, 0, loops++))
1964fcf65c5Sdjm goto err;
1975b37fcf3Sryker
1982bd9bb84Sjsing if (!safe) {
1994e5c7375Stb if (!bn_is_prime_bpsw(&is_prime, ret, ctx, 1))
2002bd9bb84Sjsing goto err;
2019d12f35aStb if (!is_prime)
2022bd9bb84Sjsing goto loop;
2032bd9bb84Sjsing } else {
2044e5c7375Stb if (!bn_is_prime_bpsw(&is_prime, ret, ctx, 1))
2052bd9bb84Sjsing goto err;
2069d12f35aStb if (!is_prime)
2072bd9bb84Sjsing goto loop;
2085b37fcf3Sryker
2099d12f35aStb /*
2109d12f35aStb * For safe prime generation, check that p = (ret-1)/2 is prime.
2119d12f35aStb * Since this prime has >= 3 bits, it is odd, and we can simply
2129d12f35aStb * divide by 2.
2139d12f35aStb */
2149d12f35aStb if (!BN_rshift1(p, ret))
2152bd9bb84Sjsing goto err;
2169d12f35aStb
2174e5c7375Stb if (!bn_is_prime_bpsw(&is_prime, p, ctx, 1))
2189d12f35aStb goto err;
2199d12f35aStb if (!is_prime)
2202bd9bb84Sjsing goto loop;
2215b37fcf3Sryker
222d99b4544Stb if (!BN_GENCB_call(cb, 2, loops - 1))
2234fcf65c5Sdjm goto err;
2245b37fcf3Sryker }
225d99b4544Stb
226ba5406e9Sbeck found = 1;
2272bd9bb84Sjsing
2285b37fcf3Sryker err:
2294fcf65c5Sdjm BN_CTX_end(ctx);
2304fcf65c5Sdjm BN_CTX_free(ctx);
231d99b4544Stb
2324fcf65c5Sdjm return found;
233ba5406e9Sbeck }
234ca1d80d6Sbeck LCRYPTO_ALIAS(BN_generate_prime_ex);
2355b37fcf3Sryker
2362bd9bb84Sjsing int
BN_is_prime_ex(const BIGNUM * a,int checks,BN_CTX * ctx_passed,BN_GENCB * cb)2372bd9bb84Sjsing BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb)
2384fcf65c5Sdjm {
2394fcf65c5Sdjm return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
2404fcf65c5Sdjm }
241ca1d80d6Sbeck LCRYPTO_ALIAS(BN_is_prime_ex);
2424fcf65c5Sdjm
243*050d837aStb #define BN_PRIME_MAXIMUM_BITS (32 * 1024)
244*050d837aStb
2452bd9bb84Sjsing int
BN_is_prime_fasttest_ex(const BIGNUM * a,int checks,BN_CTX * ctx_passed,int do_trial_division,BN_GENCB * cb)2462bd9bb84Sjsing BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
2474fcf65c5Sdjm int do_trial_division, BN_GENCB *cb)
248ba5406e9Sbeck {
2490cc5b3fcStb int is_prime;
2500cc5b3fcStb
2514e5c7375Stb if (checks < 0)
2524e5c7375Stb return -1;
2534e5c7375Stb
254*050d837aStb /*
255*050d837aStb * Prime numbers this large do not appear in everyday cryptography
256*050d837aStb * and checking such numbers for primality is very expensive.
257*050d837aStb */
258*050d837aStb if (BN_num_bits(a) > BN_PRIME_MAXIMUM_BITS) {
259*050d837aStb BNerror(BN_R_BIGNUM_TOO_LONG);
260*050d837aStb return -1;
261*050d837aStb }
262*050d837aStb
2634e5c7375Stb if (checks == BN_prime_checks)
2644e5c7375Stb checks = BN_prime_checks_for_size(BN_num_bits(a));
2654e5c7375Stb
2660cc5b3fcStb /* XXX - tickle BN_GENCB in bn_is_prime_bpsw(). */
2674e5c7375Stb if (!bn_is_prime_bpsw(&is_prime, a, ctx_passed, checks))
2680cc5b3fcStb return -1;
2690cc5b3fcStb
2700cc5b3fcStb return is_prime;
2715b37fcf3Sryker }
272ca1d80d6Sbeck LCRYPTO_ALIAS(BN_is_prime_fasttest_ex);
2735b37fcf3Sryker
2742bd9bb84Sjsing static int
probable_prime(BIGNUM * rnd,int bits)2752bd9bb84Sjsing probable_prime(BIGNUM *rnd, int bits)
2765b37fcf3Sryker {
2775b37fcf3Sryker int i;
27854ce1b6bStb BN_ULONG mods[NUMPRIMES];
2794fcf65c5Sdjm BN_ULONG delta, maxdelta;
2805b37fcf3Sryker
281913ec974Sbeck again:
2822bd9bb84Sjsing if (!BN_rand(rnd, bits, 1, 1))
2832bd9bb84Sjsing return (0);
2845b37fcf3Sryker /* we now have a random number 'rand' to test. */
285c17ab57aSbcook for (i = 1; i < NUMPRIMES; i++) {
28654ce1b6bStb BN_ULONG mod = BN_mod_word(rnd, primes[i]);
287c17ab57aSbcook if (mod == (BN_ULONG)-1)
288c17ab57aSbcook return (0);
28954ce1b6bStb mods[i] = mod;
290c17ab57aSbcook }
2914fcf65c5Sdjm maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
2925b37fcf3Sryker delta = 0;
2932bd9bb84Sjsing loop:
2942bd9bb84Sjsing for (i = 1; i < NUMPRIMES; i++) {
2955b37fcf3Sryker /* check that rnd is not a prime and also
2965b37fcf3Sryker * that gcd(rnd-1,primes) == 1 (except for 2) */
2972bd9bb84Sjsing if (((mods[i] + delta) % primes[i]) <= 1) {
2985b37fcf3Sryker delta += 2;
2992bd9bb84Sjsing if (delta > maxdelta)
3002bd9bb84Sjsing goto again;
3015b37fcf3Sryker goto loop;
3025b37fcf3Sryker }
3035b37fcf3Sryker }
3042bd9bb84Sjsing if (!BN_add_word(rnd, delta))
3052bd9bb84Sjsing return (0);
3065b37fcf3Sryker return (1);
3075b37fcf3Sryker }
3085b37fcf3Sryker
3092bd9bb84Sjsing static int
probable_prime_dh(BIGNUM * rnd,int bits,const BIGNUM * add,const BIGNUM * rem,BN_CTX * ctx)3102bd9bb84Sjsing probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem,
3112bd9bb84Sjsing BN_CTX *ctx)
3125b37fcf3Sryker {
3135b37fcf3Sryker int i, ret = 0;
3145b37fcf3Sryker BIGNUM *t1;
3155b37fcf3Sryker
316ba5406e9Sbeck BN_CTX_start(ctx);
3172bd9bb84Sjsing if ((t1 = BN_CTX_get(ctx)) == NULL)
3182bd9bb84Sjsing goto err;
3195b37fcf3Sryker
3202bd9bb84Sjsing if (!BN_rand(rnd, bits, 0, 1))
3212bd9bb84Sjsing goto err;
3225b37fcf3Sryker
3235b37fcf3Sryker /* we need ((rnd-rem) % add) == 0 */
3245b37fcf3Sryker
32544adc1eaSbeck if (!BN_mod_ct(t1, rnd, add, ctx))
3262bd9bb84Sjsing goto err;
3272bd9bb84Sjsing if (!BN_sub(rnd, rnd, t1))
3282bd9bb84Sjsing goto err;
3292bd9bb84Sjsing if (rem == NULL) {
3302bd9bb84Sjsing if (!BN_add_word(rnd, 1))
3312bd9bb84Sjsing goto err;
3322bd9bb84Sjsing } else {
3332bd9bb84Sjsing if (!BN_add(rnd, rnd, rem))
3342bd9bb84Sjsing goto err;
3352bd9bb84Sjsing }
3365b37fcf3Sryker
3375b37fcf3Sryker /* we now have a random number 'rand' to test. */
3385b37fcf3Sryker
3392bd9bb84Sjsing loop:
3402bd9bb84Sjsing for (i = 1; i < NUMPRIMES; i++) {
3415b37fcf3Sryker /* check that rnd is a prime */
34254ce1b6bStb BN_LONG mod = BN_mod_word(rnd, primes[i]);
343c17ab57aSbcook if (mod == (BN_ULONG)-1)
344c17ab57aSbcook goto err;
345c17ab57aSbcook if (mod <= 1) {
3462bd9bb84Sjsing if (!BN_add(rnd, rnd, add))
3472bd9bb84Sjsing goto err;
3485b37fcf3Sryker goto loop;
3495b37fcf3Sryker }
3505b37fcf3Sryker }
3515b37fcf3Sryker ret = 1;
3522bd9bb84Sjsing
3535b37fcf3Sryker err:
354ba5406e9Sbeck BN_CTX_end(ctx);
3555b37fcf3Sryker return (ret);
3565b37fcf3Sryker }
3575b37fcf3Sryker
3582bd9bb84Sjsing static int
probable_prime_dh_safe(BIGNUM * p,int bits,const BIGNUM * padd,const BIGNUM * rem,BN_CTX * ctx)3592bd9bb84Sjsing probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
360da347917Sbeck const BIGNUM *rem, BN_CTX *ctx)
3615b37fcf3Sryker {
3625b37fcf3Sryker int i, ret = 0;
363ba5406e9Sbeck BIGNUM *t1, *qadd, *q;
3645b37fcf3Sryker
3655b37fcf3Sryker bits--;
366ba5406e9Sbeck BN_CTX_start(ctx);
367aa389b8cSjsing if ((t1 = BN_CTX_get(ctx)) == NULL)
368aa389b8cSjsing goto err;
369aa389b8cSjsing if ((q = BN_CTX_get(ctx)) == NULL)
370aa389b8cSjsing goto err;
371aa389b8cSjsing if ((qadd = BN_CTX_get(ctx)) == NULL)
3722bd9bb84Sjsing goto err;
3735b37fcf3Sryker
3742bd9bb84Sjsing if (!BN_rshift1(qadd, padd))
3752bd9bb84Sjsing goto err;
3765b37fcf3Sryker
3772bd9bb84Sjsing if (!BN_rand(q, bits, 0, 1))
3782bd9bb84Sjsing goto err;
3795b37fcf3Sryker
3805b37fcf3Sryker /* we need ((rnd-rem) % add) == 0 */
38144adc1eaSbeck if (!BN_mod_ct(t1, q,qadd, ctx))
3822bd9bb84Sjsing goto err;
3832bd9bb84Sjsing if (!BN_sub(q, q, t1))
3842bd9bb84Sjsing goto err;
3852bd9bb84Sjsing if (rem == NULL) {
3862bd9bb84Sjsing if (!BN_add_word(q, 1))
3872bd9bb84Sjsing goto err;
3882bd9bb84Sjsing } else {
3892bd9bb84Sjsing if (!BN_rshift1(t1, rem))
3902bd9bb84Sjsing goto err;
3912bd9bb84Sjsing if (!BN_add(q, q, t1))
3922bd9bb84Sjsing goto err;
3935b37fcf3Sryker }
3945b37fcf3Sryker
3955b37fcf3Sryker /* we now have a random number 'rand' to test. */
3962bd9bb84Sjsing if (!BN_lshift1(p, q))
3972bd9bb84Sjsing goto err;
3982bd9bb84Sjsing if (!BN_add_word(p, 1))
3992bd9bb84Sjsing goto err;
4005b37fcf3Sryker
4012bd9bb84Sjsing loop:
4022bd9bb84Sjsing for (i = 1; i < NUMPRIMES; i++) {
4035b37fcf3Sryker /* check that p and q are prime */
4045b37fcf3Sryker /* check that for p and q
4055b37fcf3Sryker * gcd(p-1,primes) == 1 (except for 2) */
40654ce1b6bStb BN_ULONG pmod = BN_mod_word(p, primes[i]);
40754ce1b6bStb BN_ULONG qmod = BN_mod_word(q, primes[i]);
408c17ab57aSbcook if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1)
409c17ab57aSbcook goto err;
410c17ab57aSbcook if (pmod == 0 || qmod == 0) {
4112bd9bb84Sjsing if (!BN_add(p, p, padd))
4122bd9bb84Sjsing goto err;
4132bd9bb84Sjsing if (!BN_add(q, q, qadd))
4142bd9bb84Sjsing goto err;
4155b37fcf3Sryker goto loop;
4165b37fcf3Sryker }
4175b37fcf3Sryker }
4185b37fcf3Sryker ret = 1;
4192bd9bb84Sjsing
4205b37fcf3Sryker err:
421ba5406e9Sbeck BN_CTX_end(ctx);
4225b37fcf3Sryker return (ret);
4235b37fcf3Sryker }
424