155714Skris/* crypto/bn/bn_prime.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296465Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296465Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296465Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296465Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296465Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5859191Skris/* ====================================================================
59109998Smarkm * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
6059191Skris *
6159191Skris * Redistribution and use in source and binary forms, with or without
6259191Skris * modification, are permitted provided that the following conditions
6359191Skris * are met:
6459191Skris *
6559191Skris * 1. Redistributions of source code must retain the above copyright
66296465Sdelphij *    notice, this list of conditions and the following disclaimer.
6759191Skris *
6859191Skris * 2. Redistributions in binary form must reproduce the above copyright
6959191Skris *    notice, this list of conditions and the following disclaimer in
7059191Skris *    the documentation and/or other materials provided with the
7159191Skris *    distribution.
7259191Skris *
7359191Skris * 3. All advertising materials mentioning features or use of this
7459191Skris *    software must display the following acknowledgment:
7559191Skris *    "This product includes software developed by the OpenSSL Project
7659191Skris *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
7759191Skris *
7859191Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
7959191Skris *    endorse or promote products derived from this software without
8059191Skris *    prior written permission. For written permission, please contact
8159191Skris *    openssl-core@openssl.org.
8259191Skris *
8359191Skris * 5. Products derived from this software may not be called "OpenSSL"
8459191Skris *    nor may "OpenSSL" appear in their names without prior written
8559191Skris *    permission of the OpenSSL Project.
8659191Skris *
8759191Skris * 6. Redistributions of any form whatsoever must retain the following
8859191Skris *    acknowledgment:
8959191Skris *    "This product includes software developed by the OpenSSL Project
9059191Skris *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
9159191Skris *
9259191Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9359191Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9459191Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9559191Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9659191Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9759191Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9859191Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9959191Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10059191Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10159191Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10259191Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10359191Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
10459191Skris * ====================================================================
10559191Skris *
10659191Skris * This product includes cryptographic software written by Eric Young
10759191Skris * (eay@cryptsoft.com).  This product includes software written by Tim
10859191Skris * Hudson (tjh@cryptsoft.com).
10959191Skris *
11059191Skris */
11155714Skris
11255714Skris#include <stdio.h>
11355714Skris#include <time.h>
11455714Skris#include "cryptlib.h"
11555714Skris#include "bn_lcl.h"
11655714Skris#include <openssl/rand.h>
11755714Skris
118296465Sdelphij/*
119296465Sdelphij * NB: these functions have been "upgraded", the deprecated versions (which
120296465Sdelphij * are compatibility wrappers using these functions) are in bn_depr.c. -
121296465Sdelphij * Geoff
122160814Ssimon */
123160814Ssimon
124296465Sdelphij/*
125296465Sdelphij * The quick sieve algorithm approach to weeding out primes is Philip
126296465Sdelphij * Zimmermann's, as implemented in PGP.  I have had a read of his comments
127296465Sdelphij * and implemented my own version.
12855714Skris */
12955714Skris#include "bn_prime.h"
13055714Skris
13159191Skrisstatic int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
132296465Sdelphij                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
133296465Sdelphij                   BN_MONT_CTX *mont);
13455714Skrisstatic int probable_prime(BIGNUM *rnd, int bits);
13555714Skrisstatic int probable_prime_dh(BIGNUM *rnd, int bits,
136296465Sdelphij                             const BIGNUM *add, const BIGNUM *rem,
137296465Sdelphij                             BN_CTX *ctx);
138296465Sdelphijstatic int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add,
139296465Sdelphij                                  const BIGNUM *rem, BN_CTX *ctx);
14059191Skris
141160814Ssimonint BN_GENCB_call(BN_GENCB *cb, int a, int b)
142296465Sdelphij{
143296465Sdelphij    /* No callback means continue */
144296465Sdelphij    if (!cb)
145296465Sdelphij        return 1;
146296465Sdelphij    switch (cb->ver) {
147296465Sdelphij    case 1:
148296465Sdelphij        /* Deprecated-style callbacks */
149296465Sdelphij        if (!cb->cb.cb_1)
150296465Sdelphij            return 1;
151296465Sdelphij        cb->cb.cb_1(a, b, cb->arg);
152296465Sdelphij        return 1;
153296465Sdelphij    case 2:
154296465Sdelphij        /* New-style callbacks */
155296465Sdelphij        return cb->cb.cb_2(a, b, cb);
156296465Sdelphij    default:
157296465Sdelphij        break;
158296465Sdelphij    }
159296465Sdelphij    /* Unrecognised callback type */
160296465Sdelphij    return 0;
161296465Sdelphij}
162160814Ssimon
163160814Ssimonint BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
164296465Sdelphij                         const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
165296465Sdelphij{
166296465Sdelphij    BIGNUM *t;
167296465Sdelphij    int found = 0;
168296465Sdelphij    int i, j, c1 = 0;
169296465Sdelphij    BN_CTX *ctx;
170296465Sdelphij    int checks = BN_prime_checks_for_size(bits);
17155714Skris
172296465Sdelphij    ctx = BN_CTX_new();
173296465Sdelphij    if (ctx == NULL)
174296465Sdelphij        goto err;
175296465Sdelphij    BN_CTX_start(ctx);
176296465Sdelphij    t = BN_CTX_get(ctx);
177296465Sdelphij    if (!t)
178296465Sdelphij        goto err;
179296465Sdelphij loop:
180296465Sdelphij    /* make a random number and set the top and bottom bits */
181296465Sdelphij    if (add == NULL) {
182296465Sdelphij        if (!probable_prime(ret, bits))
183296465Sdelphij            goto err;
184296465Sdelphij    } else {
185296465Sdelphij        if (safe) {
186296465Sdelphij            if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
187296465Sdelphij                goto err;
188296465Sdelphij        } else {
189296465Sdelphij            if (!probable_prime_dh(ret, bits, add, rem, ctx))
190296465Sdelphij                goto err;
191296465Sdelphij        }
192296465Sdelphij    }
193296465Sdelphij    /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
194296465Sdelphij    if (!BN_GENCB_call(cb, 0, c1++))
195296465Sdelphij        /* aborted */
196296465Sdelphij        goto err;
19755714Skris
198296465Sdelphij    if (!safe) {
199296465Sdelphij        i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
200296465Sdelphij        if (i == -1)
201296465Sdelphij            goto err;
202296465Sdelphij        if (i == 0)
203296465Sdelphij            goto loop;
204296465Sdelphij    } else {
205296465Sdelphij        /*
206296465Sdelphij         * for "safe prime" generation, check that (p-1)/2 is prime. Since a
207296465Sdelphij         * prime is odd, We just need to divide by 2
208296465Sdelphij         */
209296465Sdelphij        if (!BN_rshift1(t, ret))
210296465Sdelphij            goto err;
21155714Skris
212296465Sdelphij        for (i = 0; i < checks; i++) {
213296465Sdelphij            j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
214296465Sdelphij            if (j == -1)
215296465Sdelphij                goto err;
216296465Sdelphij            if (j == 0)
217296465Sdelphij                goto loop;
21855714Skris
219296465Sdelphij            j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
220296465Sdelphij            if (j == -1)
221296465Sdelphij                goto err;
222296465Sdelphij            if (j == 0)
223296465Sdelphij                goto loop;
22455714Skris
225296465Sdelphij            if (!BN_GENCB_call(cb, 2, c1 - 1))
226296465Sdelphij                goto err;
227296465Sdelphij            /* We have a safe prime test pass */
228296465Sdelphij        }
229296465Sdelphij    }
230296465Sdelphij    /* we have a prime :-) */
231296465Sdelphij    found = 1;
232296465Sdelphij err:
233296465Sdelphij    if (ctx != NULL) {
234296465Sdelphij        BN_CTX_end(ctx);
235296465Sdelphij        BN_CTX_free(ctx);
236296465Sdelphij    }
237296465Sdelphij    bn_check_top(ret);
238296465Sdelphij    return found;
239296465Sdelphij}
24055714Skris
241296465Sdelphijint BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
242296465Sdelphij                   BN_GENCB *cb)
243296465Sdelphij{
244296465Sdelphij    return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
245296465Sdelphij}
24655714Skris
247160814Ssimonint BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
248296465Sdelphij                            int do_trial_division, BN_GENCB *cb)
249296465Sdelphij{
250296465Sdelphij    int i, j, ret = -1;
251296465Sdelphij    int k;
252296465Sdelphij    BN_CTX *ctx = NULL;
253296465Sdelphij    BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
254296465Sdelphij    BN_MONT_CTX *mont = NULL;
255296465Sdelphij    const BIGNUM *A = NULL;
25659191Skris
257296465Sdelphij    if (BN_cmp(a, BN_value_one()) <= 0)
258296465Sdelphij        return 0;
25959191Skris
260296465Sdelphij    if (checks == BN_prime_checks)
261296465Sdelphij        checks = BN_prime_checks_for_size(BN_num_bits(a));
26259191Skris
263296465Sdelphij    /* first look for small factors */
264296465Sdelphij    if (!BN_is_odd(a))
265296465Sdelphij        /* a is even => a is prime if and only if a == 2 */
266296465Sdelphij        return BN_is_word(a, 2);
267296465Sdelphij    if (do_trial_division) {
268296465Sdelphij        for (i = 1; i < NUMPRIMES; i++)
269296465Sdelphij            if (BN_mod_word(a, primes[i]) == 0)
270296465Sdelphij                return 0;
271296465Sdelphij        if (!BN_GENCB_call(cb, 1, -1))
272296465Sdelphij            goto err;
273296465Sdelphij    }
27455714Skris
275296465Sdelphij    if (ctx_passed != NULL)
276296465Sdelphij        ctx = ctx_passed;
277296465Sdelphij    else if ((ctx = BN_CTX_new()) == NULL)
278296465Sdelphij        goto err;
279296465Sdelphij    BN_CTX_start(ctx);
28055714Skris
281296465Sdelphij    /* A := abs(a) */
282296465Sdelphij    if (a->neg) {
283296465Sdelphij        BIGNUM *t;
284296465Sdelphij        if ((t = BN_CTX_get(ctx)) == NULL)
285296465Sdelphij            goto err;
286296465Sdelphij        BN_copy(t, a);
287296465Sdelphij        t->neg = 0;
288296465Sdelphij        A = t;
289296465Sdelphij    } else
290296465Sdelphij        A = a;
291296465Sdelphij    A1 = BN_CTX_get(ctx);
292296465Sdelphij    A1_odd = BN_CTX_get(ctx);
293296465Sdelphij    check = BN_CTX_get(ctx);
294296465Sdelphij    if (check == NULL)
295296465Sdelphij        goto err;
29655714Skris
297296465Sdelphij    /* compute A1 := A - 1 */
298296465Sdelphij    if (!BN_copy(A1, A))
299296465Sdelphij        goto err;
300296465Sdelphij    if (!BN_sub_word(A1, 1))
301296465Sdelphij        goto err;
302296465Sdelphij    if (BN_is_zero(A1)) {
303296465Sdelphij        ret = 0;
304296465Sdelphij        goto err;
305296465Sdelphij    }
30655714Skris
307296465Sdelphij    /* write  A1  as  A1_odd * 2^k */
308296465Sdelphij    k = 1;
309296465Sdelphij    while (!BN_is_bit_set(A1, k))
310296465Sdelphij        k++;
311296465Sdelphij    if (!BN_rshift(A1_odd, A1, k))
312296465Sdelphij        goto err;
31359191Skris
314296465Sdelphij    /* Montgomery setup for computations mod A */
315296465Sdelphij    mont = BN_MONT_CTX_new();
316296465Sdelphij    if (mont == NULL)
317296465Sdelphij        goto err;
318296465Sdelphij    if (!BN_MONT_CTX_set(mont, A, ctx))
319296465Sdelphij        goto err;
32059191Skris
321296465Sdelphij    for (i = 0; i < checks; i++) {
322296465Sdelphij        if (!BN_pseudo_rand_range(check, A1))
323296465Sdelphij            goto err;
324296465Sdelphij        if (!BN_add_word(check, 1))
325296465Sdelphij            goto err;
326296465Sdelphij        /* now 1 <= check < A */
32755714Skris
328296465Sdelphij        j = witness(check, A, A1, A1_odd, k, ctx, mont);
329296465Sdelphij        if (j == -1)
330296465Sdelphij            goto err;
331296465Sdelphij        if (j) {
332296465Sdelphij            ret = 0;
333296465Sdelphij            goto err;
334296465Sdelphij        }
335296465Sdelphij        if (!BN_GENCB_call(cb, 1, i))
336296465Sdelphij            goto err;
337296465Sdelphij    }
338296465Sdelphij    ret = 1;
339296465Sdelphij err:
340296465Sdelphij    if (ctx != NULL) {
341296465Sdelphij        BN_CTX_end(ctx);
342296465Sdelphij        if (ctx_passed == NULL)
343296465Sdelphij            BN_CTX_free(ctx);
344296465Sdelphij    }
345296465Sdelphij    if (mont != NULL)
346296465Sdelphij        BN_MONT_CTX_free(mont);
347296465Sdelphij
348296465Sdelphij    return (ret);
349296465Sdelphij}
350296465Sdelphij
35159191Skrisstatic int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
352296465Sdelphij                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
353296465Sdelphij                   BN_MONT_CTX *mont)
354296465Sdelphij{
355296465Sdelphij    if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
356296465Sdelphij        return -1;
357296465Sdelphij    if (BN_is_one(w))
358296465Sdelphij        return 0;               /* probably prime */
359296465Sdelphij    if (BN_cmp(w, a1) == 0)
360296465Sdelphij        return 0;               /* w == -1 (mod a), 'a' is probably prime */
361296465Sdelphij    while (--k) {
362296465Sdelphij        if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
363296465Sdelphij            return -1;
364296465Sdelphij        if (BN_is_one(w))
365296465Sdelphij            return 1;           /* 'a' is composite, otherwise a previous 'w'
366296465Sdelphij                                 * would have been == -1 (mod 'a') */
367296465Sdelphij        if (BN_cmp(w, a1) == 0)
368296465Sdelphij            return 0;           /* w == -1 (mod a), 'a' is probably prime */
369296465Sdelphij    }
370296465Sdelphij    /*
371296465Sdelphij     * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and
372296465Sdelphij     * it is neither -1 nor +1 -- so 'a' cannot be prime
373296465Sdelphij     */
374296465Sdelphij    bn_check_top(w);
375296465Sdelphij    return 1;
376296465Sdelphij}
37755714Skris
37855714Skrisstatic int probable_prime(BIGNUM *rnd, int bits)
379296465Sdelphij{
380296465Sdelphij    int i;
381296465Sdelphij    prime_t mods[NUMPRIMES];
382296465Sdelphij    BN_ULONG delta, maxdelta;
38355714Skris
384296465Sdelphij again:
385296465Sdelphij    if (!BN_rand(rnd, bits, 1, 1))
386296465Sdelphij        return (0);
387296465Sdelphij    /* we now have a random number 'rand' to test. */
388296465Sdelphij    for (i = 1; i < NUMPRIMES; i++)
389296465Sdelphij        mods[i] = (prime_t) BN_mod_word(rnd, (BN_ULONG)primes[i]);
390296465Sdelphij    maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
391296465Sdelphij    delta = 0;
392296465Sdelphij loop:for (i = 1; i < NUMPRIMES; i++) {
393296465Sdelphij        /*
394296465Sdelphij         * check that rnd is not a prime and also that gcd(rnd-1,primes) == 1
395296465Sdelphij         * (except for 2)
396296465Sdelphij         */
397296465Sdelphij        if (((mods[i] + delta) % primes[i]) <= 1) {
398296465Sdelphij            delta += 2;
399296465Sdelphij            if (delta > maxdelta)
400296465Sdelphij                goto again;
401296465Sdelphij            goto loop;
402296465Sdelphij        }
403296465Sdelphij    }
404296465Sdelphij    if (!BN_add_word(rnd, delta))
405296465Sdelphij        return (0);
406296465Sdelphij    bn_check_top(rnd);
407296465Sdelphij    return (1);
408296465Sdelphij}
40955714Skris
410109998Smarkmstatic int probable_prime_dh(BIGNUM *rnd, int bits,
411296465Sdelphij                             const BIGNUM *add, const BIGNUM *rem,
412296465Sdelphij                             BN_CTX *ctx)
413296465Sdelphij{
414296465Sdelphij    int i, ret = 0;
415296465Sdelphij    BIGNUM *t1;
41655714Skris
417296465Sdelphij    BN_CTX_start(ctx);
418296465Sdelphij    if ((t1 = BN_CTX_get(ctx)) == NULL)
419296465Sdelphij        goto err;
42055714Skris
421296465Sdelphij    if (!BN_rand(rnd, bits, 0, 1))
422296465Sdelphij        goto err;
42355714Skris
424296465Sdelphij    /* we need ((rnd-rem) % add) == 0 */
42555714Skris
426296465Sdelphij    if (!BN_mod(t1, rnd, add, ctx))
427296465Sdelphij        goto err;
428296465Sdelphij    if (!BN_sub(rnd, rnd, t1))
429296465Sdelphij        goto err;
430296465Sdelphij    if (rem == NULL) {
431296465Sdelphij        if (!BN_add_word(rnd, 1))
432296465Sdelphij            goto err;
433296465Sdelphij    } else {
434296465Sdelphij        if (!BN_add(rnd, rnd, rem))
435296465Sdelphij            goto err;
436296465Sdelphij    }
43755714Skris
438296465Sdelphij    /* we now have a random number 'rand' to test. */
43955714Skris
440296465Sdelphij loop:for (i = 1; i < NUMPRIMES; i++) {
441296465Sdelphij        /* check that rnd is a prime */
442296465Sdelphij        if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) {
443296465Sdelphij            if (!BN_add(rnd, rnd, add))
444296465Sdelphij                goto err;
445296465Sdelphij            goto loop;
446296465Sdelphij        }
447296465Sdelphij    }
448296465Sdelphij    ret = 1;
449296465Sdelphij err:
450296465Sdelphij    BN_CTX_end(ctx);
451296465Sdelphij    bn_check_top(rnd);
452296465Sdelphij    return (ret);
453296465Sdelphij}
45455714Skris
455109998Smarkmstatic int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
456296465Sdelphij                                  const BIGNUM *rem, BN_CTX *ctx)
457296465Sdelphij{
458296465Sdelphij    int i, ret = 0;
459296465Sdelphij    BIGNUM *t1, *qadd, *q;
46055714Skris
461296465Sdelphij    bits--;
462296465Sdelphij    BN_CTX_start(ctx);
463296465Sdelphij    t1 = BN_CTX_get(ctx);
464296465Sdelphij    q = BN_CTX_get(ctx);
465296465Sdelphij    qadd = BN_CTX_get(ctx);
466296465Sdelphij    if (qadd == NULL)
467296465Sdelphij        goto err;
46855714Skris
469296465Sdelphij    if (!BN_rshift1(qadd, padd))
470296465Sdelphij        goto err;
47155714Skris
472296465Sdelphij    if (!BN_rand(q, bits, 0, 1))
473296465Sdelphij        goto err;
47455714Skris
475296465Sdelphij    /* we need ((rnd-rem) % add) == 0 */
476296465Sdelphij    if (!BN_mod(t1, q, qadd, ctx))
477296465Sdelphij        goto err;
478296465Sdelphij    if (!BN_sub(q, q, t1))
479296465Sdelphij        goto err;
480296465Sdelphij    if (rem == NULL) {
481296465Sdelphij        if (!BN_add_word(q, 1))
482296465Sdelphij            goto err;
483296465Sdelphij    } else {
484296465Sdelphij        if (!BN_rshift1(t1, rem))
485296465Sdelphij            goto err;
486296465Sdelphij        if (!BN_add(q, q, t1))
487296465Sdelphij            goto err;
488296465Sdelphij    }
48955714Skris
490296465Sdelphij    /* we now have a random number 'rand' to test. */
491296465Sdelphij    if (!BN_lshift1(p, q))
492296465Sdelphij        goto err;
493296465Sdelphij    if (!BN_add_word(p, 1))
494296465Sdelphij        goto err;
495296465Sdelphij
496296465Sdelphij loop:for (i = 1; i < NUMPRIMES; i++) {
497296465Sdelphij        /* check that p and q are prime */
498296465Sdelphij        /*
499296465Sdelphij         * check that for p and q gcd(p-1,primes) == 1 (except for 2)
500296465Sdelphij         */
501296465Sdelphij        if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) ||
502296465Sdelphij            (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) {
503296465Sdelphij            if (!BN_add(p, p, padd))
504296465Sdelphij                goto err;
505296465Sdelphij            if (!BN_add(q, q, qadd))
506296465Sdelphij                goto err;
507296465Sdelphij            goto loop;
508296465Sdelphij        }
509296465Sdelphij    }
510296465Sdelphij    ret = 1;
511296465Sdelphij err:
512296465Sdelphij    BN_CTX_end(ctx);
513296465Sdelphij    bn_check_top(p);
514296465Sdelphij    return (ret);
515296465Sdelphij}
516