1*2139Sjp161948 /* crypto/bn/bn_sqrt.c */
20Sstevel@tonic-gate /* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
30Sstevel@tonic-gate * and Bodo Moeller for the OpenSSL project. */
40Sstevel@tonic-gate /* ====================================================================
50Sstevel@tonic-gate * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
60Sstevel@tonic-gate *
70Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
80Sstevel@tonic-gate * modification, are permitted provided that the following conditions
90Sstevel@tonic-gate * are met:
100Sstevel@tonic-gate *
110Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
120Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
150Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
160Sstevel@tonic-gate * the documentation and/or other materials provided with the
170Sstevel@tonic-gate * distribution.
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
200Sstevel@tonic-gate * software must display the following acknowledgment:
210Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
220Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
230Sstevel@tonic-gate *
240Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
250Sstevel@tonic-gate * endorse or promote products derived from this software without
260Sstevel@tonic-gate * prior written permission. For written permission, please contact
270Sstevel@tonic-gate * openssl-core@openssl.org.
280Sstevel@tonic-gate *
290Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
300Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
310Sstevel@tonic-gate * permission of the OpenSSL Project.
320Sstevel@tonic-gate *
330Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
340Sstevel@tonic-gate * acknowledgment:
350Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
360Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
370Sstevel@tonic-gate *
380Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
390Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
400Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
410Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
420Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
430Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
440Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
450Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
460Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
470Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
480Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
490Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
500Sstevel@tonic-gate * ====================================================================
510Sstevel@tonic-gate *
520Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
530Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
540Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
550Sstevel@tonic-gate *
560Sstevel@tonic-gate */
570Sstevel@tonic-gate
580Sstevel@tonic-gate #include "cryptlib.h"
590Sstevel@tonic-gate #include "bn_lcl.h"
600Sstevel@tonic-gate
610Sstevel@tonic-gate
BN_mod_sqrt(BIGNUM * in,const BIGNUM * a,const BIGNUM * p,BN_CTX * ctx)620Sstevel@tonic-gate BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
630Sstevel@tonic-gate /* Returns 'ret' such that
640Sstevel@tonic-gate * ret^2 == a (mod p),
650Sstevel@tonic-gate * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
660Sstevel@tonic-gate * in Algebraic Computational Number Theory", algorithm 1.5.1).
670Sstevel@tonic-gate * 'p' must be prime!
680Sstevel@tonic-gate */
690Sstevel@tonic-gate {
700Sstevel@tonic-gate BIGNUM *ret = in;
710Sstevel@tonic-gate int err = 1;
720Sstevel@tonic-gate int r;
73*2139Sjp161948 BIGNUM *A, *b, *q, *t, *x, *y;
740Sstevel@tonic-gate int e, i, j;
750Sstevel@tonic-gate
760Sstevel@tonic-gate if (!BN_is_odd(p) || BN_abs_is_word(p, 1))
770Sstevel@tonic-gate {
780Sstevel@tonic-gate if (BN_abs_is_word(p, 2))
790Sstevel@tonic-gate {
800Sstevel@tonic-gate if (ret == NULL)
810Sstevel@tonic-gate ret = BN_new();
820Sstevel@tonic-gate if (ret == NULL)
830Sstevel@tonic-gate goto end;
840Sstevel@tonic-gate if (!BN_set_word(ret, BN_is_bit_set(a, 0)))
850Sstevel@tonic-gate {
86*2139Sjp161948 if (ret != in)
87*2139Sjp161948 BN_free(ret);
880Sstevel@tonic-gate return NULL;
890Sstevel@tonic-gate }
90*2139Sjp161948 bn_check_top(ret);
910Sstevel@tonic-gate return ret;
920Sstevel@tonic-gate }
930Sstevel@tonic-gate
940Sstevel@tonic-gate BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
950Sstevel@tonic-gate return(NULL);
960Sstevel@tonic-gate }
970Sstevel@tonic-gate
980Sstevel@tonic-gate if (BN_is_zero(a) || BN_is_one(a))
990Sstevel@tonic-gate {
1000Sstevel@tonic-gate if (ret == NULL)
1010Sstevel@tonic-gate ret = BN_new();
1020Sstevel@tonic-gate if (ret == NULL)
1030Sstevel@tonic-gate goto end;
1040Sstevel@tonic-gate if (!BN_set_word(ret, BN_is_one(a)))
1050Sstevel@tonic-gate {
106*2139Sjp161948 if (ret != in)
107*2139Sjp161948 BN_free(ret);
1080Sstevel@tonic-gate return NULL;
1090Sstevel@tonic-gate }
110*2139Sjp161948 bn_check_top(ret);
1110Sstevel@tonic-gate return ret;
1120Sstevel@tonic-gate }
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate BN_CTX_start(ctx);
115*2139Sjp161948 A = BN_CTX_get(ctx);
1160Sstevel@tonic-gate b = BN_CTX_get(ctx);
1170Sstevel@tonic-gate q = BN_CTX_get(ctx);
1180Sstevel@tonic-gate t = BN_CTX_get(ctx);
1190Sstevel@tonic-gate x = BN_CTX_get(ctx);
1200Sstevel@tonic-gate y = BN_CTX_get(ctx);
1210Sstevel@tonic-gate if (y == NULL) goto end;
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate if (ret == NULL)
1240Sstevel@tonic-gate ret = BN_new();
1250Sstevel@tonic-gate if (ret == NULL) goto end;
1260Sstevel@tonic-gate
127*2139Sjp161948 /* A = a mod p */
128*2139Sjp161948 if (!BN_nnmod(A, a, p, ctx)) goto end;
129*2139Sjp161948
1300Sstevel@tonic-gate /* now write |p| - 1 as 2^e*q where q is odd */
1310Sstevel@tonic-gate e = 1;
1320Sstevel@tonic-gate while (!BN_is_bit_set(p, e))
1330Sstevel@tonic-gate e++;
1340Sstevel@tonic-gate /* we'll set q later (if needed) */
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate if (e == 1)
1370Sstevel@tonic-gate {
1380Sstevel@tonic-gate /* The easy case: (|p|-1)/2 is odd, so 2 has an inverse
1390Sstevel@tonic-gate * modulo (|p|-1)/2, and square roots can be computed
1400Sstevel@tonic-gate * directly by modular exponentiation.
1410Sstevel@tonic-gate * We have
1420Sstevel@tonic-gate * 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2),
1430Sstevel@tonic-gate * so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1.
1440Sstevel@tonic-gate */
1450Sstevel@tonic-gate if (!BN_rshift(q, p, 2)) goto end;
1460Sstevel@tonic-gate q->neg = 0;
1470Sstevel@tonic-gate if (!BN_add_word(q, 1)) goto end;
148*2139Sjp161948 if (!BN_mod_exp(ret, A, q, p, ctx)) goto end;
1490Sstevel@tonic-gate err = 0;
150*2139Sjp161948 goto vrfy;
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate if (e == 2)
1540Sstevel@tonic-gate {
1550Sstevel@tonic-gate /* |p| == 5 (mod 8)
1560Sstevel@tonic-gate *
1570Sstevel@tonic-gate * In this case 2 is always a non-square since
1580Sstevel@tonic-gate * Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime.
1590Sstevel@tonic-gate * So if a really is a square, then 2*a is a non-square.
1600Sstevel@tonic-gate * Thus for
1610Sstevel@tonic-gate * b := (2*a)^((|p|-5)/8),
1620Sstevel@tonic-gate * i := (2*a)*b^2
1630Sstevel@tonic-gate * we have
1640Sstevel@tonic-gate * i^2 = (2*a)^((1 + (|p|-5)/4)*2)
1650Sstevel@tonic-gate * = (2*a)^((p-1)/2)
1660Sstevel@tonic-gate * = -1;
1670Sstevel@tonic-gate * so if we set
1680Sstevel@tonic-gate * x := a*b*(i-1),
1690Sstevel@tonic-gate * then
1700Sstevel@tonic-gate * x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
1710Sstevel@tonic-gate * = a^2 * b^2 * (-2*i)
1720Sstevel@tonic-gate * = a*(-i)*(2*a*b^2)
1730Sstevel@tonic-gate * = a*(-i)*i
1740Sstevel@tonic-gate * = a.
1750Sstevel@tonic-gate *
1760Sstevel@tonic-gate * (This is due to A.O.L. Atkin,
1770Sstevel@tonic-gate * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
1780Sstevel@tonic-gate * November 1992.)
1790Sstevel@tonic-gate */
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate /* t := 2*a */
182*2139Sjp161948 if (!BN_mod_lshift1_quick(t, A, p)) goto end;
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate /* b := (2*a)^((|p|-5)/8) */
1850Sstevel@tonic-gate if (!BN_rshift(q, p, 3)) goto end;
1860Sstevel@tonic-gate q->neg = 0;
1870Sstevel@tonic-gate if (!BN_mod_exp(b, t, q, p, ctx)) goto end;
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate /* y := b^2 */
1900Sstevel@tonic-gate if (!BN_mod_sqr(y, b, p, ctx)) goto end;
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate /* t := (2*a)*b^2 - 1*/
1930Sstevel@tonic-gate if (!BN_mod_mul(t, t, y, p, ctx)) goto end;
1940Sstevel@tonic-gate if (!BN_sub_word(t, 1)) goto end;
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate /* x = a*b*t */
197*2139Sjp161948 if (!BN_mod_mul(x, A, b, p, ctx)) goto end;
1980Sstevel@tonic-gate if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate if (!BN_copy(ret, x)) goto end;
2010Sstevel@tonic-gate err = 0;
202*2139Sjp161948 goto vrfy;
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate /* e > 2, so we really have to use the Tonelli/Shanks algorithm.
2060Sstevel@tonic-gate * First, find some y that is not a square. */
2070Sstevel@tonic-gate if (!BN_copy(q, p)) goto end; /* use 'q' as temp */
2080Sstevel@tonic-gate q->neg = 0;
2090Sstevel@tonic-gate i = 2;
2100Sstevel@tonic-gate do
2110Sstevel@tonic-gate {
2120Sstevel@tonic-gate /* For efficiency, try small numbers first;
2130Sstevel@tonic-gate * if this fails, try random numbers.
2140Sstevel@tonic-gate */
2150Sstevel@tonic-gate if (i < 22)
2160Sstevel@tonic-gate {
2170Sstevel@tonic-gate if (!BN_set_word(y, i)) goto end;
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate else
2200Sstevel@tonic-gate {
2210Sstevel@tonic-gate if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) goto end;
2220Sstevel@tonic-gate if (BN_ucmp(y, p) >= 0)
2230Sstevel@tonic-gate {
2240Sstevel@tonic-gate if (!(p->neg ? BN_add : BN_sub)(y, y, p)) goto end;
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate /* now 0 <= y < |p| */
2270Sstevel@tonic-gate if (BN_is_zero(y))
2280Sstevel@tonic-gate if (!BN_set_word(y, i)) goto end;
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
2320Sstevel@tonic-gate if (r < -1) goto end;
2330Sstevel@tonic-gate if (r == 0)
2340Sstevel@tonic-gate {
2350Sstevel@tonic-gate /* m divides p */
2360Sstevel@tonic-gate BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
2370Sstevel@tonic-gate goto end;
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate while (r == 1 && ++i < 82);
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate if (r != -1)
2430Sstevel@tonic-gate {
2440Sstevel@tonic-gate /* Many rounds and still no non-square -- this is more likely
2450Sstevel@tonic-gate * a bug than just bad luck.
2460Sstevel@tonic-gate * Even if p is not prime, we should have found some y
2470Sstevel@tonic-gate * such that r == -1.
2480Sstevel@tonic-gate */
2490Sstevel@tonic-gate BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
2500Sstevel@tonic-gate goto end;
2510Sstevel@tonic-gate }
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate /* Here's our actual 'q': */
2540Sstevel@tonic-gate if (!BN_rshift(q, q, e)) goto end;
2550Sstevel@tonic-gate
2560Sstevel@tonic-gate /* Now that we have some non-square, we can find an element
2570Sstevel@tonic-gate * of order 2^e by computing its q'th power. */
2580Sstevel@tonic-gate if (!BN_mod_exp(y, y, q, p, ctx)) goto end;
2590Sstevel@tonic-gate if (BN_is_one(y))
2600Sstevel@tonic-gate {
2610Sstevel@tonic-gate BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
2620Sstevel@tonic-gate goto end;
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate /* Now we know that (if p is indeed prime) there is an integer
2660Sstevel@tonic-gate * k, 0 <= k < 2^e, such that
2670Sstevel@tonic-gate *
2680Sstevel@tonic-gate * a^q * y^k == 1 (mod p).
2690Sstevel@tonic-gate *
2700Sstevel@tonic-gate * As a^q is a square and y is not, k must be even.
2710Sstevel@tonic-gate * q+1 is even, too, so there is an element
2720Sstevel@tonic-gate *
2730Sstevel@tonic-gate * X := a^((q+1)/2) * y^(k/2),
2740Sstevel@tonic-gate *
2750Sstevel@tonic-gate * and it satisfies
2760Sstevel@tonic-gate *
2770Sstevel@tonic-gate * X^2 = a^q * a * y^k
2780Sstevel@tonic-gate * = a,
2790Sstevel@tonic-gate *
2800Sstevel@tonic-gate * so it is the square root that we are looking for.
2810Sstevel@tonic-gate */
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate /* t := (q-1)/2 (note that q is odd) */
2840Sstevel@tonic-gate if (!BN_rshift1(t, q)) goto end;
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate /* x := a^((q-1)/2) */
2870Sstevel@tonic-gate if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
2880Sstevel@tonic-gate {
289*2139Sjp161948 if (!BN_nnmod(t, A, p, ctx)) goto end;
2900Sstevel@tonic-gate if (BN_is_zero(t))
2910Sstevel@tonic-gate {
2920Sstevel@tonic-gate /* special case: a == 0 (mod p) */
293*2139Sjp161948 BN_zero(ret);
2940Sstevel@tonic-gate err = 0;
2950Sstevel@tonic-gate goto end;
2960Sstevel@tonic-gate }
2970Sstevel@tonic-gate else
2980Sstevel@tonic-gate if (!BN_one(x)) goto end;
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate else
3010Sstevel@tonic-gate {
302*2139Sjp161948 if (!BN_mod_exp(x, A, t, p, ctx)) goto end;
3030Sstevel@tonic-gate if (BN_is_zero(x))
3040Sstevel@tonic-gate {
3050Sstevel@tonic-gate /* special case: a == 0 (mod p) */
306*2139Sjp161948 BN_zero(ret);
3070Sstevel@tonic-gate err = 0;
3080Sstevel@tonic-gate goto end;
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate }
3110Sstevel@tonic-gate
3120Sstevel@tonic-gate /* b := a*x^2 (= a^q) */
3130Sstevel@tonic-gate if (!BN_mod_sqr(b, x, p, ctx)) goto end;
314*2139Sjp161948 if (!BN_mod_mul(b, b, A, p, ctx)) goto end;
3150Sstevel@tonic-gate
3160Sstevel@tonic-gate /* x := a*x (= a^((q+1)/2)) */
317*2139Sjp161948 if (!BN_mod_mul(x, x, A, p, ctx)) goto end;
3180Sstevel@tonic-gate
3190Sstevel@tonic-gate while (1)
3200Sstevel@tonic-gate {
3210Sstevel@tonic-gate /* Now b is a^q * y^k for some even k (0 <= k < 2^E
3220Sstevel@tonic-gate * where E refers to the original value of e, which we
3230Sstevel@tonic-gate * don't keep in a variable), and x is a^((q+1)/2) * y^(k/2).
3240Sstevel@tonic-gate *
3250Sstevel@tonic-gate * We have a*b = x^2,
3260Sstevel@tonic-gate * y^2^(e-1) = -1,
3270Sstevel@tonic-gate * b^2^(e-1) = 1.
3280Sstevel@tonic-gate */
3290Sstevel@tonic-gate
3300Sstevel@tonic-gate if (BN_is_one(b))
3310Sstevel@tonic-gate {
3320Sstevel@tonic-gate if (!BN_copy(ret, x)) goto end;
3330Sstevel@tonic-gate err = 0;
334*2139Sjp161948 goto vrfy;
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate
3370Sstevel@tonic-gate
3380Sstevel@tonic-gate /* find smallest i such that b^(2^i) = 1 */
3390Sstevel@tonic-gate i = 1;
3400Sstevel@tonic-gate if (!BN_mod_sqr(t, b, p, ctx)) goto end;
3410Sstevel@tonic-gate while (!BN_is_one(t))
3420Sstevel@tonic-gate {
3430Sstevel@tonic-gate i++;
3440Sstevel@tonic-gate if (i == e)
3450Sstevel@tonic-gate {
3460Sstevel@tonic-gate BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
3470Sstevel@tonic-gate goto end;
3480Sstevel@tonic-gate }
3490Sstevel@tonic-gate if (!BN_mod_mul(t, t, t, p, ctx)) goto end;
3500Sstevel@tonic-gate }
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate
3530Sstevel@tonic-gate /* t := y^2^(e - i - 1) */
3540Sstevel@tonic-gate if (!BN_copy(t, y)) goto end;
3550Sstevel@tonic-gate for (j = e - i - 1; j > 0; j--)
3560Sstevel@tonic-gate {
3570Sstevel@tonic-gate if (!BN_mod_sqr(t, t, p, ctx)) goto end;
3580Sstevel@tonic-gate }
3590Sstevel@tonic-gate if (!BN_mod_mul(y, t, t, p, ctx)) goto end;
3600Sstevel@tonic-gate if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
3610Sstevel@tonic-gate if (!BN_mod_mul(b, b, y, p, ctx)) goto end;
3620Sstevel@tonic-gate e = i;
3630Sstevel@tonic-gate }
3640Sstevel@tonic-gate
365*2139Sjp161948 vrfy:
366*2139Sjp161948 if (!err)
367*2139Sjp161948 {
368*2139Sjp161948 /* verify the result -- the input might have been not a square
369*2139Sjp161948 * (test added in 0.9.8) */
370*2139Sjp161948
371*2139Sjp161948 if (!BN_mod_sqr(x, ret, p, ctx))
372*2139Sjp161948 err = 1;
373*2139Sjp161948
374*2139Sjp161948 if (!err && 0 != BN_cmp(x, A))
375*2139Sjp161948 {
376*2139Sjp161948 BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
377*2139Sjp161948 err = 1;
378*2139Sjp161948 }
379*2139Sjp161948 }
380*2139Sjp161948
3810Sstevel@tonic-gate end:
3820Sstevel@tonic-gate if (err)
3830Sstevel@tonic-gate {
3840Sstevel@tonic-gate if (ret != NULL && ret != in)
3850Sstevel@tonic-gate {
3860Sstevel@tonic-gate BN_clear_free(ret);
3870Sstevel@tonic-gate }
3880Sstevel@tonic-gate ret = NULL;
3890Sstevel@tonic-gate }
3900Sstevel@tonic-gate BN_CTX_end(ctx);
391*2139Sjp161948 bn_check_top(ret);
3920Sstevel@tonic-gate return ret;
3930Sstevel@tonic-gate }
394