implement and use new macros BN_get_sign(), BN_set_sign()
Submitted by: Nils Larsch
This commit is contained in:
parent
e5f4d8279d
commit
b53e44e572
14 changed files with 87 additions and 48 deletions
9
CHANGES
9
CHANGES
|
@ -4,6 +4,15 @@
|
|||
|
||||
Changes between 0.9.7 and 0.9.8 [xx XXX 2002]
|
||||
|
||||
*) Extend the BIGNUM API by creating new macros that behave like
|
||||
functions
|
||||
|
||||
void BN_set_sign(BIGNUM *a, int neg);
|
||||
int BN_get_sign(const BIGNUM *a);
|
||||
|
||||
and avoid the need to access 'a->neg' directly in applications.
|
||||
[Nils Larsch <nla@trustcenter.de>]
|
||||
|
||||
*) Implement fast modular reduction for pseudo-Mersenne primes
|
||||
used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c).
|
||||
EC_GROUP_new_curve_GFp() will now automatically use this
|
||||
|
|
|
@ -147,7 +147,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
|||
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if(bn->neg) ret->type = V_ASN1_NEG_ENUMERATED;
|
||||
if(BN_get_sign(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
|
||||
else ret->type=V_ASN1_ENUMERATED;
|
||||
j=BN_num_bits(bn);
|
||||
len=((j == 0)?0:((j/8)+1));
|
||||
|
@ -175,6 +175,6 @@ BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
|
|||
|
||||
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
|
||||
ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN,ASN1_R_BN_LIB);
|
||||
else if(ai->type == V_ASN1_NEG_ENUMERATED) ret->neg = 1;
|
||||
else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_sign(ret,1);
|
||||
return(ret);
|
||||
}
|
||||
|
|
|
@ -393,7 +393,8 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai)
|
|||
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if(bn->neg) ret->type = V_ASN1_NEG_INTEGER;
|
||||
if (BN_get_sign(bn))
|
||||
ret->type = V_ASN1_NEG_INTEGER;
|
||||
else ret->type=V_ASN1_INTEGER;
|
||||
j=BN_num_bits(bn);
|
||||
len=((j == 0)?0:((j/8)+1));
|
||||
|
@ -426,7 +427,8 @@ BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn)
|
|||
|
||||
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
|
||||
ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB);
|
||||
else if(ai->type == V_ASN1_NEG_INTEGER) ret->neg = 1;
|
||||
else if(ai->type == V_ASN1_NEG_INTEGER)
|
||||
BN_set_sign(ret, 1);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -575,7 +575,7 @@ static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf,
|
|||
const char *neg;
|
||||
|
||||
if (num == NULL) return(1);
|
||||
neg=(num->neg)?"-":"";
|
||||
neg = (BN_get_sign(num))?"-":"";
|
||||
if (off)
|
||||
{
|
||||
if (off > 128) off=128;
|
||||
|
|
|
@ -320,6 +320,11 @@ typedef struct bn_recp_ctx_st
|
|||
|
||||
#define BN_one(a) (BN_set_word((a),1))
|
||||
#define BN_zero(a) (BN_set_word((a),0))
|
||||
/* BN_set_sign(BIGNUM *, int) sets the sign of a BIGNUM
|
||||
* (0 for a non-negative value, 1 for negative) */
|
||||
#define BN_set_sign(a,b) ((a)->neg = (b))
|
||||
/* BN_get_sign(BIGNUM *) returns the sign of the BIGNUM */
|
||||
#define BN_get_sign(a) ((a)->neg)
|
||||
|
||||
/*#define BN_ascii2bn(a) BN_hex2bn(a) */
|
||||
/*#define BN_bn2ascii(a) BN_bn2hex(a) */
|
||||
|
@ -470,37 +475,54 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
|
|||
|
||||
/* Functions for arithmetic over binary polynomials represented by BIGNUMs.
|
||||
*
|
||||
* The BIGNUM::neg property of BIGNUMs representing binary polynomials is ignored.
|
||||
* 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 */
|
||||
|
||||
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 */
|
||||
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);
|
||||
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);
|
||||
|
||||
/* faster mod functions for the 'NIST primes'
|
||||
* 0 <= a < p^2 */
|
||||
|
|
|
@ -246,12 +246,14 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
|
|||
BN_init(&u2);
|
||||
BN_init(&t1);
|
||||
|
||||
if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
|
||||
if (BN_is_zero(sig->r) || BN_get_sign(sig->r) ||
|
||||
BN_ucmp(sig->r, dsa->q) >= 0)
|
||||
{
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
|
||||
if (BN_is_zero(sig->s) || BN_get_sign(sig->s) ||
|
||||
BN_ucmp(sig->s, dsa->q) >= 0)
|
||||
{
|
||||
ret = 0;
|
||||
goto err;
|
||||
|
|
|
@ -297,8 +297,8 @@ static int point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scal
|
|||
}
|
||||
|
||||
/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
|
||||
r->X.neg = 0;
|
||||
r->Y.neg = 0;
|
||||
BN_set_sign(&r->X, 0);
|
||||
BN_set_sign(&r->Y, 0);
|
||||
|
||||
ret = 1;
|
||||
|
||||
|
@ -342,14 +342,16 @@ int ec_GF2m_mont_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
if (scalar)
|
||||
{
|
||||
if (!point_multiply(group, p, scalar, group->generator, ctx)) goto err;
|
||||
if (scalar->neg) if (!group->meth->invert(group, p, ctx)) goto err;
|
||||
if (BN_get_sign(scalar))
|
||||
if (!group->meth->invert(group, p, ctx)) goto err;
|
||||
if (!group->meth->add(group, r, r, p, ctx)) goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (!point_multiply(group, p, scalars[i], points[i], ctx)) goto err;
|
||||
if (scalars[i]->neg) if (!group->meth->invert(group, p, ctx)) goto err;
|
||||
if (BN_get_sign(scalars[i]))
|
||||
if (!group->meth->invert(group, p, ctx)) goto err;
|
||||
if (!group->meth->add(group, r, r, p, ctx)) goto err;
|
||||
}
|
||||
|
||||
|
|
|
@ -349,11 +349,11 @@ int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT
|
|||
}
|
||||
|
||||
if (!BN_copy(&point->X, x)) goto err;
|
||||
point->X.neg = 0;
|
||||
BN_set_sign(&point->X, 0);
|
||||
if (!BN_copy(&point->Y, y)) goto err;
|
||||
point->Y.neg = 0;
|
||||
BN_set_sign(&point->Y, 0);
|
||||
if (!BN_copy(&point->Z, BN_value_one())) goto err;
|
||||
point->Z.neg = 0;
|
||||
BN_set_sign(&point->Z, 0);
|
||||
point->Z_is_one = 1;
|
||||
ret = 1;
|
||||
|
||||
|
@ -384,12 +384,12 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_
|
|||
if (x != NULL)
|
||||
{
|
||||
if (!BN_copy(x, &point->X)) goto err;
|
||||
x->neg = 0;
|
||||
BN_set_sign(x, 0);
|
||||
}
|
||||
if (y != NULL)
|
||||
{
|
||||
if (!BN_copy(y, &point->Y)) goto err;
|
||||
y->neg = 0;
|
||||
BN_set_sign(y, 0);
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
|
|||
next_bit = bit << 1; /* at most 256 */
|
||||
mask = next_bit - 1; /* at most 255 */
|
||||
|
||||
if (scalar->neg)
|
||||
if (BN_get_sign(scalar))
|
||||
{
|
||||
sign = -1;
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
|||
|
||||
/* group->field */
|
||||
if (!BN_copy(&group->field, p)) goto err;
|
||||
group->field.neg = 0;
|
||||
BN_set_sign(&group->field, 0);
|
||||
|
||||
/* group->a */
|
||||
if (!group->field_mod_func(&group->a, a, p, ctx)) goto err;
|
||||
|
|
|
@ -177,7 +177,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group,
|
|||
|
||||
/* group->field */
|
||||
if (!BN_copy(&group->field, p)) goto err;
|
||||
group->field.neg = 0;
|
||||
BN_set_sign(&group->field, 0);
|
||||
|
||||
/* group->a */
|
||||
if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
|
||||
|
|
|
@ -603,7 +603,7 @@ void prime_field_tests()
|
|||
|
||||
if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
|
||||
if (!BN_add(z, z, y)) ABORT;
|
||||
z->neg = 1;
|
||||
BN_set_sign(z, 1);
|
||||
scalars[0] = y;
|
||||
scalars[1] = z; /* z = -(order + y) */
|
||||
|
||||
|
@ -615,7 +615,7 @@ void prime_field_tests()
|
|||
|
||||
if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
|
||||
if (!BN_add(z, x, y)) ABORT;
|
||||
z->neg = 1;
|
||||
BN_set_sign(z, 1);
|
||||
scalars[0] = x;
|
||||
scalars[1] = y;
|
||||
scalars[2] = z; /* z = -(x+y) */
|
||||
|
@ -1069,7 +1069,7 @@ void char2_field_tests()
|
|||
|
||||
if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
|
||||
if (!BN_add(z, z, y)) ABORT;
|
||||
z->neg = 1;
|
||||
BN_set_sign(z, 1);
|
||||
scalars[0] = y;
|
||||
scalars[1] = z; /* z = -(order + y) */
|
||||
|
||||
|
@ -1081,7 +1081,7 @@ void char2_field_tests()
|
|||
|
||||
if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
|
||||
if (!BN_add(z, x, y)) ABORT;
|
||||
z->neg = 1;
|
||||
BN_set_sign(z, 1);
|
||||
scalars[0] = x;
|
||||
scalars[1] = y;
|
||||
scalars[2] = z; /* z = -(x+y) */
|
||||
|
|
|
@ -353,13 +353,15 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, order) >= 0)
|
||||
if (BN_is_zero(sig->r) || BN_get_sign(sig->r) ||
|
||||
BN_ucmp(sig->r, order) >= 0)
|
||||
{
|
||||
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, order) >= 0)
|
||||
if (BN_is_zero(sig->s) || BN_get_sign(sig->s) ||
|
||||
BN_ucmp(sig->s, order) >= 0)
|
||||
{
|
||||
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
|
||||
ret = 0;
|
||||
|
|
|
@ -546,7 +546,7 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
|
|||
if (!BN_sub(r0,r0,&m1)) goto err;
|
||||
/* This will help stop the size of r0 increasing, which does
|
||||
* affect the multiply if it optimised for a power of 2 size */
|
||||
if (r0->neg)
|
||||
if (BN_get_sign(r0))
|
||||
if (!BN_add(r0,r0,rsa->p)) goto err;
|
||||
|
||||
if (!BN_mul(&r1,r0,rsa->iqmp,ctx)) goto err;
|
||||
|
@ -558,7 +558,7 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
|
|||
* This will *never* happen with OpenSSL generated keys because
|
||||
* they ensure p > q [steve]
|
||||
*/
|
||||
if (r0->neg)
|
||||
if (BN_get_sign(r0))
|
||||
if (!BN_add(r0,r0,rsa->p)) goto err;
|
||||
if (!BN_mul(&r1,r0,rsa->q,ctx)) goto err;
|
||||
if (!BN_add(r0,&r1,&m1)) goto err;
|
||||
|
@ -572,7 +572,7 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
|
|||
* for absolute equality, just congruency. */
|
||||
if (!BN_sub(&vrfy, &vrfy, I)) goto err;
|
||||
if (!BN_mod(&vrfy, &vrfy, rsa->n, ctx)) goto err;
|
||||
if (vrfy.neg)
|
||||
if (BN_get_sign(&vrfy))
|
||||
if (!BN_add(&vrfy, &vrfy, rsa->n)) goto err;
|
||||
if (!BN_is_zero(&vrfy))
|
||||
/* 'I' and 'vrfy' aren't congruent mod n. Don't leak
|
||||
|
|
Loading…
Reference in a new issue