提交 1dc920c8 编写于 作者: B Bodo Möller

Binary field arithmetic contributed by Sun Microsystems.

The 'OPENSSL_NO_SUN_DIV' default is still subject to change,
so I didn't bother to finish the CHANGES entry yet.

Submitted by: Douglas Stebila <douglas.stebila@sun.com>, Sheueling Chang <sheueling.chang@sun.com>
(CHANGES entry by Bodo Moeller)
上级 16dc1cfb
......@@ -4,6 +4,58 @@
Changes between 0.9.7 and 0.9.8 [xx XXX 2002]
*) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c.
Polynomials are represented as BIGNUMs (where the sign bit is not
used) in the following functions [macros]:
BN_GF2m_add
BN_GF2m_sub [= BN_GF2m_add]
BN_GF2m_mod [wrapper for BN_GF2m_mod_arr]
BN_GF2m_mod_mul [wrapper for BN_GF2m_mod_mul_arr]
BN_GF2m_mod_sqr [wrapper for BN_GF2m_mod_sqr_arr]
BN_GF2m_mod_inv
BN_GF2m_mod_exp [wrapper for BN_GF2m_mod_exp_arr]
BN_GF2m_mod_sqrt [wrapper for BN_GF2m_mod_sqrt_arr]
BN_GF2m_mod_solve_quad [wrapper for BN_GF2m_mod_solve_quad_arr]
BN_GF2m_cmp [= BN_ucmp]
(Note that only the 'mod' functions are actually for fields GF(2^m).
BN_GF2m_add() is misnomer, but this is for the sake of consistency.)
For some functions, an the irreducible polynomial defining a
field can be given as an 'unsigned int[]' with strictly
decreasing elements giving the indices of those bits that are set;
i.e., p[] represents the polynomial
f(t) = t^p[0] + t^p[1] + ... + t^p[k]
where
p[0] > p[1] > ... > p[k] = 0.
This applies to the following functions:
BN_GF2m_mod_arr
BN_GF2m_mod_mul_arr
BN_GF2m_mod_sqr_arr
BN_GF2m_mod_inv_arr [wrapper for BN_GF2m_mod_inv]
BN_GF2m_mod_div_arr [wrapper for BN_GF2m_mod_div]
BN_GF2m_mod_exp_arr
BN_GF2m_mod_sqrt_arr
BN_GF2m_mod_solve_quad_arr
BN_GF2m_poly2arr
BN_GF2m_arr2poly
Conversion can be performed by the following functions:
BN_GF2m_poly2arr
BN_GF2m_arr2poly
bntest.c has additional tests for binary polynomial arithmetic.
Two implementations for BN_GF2m_mod_div() are available (selected
at compile-time). ...
TBD ... OPENSSL_NO_SUN_DIV ... --Bodo
[Sheueling Chang Shantz and Douglas Stebila
(Sun Microsystems Laboratories)]
*) Add more WAP/WTLS elliptic curve OIDs.
[Douglas Stebila <douglas.stebila@sun.com>]
......
......@@ -39,12 +39,12 @@ LIB=$(TOP)/libcrypto.a
LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \
bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \
bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c
bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c
LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \
bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \
bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \
bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o
bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o
SRC= $(LIBSRC)
......@@ -194,6 +194,13 @@ bn_asm.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
bn_asm.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
bn_asm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
bn_asm.o: ../cryptlib.h bn_asm.c bn_lcl.h
bn_gf2m.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
bn_gf2m.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
bn_gf2m.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
bn_gf2m.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
bn_gf2m.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
bn_gf2m.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
bn_gf2m.o: ../cryptlib.h bn_gf2m.c bn_lcl.h
bn_blind.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
bn_blind.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
bn_blind.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
......
......@@ -55,6 +55,32 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the Eric Young open source
* license provided above.
*
* In addition, Sun covenants to all licensees who provide a reciprocal
* covenant with respect to their own patents if any, not to sue under
* current and future patent claims necessarily infringed by the making,
* using, practicing, selling, offering for sale and/or otherwise
* disposing of the Contribution as delivered hereunder
* (or portions thereof), provided that such covenant shall not apply:
* 1) for code that a licensee deletes from the Contribution;
* 2) separates from the Contribution; or
* 3) for infringements caused by:
* i) the modification of the Contribution or
* ii) the combination of the Contribution with other software or
* devices where such combination causes the infringement.
*
* The binary polynomial arithmetic software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
*
*/
#ifndef HEADER_BN_H
#define HEADER_BN_H
......@@ -453,6 +479,40 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
BN_RECP_CTX *recp, BN_CTX *ctx);
/* Functions for arithmetic over binary polynomials represented by BIGNUMs.
*
* The BIGNUM::neg property of BIGNUMs representing binary polynomials is ignored.
*
* Note that input arguments are not const so that their bit arrays can
* be expanded to the appropriate size if needed.
*/
int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); /* r = a + b */
#define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /* r = a mod p */
int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */
int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); /* r = (a * a) mod p */
int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); /* r = (1 / b) mod p */
int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */
int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */
int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); /* r = sqrt(a) mod p */
int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); /* r^2 + r = a mod p */
#define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
/* Some functions allow for representation of the irreducible polynomials
* as an unsigned int[], say p. The irreducible f(t) is then of the form:
* t^p[0] + t^p[1] + ... + t^p[k]
* where m = p[0] > p[1] > ... > p[k] = 0.
*/
int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]); /* r = a mod p */
int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx); /* r = (a * b) mod p */
int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx); /* r = (a * a) mod p */
int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx); /* r = (1 / b) mod p */
int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx); /* r = (a / b) mod p */
int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max);
int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a);
/* library internal functions */
#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
......@@ -510,6 +570,13 @@ void ERR_load_BN_strings(void);
#define BN_F_BN_DIV 107
#define BN_F_BN_EXPAND2 108
#define BN_F_BN_EXPAND_INTERNAL 120
#define BN_F_BN_GF2M_MOD 126
#define BN_F_BN_GF2M_MOD_DIV 123
#define BN_F_BN_GF2M_MOD_EXP 127
#define BN_F_BN_GF2M_MOD_MUL 124
#define BN_F_BN_GF2M_MOD_SOLVE_QUAD 128
#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 129
#define BN_F_BN_GF2M_MOD_SQR 125
#define BN_F_BN_MOD_EXP2_MONT 118
#define BN_F_BN_MOD_EXP_MONT 109
#define BN_F_BN_MOD_EXP_MONT_WORD 117
......@@ -535,6 +602,7 @@ void ERR_load_BN_strings(void);
#define BN_R_INVALID_LENGTH 106
#define BN_R_INVALID_RANGE 115
#define BN_R_NOT_A_SQUARE 111
#define BN_R_NOT_IMPLEMENTED 116
#define BN_R_NOT_INITIALIZED 107
#define BN_R_NO_INVERSE 108
#define BN_R_P_IS_NOT_PRIME 112
......
/* crypto/bn/bn_err.c */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -77,6 +77,13 @@ static ERR_STRING_DATA BN_str_functs[]=
{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"},
{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"},
{ERR_PACK(0,BN_F_BN_EXPAND_INTERNAL,0), "BN_EXPAND_INTERNAL"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD,0), "BN_GF2m_mod"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_DIV,0), "BN_GF2m_mod_div"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_EXP,0), "BN_GF2m_mod_exp"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_MUL,0), "BN_GF2m_mod_mul"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_SOLVE_QUAD,0), "BN_GF2m_mod_solve_quad"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR,0), "BN_GF2m_mod_solve_quad_arr"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_SQR,0), "BN_GF2m_mod_sqr"},
{ERR_PACK(0,BN_F_BN_MOD_EXP2_MONT,0), "BN_mod_exp2_mont"},
{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0), "BN_mod_exp_mont"},
{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT_WORD,0), "BN_mod_exp_mont_word"},
......@@ -105,6 +112,7 @@ static ERR_STRING_DATA BN_str_reasons[]=
{BN_R_INVALID_LENGTH ,"invalid length"},
{BN_R_INVALID_RANGE ,"invalid range"},
{BN_R_NOT_A_SQUARE ,"not a square"},
{BN_R_NOT_IMPLEMENTED ,"not implemented"},
{BN_R_NOT_INITIALIZED ,"not initialized"},
{BN_R_NO_INVERSE ,"no inverse"},
{BN_R_P_IS_NOT_PRIME ,"p is not prime"},
......
此差异已折叠。
......@@ -55,6 +55,32 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the Eric Young open source
* license provided above.
*
* In addition, Sun covenants to all licensees who provide a reciprocal
* covenant with respect to their own patents if any, not to sue under
* current and future patent claims necessarily infringed by the making,
* using, practicing, selling, offering for sale and/or otherwise
* disposing of the Contribution as delivered hereunder
* (or portions thereof), provided that such covenant shall not apply:
* 1) for code that a licensee deletes from the Contribution;
* 2) separates from the Contribution; or
* 3) for infringements caused by:
* i) the modification of the Contribution or
* ii) the combination of the Contribution with other software or
* devices where such combination causes the infringement.
*
* The binary polynomial arithmetic software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
*
*/
#include <stdio.h>
#include <stdlib.h>
......@@ -91,6 +117,15 @@ int test_mod(BIO *bp,BN_CTX *ctx);
int test_mod_mul(BIO *bp,BN_CTX *ctx);
int test_mod_exp(BIO *bp,BN_CTX *ctx);
int test_exp(BIO *bp,BN_CTX *ctx);
int test_gf2m_add(BIO *bp);
int test_gf2m_mod(BIO *bp);
int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
int test_kron(BIO *bp,BN_CTX *ctx);
int test_sqrt(BIO *bp,BN_CTX *ctx);
int rand_neg(void);
......@@ -226,6 +261,42 @@ int main(int argc, char *argv[])
if (!test_exp(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_add");
if (!test_gf2m_add(out)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod");
if (!test_gf2m_mod(out)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_mul");
if (!test_gf2m_mod_mul(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_sqr");
if (!test_gf2m_mod_sqr(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_inv");
if (!test_gf2m_mod_inv(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_div");
if (!test_gf2m_mod_div(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_exp");
if (!test_gf2m_mod_exp(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_sqrt");
if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_solve_quad");
if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_kronecker");
if (!test_kron(out,ctx)) goto err;
BIO_flush(out);
......@@ -872,6 +943,581 @@ int test_exp(BIO *bp, BN_CTX *ctx)
return(1);
}
int test_gf2m_add(BIO *bp)
{
BIGNUM a,b,c;
int i, ret = 0;
BN_init(&a);
BN_init(&b);
BN_init(&c);
for (i=0; i<num0; i++)
{
BN_rand(&a,512,0,0);
BN_copy(&b, BN_value_one());
a.neg=rand_neg();
b.neg=rand_neg();
BN_GF2m_add(&c,&a,&b);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,&a);
BIO_puts(bp," ^ ");
BN_print(bp,&b);
BIO_puts(bp," = ");
}
BN_print(bp,&c);
BIO_puts(bp,"\n");
}
#endif
/* Test that two added values have the correct parity. */
if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
{
fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
goto err;
}
BN_GF2m_add(&c,&c,&c);
/* Test that c + c = 0. */
if(!BN_is_zero(&c))
{
fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
goto err;
}
}
ret = 1;
err:
BN_free(&a);
BN_free(&b);
BN_free(&c);
return ret;
}
int test_gf2m_mod(BIO *bp)
{
BIGNUM *a,*b[2],*c,*d,*e;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 1024, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod(c, a, b[j]);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp," % ");
BN_print(bp,b[j]);
BIO_puts(bp," - ");
BN_print(bp,c);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(d, a, c);
BN_GF2m_mod(e, d, b[j]);
/* Test that a + (a mod p) mod p == 0. */
if(!BN_is_zero(e))
{
fprintf(stderr,"GF(2^m) modulo test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
return ret;
}
int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
f=BN_new();
g=BN_new();
h=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 1024, 0, 0);
BN_bntest_rand(c, 1024, 0, 0);
BN_bntest_rand(d, 1024, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_mul(e, a, c, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp," * ");
BN_print(bp,c);
BIO_puts(bp," % ");
BN_print(bp,b[j]);
BIO_puts(bp," - ");
BN_print(bp,e);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(f, a, d);
BN_GF2m_mod_mul(g, f, c, b[j], ctx);
BN_GF2m_mod_mul(h, d, c, b[j], ctx);
BN_GF2m_add(f, e, g);
BN_GF2m_add(f, f, h);
/* Test that (a+d)*c = a*c + d*c. */
if(!BN_is_zero(f))
{
fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
BN_free(f);
BN_free(g);
BN_free(h);
return ret;
}
int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 1024, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_sqr(c, a, b[j], ctx);
BN_copy(d, a);
BN_GF2m_mod_mul(d, a, d, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp," ^ 2 % ");
BN_print(bp,b[j]);
BIO_puts(bp, " = ");
BN_print(bp,c);
BIO_puts(bp,"; a * a = ");
BN_print(bp,d);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(d, c, d);
/* Test that a*a = a^2. */
if(!BN_is_zero(d))
{
fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
return ret;
}
int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_inv(c, a, b[j], ctx);
BN_GF2m_mod_mul(d, a, c, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp, " * ");
BN_print(bp,c);
BIO_puts(bp," - 1 % ");
BN_print(bp,b[j]);
BIO_puts(bp,"\n");
}
}
#endif
/* Test that ((1/a)*a) = 1. */
if(!BN_is_one(d))
{
fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
return ret;
}
int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e,*f;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
f=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
BN_bntest_rand(c, 512, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_div(d, a, c, b[j], ctx);
BN_GF2m_mod_mul(e, d, c, b[j], ctx);
BN_GF2m_mod_div(f, a, e, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp, " = ");
BN_print(bp,c);
BIO_puts(bp," * ");
BN_print(bp,d);
BIO_puts(bp, " % ");
BN_print(bp,b[j]);
BIO_puts(bp,"\n");
}
}
#endif
/* Test that ((a/c)*c)/a = 1. */
if(!BN_is_one(f))
{
fprintf(stderr,"GF(2^m) modular division test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
BN_free(f);
return ret;
}
int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e,*f;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
f=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
BN_bntest_rand(c, 512, 0, 0);
BN_bntest_rand(d, 512, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_exp(e, a, c, b[j], ctx);
BN_GF2m_mod_exp(f, a, d, b[j], ctx);
BN_GF2m_mod_mul(e, e, f, b[j], ctx);
BN_add(f, c, d);
BN_GF2m_mod_exp(f, a, f, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp, " ^ (");
BN_print(bp,c);
BIO_puts(bp," + ");
BN_print(bp,d);
BIO_puts(bp, ") = ");
BN_print(bp,e);
BIO_puts(bp, "; - ");
BN_print(bp,f);
BIO_puts(bp, " % ");
BN_print(bp,b[j]);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(f, e, f);
/* Test that a^(c+d)=a^c*a^d. */
if(!BN_is_zero(f))
{
fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
BN_free(f);
return ret;
}
int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e,*f;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
f=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod(c, a, b[j]);
BN_GF2m_mod_sqrt(d, a, b[j], ctx);
BN_GF2m_mod_sqr(e, d, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,d);
BIO_puts(bp, " ^ 2 - ");
BN_print(bp,a);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(f, c, e);
/* Test that d^2 = a, where d = sqrt(a). */
if(!BN_is_zero(f))
{
fprintf(stderr,"GF(2^m) modular square root test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
BN_free(f);
return ret;
}
int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e;
int i, j, s = 0, t, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
for (j=0; j < 2; j++)
{
t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
if (t)
{
s++;
BN_GF2m_mod_sqr(d, c, b[j], ctx);
BN_GF2m_add(d, c, d);
BN_GF2m_mod(e, a, b[j]);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,c);
BIO_puts(bp, " is root of z^2 + z = ");
BN_print(bp,a);
BIO_puts(bp, " % ");
BN_print(bp,b[j]);
BIO_puts(bp, "\n");
}
}
#endif
BN_GF2m_add(e, e, d);
/* Test that solution of quadratic c satisfies c^2 + c = a. */
if(!BN_is_zero(e))
{
fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
goto err;
}
}
else
{
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BIO_puts(bp, "There are no roots of z^2 + z = ");
BN_print(bp,a);
BIO_puts(bp, " % ");
BN_print(bp,b[j]);
BIO_puts(bp, "\n");
}
}
#endif
}
}
}
if (s == 0)
{
fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
goto err;
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
return ret;
}
static void genprime_cb(int p, int n, void *arg)
{
char c='*';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册