10Sstevel@tonic-gate /* crypto/bn/bntest.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate * All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This package is an SSL implementation written
60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate *
160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate * the code are not to be removed.
180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate * as the author of the parts of the library used.
200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate * are met:
260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate * must display the following acknowledgement:
330Sstevel@tonic-gate * "This product includes cryptographic software written by
340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate * being used are not cryptographic related :-).
370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate * SUCH DAMAGE.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
550Sstevel@tonic-gate * copied and put under another distribution licence
560Sstevel@tonic-gate * [including the GNU Public Licence.]
570Sstevel@tonic-gate */
58*2139Sjp161948 /* ====================================================================
59*2139Sjp161948 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60*2139Sjp161948 *
61*2139Sjp161948 * Portions of the attached software ("Contribution") are developed by
62*2139Sjp161948 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63*2139Sjp161948 *
64*2139Sjp161948 * The Contribution is licensed pursuant to the Eric Young open source
65*2139Sjp161948 * license provided above.
66*2139Sjp161948 *
67*2139Sjp161948 * The binary polynomial arithmetic software is originally written by
68*2139Sjp161948 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69*2139Sjp161948 *
70*2139Sjp161948 */
71*2139Sjp161948
72*2139Sjp161948 /* Until the key-gen callbacks are modified to use newer prototypes, we allow
73*2139Sjp161948 * deprecated functions for openssl-internal code */
74*2139Sjp161948 #ifdef OPENSSL_NO_DEPRECATED
75*2139Sjp161948 #undef OPENSSL_NO_DEPRECATED
76*2139Sjp161948 #endif
770Sstevel@tonic-gate
780Sstevel@tonic-gate #include <stdio.h>
790Sstevel@tonic-gate #include <stdlib.h>
800Sstevel@tonic-gate #include <string.h>
810Sstevel@tonic-gate
820Sstevel@tonic-gate #include "e_os.h"
830Sstevel@tonic-gate
840Sstevel@tonic-gate #include <openssl/bio.h>
850Sstevel@tonic-gate #include <openssl/bn.h>
860Sstevel@tonic-gate #include <openssl/rand.h>
870Sstevel@tonic-gate #include <openssl/x509.h>
880Sstevel@tonic-gate #include <openssl/err.h>
890Sstevel@tonic-gate
900Sstevel@tonic-gate const int num0 = 100; /* number of tests */
910Sstevel@tonic-gate const int num1 = 50; /* additional tests for some functions */
920Sstevel@tonic-gate const int num2 = 5; /* number of tests for slow functions */
930Sstevel@tonic-gate
940Sstevel@tonic-gate int test_add(BIO *bp);
950Sstevel@tonic-gate int test_sub(BIO *bp);
960Sstevel@tonic-gate int test_lshift1(BIO *bp);
970Sstevel@tonic-gate int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
980Sstevel@tonic-gate int test_rshift1(BIO *bp);
990Sstevel@tonic-gate int test_rshift(BIO *bp,BN_CTX *ctx);
1000Sstevel@tonic-gate int test_div(BIO *bp,BN_CTX *ctx);
101*2139Sjp161948 int test_div_word(BIO *bp);
1020Sstevel@tonic-gate int test_div_recp(BIO *bp,BN_CTX *ctx);
1030Sstevel@tonic-gate int test_mul(BIO *bp);
1040Sstevel@tonic-gate int test_sqr(BIO *bp,BN_CTX *ctx);
1050Sstevel@tonic-gate int test_mont(BIO *bp,BN_CTX *ctx);
1060Sstevel@tonic-gate int test_mod(BIO *bp,BN_CTX *ctx);
1070Sstevel@tonic-gate int test_mod_mul(BIO *bp,BN_CTX *ctx);
1080Sstevel@tonic-gate int test_mod_exp(BIO *bp,BN_CTX *ctx);
109*2139Sjp161948 int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
1100Sstevel@tonic-gate int test_exp(BIO *bp,BN_CTX *ctx);
111*2139Sjp161948 int test_gf2m_add(BIO *bp);
112*2139Sjp161948 int test_gf2m_mod(BIO *bp);
113*2139Sjp161948 int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
114*2139Sjp161948 int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
115*2139Sjp161948 int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
116*2139Sjp161948 int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
117*2139Sjp161948 int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
118*2139Sjp161948 int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
119*2139Sjp161948 int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
1200Sstevel@tonic-gate int test_kron(BIO *bp,BN_CTX *ctx);
1210Sstevel@tonic-gate int test_sqrt(BIO *bp,BN_CTX *ctx);
1220Sstevel@tonic-gate int rand_neg(void);
1230Sstevel@tonic-gate static int results=0;
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
1260Sstevel@tonic-gate "\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate static const char rnd_seed[] = "string to make the random number generator think it has entropy";
1290Sstevel@tonic-gate
message(BIO * out,char * m)1300Sstevel@tonic-gate static void message(BIO *out, char *m)
1310Sstevel@tonic-gate {
1320Sstevel@tonic-gate fprintf(stderr, "test %s\n", m);
1330Sstevel@tonic-gate BIO_puts(out, "print \"test ");
1340Sstevel@tonic-gate BIO_puts(out, m);
1350Sstevel@tonic-gate BIO_puts(out, "\\n\"\n");
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate
main(int argc,char * argv[])1380Sstevel@tonic-gate int main(int argc, char *argv[])
1390Sstevel@tonic-gate {
1400Sstevel@tonic-gate BN_CTX *ctx;
1410Sstevel@tonic-gate BIO *out;
1420Sstevel@tonic-gate char *outfile=NULL;
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate results = 0;
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate argc--;
1490Sstevel@tonic-gate argv++;
1500Sstevel@tonic-gate while (argc >= 1)
1510Sstevel@tonic-gate {
1520Sstevel@tonic-gate if (strcmp(*argv,"-results") == 0)
1530Sstevel@tonic-gate results=1;
1540Sstevel@tonic-gate else if (strcmp(*argv,"-out") == 0)
1550Sstevel@tonic-gate {
1560Sstevel@tonic-gate if (--argc < 1) break;
1570Sstevel@tonic-gate outfile= *(++argv);
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate argc--;
1600Sstevel@tonic-gate argv++;
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate ctx=BN_CTX_new();
1650Sstevel@tonic-gate if (ctx == NULL) EXIT(1);
1660Sstevel@tonic-gate
1670Sstevel@tonic-gate out=BIO_new(BIO_s_file());
1680Sstevel@tonic-gate if (out == NULL) EXIT(1);
1690Sstevel@tonic-gate if (outfile == NULL)
1700Sstevel@tonic-gate {
1710Sstevel@tonic-gate BIO_set_fp(out,stdout,BIO_NOCLOSE);
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate else
1740Sstevel@tonic-gate {
1750Sstevel@tonic-gate if (!BIO_write_filename(out,outfile))
1760Sstevel@tonic-gate {
1770Sstevel@tonic-gate perror(outfile);
1780Sstevel@tonic-gate EXIT(1);
1790Sstevel@tonic-gate }
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate
1820Sstevel@tonic-gate if (!results)
1830Sstevel@tonic-gate BIO_puts(out,"obase=16\nibase=16\n");
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate message(out,"BN_add");
1860Sstevel@tonic-gate if (!test_add(out)) goto err;
1870Sstevel@tonic-gate BIO_flush(out);
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate message(out,"BN_sub");
1900Sstevel@tonic-gate if (!test_sub(out)) goto err;
1910Sstevel@tonic-gate BIO_flush(out);
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate message(out,"BN_lshift1");
1940Sstevel@tonic-gate if (!test_lshift1(out)) goto err;
1950Sstevel@tonic-gate BIO_flush(out);
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate message(out,"BN_lshift (fixed)");
1980Sstevel@tonic-gate if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
1990Sstevel@tonic-gate goto err;
2000Sstevel@tonic-gate BIO_flush(out);
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate message(out,"BN_lshift");
2030Sstevel@tonic-gate if (!test_lshift(out,ctx,NULL)) goto err;
2040Sstevel@tonic-gate BIO_flush(out);
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate message(out,"BN_rshift1");
2070Sstevel@tonic-gate if (!test_rshift1(out)) goto err;
2080Sstevel@tonic-gate BIO_flush(out);
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate message(out,"BN_rshift");
2110Sstevel@tonic-gate if (!test_rshift(out,ctx)) goto err;
2120Sstevel@tonic-gate BIO_flush(out);
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate message(out,"BN_sqr");
2150Sstevel@tonic-gate if (!test_sqr(out,ctx)) goto err;
2160Sstevel@tonic-gate BIO_flush(out);
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate message(out,"BN_mul");
2190Sstevel@tonic-gate if (!test_mul(out)) goto err;
2200Sstevel@tonic-gate BIO_flush(out);
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate message(out,"BN_div");
2230Sstevel@tonic-gate if (!test_div(out,ctx)) goto err;
2240Sstevel@tonic-gate BIO_flush(out);
2250Sstevel@tonic-gate
226*2139Sjp161948 message(out,"BN_div_word");
227*2139Sjp161948 if (!test_div_word(out)) goto err;
228*2139Sjp161948 BIO_flush(out);
229*2139Sjp161948
2300Sstevel@tonic-gate message(out,"BN_div_recp");
2310Sstevel@tonic-gate if (!test_div_recp(out,ctx)) goto err;
2320Sstevel@tonic-gate BIO_flush(out);
2330Sstevel@tonic-gate
2340Sstevel@tonic-gate message(out,"BN_mod");
2350Sstevel@tonic-gate if (!test_mod(out,ctx)) goto err;
2360Sstevel@tonic-gate BIO_flush(out);
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate message(out,"BN_mod_mul");
2390Sstevel@tonic-gate if (!test_mod_mul(out,ctx)) goto err;
2400Sstevel@tonic-gate BIO_flush(out);
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate message(out,"BN_mont");
2430Sstevel@tonic-gate if (!test_mont(out,ctx)) goto err;
2440Sstevel@tonic-gate BIO_flush(out);
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate message(out,"BN_mod_exp");
2470Sstevel@tonic-gate if (!test_mod_exp(out,ctx)) goto err;
2480Sstevel@tonic-gate BIO_flush(out);
2490Sstevel@tonic-gate
250*2139Sjp161948 message(out,"BN_mod_exp_mont_consttime");
251*2139Sjp161948 if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
252*2139Sjp161948 BIO_flush(out);
253*2139Sjp161948
2540Sstevel@tonic-gate message(out,"BN_exp");
2550Sstevel@tonic-gate if (!test_exp(out,ctx)) goto err;
2560Sstevel@tonic-gate BIO_flush(out);
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate message(out,"BN_kronecker");
2590Sstevel@tonic-gate if (!test_kron(out,ctx)) goto err;
2600Sstevel@tonic-gate BIO_flush(out);
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate message(out,"BN_mod_sqrt");
2630Sstevel@tonic-gate if (!test_sqrt(out,ctx)) goto err;
2640Sstevel@tonic-gate BIO_flush(out);
2650Sstevel@tonic-gate
266*2139Sjp161948 message(out,"BN_GF2m_add");
267*2139Sjp161948 if (!test_gf2m_add(out)) goto err;
268*2139Sjp161948 BIO_flush(out);
269*2139Sjp161948
270*2139Sjp161948 message(out,"BN_GF2m_mod");
271*2139Sjp161948 if (!test_gf2m_mod(out)) goto err;
272*2139Sjp161948 BIO_flush(out);
273*2139Sjp161948
274*2139Sjp161948 message(out,"BN_GF2m_mod_mul");
275*2139Sjp161948 if (!test_gf2m_mod_mul(out,ctx)) goto err;
276*2139Sjp161948 BIO_flush(out);
277*2139Sjp161948
278*2139Sjp161948 message(out,"BN_GF2m_mod_sqr");
279*2139Sjp161948 if (!test_gf2m_mod_sqr(out,ctx)) goto err;
280*2139Sjp161948 BIO_flush(out);
281*2139Sjp161948
282*2139Sjp161948 message(out,"BN_GF2m_mod_inv");
283*2139Sjp161948 if (!test_gf2m_mod_inv(out,ctx)) goto err;
284*2139Sjp161948 BIO_flush(out);
285*2139Sjp161948
286*2139Sjp161948 message(out,"BN_GF2m_mod_div");
287*2139Sjp161948 if (!test_gf2m_mod_div(out,ctx)) goto err;
288*2139Sjp161948 BIO_flush(out);
289*2139Sjp161948
290*2139Sjp161948 message(out,"BN_GF2m_mod_exp");
291*2139Sjp161948 if (!test_gf2m_mod_exp(out,ctx)) goto err;
292*2139Sjp161948 BIO_flush(out);
293*2139Sjp161948
294*2139Sjp161948 message(out,"BN_GF2m_mod_sqrt");
295*2139Sjp161948 if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
296*2139Sjp161948 BIO_flush(out);
297*2139Sjp161948
298*2139Sjp161948 message(out,"BN_GF2m_mod_solve_quad");
299*2139Sjp161948 if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
300*2139Sjp161948 BIO_flush(out);
301*2139Sjp161948
3020Sstevel@tonic-gate BN_CTX_free(ctx);
3030Sstevel@tonic-gate BIO_free(out);
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate /**/
3060Sstevel@tonic-gate EXIT(0);
3070Sstevel@tonic-gate err:
3080Sstevel@tonic-gate BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
3090Sstevel@tonic-gate * the failure, see test_bn in test/Makefile.ssl*/
3100Sstevel@tonic-gate BIO_flush(out);
3110Sstevel@tonic-gate ERR_load_crypto_strings();
3120Sstevel@tonic-gate ERR_print_errors_fp(stderr);
3130Sstevel@tonic-gate EXIT(1);
3140Sstevel@tonic-gate return(1);
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate
test_add(BIO * bp)3170Sstevel@tonic-gate int test_add(BIO *bp)
3180Sstevel@tonic-gate {
3190Sstevel@tonic-gate BIGNUM a,b,c;
3200Sstevel@tonic-gate int i;
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate BN_init(&a);
3230Sstevel@tonic-gate BN_init(&b);
3240Sstevel@tonic-gate BN_init(&c);
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate BN_bntest_rand(&a,512,0,0);
3270Sstevel@tonic-gate for (i=0; i<num0; i++)
3280Sstevel@tonic-gate {
3290Sstevel@tonic-gate BN_bntest_rand(&b,450+i,0,0);
3300Sstevel@tonic-gate a.neg=rand_neg();
3310Sstevel@tonic-gate b.neg=rand_neg();
3320Sstevel@tonic-gate BN_add(&c,&a,&b);
3330Sstevel@tonic-gate if (bp != NULL)
3340Sstevel@tonic-gate {
3350Sstevel@tonic-gate if (!results)
3360Sstevel@tonic-gate {
3370Sstevel@tonic-gate BN_print(bp,&a);
3380Sstevel@tonic-gate BIO_puts(bp," + ");
3390Sstevel@tonic-gate BN_print(bp,&b);
3400Sstevel@tonic-gate BIO_puts(bp," - ");
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate BN_print(bp,&c);
3430Sstevel@tonic-gate BIO_puts(bp,"\n");
3440Sstevel@tonic-gate }
3450Sstevel@tonic-gate a.neg=!a.neg;
3460Sstevel@tonic-gate b.neg=!b.neg;
3470Sstevel@tonic-gate BN_add(&c,&c,&b);
3480Sstevel@tonic-gate BN_add(&c,&c,&a);
3490Sstevel@tonic-gate if(!BN_is_zero(&c))
3500Sstevel@tonic-gate {
3510Sstevel@tonic-gate fprintf(stderr,"Add test failed!\n");
3520Sstevel@tonic-gate return 0;
3530Sstevel@tonic-gate }
3540Sstevel@tonic-gate }
3550Sstevel@tonic-gate BN_free(&a);
3560Sstevel@tonic-gate BN_free(&b);
3570Sstevel@tonic-gate BN_free(&c);
3580Sstevel@tonic-gate return(1);
3590Sstevel@tonic-gate }
3600Sstevel@tonic-gate
test_sub(BIO * bp)3610Sstevel@tonic-gate int test_sub(BIO *bp)
3620Sstevel@tonic-gate {
3630Sstevel@tonic-gate BIGNUM a,b,c;
3640Sstevel@tonic-gate int i;
3650Sstevel@tonic-gate
3660Sstevel@tonic-gate BN_init(&a);
3670Sstevel@tonic-gate BN_init(&b);
3680Sstevel@tonic-gate BN_init(&c);
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate for (i=0; i<num0+num1; i++)
3710Sstevel@tonic-gate {
3720Sstevel@tonic-gate if (i < num1)
3730Sstevel@tonic-gate {
3740Sstevel@tonic-gate BN_bntest_rand(&a,512,0,0);
3750Sstevel@tonic-gate BN_copy(&b,&a);
3760Sstevel@tonic-gate if (BN_set_bit(&a,i)==0) return(0);
3770Sstevel@tonic-gate BN_add_word(&b,i);
3780Sstevel@tonic-gate }
3790Sstevel@tonic-gate else
3800Sstevel@tonic-gate {
3810Sstevel@tonic-gate BN_bntest_rand(&b,400+i-num1,0,0);
3820Sstevel@tonic-gate a.neg=rand_neg();
3830Sstevel@tonic-gate b.neg=rand_neg();
3840Sstevel@tonic-gate }
3850Sstevel@tonic-gate BN_sub(&c,&a,&b);
3860Sstevel@tonic-gate if (bp != NULL)
3870Sstevel@tonic-gate {
3880Sstevel@tonic-gate if (!results)
3890Sstevel@tonic-gate {
3900Sstevel@tonic-gate BN_print(bp,&a);
3910Sstevel@tonic-gate BIO_puts(bp," - ");
3920Sstevel@tonic-gate BN_print(bp,&b);
3930Sstevel@tonic-gate BIO_puts(bp," - ");
3940Sstevel@tonic-gate }
3950Sstevel@tonic-gate BN_print(bp,&c);
3960Sstevel@tonic-gate BIO_puts(bp,"\n");
3970Sstevel@tonic-gate }
3980Sstevel@tonic-gate BN_add(&c,&c,&b);
3990Sstevel@tonic-gate BN_sub(&c,&c,&a);
4000Sstevel@tonic-gate if(!BN_is_zero(&c))
4010Sstevel@tonic-gate {
4020Sstevel@tonic-gate fprintf(stderr,"Subtract test failed!\n");
4030Sstevel@tonic-gate return 0;
4040Sstevel@tonic-gate }
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate BN_free(&a);
4070Sstevel@tonic-gate BN_free(&b);
4080Sstevel@tonic-gate BN_free(&c);
4090Sstevel@tonic-gate return(1);
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate
test_div(BIO * bp,BN_CTX * ctx)4120Sstevel@tonic-gate int test_div(BIO *bp, BN_CTX *ctx)
4130Sstevel@tonic-gate {
4140Sstevel@tonic-gate BIGNUM a,b,c,d,e;
4150Sstevel@tonic-gate int i;
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate BN_init(&a);
4180Sstevel@tonic-gate BN_init(&b);
4190Sstevel@tonic-gate BN_init(&c);
4200Sstevel@tonic-gate BN_init(&d);
4210Sstevel@tonic-gate BN_init(&e);
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate for (i=0; i<num0+num1; i++)
4240Sstevel@tonic-gate {
4250Sstevel@tonic-gate if (i < num1)
4260Sstevel@tonic-gate {
4270Sstevel@tonic-gate BN_bntest_rand(&a,400,0,0);
4280Sstevel@tonic-gate BN_copy(&b,&a);
4290Sstevel@tonic-gate BN_lshift(&a,&a,i);
4300Sstevel@tonic-gate BN_add_word(&a,i);
4310Sstevel@tonic-gate }
4320Sstevel@tonic-gate else
4330Sstevel@tonic-gate BN_bntest_rand(&b,50+3*(i-num1),0,0);
4340Sstevel@tonic-gate a.neg=rand_neg();
4350Sstevel@tonic-gate b.neg=rand_neg();
4360Sstevel@tonic-gate BN_div(&d,&c,&a,&b,ctx);
4370Sstevel@tonic-gate if (bp != NULL)
4380Sstevel@tonic-gate {
4390Sstevel@tonic-gate if (!results)
4400Sstevel@tonic-gate {
4410Sstevel@tonic-gate BN_print(bp,&a);
4420Sstevel@tonic-gate BIO_puts(bp," / ");
4430Sstevel@tonic-gate BN_print(bp,&b);
4440Sstevel@tonic-gate BIO_puts(bp," - ");
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate BN_print(bp,&d);
4470Sstevel@tonic-gate BIO_puts(bp,"\n");
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate if (!results)
4500Sstevel@tonic-gate {
4510Sstevel@tonic-gate BN_print(bp,&a);
4520Sstevel@tonic-gate BIO_puts(bp," % ");
4530Sstevel@tonic-gate BN_print(bp,&b);
4540Sstevel@tonic-gate BIO_puts(bp," - ");
4550Sstevel@tonic-gate }
4560Sstevel@tonic-gate BN_print(bp,&c);
4570Sstevel@tonic-gate BIO_puts(bp,"\n");
4580Sstevel@tonic-gate }
4590Sstevel@tonic-gate BN_mul(&e,&d,&b,ctx);
4600Sstevel@tonic-gate BN_add(&d,&e,&c);
4610Sstevel@tonic-gate BN_sub(&d,&d,&a);
4620Sstevel@tonic-gate if(!BN_is_zero(&d))
4630Sstevel@tonic-gate {
4640Sstevel@tonic-gate fprintf(stderr,"Division test failed!\n");
4650Sstevel@tonic-gate return 0;
4660Sstevel@tonic-gate }
4670Sstevel@tonic-gate }
4680Sstevel@tonic-gate BN_free(&a);
4690Sstevel@tonic-gate BN_free(&b);
4700Sstevel@tonic-gate BN_free(&c);
4710Sstevel@tonic-gate BN_free(&d);
4720Sstevel@tonic-gate BN_free(&e);
4730Sstevel@tonic-gate return(1);
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate
print_word(BIO * bp,BN_ULONG w)476*2139Sjp161948 static void print_word(BIO *bp,BN_ULONG w)
477*2139Sjp161948 {
478*2139Sjp161948 #ifdef SIXTY_FOUR_BIT
479*2139Sjp161948 if (sizeof(w) > sizeof(unsigned long))
480*2139Sjp161948 {
481*2139Sjp161948 unsigned long h=(unsigned long)(w>>32),
482*2139Sjp161948 l=(unsigned long)(w);
483*2139Sjp161948
484*2139Sjp161948 if (h) BIO_printf(bp,"%lX%08lX",h,l);
485*2139Sjp161948 else BIO_printf(bp,"%lX",l);
486*2139Sjp161948 return;
487*2139Sjp161948 }
488*2139Sjp161948 #endif
489*2139Sjp161948 BIO_printf(bp,"%lX",w);
490*2139Sjp161948 }
491*2139Sjp161948
test_div_word(BIO * bp)492*2139Sjp161948 int test_div_word(BIO *bp)
493*2139Sjp161948 {
494*2139Sjp161948 BIGNUM a,b;
495*2139Sjp161948 BN_ULONG r,s;
496*2139Sjp161948 int i;
497*2139Sjp161948
498*2139Sjp161948 BN_init(&a);
499*2139Sjp161948 BN_init(&b);
500*2139Sjp161948
501*2139Sjp161948 for (i=0; i<num0; i++)
502*2139Sjp161948 {
503*2139Sjp161948 do {
504*2139Sjp161948 BN_bntest_rand(&a,512,-1,0);
505*2139Sjp161948 BN_bntest_rand(&b,BN_BITS2,-1,0);
506*2139Sjp161948 s = b.d[0];
507*2139Sjp161948 } while (!s);
508*2139Sjp161948
509*2139Sjp161948 BN_copy(&b, &a);
510*2139Sjp161948 r = BN_div_word(&b, s);
511*2139Sjp161948
512*2139Sjp161948 if (bp != NULL)
513*2139Sjp161948 {
514*2139Sjp161948 if (!results)
515*2139Sjp161948 {
516*2139Sjp161948 BN_print(bp,&a);
517*2139Sjp161948 BIO_puts(bp," / ");
518*2139Sjp161948 print_word(bp,s);
519*2139Sjp161948 BIO_puts(bp," - ");
520*2139Sjp161948 }
521*2139Sjp161948 BN_print(bp,&b);
522*2139Sjp161948 BIO_puts(bp,"\n");
523*2139Sjp161948
524*2139Sjp161948 if (!results)
525*2139Sjp161948 {
526*2139Sjp161948 BN_print(bp,&a);
527*2139Sjp161948 BIO_puts(bp," % ");
528*2139Sjp161948 print_word(bp,s);
529*2139Sjp161948 BIO_puts(bp," - ");
530*2139Sjp161948 }
531*2139Sjp161948 print_word(bp,r);
532*2139Sjp161948 BIO_puts(bp,"\n");
533*2139Sjp161948 }
534*2139Sjp161948 BN_mul_word(&b,s);
535*2139Sjp161948 BN_add_word(&b,r);
536*2139Sjp161948 BN_sub(&b,&a,&b);
537*2139Sjp161948 if(!BN_is_zero(&b))
538*2139Sjp161948 {
539*2139Sjp161948 fprintf(stderr,"Division (word) test failed!\n");
540*2139Sjp161948 return 0;
541*2139Sjp161948 }
542*2139Sjp161948 }
543*2139Sjp161948 BN_free(&a);
544*2139Sjp161948 BN_free(&b);
545*2139Sjp161948 return(1);
546*2139Sjp161948 }
547*2139Sjp161948
test_div_recp(BIO * bp,BN_CTX * ctx)5480Sstevel@tonic-gate int test_div_recp(BIO *bp, BN_CTX *ctx)
5490Sstevel@tonic-gate {
5500Sstevel@tonic-gate BIGNUM a,b,c,d,e;
5510Sstevel@tonic-gate BN_RECP_CTX recp;
5520Sstevel@tonic-gate int i;
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate BN_RECP_CTX_init(&recp);
5550Sstevel@tonic-gate BN_init(&a);
5560Sstevel@tonic-gate BN_init(&b);
5570Sstevel@tonic-gate BN_init(&c);
5580Sstevel@tonic-gate BN_init(&d);
5590Sstevel@tonic-gate BN_init(&e);
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate for (i=0; i<num0+num1; i++)
5620Sstevel@tonic-gate {
5630Sstevel@tonic-gate if (i < num1)
5640Sstevel@tonic-gate {
5650Sstevel@tonic-gate BN_bntest_rand(&a,400,0,0);
5660Sstevel@tonic-gate BN_copy(&b,&a);
5670Sstevel@tonic-gate BN_lshift(&a,&a,i);
5680Sstevel@tonic-gate BN_add_word(&a,i);
5690Sstevel@tonic-gate }
5700Sstevel@tonic-gate else
5710Sstevel@tonic-gate BN_bntest_rand(&b,50+3*(i-num1),0,0);
5720Sstevel@tonic-gate a.neg=rand_neg();
5730Sstevel@tonic-gate b.neg=rand_neg();
5740Sstevel@tonic-gate BN_RECP_CTX_set(&recp,&b,ctx);
5750Sstevel@tonic-gate BN_div_recp(&d,&c,&a,&recp,ctx);
5760Sstevel@tonic-gate if (bp != NULL)
5770Sstevel@tonic-gate {
5780Sstevel@tonic-gate if (!results)
5790Sstevel@tonic-gate {
5800Sstevel@tonic-gate BN_print(bp,&a);
5810Sstevel@tonic-gate BIO_puts(bp," / ");
5820Sstevel@tonic-gate BN_print(bp,&b);
5830Sstevel@tonic-gate BIO_puts(bp," - ");
5840Sstevel@tonic-gate }
5850Sstevel@tonic-gate BN_print(bp,&d);
5860Sstevel@tonic-gate BIO_puts(bp,"\n");
5870Sstevel@tonic-gate
5880Sstevel@tonic-gate if (!results)
5890Sstevel@tonic-gate {
5900Sstevel@tonic-gate BN_print(bp,&a);
5910Sstevel@tonic-gate BIO_puts(bp," % ");
5920Sstevel@tonic-gate BN_print(bp,&b);
5930Sstevel@tonic-gate BIO_puts(bp," - ");
5940Sstevel@tonic-gate }
5950Sstevel@tonic-gate BN_print(bp,&c);
5960Sstevel@tonic-gate BIO_puts(bp,"\n");
5970Sstevel@tonic-gate }
5980Sstevel@tonic-gate BN_mul(&e,&d,&b,ctx);
5990Sstevel@tonic-gate BN_add(&d,&e,&c);
6000Sstevel@tonic-gate BN_sub(&d,&d,&a);
6010Sstevel@tonic-gate if(!BN_is_zero(&d))
6020Sstevel@tonic-gate {
6030Sstevel@tonic-gate fprintf(stderr,"Reciprocal division test failed!\n");
6040Sstevel@tonic-gate fprintf(stderr,"a=");
6050Sstevel@tonic-gate BN_print_fp(stderr,&a);
6060Sstevel@tonic-gate fprintf(stderr,"\nb=");
6070Sstevel@tonic-gate BN_print_fp(stderr,&b);
6080Sstevel@tonic-gate fprintf(stderr,"\n");
6090Sstevel@tonic-gate return 0;
6100Sstevel@tonic-gate }
6110Sstevel@tonic-gate }
6120Sstevel@tonic-gate BN_free(&a);
6130Sstevel@tonic-gate BN_free(&b);
6140Sstevel@tonic-gate BN_free(&c);
6150Sstevel@tonic-gate BN_free(&d);
6160Sstevel@tonic-gate BN_free(&e);
6170Sstevel@tonic-gate BN_RECP_CTX_free(&recp);
6180Sstevel@tonic-gate return(1);
6190Sstevel@tonic-gate }
6200Sstevel@tonic-gate
test_mul(BIO * bp)6210Sstevel@tonic-gate int test_mul(BIO *bp)
6220Sstevel@tonic-gate {
6230Sstevel@tonic-gate BIGNUM a,b,c,d,e;
6240Sstevel@tonic-gate int i;
6250Sstevel@tonic-gate BN_CTX *ctx;
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate ctx = BN_CTX_new();
6280Sstevel@tonic-gate if (ctx == NULL) EXIT(1);
6290Sstevel@tonic-gate
6300Sstevel@tonic-gate BN_init(&a);
6310Sstevel@tonic-gate BN_init(&b);
6320Sstevel@tonic-gate BN_init(&c);
6330Sstevel@tonic-gate BN_init(&d);
6340Sstevel@tonic-gate BN_init(&e);
6350Sstevel@tonic-gate
6360Sstevel@tonic-gate for (i=0; i<num0+num1; i++)
6370Sstevel@tonic-gate {
6380Sstevel@tonic-gate if (i <= num1)
6390Sstevel@tonic-gate {
6400Sstevel@tonic-gate BN_bntest_rand(&a,100,0,0);
6410Sstevel@tonic-gate BN_bntest_rand(&b,100,0,0);
6420Sstevel@tonic-gate }
6430Sstevel@tonic-gate else
6440Sstevel@tonic-gate BN_bntest_rand(&b,i-num1,0,0);
6450Sstevel@tonic-gate a.neg=rand_neg();
6460Sstevel@tonic-gate b.neg=rand_neg();
6470Sstevel@tonic-gate BN_mul(&c,&a,&b,ctx);
6480Sstevel@tonic-gate if (bp != NULL)
6490Sstevel@tonic-gate {
6500Sstevel@tonic-gate if (!results)
6510Sstevel@tonic-gate {
6520Sstevel@tonic-gate BN_print(bp,&a);
6530Sstevel@tonic-gate BIO_puts(bp," * ");
6540Sstevel@tonic-gate BN_print(bp,&b);
6550Sstevel@tonic-gate BIO_puts(bp," - ");
6560Sstevel@tonic-gate }
6570Sstevel@tonic-gate BN_print(bp,&c);
6580Sstevel@tonic-gate BIO_puts(bp,"\n");
6590Sstevel@tonic-gate }
6600Sstevel@tonic-gate BN_div(&d,&e,&c,&a,ctx);
6610Sstevel@tonic-gate BN_sub(&d,&d,&b);
6620Sstevel@tonic-gate if(!BN_is_zero(&d) || !BN_is_zero(&e))
6630Sstevel@tonic-gate {
6640Sstevel@tonic-gate fprintf(stderr,"Multiplication test failed!\n");
6650Sstevel@tonic-gate return 0;
6660Sstevel@tonic-gate }
6670Sstevel@tonic-gate }
6680Sstevel@tonic-gate BN_free(&a);
6690Sstevel@tonic-gate BN_free(&b);
6700Sstevel@tonic-gate BN_free(&c);
6710Sstevel@tonic-gate BN_free(&d);
6720Sstevel@tonic-gate BN_free(&e);
6730Sstevel@tonic-gate BN_CTX_free(ctx);
6740Sstevel@tonic-gate return(1);
6750Sstevel@tonic-gate }
6760Sstevel@tonic-gate
test_sqr(BIO * bp,BN_CTX * ctx)6770Sstevel@tonic-gate int test_sqr(BIO *bp, BN_CTX *ctx)
6780Sstevel@tonic-gate {
6790Sstevel@tonic-gate BIGNUM a,c,d,e;
6800Sstevel@tonic-gate int i;
6810Sstevel@tonic-gate
6820Sstevel@tonic-gate BN_init(&a);
6830Sstevel@tonic-gate BN_init(&c);
6840Sstevel@tonic-gate BN_init(&d);
6850Sstevel@tonic-gate BN_init(&e);
6860Sstevel@tonic-gate
6870Sstevel@tonic-gate for (i=0; i<num0; i++)
6880Sstevel@tonic-gate {
6890Sstevel@tonic-gate BN_bntest_rand(&a,40+i*10,0,0);
6900Sstevel@tonic-gate a.neg=rand_neg();
6910Sstevel@tonic-gate BN_sqr(&c,&a,ctx);
6920Sstevel@tonic-gate if (bp != NULL)
6930Sstevel@tonic-gate {
6940Sstevel@tonic-gate if (!results)
6950Sstevel@tonic-gate {
6960Sstevel@tonic-gate BN_print(bp,&a);
6970Sstevel@tonic-gate BIO_puts(bp," * ");
6980Sstevel@tonic-gate BN_print(bp,&a);
6990Sstevel@tonic-gate BIO_puts(bp," - ");
7000Sstevel@tonic-gate }
7010Sstevel@tonic-gate BN_print(bp,&c);
7020Sstevel@tonic-gate BIO_puts(bp,"\n");
7030Sstevel@tonic-gate }
7040Sstevel@tonic-gate BN_div(&d,&e,&c,&a,ctx);
7050Sstevel@tonic-gate BN_sub(&d,&d,&a);
7060Sstevel@tonic-gate if(!BN_is_zero(&d) || !BN_is_zero(&e))
7070Sstevel@tonic-gate {
7080Sstevel@tonic-gate fprintf(stderr,"Square test failed!\n");
7090Sstevel@tonic-gate return 0;
7100Sstevel@tonic-gate }
7110Sstevel@tonic-gate }
7120Sstevel@tonic-gate BN_free(&a);
7130Sstevel@tonic-gate BN_free(&c);
7140Sstevel@tonic-gate BN_free(&d);
7150Sstevel@tonic-gate BN_free(&e);
7160Sstevel@tonic-gate return(1);
7170Sstevel@tonic-gate }
7180Sstevel@tonic-gate
test_mont(BIO * bp,BN_CTX * ctx)7190Sstevel@tonic-gate int test_mont(BIO *bp, BN_CTX *ctx)
7200Sstevel@tonic-gate {
7210Sstevel@tonic-gate BIGNUM a,b,c,d,A,B;
7220Sstevel@tonic-gate BIGNUM n;
7230Sstevel@tonic-gate int i;
7240Sstevel@tonic-gate BN_MONT_CTX *mont;
7250Sstevel@tonic-gate
7260Sstevel@tonic-gate BN_init(&a);
7270Sstevel@tonic-gate BN_init(&b);
7280Sstevel@tonic-gate BN_init(&c);
7290Sstevel@tonic-gate BN_init(&d);
7300Sstevel@tonic-gate BN_init(&A);
7310Sstevel@tonic-gate BN_init(&B);
7320Sstevel@tonic-gate BN_init(&n);
7330Sstevel@tonic-gate
7340Sstevel@tonic-gate mont=BN_MONT_CTX_new();
7350Sstevel@tonic-gate
7360Sstevel@tonic-gate BN_bntest_rand(&a,100,0,0); /**/
7370Sstevel@tonic-gate BN_bntest_rand(&b,100,0,0); /**/
7380Sstevel@tonic-gate for (i=0; i<num2; i++)
7390Sstevel@tonic-gate {
7400Sstevel@tonic-gate int bits = (200*(i+1))/num2;
7410Sstevel@tonic-gate
7420Sstevel@tonic-gate if (bits == 0)
7430Sstevel@tonic-gate continue;
7440Sstevel@tonic-gate BN_bntest_rand(&n,bits,0,1);
7450Sstevel@tonic-gate BN_MONT_CTX_set(mont,&n,ctx);
7460Sstevel@tonic-gate
7470Sstevel@tonic-gate BN_nnmod(&a,&a,&n,ctx);
7480Sstevel@tonic-gate BN_nnmod(&b,&b,&n,ctx);
7490Sstevel@tonic-gate
7500Sstevel@tonic-gate BN_to_montgomery(&A,&a,mont,ctx);
7510Sstevel@tonic-gate BN_to_montgomery(&B,&b,mont,ctx);
7520Sstevel@tonic-gate
7530Sstevel@tonic-gate BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
7540Sstevel@tonic-gate BN_from_montgomery(&A,&c,mont,ctx);/**/
7550Sstevel@tonic-gate if (bp != NULL)
7560Sstevel@tonic-gate {
7570Sstevel@tonic-gate if (!results)
7580Sstevel@tonic-gate {
7590Sstevel@tonic-gate #ifdef undef
7600Sstevel@tonic-gate fprintf(stderr,"%d * %d %% %d\n",
7610Sstevel@tonic-gate BN_num_bits(&a),
7620Sstevel@tonic-gate BN_num_bits(&b),
7630Sstevel@tonic-gate BN_num_bits(mont->N));
7640Sstevel@tonic-gate #endif
7650Sstevel@tonic-gate BN_print(bp,&a);
7660Sstevel@tonic-gate BIO_puts(bp," * ");
7670Sstevel@tonic-gate BN_print(bp,&b);
7680Sstevel@tonic-gate BIO_puts(bp," % ");
7690Sstevel@tonic-gate BN_print(bp,&(mont->N));
7700Sstevel@tonic-gate BIO_puts(bp," - ");
7710Sstevel@tonic-gate }
7720Sstevel@tonic-gate BN_print(bp,&A);
7730Sstevel@tonic-gate BIO_puts(bp,"\n");
7740Sstevel@tonic-gate }
7750Sstevel@tonic-gate BN_mod_mul(&d,&a,&b,&n,ctx);
7760Sstevel@tonic-gate BN_sub(&d,&d,&A);
7770Sstevel@tonic-gate if(!BN_is_zero(&d))
7780Sstevel@tonic-gate {
7790Sstevel@tonic-gate fprintf(stderr,"Montgomery multiplication test failed!\n");
7800Sstevel@tonic-gate return 0;
7810Sstevel@tonic-gate }
7820Sstevel@tonic-gate }
7830Sstevel@tonic-gate BN_MONT_CTX_free(mont);
7840Sstevel@tonic-gate BN_free(&a);
7850Sstevel@tonic-gate BN_free(&b);
7860Sstevel@tonic-gate BN_free(&c);
7870Sstevel@tonic-gate BN_free(&d);
7880Sstevel@tonic-gate BN_free(&A);
7890Sstevel@tonic-gate BN_free(&B);
7900Sstevel@tonic-gate BN_free(&n);
7910Sstevel@tonic-gate return(1);
7920Sstevel@tonic-gate }
7930Sstevel@tonic-gate
test_mod(BIO * bp,BN_CTX * ctx)7940Sstevel@tonic-gate int test_mod(BIO *bp, BN_CTX *ctx)
7950Sstevel@tonic-gate {
7960Sstevel@tonic-gate BIGNUM *a,*b,*c,*d,*e;
7970Sstevel@tonic-gate int i;
7980Sstevel@tonic-gate
7990Sstevel@tonic-gate a=BN_new();
8000Sstevel@tonic-gate b=BN_new();
8010Sstevel@tonic-gate c=BN_new();
8020Sstevel@tonic-gate d=BN_new();
8030Sstevel@tonic-gate e=BN_new();
8040Sstevel@tonic-gate
8050Sstevel@tonic-gate BN_bntest_rand(a,1024,0,0); /**/
8060Sstevel@tonic-gate for (i=0; i<num0; i++)
8070Sstevel@tonic-gate {
8080Sstevel@tonic-gate BN_bntest_rand(b,450+i*10,0,0); /**/
8090Sstevel@tonic-gate a->neg=rand_neg();
8100Sstevel@tonic-gate b->neg=rand_neg();
8110Sstevel@tonic-gate BN_mod(c,a,b,ctx);/**/
8120Sstevel@tonic-gate if (bp != NULL)
8130Sstevel@tonic-gate {
8140Sstevel@tonic-gate if (!results)
8150Sstevel@tonic-gate {
8160Sstevel@tonic-gate BN_print(bp,a);
8170Sstevel@tonic-gate BIO_puts(bp," % ");
8180Sstevel@tonic-gate BN_print(bp,b);
8190Sstevel@tonic-gate BIO_puts(bp," - ");
8200Sstevel@tonic-gate }
8210Sstevel@tonic-gate BN_print(bp,c);
8220Sstevel@tonic-gate BIO_puts(bp,"\n");
8230Sstevel@tonic-gate }
8240Sstevel@tonic-gate BN_div(d,e,a,b,ctx);
8250Sstevel@tonic-gate BN_sub(e,e,c);
8260Sstevel@tonic-gate if(!BN_is_zero(e))
8270Sstevel@tonic-gate {
8280Sstevel@tonic-gate fprintf(stderr,"Modulo test failed!\n");
8290Sstevel@tonic-gate return 0;
8300Sstevel@tonic-gate }
8310Sstevel@tonic-gate }
8320Sstevel@tonic-gate BN_free(a);
8330Sstevel@tonic-gate BN_free(b);
8340Sstevel@tonic-gate BN_free(c);
8350Sstevel@tonic-gate BN_free(d);
8360Sstevel@tonic-gate BN_free(e);
8370Sstevel@tonic-gate return(1);
8380Sstevel@tonic-gate }
8390Sstevel@tonic-gate
test_mod_mul(BIO * bp,BN_CTX * ctx)8400Sstevel@tonic-gate int test_mod_mul(BIO *bp, BN_CTX *ctx)
8410Sstevel@tonic-gate {
8420Sstevel@tonic-gate BIGNUM *a,*b,*c,*d,*e;
8430Sstevel@tonic-gate int i,j;
8440Sstevel@tonic-gate
8450Sstevel@tonic-gate a=BN_new();
8460Sstevel@tonic-gate b=BN_new();
8470Sstevel@tonic-gate c=BN_new();
8480Sstevel@tonic-gate d=BN_new();
8490Sstevel@tonic-gate e=BN_new();
8500Sstevel@tonic-gate
8510Sstevel@tonic-gate for (j=0; j<3; j++) {
8520Sstevel@tonic-gate BN_bntest_rand(c,1024,0,0); /**/
8530Sstevel@tonic-gate for (i=0; i<num0; i++)
8540Sstevel@tonic-gate {
8550Sstevel@tonic-gate BN_bntest_rand(a,475+i*10,0,0); /**/
8560Sstevel@tonic-gate BN_bntest_rand(b,425+i*11,0,0); /**/
8570Sstevel@tonic-gate a->neg=rand_neg();
8580Sstevel@tonic-gate b->neg=rand_neg();
8590Sstevel@tonic-gate if (!BN_mod_mul(e,a,b,c,ctx))
8600Sstevel@tonic-gate {
8610Sstevel@tonic-gate unsigned long l;
8620Sstevel@tonic-gate
8630Sstevel@tonic-gate while ((l=ERR_get_error()))
8640Sstevel@tonic-gate fprintf(stderr,"ERROR:%s\n",
8650Sstevel@tonic-gate ERR_error_string(l,NULL));
8660Sstevel@tonic-gate EXIT(1);
8670Sstevel@tonic-gate }
8680Sstevel@tonic-gate if (bp != NULL)
8690Sstevel@tonic-gate {
8700Sstevel@tonic-gate if (!results)
8710Sstevel@tonic-gate {
8720Sstevel@tonic-gate BN_print(bp,a);
8730Sstevel@tonic-gate BIO_puts(bp," * ");
8740Sstevel@tonic-gate BN_print(bp,b);
8750Sstevel@tonic-gate BIO_puts(bp," % ");
8760Sstevel@tonic-gate BN_print(bp,c);
8770Sstevel@tonic-gate if ((a->neg ^ b->neg) && !BN_is_zero(e))
8780Sstevel@tonic-gate {
8790Sstevel@tonic-gate /* If (a*b) % c is negative, c must be added
8800Sstevel@tonic-gate * in order to obtain the normalized remainder
8810Sstevel@tonic-gate * (new with OpenSSL 0.9.7, previous versions of
8820Sstevel@tonic-gate * BN_mod_mul could generate negative results)
8830Sstevel@tonic-gate */
8840Sstevel@tonic-gate BIO_puts(bp," + ");
8850Sstevel@tonic-gate BN_print(bp,c);
8860Sstevel@tonic-gate }
8870Sstevel@tonic-gate BIO_puts(bp," - ");
8880Sstevel@tonic-gate }
8890Sstevel@tonic-gate BN_print(bp,e);
8900Sstevel@tonic-gate BIO_puts(bp,"\n");
8910Sstevel@tonic-gate }
8920Sstevel@tonic-gate BN_mul(d,a,b,ctx);
8930Sstevel@tonic-gate BN_sub(d,d,e);
8940Sstevel@tonic-gate BN_div(a,b,d,c,ctx);
8950Sstevel@tonic-gate if(!BN_is_zero(b))
8960Sstevel@tonic-gate {
8970Sstevel@tonic-gate fprintf(stderr,"Modulo multiply test failed!\n");
8980Sstevel@tonic-gate ERR_print_errors_fp(stderr);
8990Sstevel@tonic-gate return 0;
9000Sstevel@tonic-gate }
9010Sstevel@tonic-gate }
9020Sstevel@tonic-gate }
9030Sstevel@tonic-gate BN_free(a);
9040Sstevel@tonic-gate BN_free(b);
9050Sstevel@tonic-gate BN_free(c);
9060Sstevel@tonic-gate BN_free(d);
9070Sstevel@tonic-gate BN_free(e);
9080Sstevel@tonic-gate return(1);
9090Sstevel@tonic-gate }
9100Sstevel@tonic-gate
test_mod_exp(BIO * bp,BN_CTX * ctx)9110Sstevel@tonic-gate int test_mod_exp(BIO *bp, BN_CTX *ctx)
9120Sstevel@tonic-gate {
9130Sstevel@tonic-gate BIGNUM *a,*b,*c,*d,*e;
9140Sstevel@tonic-gate int i;
9150Sstevel@tonic-gate
9160Sstevel@tonic-gate a=BN_new();
9170Sstevel@tonic-gate b=BN_new();
9180Sstevel@tonic-gate c=BN_new();
9190Sstevel@tonic-gate d=BN_new();
9200Sstevel@tonic-gate e=BN_new();
9210Sstevel@tonic-gate
9220Sstevel@tonic-gate BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
9230Sstevel@tonic-gate for (i=0; i<num2; i++)
9240Sstevel@tonic-gate {
9250Sstevel@tonic-gate BN_bntest_rand(a,20+i*5,0,0); /**/
9260Sstevel@tonic-gate BN_bntest_rand(b,2+i,0,0); /**/
9270Sstevel@tonic-gate
9280Sstevel@tonic-gate if (!BN_mod_exp(d,a,b,c,ctx))
9290Sstevel@tonic-gate return(00);
9300Sstevel@tonic-gate
9310Sstevel@tonic-gate if (bp != NULL)
9320Sstevel@tonic-gate {
9330Sstevel@tonic-gate if (!results)
9340Sstevel@tonic-gate {
9350Sstevel@tonic-gate BN_print(bp,a);
9360Sstevel@tonic-gate BIO_puts(bp," ^ ");
9370Sstevel@tonic-gate BN_print(bp,b);
9380Sstevel@tonic-gate BIO_puts(bp," % ");
9390Sstevel@tonic-gate BN_print(bp,c);
9400Sstevel@tonic-gate BIO_puts(bp," - ");
9410Sstevel@tonic-gate }
9420Sstevel@tonic-gate BN_print(bp,d);
9430Sstevel@tonic-gate BIO_puts(bp,"\n");
9440Sstevel@tonic-gate }
9450Sstevel@tonic-gate BN_exp(e,a,b,ctx);
9460Sstevel@tonic-gate BN_sub(e,e,d);
9470Sstevel@tonic-gate BN_div(a,b,e,c,ctx);
9480Sstevel@tonic-gate if(!BN_is_zero(b))
9490Sstevel@tonic-gate {
9500Sstevel@tonic-gate fprintf(stderr,"Modulo exponentiation test failed!\n");
9510Sstevel@tonic-gate return 0;
9520Sstevel@tonic-gate }
9530Sstevel@tonic-gate }
9540Sstevel@tonic-gate BN_free(a);
9550Sstevel@tonic-gate BN_free(b);
9560Sstevel@tonic-gate BN_free(c);
9570Sstevel@tonic-gate BN_free(d);
9580Sstevel@tonic-gate BN_free(e);
9590Sstevel@tonic-gate return(1);
9600Sstevel@tonic-gate }
9610Sstevel@tonic-gate
test_mod_exp_mont_consttime(BIO * bp,BN_CTX * ctx)962*2139Sjp161948 int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
963*2139Sjp161948 {
964*2139Sjp161948 BIGNUM *a,*b,*c,*d,*e;
965*2139Sjp161948 int i;
966*2139Sjp161948
967*2139Sjp161948 a=BN_new();
968*2139Sjp161948 b=BN_new();
969*2139Sjp161948 c=BN_new();
970*2139Sjp161948 d=BN_new();
971*2139Sjp161948 e=BN_new();
972*2139Sjp161948
973*2139Sjp161948 BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
974*2139Sjp161948 for (i=0; i<num2; i++)
975*2139Sjp161948 {
976*2139Sjp161948 BN_bntest_rand(a,20+i*5,0,0); /**/
977*2139Sjp161948 BN_bntest_rand(b,2+i,0,0); /**/
978*2139Sjp161948
979*2139Sjp161948 if (!BN_mod_exp_mont_consttime(d,a,b,c,ctx,NULL))
980*2139Sjp161948 return(00);
981*2139Sjp161948
982*2139Sjp161948 if (bp != NULL)
983*2139Sjp161948 {
984*2139Sjp161948 if (!results)
985*2139Sjp161948 {
986*2139Sjp161948 BN_print(bp,a);
987*2139Sjp161948 BIO_puts(bp," ^ ");
988*2139Sjp161948 BN_print(bp,b);
989*2139Sjp161948 BIO_puts(bp," % ");
990*2139Sjp161948 BN_print(bp,c);
991*2139Sjp161948 BIO_puts(bp," - ");
992*2139Sjp161948 }
993*2139Sjp161948 BN_print(bp,d);
994*2139Sjp161948 BIO_puts(bp,"\n");
995*2139Sjp161948 }
996*2139Sjp161948 BN_exp(e,a,b,ctx);
997*2139Sjp161948 BN_sub(e,e,d);
998*2139Sjp161948 BN_div(a,b,e,c,ctx);
999*2139Sjp161948 if(!BN_is_zero(b))
1000*2139Sjp161948 {
1001*2139Sjp161948 fprintf(stderr,"Modulo exponentiation test failed!\n");
1002*2139Sjp161948 return 0;
1003*2139Sjp161948 }
1004*2139Sjp161948 }
1005*2139Sjp161948 BN_free(a);
1006*2139Sjp161948 BN_free(b);
1007*2139Sjp161948 BN_free(c);
1008*2139Sjp161948 BN_free(d);
1009*2139Sjp161948 BN_free(e);
1010*2139Sjp161948 return(1);
1011*2139Sjp161948 }
1012*2139Sjp161948
test_exp(BIO * bp,BN_CTX * ctx)10130Sstevel@tonic-gate int test_exp(BIO *bp, BN_CTX *ctx)
10140Sstevel@tonic-gate {
10150Sstevel@tonic-gate BIGNUM *a,*b,*d,*e,*one;
10160Sstevel@tonic-gate int i;
10170Sstevel@tonic-gate
10180Sstevel@tonic-gate a=BN_new();
10190Sstevel@tonic-gate b=BN_new();
10200Sstevel@tonic-gate d=BN_new();
10210Sstevel@tonic-gate e=BN_new();
10220Sstevel@tonic-gate one=BN_new();
10230Sstevel@tonic-gate BN_one(one);
10240Sstevel@tonic-gate
10250Sstevel@tonic-gate for (i=0; i<num2; i++)
10260Sstevel@tonic-gate {
10270Sstevel@tonic-gate BN_bntest_rand(a,20+i*5,0,0); /**/
10280Sstevel@tonic-gate BN_bntest_rand(b,2+i,0,0); /**/
10290Sstevel@tonic-gate
10300Sstevel@tonic-gate if (!BN_exp(d,a,b,ctx))
10310Sstevel@tonic-gate return(00);
10320Sstevel@tonic-gate
10330Sstevel@tonic-gate if (bp != NULL)
10340Sstevel@tonic-gate {
10350Sstevel@tonic-gate if (!results)
10360Sstevel@tonic-gate {
10370Sstevel@tonic-gate BN_print(bp,a);
10380Sstevel@tonic-gate BIO_puts(bp," ^ ");
10390Sstevel@tonic-gate BN_print(bp,b);
10400Sstevel@tonic-gate BIO_puts(bp," - ");
10410Sstevel@tonic-gate }
10420Sstevel@tonic-gate BN_print(bp,d);
10430Sstevel@tonic-gate BIO_puts(bp,"\n");
10440Sstevel@tonic-gate }
10450Sstevel@tonic-gate BN_one(e);
10460Sstevel@tonic-gate for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
10470Sstevel@tonic-gate BN_mul(e,e,a,ctx);
10480Sstevel@tonic-gate BN_sub(e,e,d);
10490Sstevel@tonic-gate if(!BN_is_zero(e))
10500Sstevel@tonic-gate {
10510Sstevel@tonic-gate fprintf(stderr,"Exponentiation test failed!\n");
10520Sstevel@tonic-gate return 0;
10530Sstevel@tonic-gate }
10540Sstevel@tonic-gate }
10550Sstevel@tonic-gate BN_free(a);
10560Sstevel@tonic-gate BN_free(b);
10570Sstevel@tonic-gate BN_free(d);
10580Sstevel@tonic-gate BN_free(e);
10590Sstevel@tonic-gate BN_free(one);
10600Sstevel@tonic-gate return(1);
10610Sstevel@tonic-gate }
10620Sstevel@tonic-gate
test_gf2m_add(BIO * bp)1063*2139Sjp161948 int test_gf2m_add(BIO *bp)
1064*2139Sjp161948 {
1065*2139Sjp161948 BIGNUM a,b,c;
1066*2139Sjp161948 int i, ret = 0;
1067*2139Sjp161948
1068*2139Sjp161948 BN_init(&a);
1069*2139Sjp161948 BN_init(&b);
1070*2139Sjp161948 BN_init(&c);
1071*2139Sjp161948
1072*2139Sjp161948 for (i=0; i<num0; i++)
1073*2139Sjp161948 {
1074*2139Sjp161948 BN_rand(&a,512,0,0);
1075*2139Sjp161948 BN_copy(&b, BN_value_one());
1076*2139Sjp161948 a.neg=rand_neg();
1077*2139Sjp161948 b.neg=rand_neg();
1078*2139Sjp161948 BN_GF2m_add(&c,&a,&b);
1079*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1080*2139Sjp161948 if (bp != NULL)
1081*2139Sjp161948 {
1082*2139Sjp161948 if (!results)
1083*2139Sjp161948 {
1084*2139Sjp161948 BN_print(bp,&a);
1085*2139Sjp161948 BIO_puts(bp," ^ ");
1086*2139Sjp161948 BN_print(bp,&b);
1087*2139Sjp161948 BIO_puts(bp," = ");
1088*2139Sjp161948 }
1089*2139Sjp161948 BN_print(bp,&c);
1090*2139Sjp161948 BIO_puts(bp,"\n");
1091*2139Sjp161948 }
1092*2139Sjp161948 #endif
1093*2139Sjp161948 /* Test that two added values have the correct parity. */
1094*2139Sjp161948 if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
1095*2139Sjp161948 {
1096*2139Sjp161948 fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
1097*2139Sjp161948 goto err;
1098*2139Sjp161948 }
1099*2139Sjp161948 BN_GF2m_add(&c,&c,&c);
1100*2139Sjp161948 /* Test that c + c = 0. */
1101*2139Sjp161948 if(!BN_is_zero(&c))
1102*2139Sjp161948 {
1103*2139Sjp161948 fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
1104*2139Sjp161948 goto err;
1105*2139Sjp161948 }
1106*2139Sjp161948 }
1107*2139Sjp161948 ret = 1;
1108*2139Sjp161948 err:
1109*2139Sjp161948 BN_free(&a);
1110*2139Sjp161948 BN_free(&b);
1111*2139Sjp161948 BN_free(&c);
1112*2139Sjp161948 return ret;
1113*2139Sjp161948 }
1114*2139Sjp161948
test_gf2m_mod(BIO * bp)1115*2139Sjp161948 int test_gf2m_mod(BIO *bp)
1116*2139Sjp161948 {
1117*2139Sjp161948 BIGNUM *a,*b[2],*c,*d,*e;
1118*2139Sjp161948 int i, j, ret = 0;
1119*2139Sjp161948 unsigned int p0[] = {163,7,6,3,0};
1120*2139Sjp161948 unsigned int p1[] = {193,15,0};
1121*2139Sjp161948
1122*2139Sjp161948 a=BN_new();
1123*2139Sjp161948 b[0]=BN_new();
1124*2139Sjp161948 b[1]=BN_new();
1125*2139Sjp161948 c=BN_new();
1126*2139Sjp161948 d=BN_new();
1127*2139Sjp161948 e=BN_new();
1128*2139Sjp161948
1129*2139Sjp161948 BN_GF2m_arr2poly(p0, b[0]);
1130*2139Sjp161948 BN_GF2m_arr2poly(p1, b[1]);
1131*2139Sjp161948
1132*2139Sjp161948 for (i=0; i<num0; i++)
1133*2139Sjp161948 {
1134*2139Sjp161948 BN_bntest_rand(a, 1024, 0, 0);
1135*2139Sjp161948 for (j=0; j < 2; j++)
1136*2139Sjp161948 {
1137*2139Sjp161948 BN_GF2m_mod(c, a, b[j]);
1138*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1139*2139Sjp161948 if (bp != NULL)
1140*2139Sjp161948 {
1141*2139Sjp161948 if (!results)
1142*2139Sjp161948 {
1143*2139Sjp161948 BN_print(bp,a);
1144*2139Sjp161948 BIO_puts(bp," % ");
1145*2139Sjp161948 BN_print(bp,b[j]);
1146*2139Sjp161948 BIO_puts(bp," - ");
1147*2139Sjp161948 BN_print(bp,c);
1148*2139Sjp161948 BIO_puts(bp,"\n");
1149*2139Sjp161948 }
1150*2139Sjp161948 }
1151*2139Sjp161948 #endif
1152*2139Sjp161948 BN_GF2m_add(d, a, c);
1153*2139Sjp161948 BN_GF2m_mod(e, d, b[j]);
1154*2139Sjp161948 /* Test that a + (a mod p) mod p == 0. */
1155*2139Sjp161948 if(!BN_is_zero(e))
1156*2139Sjp161948 {
1157*2139Sjp161948 fprintf(stderr,"GF(2^m) modulo test failed!\n");
1158*2139Sjp161948 goto err;
1159*2139Sjp161948 }
1160*2139Sjp161948 }
1161*2139Sjp161948 }
1162*2139Sjp161948 ret = 1;
1163*2139Sjp161948 err:
1164*2139Sjp161948 BN_free(a);
1165*2139Sjp161948 BN_free(b[0]);
1166*2139Sjp161948 BN_free(b[1]);
1167*2139Sjp161948 BN_free(c);
1168*2139Sjp161948 BN_free(d);
1169*2139Sjp161948 BN_free(e);
1170*2139Sjp161948 return ret;
1171*2139Sjp161948 }
1172*2139Sjp161948
test_gf2m_mod_mul(BIO * bp,BN_CTX * ctx)1173*2139Sjp161948 int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
1174*2139Sjp161948 {
1175*2139Sjp161948 BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
1176*2139Sjp161948 int i, j, ret = 0;
1177*2139Sjp161948 unsigned int p0[] = {163,7,6,3,0};
1178*2139Sjp161948 unsigned int p1[] = {193,15,0};
1179*2139Sjp161948
1180*2139Sjp161948 a=BN_new();
1181*2139Sjp161948 b[0]=BN_new();
1182*2139Sjp161948 b[1]=BN_new();
1183*2139Sjp161948 c=BN_new();
1184*2139Sjp161948 d=BN_new();
1185*2139Sjp161948 e=BN_new();
1186*2139Sjp161948 f=BN_new();
1187*2139Sjp161948 g=BN_new();
1188*2139Sjp161948 h=BN_new();
1189*2139Sjp161948
1190*2139Sjp161948 BN_GF2m_arr2poly(p0, b[0]);
1191*2139Sjp161948 BN_GF2m_arr2poly(p1, b[1]);
1192*2139Sjp161948
1193*2139Sjp161948 for (i=0; i<num0; i++)
1194*2139Sjp161948 {
1195*2139Sjp161948 BN_bntest_rand(a, 1024, 0, 0);
1196*2139Sjp161948 BN_bntest_rand(c, 1024, 0, 0);
1197*2139Sjp161948 BN_bntest_rand(d, 1024, 0, 0);
1198*2139Sjp161948 for (j=0; j < 2; j++)
1199*2139Sjp161948 {
1200*2139Sjp161948 BN_GF2m_mod_mul(e, a, c, b[j], ctx);
1201*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1202*2139Sjp161948 if (bp != NULL)
1203*2139Sjp161948 {
1204*2139Sjp161948 if (!results)
1205*2139Sjp161948 {
1206*2139Sjp161948 BN_print(bp,a);
1207*2139Sjp161948 BIO_puts(bp," * ");
1208*2139Sjp161948 BN_print(bp,c);
1209*2139Sjp161948 BIO_puts(bp," % ");
1210*2139Sjp161948 BN_print(bp,b[j]);
1211*2139Sjp161948 BIO_puts(bp," - ");
1212*2139Sjp161948 BN_print(bp,e);
1213*2139Sjp161948 BIO_puts(bp,"\n");
1214*2139Sjp161948 }
1215*2139Sjp161948 }
1216*2139Sjp161948 #endif
1217*2139Sjp161948 BN_GF2m_add(f, a, d);
1218*2139Sjp161948 BN_GF2m_mod_mul(g, f, c, b[j], ctx);
1219*2139Sjp161948 BN_GF2m_mod_mul(h, d, c, b[j], ctx);
1220*2139Sjp161948 BN_GF2m_add(f, e, g);
1221*2139Sjp161948 BN_GF2m_add(f, f, h);
1222*2139Sjp161948 /* Test that (a+d)*c = a*c + d*c. */
1223*2139Sjp161948 if(!BN_is_zero(f))
1224*2139Sjp161948 {
1225*2139Sjp161948 fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
1226*2139Sjp161948 goto err;
1227*2139Sjp161948 }
1228*2139Sjp161948 }
1229*2139Sjp161948 }
1230*2139Sjp161948 ret = 1;
1231*2139Sjp161948 err:
1232*2139Sjp161948 BN_free(a);
1233*2139Sjp161948 BN_free(b[0]);
1234*2139Sjp161948 BN_free(b[1]);
1235*2139Sjp161948 BN_free(c);
1236*2139Sjp161948 BN_free(d);
1237*2139Sjp161948 BN_free(e);
1238*2139Sjp161948 BN_free(f);
1239*2139Sjp161948 BN_free(g);
1240*2139Sjp161948 BN_free(h);
1241*2139Sjp161948 return ret;
1242*2139Sjp161948 }
1243*2139Sjp161948
test_gf2m_mod_sqr(BIO * bp,BN_CTX * ctx)1244*2139Sjp161948 int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
1245*2139Sjp161948 {
1246*2139Sjp161948 BIGNUM *a,*b[2],*c,*d;
1247*2139Sjp161948 int i, j, ret = 0;
1248*2139Sjp161948 unsigned int p0[] = {163,7,6,3,0};
1249*2139Sjp161948 unsigned int p1[] = {193,15,0};
1250*2139Sjp161948
1251*2139Sjp161948 a=BN_new();
1252*2139Sjp161948 b[0]=BN_new();
1253*2139Sjp161948 b[1]=BN_new();
1254*2139Sjp161948 c=BN_new();
1255*2139Sjp161948 d=BN_new();
1256*2139Sjp161948
1257*2139Sjp161948 BN_GF2m_arr2poly(p0, b[0]);
1258*2139Sjp161948 BN_GF2m_arr2poly(p1, b[1]);
1259*2139Sjp161948
1260*2139Sjp161948 for (i=0; i<num0; i++)
1261*2139Sjp161948 {
1262*2139Sjp161948 BN_bntest_rand(a, 1024, 0, 0);
1263*2139Sjp161948 for (j=0; j < 2; j++)
1264*2139Sjp161948 {
1265*2139Sjp161948 BN_GF2m_mod_sqr(c, a, b[j], ctx);
1266*2139Sjp161948 BN_copy(d, a);
1267*2139Sjp161948 BN_GF2m_mod_mul(d, a, d, b[j], ctx);
1268*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1269*2139Sjp161948 if (bp != NULL)
1270*2139Sjp161948 {
1271*2139Sjp161948 if (!results)
1272*2139Sjp161948 {
1273*2139Sjp161948 BN_print(bp,a);
1274*2139Sjp161948 BIO_puts(bp," ^ 2 % ");
1275*2139Sjp161948 BN_print(bp,b[j]);
1276*2139Sjp161948 BIO_puts(bp, " = ");
1277*2139Sjp161948 BN_print(bp,c);
1278*2139Sjp161948 BIO_puts(bp,"; a * a = ");
1279*2139Sjp161948 BN_print(bp,d);
1280*2139Sjp161948 BIO_puts(bp,"\n");
1281*2139Sjp161948 }
1282*2139Sjp161948 }
1283*2139Sjp161948 #endif
1284*2139Sjp161948 BN_GF2m_add(d, c, d);
1285*2139Sjp161948 /* Test that a*a = a^2. */
1286*2139Sjp161948 if(!BN_is_zero(d))
1287*2139Sjp161948 {
1288*2139Sjp161948 fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
1289*2139Sjp161948 goto err;
1290*2139Sjp161948 }
1291*2139Sjp161948 }
1292*2139Sjp161948 }
1293*2139Sjp161948 ret = 1;
1294*2139Sjp161948 err:
1295*2139Sjp161948 BN_free(a);
1296*2139Sjp161948 BN_free(b[0]);
1297*2139Sjp161948 BN_free(b[1]);
1298*2139Sjp161948 BN_free(c);
1299*2139Sjp161948 BN_free(d);
1300*2139Sjp161948 return ret;
1301*2139Sjp161948 }
1302*2139Sjp161948
test_gf2m_mod_inv(BIO * bp,BN_CTX * ctx)1303*2139Sjp161948 int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
1304*2139Sjp161948 {
1305*2139Sjp161948 BIGNUM *a,*b[2],*c,*d;
1306*2139Sjp161948 int i, j, ret = 0;
1307*2139Sjp161948 unsigned int p0[] = {163,7,6,3,0};
1308*2139Sjp161948 unsigned int p1[] = {193,15,0};
1309*2139Sjp161948
1310*2139Sjp161948 a=BN_new();
1311*2139Sjp161948 b[0]=BN_new();
1312*2139Sjp161948 b[1]=BN_new();
1313*2139Sjp161948 c=BN_new();
1314*2139Sjp161948 d=BN_new();
1315*2139Sjp161948
1316*2139Sjp161948 BN_GF2m_arr2poly(p0, b[0]);
1317*2139Sjp161948 BN_GF2m_arr2poly(p1, b[1]);
1318*2139Sjp161948
1319*2139Sjp161948 for (i=0; i<num0; i++)
1320*2139Sjp161948 {
1321*2139Sjp161948 BN_bntest_rand(a, 512, 0, 0);
1322*2139Sjp161948 for (j=0; j < 2; j++)
1323*2139Sjp161948 {
1324*2139Sjp161948 BN_GF2m_mod_inv(c, a, b[j], ctx);
1325*2139Sjp161948 BN_GF2m_mod_mul(d, a, c, b[j], ctx);
1326*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1327*2139Sjp161948 if (bp != NULL)
1328*2139Sjp161948 {
1329*2139Sjp161948 if (!results)
1330*2139Sjp161948 {
1331*2139Sjp161948 BN_print(bp,a);
1332*2139Sjp161948 BIO_puts(bp, " * ");
1333*2139Sjp161948 BN_print(bp,c);
1334*2139Sjp161948 BIO_puts(bp," - 1 % ");
1335*2139Sjp161948 BN_print(bp,b[j]);
1336*2139Sjp161948 BIO_puts(bp,"\n");
1337*2139Sjp161948 }
1338*2139Sjp161948 }
1339*2139Sjp161948 #endif
1340*2139Sjp161948 /* Test that ((1/a)*a) = 1. */
1341*2139Sjp161948 if(!BN_is_one(d))
1342*2139Sjp161948 {
1343*2139Sjp161948 fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
1344*2139Sjp161948 goto err;
1345*2139Sjp161948 }
1346*2139Sjp161948 }
1347*2139Sjp161948 }
1348*2139Sjp161948 ret = 1;
1349*2139Sjp161948 err:
1350*2139Sjp161948 BN_free(a);
1351*2139Sjp161948 BN_free(b[0]);
1352*2139Sjp161948 BN_free(b[1]);
1353*2139Sjp161948 BN_free(c);
1354*2139Sjp161948 BN_free(d);
1355*2139Sjp161948 return ret;
1356*2139Sjp161948 }
1357*2139Sjp161948
test_gf2m_mod_div(BIO * bp,BN_CTX * ctx)1358*2139Sjp161948 int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
1359*2139Sjp161948 {
1360*2139Sjp161948 BIGNUM *a,*b[2],*c,*d,*e,*f;
1361*2139Sjp161948 int i, j, ret = 0;
1362*2139Sjp161948 unsigned int p0[] = {163,7,6,3,0};
1363*2139Sjp161948 unsigned int p1[] = {193,15,0};
1364*2139Sjp161948
1365*2139Sjp161948 a=BN_new();
1366*2139Sjp161948 b[0]=BN_new();
1367*2139Sjp161948 b[1]=BN_new();
1368*2139Sjp161948 c=BN_new();
1369*2139Sjp161948 d=BN_new();
1370*2139Sjp161948 e=BN_new();
1371*2139Sjp161948 f=BN_new();
1372*2139Sjp161948
1373*2139Sjp161948 BN_GF2m_arr2poly(p0, b[0]);
1374*2139Sjp161948 BN_GF2m_arr2poly(p1, b[1]);
1375*2139Sjp161948
1376*2139Sjp161948 for (i=0; i<num0; i++)
1377*2139Sjp161948 {
1378*2139Sjp161948 BN_bntest_rand(a, 512, 0, 0);
1379*2139Sjp161948 BN_bntest_rand(c, 512, 0, 0);
1380*2139Sjp161948 for (j=0; j < 2; j++)
1381*2139Sjp161948 {
1382*2139Sjp161948 BN_GF2m_mod_div(d, a, c, b[j], ctx);
1383*2139Sjp161948 BN_GF2m_mod_mul(e, d, c, b[j], ctx);
1384*2139Sjp161948 BN_GF2m_mod_div(f, a, e, b[j], ctx);
1385*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1386*2139Sjp161948 if (bp != NULL)
1387*2139Sjp161948 {
1388*2139Sjp161948 if (!results)
1389*2139Sjp161948 {
1390*2139Sjp161948 BN_print(bp,a);
1391*2139Sjp161948 BIO_puts(bp, " = ");
1392*2139Sjp161948 BN_print(bp,c);
1393*2139Sjp161948 BIO_puts(bp," * ");
1394*2139Sjp161948 BN_print(bp,d);
1395*2139Sjp161948 BIO_puts(bp, " % ");
1396*2139Sjp161948 BN_print(bp,b[j]);
1397*2139Sjp161948 BIO_puts(bp,"\n");
1398*2139Sjp161948 }
1399*2139Sjp161948 }
1400*2139Sjp161948 #endif
1401*2139Sjp161948 /* Test that ((a/c)*c)/a = 1. */
1402*2139Sjp161948 if(!BN_is_one(f))
1403*2139Sjp161948 {
1404*2139Sjp161948 fprintf(stderr,"GF(2^m) modular division test failed!\n");
1405*2139Sjp161948 goto err;
1406*2139Sjp161948 }
1407*2139Sjp161948 }
1408*2139Sjp161948 }
1409*2139Sjp161948 ret = 1;
1410*2139Sjp161948 err:
1411*2139Sjp161948 BN_free(a);
1412*2139Sjp161948 BN_free(b[0]);
1413*2139Sjp161948 BN_free(b[1]);
1414*2139Sjp161948 BN_free(c);
1415*2139Sjp161948 BN_free(d);
1416*2139Sjp161948 BN_free(e);
1417*2139Sjp161948 BN_free(f);
1418*2139Sjp161948 return ret;
1419*2139Sjp161948 }
1420*2139Sjp161948
test_gf2m_mod_exp(BIO * bp,BN_CTX * ctx)1421*2139Sjp161948 int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
1422*2139Sjp161948 {
1423*2139Sjp161948 BIGNUM *a,*b[2],*c,*d,*e,*f;
1424*2139Sjp161948 int i, j, ret = 0;
1425*2139Sjp161948 unsigned int p0[] = {163,7,6,3,0};
1426*2139Sjp161948 unsigned int p1[] = {193,15,0};
1427*2139Sjp161948
1428*2139Sjp161948 a=BN_new();
1429*2139Sjp161948 b[0]=BN_new();
1430*2139Sjp161948 b[1]=BN_new();
1431*2139Sjp161948 c=BN_new();
1432*2139Sjp161948 d=BN_new();
1433*2139Sjp161948 e=BN_new();
1434*2139Sjp161948 f=BN_new();
1435*2139Sjp161948
1436*2139Sjp161948 BN_GF2m_arr2poly(p0, b[0]);
1437*2139Sjp161948 BN_GF2m_arr2poly(p1, b[1]);
1438*2139Sjp161948
1439*2139Sjp161948 for (i=0; i<num0; i++)
1440*2139Sjp161948 {
1441*2139Sjp161948 BN_bntest_rand(a, 512, 0, 0);
1442*2139Sjp161948 BN_bntest_rand(c, 512, 0, 0);
1443*2139Sjp161948 BN_bntest_rand(d, 512, 0, 0);
1444*2139Sjp161948 for (j=0; j < 2; j++)
1445*2139Sjp161948 {
1446*2139Sjp161948 BN_GF2m_mod_exp(e, a, c, b[j], ctx);
1447*2139Sjp161948 BN_GF2m_mod_exp(f, a, d, b[j], ctx);
1448*2139Sjp161948 BN_GF2m_mod_mul(e, e, f, b[j], ctx);
1449*2139Sjp161948 BN_add(f, c, d);
1450*2139Sjp161948 BN_GF2m_mod_exp(f, a, f, b[j], ctx);
1451*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1452*2139Sjp161948 if (bp != NULL)
1453*2139Sjp161948 {
1454*2139Sjp161948 if (!results)
1455*2139Sjp161948 {
1456*2139Sjp161948 BN_print(bp,a);
1457*2139Sjp161948 BIO_puts(bp, " ^ (");
1458*2139Sjp161948 BN_print(bp,c);
1459*2139Sjp161948 BIO_puts(bp," + ");
1460*2139Sjp161948 BN_print(bp,d);
1461*2139Sjp161948 BIO_puts(bp, ") = ");
1462*2139Sjp161948 BN_print(bp,e);
1463*2139Sjp161948 BIO_puts(bp, "; - ");
1464*2139Sjp161948 BN_print(bp,f);
1465*2139Sjp161948 BIO_puts(bp, " % ");
1466*2139Sjp161948 BN_print(bp,b[j]);
1467*2139Sjp161948 BIO_puts(bp,"\n");
1468*2139Sjp161948 }
1469*2139Sjp161948 }
1470*2139Sjp161948 #endif
1471*2139Sjp161948 BN_GF2m_add(f, e, f);
1472*2139Sjp161948 /* Test that a^(c+d)=a^c*a^d. */
1473*2139Sjp161948 if(!BN_is_zero(f))
1474*2139Sjp161948 {
1475*2139Sjp161948 fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
1476*2139Sjp161948 goto err;
1477*2139Sjp161948 }
1478*2139Sjp161948 }
1479*2139Sjp161948 }
1480*2139Sjp161948 ret = 1;
1481*2139Sjp161948 err:
1482*2139Sjp161948 BN_free(a);
1483*2139Sjp161948 BN_free(b[0]);
1484*2139Sjp161948 BN_free(b[1]);
1485*2139Sjp161948 BN_free(c);
1486*2139Sjp161948 BN_free(d);
1487*2139Sjp161948 BN_free(e);
1488*2139Sjp161948 BN_free(f);
1489*2139Sjp161948 return ret;
1490*2139Sjp161948 }
1491*2139Sjp161948
test_gf2m_mod_sqrt(BIO * bp,BN_CTX * ctx)1492*2139Sjp161948 int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
1493*2139Sjp161948 {
1494*2139Sjp161948 BIGNUM *a,*b[2],*c,*d,*e,*f;
1495*2139Sjp161948 int i, j, ret = 0;
1496*2139Sjp161948 unsigned int p0[] = {163,7,6,3,0};
1497*2139Sjp161948 unsigned int p1[] = {193,15,0};
1498*2139Sjp161948
1499*2139Sjp161948 a=BN_new();
1500*2139Sjp161948 b[0]=BN_new();
1501*2139Sjp161948 b[1]=BN_new();
1502*2139Sjp161948 c=BN_new();
1503*2139Sjp161948 d=BN_new();
1504*2139Sjp161948 e=BN_new();
1505*2139Sjp161948 f=BN_new();
1506*2139Sjp161948
1507*2139Sjp161948 BN_GF2m_arr2poly(p0, b[0]);
1508*2139Sjp161948 BN_GF2m_arr2poly(p1, b[1]);
1509*2139Sjp161948
1510*2139Sjp161948 for (i=0; i<num0; i++)
1511*2139Sjp161948 {
1512*2139Sjp161948 BN_bntest_rand(a, 512, 0, 0);
1513*2139Sjp161948 for (j=0; j < 2; j++)
1514*2139Sjp161948 {
1515*2139Sjp161948 BN_GF2m_mod(c, a, b[j]);
1516*2139Sjp161948 BN_GF2m_mod_sqrt(d, a, b[j], ctx);
1517*2139Sjp161948 BN_GF2m_mod_sqr(e, d, b[j], ctx);
1518*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1519*2139Sjp161948 if (bp != NULL)
1520*2139Sjp161948 {
1521*2139Sjp161948 if (!results)
1522*2139Sjp161948 {
1523*2139Sjp161948 BN_print(bp,d);
1524*2139Sjp161948 BIO_puts(bp, " ^ 2 - ");
1525*2139Sjp161948 BN_print(bp,a);
1526*2139Sjp161948 BIO_puts(bp,"\n");
1527*2139Sjp161948 }
1528*2139Sjp161948 }
1529*2139Sjp161948 #endif
1530*2139Sjp161948 BN_GF2m_add(f, c, e);
1531*2139Sjp161948 /* Test that d^2 = a, where d = sqrt(a). */
1532*2139Sjp161948 if(!BN_is_zero(f))
1533*2139Sjp161948 {
1534*2139Sjp161948 fprintf(stderr,"GF(2^m) modular square root test failed!\n");
1535*2139Sjp161948 goto err;
1536*2139Sjp161948 }
1537*2139Sjp161948 }
1538*2139Sjp161948 }
1539*2139Sjp161948 ret = 1;
1540*2139Sjp161948 err:
1541*2139Sjp161948 BN_free(a);
1542*2139Sjp161948 BN_free(b[0]);
1543*2139Sjp161948 BN_free(b[1]);
1544*2139Sjp161948 BN_free(c);
1545*2139Sjp161948 BN_free(d);
1546*2139Sjp161948 BN_free(e);
1547*2139Sjp161948 BN_free(f);
1548*2139Sjp161948 return ret;
1549*2139Sjp161948 }
1550*2139Sjp161948
test_gf2m_mod_solve_quad(BIO * bp,BN_CTX * ctx)1551*2139Sjp161948 int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
1552*2139Sjp161948 {
1553*2139Sjp161948 BIGNUM *a,*b[2],*c,*d,*e;
1554*2139Sjp161948 int i, j, s = 0, t, ret = 0;
1555*2139Sjp161948 unsigned int p0[] = {163,7,6,3,0};
1556*2139Sjp161948 unsigned int p1[] = {193,15,0};
1557*2139Sjp161948
1558*2139Sjp161948 a=BN_new();
1559*2139Sjp161948 b[0]=BN_new();
1560*2139Sjp161948 b[1]=BN_new();
1561*2139Sjp161948 c=BN_new();
1562*2139Sjp161948 d=BN_new();
1563*2139Sjp161948 e=BN_new();
1564*2139Sjp161948
1565*2139Sjp161948 BN_GF2m_arr2poly(p0, b[0]);
1566*2139Sjp161948 BN_GF2m_arr2poly(p1, b[1]);
1567*2139Sjp161948
1568*2139Sjp161948 for (i=0; i<num0; i++)
1569*2139Sjp161948 {
1570*2139Sjp161948 BN_bntest_rand(a, 512, 0, 0);
1571*2139Sjp161948 for (j=0; j < 2; j++)
1572*2139Sjp161948 {
1573*2139Sjp161948 t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
1574*2139Sjp161948 if (t)
1575*2139Sjp161948 {
1576*2139Sjp161948 s++;
1577*2139Sjp161948 BN_GF2m_mod_sqr(d, c, b[j], ctx);
1578*2139Sjp161948 BN_GF2m_add(d, c, d);
1579*2139Sjp161948 BN_GF2m_mod(e, a, b[j]);
1580*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1581*2139Sjp161948 if (bp != NULL)
1582*2139Sjp161948 {
1583*2139Sjp161948 if (!results)
1584*2139Sjp161948 {
1585*2139Sjp161948 BN_print(bp,c);
1586*2139Sjp161948 BIO_puts(bp, " is root of z^2 + z = ");
1587*2139Sjp161948 BN_print(bp,a);
1588*2139Sjp161948 BIO_puts(bp, " % ");
1589*2139Sjp161948 BN_print(bp,b[j]);
1590*2139Sjp161948 BIO_puts(bp, "\n");
1591*2139Sjp161948 }
1592*2139Sjp161948 }
1593*2139Sjp161948 #endif
1594*2139Sjp161948 BN_GF2m_add(e, e, d);
1595*2139Sjp161948 /* Test that solution of quadratic c satisfies c^2 + c = a. */
1596*2139Sjp161948 if(!BN_is_zero(e))
1597*2139Sjp161948 {
1598*2139Sjp161948 fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
1599*2139Sjp161948 goto err;
1600*2139Sjp161948 }
1601*2139Sjp161948
1602*2139Sjp161948 }
1603*2139Sjp161948 else
1604*2139Sjp161948 {
1605*2139Sjp161948 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1606*2139Sjp161948 if (bp != NULL)
1607*2139Sjp161948 {
1608*2139Sjp161948 if (!results)
1609*2139Sjp161948 {
1610*2139Sjp161948 BIO_puts(bp, "There are no roots of z^2 + z = ");
1611*2139Sjp161948 BN_print(bp,a);
1612*2139Sjp161948 BIO_puts(bp, " % ");
1613*2139Sjp161948 BN_print(bp,b[j]);
1614*2139Sjp161948 BIO_puts(bp, "\n");
1615*2139Sjp161948 }
1616*2139Sjp161948 }
1617*2139Sjp161948 #endif
1618*2139Sjp161948 }
1619*2139Sjp161948 }
1620*2139Sjp161948 }
1621*2139Sjp161948 if (s == 0)
1622*2139Sjp161948 {
1623*2139Sjp161948 fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
1624*2139Sjp161948 fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
1625*2139Sjp161948 goto err;
1626*2139Sjp161948 }
1627*2139Sjp161948 ret = 1;
1628*2139Sjp161948 err:
1629*2139Sjp161948 BN_free(a);
1630*2139Sjp161948 BN_free(b[0]);
1631*2139Sjp161948 BN_free(b[1]);
1632*2139Sjp161948 BN_free(c);
1633*2139Sjp161948 BN_free(d);
1634*2139Sjp161948 BN_free(e);
1635*2139Sjp161948 return ret;
1636*2139Sjp161948 }
1637*2139Sjp161948
genprime_cb(int p,int n,BN_GENCB * arg)1638*2139Sjp161948 static int genprime_cb(int p, int n, BN_GENCB *arg)
16390Sstevel@tonic-gate {
16400Sstevel@tonic-gate char c='*';
16410Sstevel@tonic-gate
16420Sstevel@tonic-gate if (p == 0) c='.';
16430Sstevel@tonic-gate if (p == 1) c='+';
16440Sstevel@tonic-gate if (p == 2) c='*';
16450Sstevel@tonic-gate if (p == 3) c='\n';
16460Sstevel@tonic-gate putc(c, stderr);
16470Sstevel@tonic-gate fflush(stderr);
1648*2139Sjp161948 return 1;
16490Sstevel@tonic-gate }
16500Sstevel@tonic-gate
test_kron(BIO * bp,BN_CTX * ctx)16510Sstevel@tonic-gate int test_kron(BIO *bp, BN_CTX *ctx)
16520Sstevel@tonic-gate {
1653*2139Sjp161948 BN_GENCB cb;
16540Sstevel@tonic-gate BIGNUM *a,*b,*r,*t;
16550Sstevel@tonic-gate int i;
16560Sstevel@tonic-gate int legendre, kronecker;
16570Sstevel@tonic-gate int ret = 0;
16580Sstevel@tonic-gate
16590Sstevel@tonic-gate a = BN_new();
16600Sstevel@tonic-gate b = BN_new();
16610Sstevel@tonic-gate r = BN_new();
16620Sstevel@tonic-gate t = BN_new();
16630Sstevel@tonic-gate if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
1664*2139Sjp161948
1665*2139Sjp161948 BN_GENCB_set(&cb, genprime_cb, NULL);
16660Sstevel@tonic-gate
16670Sstevel@tonic-gate /* We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol).
16680Sstevel@tonic-gate * In this case we know that if b is prime, then BN_kronecker(a, b, ctx)
16690Sstevel@tonic-gate * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
16700Sstevel@tonic-gate * So we generate a random prime b and compare these values
16710Sstevel@tonic-gate * for a number of random a's. (That is, we run the Solovay-Strassen
16720Sstevel@tonic-gate * primality test to confirm that b is prime, except that we
16730Sstevel@tonic-gate * don't want to test whether b is prime but whether BN_kronecker
16740Sstevel@tonic-gate * works.) */
16750Sstevel@tonic-gate
1676*2139Sjp161948 if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) goto err;
16770Sstevel@tonic-gate b->neg = rand_neg();
16780Sstevel@tonic-gate putc('\n', stderr);
16790Sstevel@tonic-gate
16800Sstevel@tonic-gate for (i = 0; i < num0; i++)
16810Sstevel@tonic-gate {
16820Sstevel@tonic-gate if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
16830Sstevel@tonic-gate a->neg = rand_neg();
16840Sstevel@tonic-gate
16850Sstevel@tonic-gate /* t := (|b|-1)/2 (note that b is odd) */
16860Sstevel@tonic-gate if (!BN_copy(t, b)) goto err;
16870Sstevel@tonic-gate t->neg = 0;
16880Sstevel@tonic-gate if (!BN_sub_word(t, 1)) goto err;
16890Sstevel@tonic-gate if (!BN_rshift1(t, t)) goto err;
16900Sstevel@tonic-gate /* r := a^t mod b */
16910Sstevel@tonic-gate b->neg=0;
16920Sstevel@tonic-gate
16930Sstevel@tonic-gate if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
16940Sstevel@tonic-gate b->neg=1;
16950Sstevel@tonic-gate
16960Sstevel@tonic-gate if (BN_is_word(r, 1))
16970Sstevel@tonic-gate legendre = 1;
16980Sstevel@tonic-gate else if (BN_is_zero(r))
16990Sstevel@tonic-gate legendre = 0;
17000Sstevel@tonic-gate else
17010Sstevel@tonic-gate {
17020Sstevel@tonic-gate if (!BN_add_word(r, 1)) goto err;
17030Sstevel@tonic-gate if (0 != BN_ucmp(r, b))
17040Sstevel@tonic-gate {
17050Sstevel@tonic-gate fprintf(stderr, "Legendre symbol computation failed\n");
17060Sstevel@tonic-gate goto err;
17070Sstevel@tonic-gate }
17080Sstevel@tonic-gate legendre = -1;
17090Sstevel@tonic-gate }
17100Sstevel@tonic-gate
17110Sstevel@tonic-gate kronecker = BN_kronecker(a, b, ctx);
17120Sstevel@tonic-gate if (kronecker < -1) goto err;
17130Sstevel@tonic-gate /* we actually need BN_kronecker(a, |b|) */
17140Sstevel@tonic-gate if (a->neg && b->neg)
17150Sstevel@tonic-gate kronecker = -kronecker;
17160Sstevel@tonic-gate
17170Sstevel@tonic-gate if (legendre != kronecker)
17180Sstevel@tonic-gate {
17190Sstevel@tonic-gate fprintf(stderr, "legendre != kronecker; a = ");
17200Sstevel@tonic-gate BN_print_fp(stderr, a);
17210Sstevel@tonic-gate fprintf(stderr, ", b = ");
17220Sstevel@tonic-gate BN_print_fp(stderr, b);
17230Sstevel@tonic-gate fprintf(stderr, "\n");
17240Sstevel@tonic-gate goto err;
17250Sstevel@tonic-gate }
17260Sstevel@tonic-gate
17270Sstevel@tonic-gate putc('.', stderr);
17280Sstevel@tonic-gate fflush(stderr);
17290Sstevel@tonic-gate }
17300Sstevel@tonic-gate
17310Sstevel@tonic-gate putc('\n', stderr);
17320Sstevel@tonic-gate fflush(stderr);
17330Sstevel@tonic-gate ret = 1;
17340Sstevel@tonic-gate err:
17350Sstevel@tonic-gate if (a != NULL) BN_free(a);
17360Sstevel@tonic-gate if (b != NULL) BN_free(b);
17370Sstevel@tonic-gate if (r != NULL) BN_free(r);
17380Sstevel@tonic-gate if (t != NULL) BN_free(t);
17390Sstevel@tonic-gate return ret;
17400Sstevel@tonic-gate }
17410Sstevel@tonic-gate
test_sqrt(BIO * bp,BN_CTX * ctx)17420Sstevel@tonic-gate int test_sqrt(BIO *bp, BN_CTX *ctx)
17430Sstevel@tonic-gate {
1744*2139Sjp161948 BN_GENCB cb;
17450Sstevel@tonic-gate BIGNUM *a,*p,*r;
17460Sstevel@tonic-gate int i, j;
17470Sstevel@tonic-gate int ret = 0;
17480Sstevel@tonic-gate
17490Sstevel@tonic-gate a = BN_new();
17500Sstevel@tonic-gate p = BN_new();
17510Sstevel@tonic-gate r = BN_new();
17520Sstevel@tonic-gate if (a == NULL || p == NULL || r == NULL) goto err;
1753*2139Sjp161948
1754*2139Sjp161948 BN_GENCB_set(&cb, genprime_cb, NULL);
1755*2139Sjp161948
17560Sstevel@tonic-gate for (i = 0; i < 16; i++)
17570Sstevel@tonic-gate {
17580Sstevel@tonic-gate if (i < 8)
17590Sstevel@tonic-gate {
17600Sstevel@tonic-gate unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
17610Sstevel@tonic-gate
17620Sstevel@tonic-gate if (!BN_set_word(p, primes[i])) goto err;
17630Sstevel@tonic-gate }
17640Sstevel@tonic-gate else
17650Sstevel@tonic-gate {
17660Sstevel@tonic-gate if (!BN_set_word(a, 32)) goto err;
17670Sstevel@tonic-gate if (!BN_set_word(r, 2*i + 1)) goto err;
17680Sstevel@tonic-gate
1769*2139Sjp161948 if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) goto err;
17700Sstevel@tonic-gate putc('\n', stderr);
17710Sstevel@tonic-gate }
17720Sstevel@tonic-gate p->neg = rand_neg();
17730Sstevel@tonic-gate
17740Sstevel@tonic-gate for (j = 0; j < num2; j++)
17750Sstevel@tonic-gate {
17760Sstevel@tonic-gate /* construct 'a' such that it is a square modulo p,
17770Sstevel@tonic-gate * but in general not a proper square and not reduced modulo p */
17780Sstevel@tonic-gate if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
17790Sstevel@tonic-gate if (!BN_nnmod(r, r, p, ctx)) goto err;
17800Sstevel@tonic-gate if (!BN_mod_sqr(r, r, p, ctx)) goto err;
17810Sstevel@tonic-gate if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
17820Sstevel@tonic-gate if (!BN_nnmod(a, a, p, ctx)) goto err;
17830Sstevel@tonic-gate if (!BN_mod_sqr(a, a, p, ctx)) goto err;
17840Sstevel@tonic-gate if (!BN_mul(a, a, r, ctx)) goto err;
17850Sstevel@tonic-gate if (rand_neg())
17860Sstevel@tonic-gate if (!BN_sub(a, a, p)) goto err;
17870Sstevel@tonic-gate
17880Sstevel@tonic-gate if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
17890Sstevel@tonic-gate if (!BN_mod_sqr(r, r, p, ctx)) goto err;
17900Sstevel@tonic-gate
17910Sstevel@tonic-gate if (!BN_nnmod(a, a, p, ctx)) goto err;
17920Sstevel@tonic-gate
17930Sstevel@tonic-gate if (BN_cmp(a, r) != 0)
17940Sstevel@tonic-gate {
17950Sstevel@tonic-gate fprintf(stderr, "BN_mod_sqrt failed: a = ");
17960Sstevel@tonic-gate BN_print_fp(stderr, a);
17970Sstevel@tonic-gate fprintf(stderr, ", r = ");
17980Sstevel@tonic-gate BN_print_fp(stderr, r);
17990Sstevel@tonic-gate fprintf(stderr, ", p = ");
18000Sstevel@tonic-gate BN_print_fp(stderr, p);
18010Sstevel@tonic-gate fprintf(stderr, "\n");
18020Sstevel@tonic-gate goto err;
18030Sstevel@tonic-gate }
18040Sstevel@tonic-gate
18050Sstevel@tonic-gate putc('.', stderr);
18060Sstevel@tonic-gate fflush(stderr);
18070Sstevel@tonic-gate }
18080Sstevel@tonic-gate
18090Sstevel@tonic-gate putc('\n', stderr);
18100Sstevel@tonic-gate fflush(stderr);
18110Sstevel@tonic-gate }
18120Sstevel@tonic-gate ret = 1;
18130Sstevel@tonic-gate err:
18140Sstevel@tonic-gate if (a != NULL) BN_free(a);
18150Sstevel@tonic-gate if (p != NULL) BN_free(p);
18160Sstevel@tonic-gate if (r != NULL) BN_free(r);
18170Sstevel@tonic-gate return ret;
18180Sstevel@tonic-gate }
18190Sstevel@tonic-gate
test_lshift(BIO * bp,BN_CTX * ctx,BIGNUM * a_)18200Sstevel@tonic-gate int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
18210Sstevel@tonic-gate {
18220Sstevel@tonic-gate BIGNUM *a,*b,*c,*d;
18230Sstevel@tonic-gate int i;
18240Sstevel@tonic-gate
18250Sstevel@tonic-gate b=BN_new();
18260Sstevel@tonic-gate c=BN_new();
18270Sstevel@tonic-gate d=BN_new();
18280Sstevel@tonic-gate BN_one(c);
18290Sstevel@tonic-gate
18300Sstevel@tonic-gate if(a_)
18310Sstevel@tonic-gate a=a_;
18320Sstevel@tonic-gate else
18330Sstevel@tonic-gate {
18340Sstevel@tonic-gate a=BN_new();
18350Sstevel@tonic-gate BN_bntest_rand(a,200,0,0); /**/
18360Sstevel@tonic-gate a->neg=rand_neg();
18370Sstevel@tonic-gate }
18380Sstevel@tonic-gate for (i=0; i<num0; i++)
18390Sstevel@tonic-gate {
18400Sstevel@tonic-gate BN_lshift(b,a,i+1);
18410Sstevel@tonic-gate BN_add(c,c,c);
18420Sstevel@tonic-gate if (bp != NULL)
18430Sstevel@tonic-gate {
18440Sstevel@tonic-gate if (!results)
18450Sstevel@tonic-gate {
18460Sstevel@tonic-gate BN_print(bp,a);
18470Sstevel@tonic-gate BIO_puts(bp," * ");
18480Sstevel@tonic-gate BN_print(bp,c);
18490Sstevel@tonic-gate BIO_puts(bp," - ");
18500Sstevel@tonic-gate }
18510Sstevel@tonic-gate BN_print(bp,b);
18520Sstevel@tonic-gate BIO_puts(bp,"\n");
18530Sstevel@tonic-gate }
18540Sstevel@tonic-gate BN_mul(d,a,c,ctx);
18550Sstevel@tonic-gate BN_sub(d,d,b);
18560Sstevel@tonic-gate if(!BN_is_zero(d))
18570Sstevel@tonic-gate {
18580Sstevel@tonic-gate fprintf(stderr,"Left shift test failed!\n");
18590Sstevel@tonic-gate fprintf(stderr,"a=");
18600Sstevel@tonic-gate BN_print_fp(stderr,a);
18610Sstevel@tonic-gate fprintf(stderr,"\nb=");
18620Sstevel@tonic-gate BN_print_fp(stderr,b);
18630Sstevel@tonic-gate fprintf(stderr,"\nc=");
18640Sstevel@tonic-gate BN_print_fp(stderr,c);
18650Sstevel@tonic-gate fprintf(stderr,"\nd=");
18660Sstevel@tonic-gate BN_print_fp(stderr,d);
18670Sstevel@tonic-gate fprintf(stderr,"\n");
18680Sstevel@tonic-gate return 0;
18690Sstevel@tonic-gate }
18700Sstevel@tonic-gate }
18710Sstevel@tonic-gate BN_free(a);
18720Sstevel@tonic-gate BN_free(b);
18730Sstevel@tonic-gate BN_free(c);
18740Sstevel@tonic-gate BN_free(d);
18750Sstevel@tonic-gate return(1);
18760Sstevel@tonic-gate }
18770Sstevel@tonic-gate
test_lshift1(BIO * bp)18780Sstevel@tonic-gate int test_lshift1(BIO *bp)
18790Sstevel@tonic-gate {
18800Sstevel@tonic-gate BIGNUM *a,*b,*c;
18810Sstevel@tonic-gate int i;
18820Sstevel@tonic-gate
18830Sstevel@tonic-gate a=BN_new();
18840Sstevel@tonic-gate b=BN_new();
18850Sstevel@tonic-gate c=BN_new();
18860Sstevel@tonic-gate
18870Sstevel@tonic-gate BN_bntest_rand(a,200,0,0); /**/
18880Sstevel@tonic-gate a->neg=rand_neg();
18890Sstevel@tonic-gate for (i=0; i<num0; i++)
18900Sstevel@tonic-gate {
18910Sstevel@tonic-gate BN_lshift1(b,a);
18920Sstevel@tonic-gate if (bp != NULL)
18930Sstevel@tonic-gate {
18940Sstevel@tonic-gate if (!results)
18950Sstevel@tonic-gate {
18960Sstevel@tonic-gate BN_print(bp,a);
18970Sstevel@tonic-gate BIO_puts(bp," * 2");
18980Sstevel@tonic-gate BIO_puts(bp," - ");
18990Sstevel@tonic-gate }
19000Sstevel@tonic-gate BN_print(bp,b);
19010Sstevel@tonic-gate BIO_puts(bp,"\n");
19020Sstevel@tonic-gate }
19030Sstevel@tonic-gate BN_add(c,a,a);
19040Sstevel@tonic-gate BN_sub(a,b,c);
19050Sstevel@tonic-gate if(!BN_is_zero(a))
19060Sstevel@tonic-gate {
19070Sstevel@tonic-gate fprintf(stderr,"Left shift one test failed!\n");
19080Sstevel@tonic-gate return 0;
19090Sstevel@tonic-gate }
19100Sstevel@tonic-gate
19110Sstevel@tonic-gate BN_copy(a,b);
19120Sstevel@tonic-gate }
19130Sstevel@tonic-gate BN_free(a);
19140Sstevel@tonic-gate BN_free(b);
19150Sstevel@tonic-gate BN_free(c);
19160Sstevel@tonic-gate return(1);
19170Sstevel@tonic-gate }
19180Sstevel@tonic-gate
test_rshift(BIO * bp,BN_CTX * ctx)19190Sstevel@tonic-gate int test_rshift(BIO *bp,BN_CTX *ctx)
19200Sstevel@tonic-gate {
19210Sstevel@tonic-gate BIGNUM *a,*b,*c,*d,*e;
19220Sstevel@tonic-gate int i;
19230Sstevel@tonic-gate
19240Sstevel@tonic-gate a=BN_new();
19250Sstevel@tonic-gate b=BN_new();
19260Sstevel@tonic-gate c=BN_new();
19270Sstevel@tonic-gate d=BN_new();
19280Sstevel@tonic-gate e=BN_new();
19290Sstevel@tonic-gate BN_one(c);
19300Sstevel@tonic-gate
19310Sstevel@tonic-gate BN_bntest_rand(a,200,0,0); /**/
19320Sstevel@tonic-gate a->neg=rand_neg();
19330Sstevel@tonic-gate for (i=0; i<num0; i++)
19340Sstevel@tonic-gate {
19350Sstevel@tonic-gate BN_rshift(b,a,i+1);
19360Sstevel@tonic-gate BN_add(c,c,c);
19370Sstevel@tonic-gate if (bp != NULL)
19380Sstevel@tonic-gate {
19390Sstevel@tonic-gate if (!results)
19400Sstevel@tonic-gate {
19410Sstevel@tonic-gate BN_print(bp,a);
19420Sstevel@tonic-gate BIO_puts(bp," / ");
19430Sstevel@tonic-gate BN_print(bp,c);
19440Sstevel@tonic-gate BIO_puts(bp," - ");
19450Sstevel@tonic-gate }
19460Sstevel@tonic-gate BN_print(bp,b);
19470Sstevel@tonic-gate BIO_puts(bp,"\n");
19480Sstevel@tonic-gate }
19490Sstevel@tonic-gate BN_div(d,e,a,c,ctx);
19500Sstevel@tonic-gate BN_sub(d,d,b);
19510Sstevel@tonic-gate if(!BN_is_zero(d))
19520Sstevel@tonic-gate {
19530Sstevel@tonic-gate fprintf(stderr,"Right shift test failed!\n");
19540Sstevel@tonic-gate return 0;
19550Sstevel@tonic-gate }
19560Sstevel@tonic-gate }
19570Sstevel@tonic-gate BN_free(a);
19580Sstevel@tonic-gate BN_free(b);
19590Sstevel@tonic-gate BN_free(c);
19600Sstevel@tonic-gate BN_free(d);
19610Sstevel@tonic-gate BN_free(e);
19620Sstevel@tonic-gate return(1);
19630Sstevel@tonic-gate }
19640Sstevel@tonic-gate
test_rshift1(BIO * bp)19650Sstevel@tonic-gate int test_rshift1(BIO *bp)
19660Sstevel@tonic-gate {
19670Sstevel@tonic-gate BIGNUM *a,*b,*c;
19680Sstevel@tonic-gate int i;
19690Sstevel@tonic-gate
19700Sstevel@tonic-gate a=BN_new();
19710Sstevel@tonic-gate b=BN_new();
19720Sstevel@tonic-gate c=BN_new();
19730Sstevel@tonic-gate
19740Sstevel@tonic-gate BN_bntest_rand(a,200,0,0); /**/
19750Sstevel@tonic-gate a->neg=rand_neg();
19760Sstevel@tonic-gate for (i=0; i<num0; i++)
19770Sstevel@tonic-gate {
19780Sstevel@tonic-gate BN_rshift1(b,a);
19790Sstevel@tonic-gate if (bp != NULL)
19800Sstevel@tonic-gate {
19810Sstevel@tonic-gate if (!results)
19820Sstevel@tonic-gate {
19830Sstevel@tonic-gate BN_print(bp,a);
19840Sstevel@tonic-gate BIO_puts(bp," / 2");
19850Sstevel@tonic-gate BIO_puts(bp," - ");
19860Sstevel@tonic-gate }
19870Sstevel@tonic-gate BN_print(bp,b);
19880Sstevel@tonic-gate BIO_puts(bp,"\n");
19890Sstevel@tonic-gate }
19900Sstevel@tonic-gate BN_sub(c,a,b);
19910Sstevel@tonic-gate BN_sub(c,c,b);
19920Sstevel@tonic-gate if(!BN_is_zero(c) && !BN_abs_is_word(c, 1))
19930Sstevel@tonic-gate {
19940Sstevel@tonic-gate fprintf(stderr,"Right shift one test failed!\n");
19950Sstevel@tonic-gate return 0;
19960Sstevel@tonic-gate }
19970Sstevel@tonic-gate BN_copy(a,b);
19980Sstevel@tonic-gate }
19990Sstevel@tonic-gate BN_free(a);
20000Sstevel@tonic-gate BN_free(b);
20010Sstevel@tonic-gate BN_free(c);
20020Sstevel@tonic-gate return(1);
20030Sstevel@tonic-gate }
20040Sstevel@tonic-gate
rand_neg(void)20050Sstevel@tonic-gate int rand_neg(void)
20060Sstevel@tonic-gate {
20070Sstevel@tonic-gate static unsigned int neg=0;
20080Sstevel@tonic-gate static int sign[8]={0,0,0,1,1,0,1,1};
20090Sstevel@tonic-gate
20100Sstevel@tonic-gate return(sign[(neg++)%8]);
20110Sstevel@tonic-gate }
2012