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.
8296341Sdelphij *
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).
15296341Sdelphij *
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.
22296341Sdelphij *
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 :-).
37296341Sdelphij * 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)"
40296341Sdelphij *
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.
52296341Sdelphij *
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
66296341Sdelphij *    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
118296341Sdelphij/*
119296341Sdelphij * NB: these functions have been "upgraded", the deprecated versions (which
120296341Sdelphij * are compatibility wrappers using these functions) are in bn_depr.c. -
121296341Sdelphij * Geoff
122160814Ssimon */
123160814Ssimon
124296341Sdelphij/*
125296341Sdelphij * The quick sieve algorithm approach to weeding out primes is Philip
126296341Sdelphij * Zimmermann's, as implemented in PGP.  I have had a read of his comments
127296341Sdelphij * and implemented my own version.
12855714Skris */
12955714Skris#include "bn_prime.h"
13055714Skris
13159191Skrisstatic int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
132296341Sdelphij                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
133296341Sdelphij                   BN_MONT_CTX *mont);
13455714Skrisstatic int probable_prime(BIGNUM *rnd, int bits);
13555714Skrisstatic int probable_prime_dh(BIGNUM *rnd, int bits,
136296341Sdelphij                             const BIGNUM *add, const BIGNUM *rem,
137296341Sdelphij                             BN_CTX *ctx);
138296341Sdelphijstatic int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add,
139296341Sdelphij                                  const BIGNUM *rem, BN_CTX *ctx);
14059191Skris
141160814Ssimonint BN_GENCB_call(BN_GENCB *cb, int a, int b)
142296341Sdelphij{
143296341Sdelphij    /* No callback means continue */
144296341Sdelphij    if (!cb)
145296341Sdelphij        return 1;
146296341Sdelphij    switch (cb->ver) {
147296341Sdelphij    case 1:
148296341Sdelphij        /* Deprecated-style callbacks */
149296341Sdelphij        if (!cb->cb.cb_1)
150296341Sdelphij            return 1;
151296341Sdelphij        cb->cb.cb_1(a, b, cb->arg);
152296341Sdelphij        return 1;
153296341Sdelphij    case 2:
154296341Sdelphij        /* New-style callbacks */
155296341Sdelphij        return cb->cb.cb_2(a, b, cb);
156296341Sdelphij    default:
157296341Sdelphij        break;
158296341Sdelphij    }
159296341Sdelphij    /* Unrecognised callback type */
160296341Sdelphij    return 0;
161296341Sdelphij}
162160814Ssimon
163160814Ssimonint BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
164296341Sdelphij                         const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
165296341Sdelphij{
166296341Sdelphij    BIGNUM *t;
167296341Sdelphij    int found = 0;
168296341Sdelphij    int i, j, c1 = 0;
169296341Sdelphij    BN_CTX *ctx;
170296341Sdelphij    int checks = BN_prime_checks_for_size(bits);
17155714Skris
172296341Sdelphij    ctx = BN_CTX_new();
173296341Sdelphij    if (ctx == NULL)
174296341Sdelphij        goto err;
175296341Sdelphij    BN_CTX_start(ctx);
176296341Sdelphij    t = BN_CTX_get(ctx);
177296341Sdelphij    if (!t)
178296341Sdelphij        goto err;
179296341Sdelphij loop:
180296341Sdelphij    /* make a random number and set the top and bottom bits */
181296341Sdelphij    if (add == NULL) {
182296341Sdelphij        if (!probable_prime(ret, bits))
183296341Sdelphij            goto err;
184296341Sdelphij    } else {
185296341Sdelphij        if (safe) {
186296341Sdelphij            if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
187296341Sdelphij                goto err;
188296341Sdelphij        } else {
189296341Sdelphij            if (!probable_prime_dh(ret, bits, add, rem, ctx))
190296341Sdelphij                goto err;
191296341Sdelphij        }
192296341Sdelphij    }
193296341Sdelphij    /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
194296341Sdelphij    if (!BN_GENCB_call(cb, 0, c1++))
195296341Sdelphij        /* aborted */
196296341Sdelphij        goto err;
19755714Skris
198296341Sdelphij    if (!safe) {
199296341Sdelphij        i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
200296341Sdelphij        if (i == -1)
201296341Sdelphij            goto err;
202296341Sdelphij        if (i == 0)
203296341Sdelphij            goto loop;
204296341Sdelphij    } else {
205296341Sdelphij        /*
206296341Sdelphij         * for "safe prime" generation, check that (p-1)/2 is prime. Since a
207296341Sdelphij         * prime is odd, We just need to divide by 2
208296341Sdelphij         */
209296341Sdelphij        if (!BN_rshift1(t, ret))
210296341Sdelphij            goto err;
21155714Skris
212296341Sdelphij        for (i = 0; i < checks; i++) {
213296341Sdelphij            j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
214296341Sdelphij            if (j == -1)
215296341Sdelphij                goto err;
216296341Sdelphij            if (j == 0)
217296341Sdelphij                goto loop;
21855714Skris
219296341Sdelphij            j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
220296341Sdelphij            if (j == -1)
221296341Sdelphij                goto err;
222296341Sdelphij            if (j == 0)
223296341Sdelphij                goto loop;
22455714Skris
225296341Sdelphij            if (!BN_GENCB_call(cb, 2, c1 - 1))
226296341Sdelphij                goto err;
227296341Sdelphij            /* We have a safe prime test pass */
228296341Sdelphij        }
229296341Sdelphij    }
230296341Sdelphij    /* we have a prime :-) */
231296341Sdelphij    found = 1;
232296341Sdelphij err:
233296341Sdelphij    if (ctx != NULL) {
234296341Sdelphij        BN_CTX_end(ctx);
235296341Sdelphij        BN_CTX_free(ctx);
236296341Sdelphij    }
237296341Sdelphij    bn_check_top(ret);
238296341Sdelphij    return found;
239296341Sdelphij}
24055714Skris
241296341Sdelphijint BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
242296341Sdelphij                   BN_GENCB *cb)
243296341Sdelphij{
244296341Sdelphij    return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
245296341Sdelphij}
24655714Skris
247160814Ssimonint BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
248296341Sdelphij                            int do_trial_division, BN_GENCB *cb)
249296341Sdelphij{
250296341Sdelphij    int i, j, ret = -1;
251296341Sdelphij    int k;
252296341Sdelphij    BN_CTX *ctx = NULL;
253296341Sdelphij    BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
254296341Sdelphij    BN_MONT_CTX *mont = NULL;
255296341Sdelphij    const BIGNUM *A = NULL;
25659191Skris
257296341Sdelphij    if (BN_cmp(a, BN_value_one()) <= 0)
258296341Sdelphij        return 0;
25959191Skris
260296341Sdelphij    if (checks == BN_prime_checks)
261296341Sdelphij        checks = BN_prime_checks_for_size(BN_num_bits(a));
26259191Skris
263296341Sdelphij    /* first look for small factors */
264296341Sdelphij    if (!BN_is_odd(a))
265296341Sdelphij        /* a is even => a is prime if and only if a == 2 */
266296341Sdelphij        return BN_is_word(a, 2);
267296341Sdelphij    if (do_trial_division) {
268296341Sdelphij        for (i = 1; i < NUMPRIMES; i++)
269296341Sdelphij            if (BN_mod_word(a, primes[i]) == 0)
270296341Sdelphij                return 0;
271296341Sdelphij        if (!BN_GENCB_call(cb, 1, -1))
272296341Sdelphij            goto err;
273296341Sdelphij    }
27455714Skris
275296341Sdelphij    if (ctx_passed != NULL)
276296341Sdelphij        ctx = ctx_passed;
277296341Sdelphij    else if ((ctx = BN_CTX_new()) == NULL)
278296341Sdelphij        goto err;
279296341Sdelphij    BN_CTX_start(ctx);
28055714Skris
281296341Sdelphij    /* A := abs(a) */
282296341Sdelphij    if (a->neg) {
283296341Sdelphij        BIGNUM *t;
284296341Sdelphij        if ((t = BN_CTX_get(ctx)) == NULL)
285296341Sdelphij            goto err;
286296341Sdelphij        BN_copy(t, a);
287296341Sdelphij        t->neg = 0;
288296341Sdelphij        A = t;
289296341Sdelphij    } else
290296341Sdelphij        A = a;
291296341Sdelphij    A1 = BN_CTX_get(ctx);
292296341Sdelphij    A1_odd = BN_CTX_get(ctx);
293296341Sdelphij    check = BN_CTX_get(ctx);
294296341Sdelphij    if (check == NULL)
295296341Sdelphij        goto err;
29655714Skris
297296341Sdelphij    /* compute A1 := A - 1 */
298296341Sdelphij    if (!BN_copy(A1, A))
299296341Sdelphij        goto err;
300296341Sdelphij    if (!BN_sub_word(A1, 1))
301296341Sdelphij        goto err;
302296341Sdelphij    if (BN_is_zero(A1)) {
303296341Sdelphij        ret = 0;
304296341Sdelphij        goto err;
305296341Sdelphij    }
30655714Skris
307296341Sdelphij    /* write  A1  as  A1_odd * 2^k */
308296341Sdelphij    k = 1;
309296341Sdelphij    while (!BN_is_bit_set(A1, k))
310296341Sdelphij        k++;
311296341Sdelphij    if (!BN_rshift(A1_odd, A1, k))
312296341Sdelphij        goto err;
31359191Skris
314296341Sdelphij    /* Montgomery setup for computations mod A */
315296341Sdelphij    mont = BN_MONT_CTX_new();
316296341Sdelphij    if (mont == NULL)
317296341Sdelphij        goto err;
318296341Sdelphij    if (!BN_MONT_CTX_set(mont, A, ctx))
319296341Sdelphij        goto err;
32059191Skris
321296341Sdelphij    for (i = 0; i < checks; i++) {
322296341Sdelphij        if (!BN_pseudo_rand_range(check, A1))
323296341Sdelphij            goto err;
324296341Sdelphij        if (!BN_add_word(check, 1))
325296341Sdelphij            goto err;
326296341Sdelphij        /* now 1 <= check < A */
32755714Skris
328296341Sdelphij        j = witness(check, A, A1, A1_odd, k, ctx, mont);
329296341Sdelphij        if (j == -1)
330296341Sdelphij            goto err;
331296341Sdelphij        if (j) {
332296341Sdelphij            ret = 0;
333296341Sdelphij            goto err;
334296341Sdelphij        }
335296341Sdelphij        if (!BN_GENCB_call(cb, 1, i))
336296341Sdelphij            goto err;
337296341Sdelphij    }
338296341Sdelphij    ret = 1;
339296341Sdelphij err:
340296341Sdelphij    if (ctx != NULL) {
341296341Sdelphij        BN_CTX_end(ctx);
342296341Sdelphij        if (ctx_passed == NULL)
343296341Sdelphij            BN_CTX_free(ctx);
344296341Sdelphij    }
345296341Sdelphij    if (mont != NULL)
346296341Sdelphij        BN_MONT_CTX_free(mont);
347296341Sdelphij
348296341Sdelphij    return (ret);
349296341Sdelphij}
350296341Sdelphij
35159191Skrisstatic int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
352296341Sdelphij                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
353296341Sdelphij                   BN_MONT_CTX *mont)
354296341Sdelphij{
355296341Sdelphij    if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
356296341Sdelphij        return -1;
357296341Sdelphij    if (BN_is_one(w))
358296341Sdelphij        return 0;               /* probably prime */
359296341Sdelphij    if (BN_cmp(w, a1) == 0)
360296341Sdelphij        return 0;               /* w == -1 (mod a), 'a' is probably prime */
361296341Sdelphij    while (--k) {
362296341Sdelphij        if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
363296341Sdelphij            return -1;
364296341Sdelphij        if (BN_is_one(w))
365296341Sdelphij            return 1;           /* 'a' is composite, otherwise a previous 'w'
366296341Sdelphij                                 * would have been == -1 (mod 'a') */
367296341Sdelphij        if (BN_cmp(w, a1) == 0)
368296341Sdelphij            return 0;           /* w == -1 (mod a), 'a' is probably prime */
369296341Sdelphij    }
370296341Sdelphij    /*
371296341Sdelphij     * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and
372296341Sdelphij     * it is neither -1 nor +1 -- so 'a' cannot be prime
373296341Sdelphij     */
374296341Sdelphij    bn_check_top(w);
375296341Sdelphij    return 1;
376296341Sdelphij}
37755714Skris
37855714Skrisstatic int probable_prime(BIGNUM *rnd, int bits)
379296341Sdelphij{
380296341Sdelphij    int i;
381296341Sdelphij    prime_t mods[NUMPRIMES];
382296341Sdelphij    BN_ULONG delta, maxdelta;
38355714Skris
384296341Sdelphij again:
385296341Sdelphij    if (!BN_rand(rnd, bits, 1, 1))
386296341Sdelphij        return (0);
387296341Sdelphij    /* we now have a random number 'rand' to test. */
388296341Sdelphij    for (i = 1; i < NUMPRIMES; i++)
389296341Sdelphij        mods[i] = (prime_t) BN_mod_word(rnd, (BN_ULONG)primes[i]);
390296341Sdelphij    maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
391296341Sdelphij    delta = 0;
392296341Sdelphij loop:for (i = 1; i < NUMPRIMES; i++) {
393296341Sdelphij        /*
394296341Sdelphij         * check that rnd is not a prime and also that gcd(rnd-1,primes) == 1
395296341Sdelphij         * (except for 2)
396296341Sdelphij         */
397296341Sdelphij        if (((mods[i] + delta) % primes[i]) <= 1) {
398296341Sdelphij            delta += 2;
399296341Sdelphij            if (delta > maxdelta)
400296341Sdelphij                goto again;
401296341Sdelphij            goto loop;
402296341Sdelphij        }
403296341Sdelphij    }
404296341Sdelphij    if (!BN_add_word(rnd, delta))
405296341Sdelphij        return (0);
406296341Sdelphij    bn_check_top(rnd);
407296341Sdelphij    return (1);
408296341Sdelphij}
40955714Skris
410109998Smarkmstatic int probable_prime_dh(BIGNUM *rnd, int bits,
411296341Sdelphij                             const BIGNUM *add, const BIGNUM *rem,
412296341Sdelphij                             BN_CTX *ctx)
413296341Sdelphij{
414296341Sdelphij    int i, ret = 0;
415296341Sdelphij    BIGNUM *t1;
41655714Skris
417296341Sdelphij    BN_CTX_start(ctx);
418296341Sdelphij    if ((t1 = BN_CTX_get(ctx)) == NULL)
419296341Sdelphij        goto err;
42055714Skris
421296341Sdelphij    if (!BN_rand(rnd, bits, 0, 1))
422296341Sdelphij        goto err;
42355714Skris
424296341Sdelphij    /* we need ((rnd-rem) % add) == 0 */
42555714Skris
426296341Sdelphij    if (!BN_mod(t1, rnd, add, ctx))
427296341Sdelphij        goto err;
428296341Sdelphij    if (!BN_sub(rnd, rnd, t1))
429296341Sdelphij        goto err;
430296341Sdelphij    if (rem == NULL) {
431296341Sdelphij        if (!BN_add_word(rnd, 1))
432296341Sdelphij            goto err;
433296341Sdelphij    } else {
434296341Sdelphij        if (!BN_add(rnd, rnd, rem))
435296341Sdelphij            goto err;
436296341Sdelphij    }
43755714Skris
438296341Sdelphij    /* we now have a random number 'rand' to test. */
43955714Skris
440296341Sdelphij loop:for (i = 1; i < NUMPRIMES; i++) {
441296341Sdelphij        /* check that rnd is a prime */
442296341Sdelphij        if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) {
443296341Sdelphij            if (!BN_add(rnd, rnd, add))
444296341Sdelphij                goto err;
445296341Sdelphij            goto loop;
446296341Sdelphij        }
447296341Sdelphij    }
448296341Sdelphij    ret = 1;
449296341Sdelphij err:
450296341Sdelphij    BN_CTX_end(ctx);
451296341Sdelphij    bn_check_top(rnd);
452296341Sdelphij    return (ret);
453296341Sdelphij}
45455714Skris
455109998Smarkmstatic int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
456296341Sdelphij                                  const BIGNUM *rem, BN_CTX *ctx)
457296341Sdelphij{
458296341Sdelphij    int i, ret = 0;
459296341Sdelphij    BIGNUM *t1, *qadd, *q;
46055714Skris
461296341Sdelphij    bits--;
462296341Sdelphij    BN_CTX_start(ctx);
463296341Sdelphij    t1 = BN_CTX_get(ctx);
464296341Sdelphij    q = BN_CTX_get(ctx);
465296341Sdelphij    qadd = BN_CTX_get(ctx);
466296341Sdelphij    if (qadd == NULL)
467296341Sdelphij        goto err;
46855714Skris
469296341Sdelphij    if (!BN_rshift1(qadd, padd))
470296341Sdelphij        goto err;
47155714Skris
472296341Sdelphij    if (!BN_rand(q, bits, 0, 1))
473296341Sdelphij        goto err;
47455714Skris
475296341Sdelphij    /* we need ((rnd-rem) % add) == 0 */
476296341Sdelphij    if (!BN_mod(t1, q, qadd, ctx))
477296341Sdelphij        goto err;
478296341Sdelphij    if (!BN_sub(q, q, t1))
479296341Sdelphij        goto err;
480296341Sdelphij    if (rem == NULL) {
481296341Sdelphij        if (!BN_add_word(q, 1))
482296341Sdelphij            goto err;
483296341Sdelphij    } else {
484296341Sdelphij        if (!BN_rshift1(t1, rem))
485296341Sdelphij            goto err;
486296341Sdelphij        if (!BN_add(q, q, t1))
487296341Sdelphij            goto err;
488296341Sdelphij    }
48955714Skris
490296341Sdelphij    /* we now have a random number 'rand' to test. */
491296341Sdelphij    if (!BN_lshift1(p, q))
492296341Sdelphij        goto err;
493296341Sdelphij    if (!BN_add_word(p, 1))
494296341Sdelphij        goto err;
495296341Sdelphij
496296341Sdelphij loop:for (i = 1; i < NUMPRIMES; i++) {
497296341Sdelphij        /* check that p and q are prime */
498296341Sdelphij        /*
499296341Sdelphij         * check that for p and q gcd(p-1,primes) == 1 (except for 2)
500296341Sdelphij         */
501296341Sdelphij        if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) ||
502296341Sdelphij            (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) {
503296341Sdelphij            if (!BN_add(p, p, padd))
504296341Sdelphij                goto err;
505296341Sdelphij            if (!BN_add(q, q, qadd))
506296341Sdelphij                goto err;
507296341Sdelphij            goto loop;
508296341Sdelphij        }
509296341Sdelphij    }
510296341Sdelphij    ret = 1;
511296341Sdelphij err:
512296341Sdelphij    BN_CTX_end(ctx);
513296341Sdelphij    bn_check_top(p);
514296341Sdelphij    return (ret);
515296341Sdelphij}
516