From: Bodo Möller Date: Wed, 8 May 2002 11:54:24 +0000 (+0000) Subject: Change internals of the EC library so that the functions X-Git-Tag: BEFORE_COMPAQ_PATCH~27 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=b6db386ffd66f9227989df64ebedd95bc61597de Change internals of the EC library so that the functions EC_GROUP_{set_generator,get_generator,get_order,get_cofactor} are implemented directly in crypto/ec/ec_lib.c and not dispatched to methods. Also fix EC_GROUP_copy to copy the NID. --- diff --git a/CHANGES b/CHANGES index d8b1b629bc..ed2bcead6c 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,16 @@ Changes between 0.9.7 and 0.9.8 [xx XXX 2002] + *) Change internals of the EC library so that the functions + EC_GROUP_set_generator() + EC_GROUP_get_generator() + EC_GROUP_get_order() + EC_GROUP_get_cofactor() + are implemented directly in crypto/ec/ec_lib.c and not dispatched + to methods, which would lead to unnecessary code duplication when + adding different types of curves. + [Nils Larsch with input by Bodo Moeller] + *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM arithmetic, and such that modified wNAFs are generated (which avoid length expansion in many cases). diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h index 05b454c921..6baf39cfa6 100644 --- a/crypto/ec/ec.h +++ b/crypto/ec/ec.h @@ -107,11 +107,16 @@ void EC_GROUP_free(EC_GROUP *); void EC_GROUP_clear_free(EC_GROUP *); int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *); +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); + +int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); +EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *); +int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *); +int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *); + void EC_GROUP_set_nid(EC_GROUP *, int); int EC_GROUP_get_nid(const EC_GROUP *); -const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); - /* We don't have types for field specifications and field elements in general. * Otherwise we could declare @@ -120,11 +125,6 @@ const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); -int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); -EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *); -int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *); -int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *); - /* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); /* EC_GROUP_check_discriminant() returns 1 if the discriminant of the diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index ece0de852c..79655e3d3a 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -73,15 +73,6 @@ struct ec_method_st { int (*group_set_curve_GFp)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int (*group_get_curve_GFp)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); - /* used by EC_GROUP_set_generator, EC_GROUP_get0_generator, - * EC_GROUP_get_order, EC_GROUP_get_cofactor: - */ - int (*group_set_generator)(EC_GROUP *, const EC_POINT *generator, - const BIGNUM *order, const BIGNUM *cofactor); - EC_POINT *(*group_get0_generator)(const EC_GROUP *); - int (*group_get_order)(const EC_GROUP *, BIGNUM *order, BN_CTX *); - int (*group_get_cofactor)(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *); - /* used by EC_GROUP_check: */ int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *); @@ -146,16 +137,24 @@ struct ec_method_st { struct ec_group_st { const EC_METHOD *meth; + EC_POINT *generator; /* optional */ + BIGNUM order, cofactor; + + int nid; /* optional NID for named curve */ + void *extra_data; void *(*extra_data_dup_func)(void *); void (*extra_data_free_func)(void *); void (*extra_data_clear_free_func)(void *); - /* All members except 'meth' and 'extra_data...' are handled by - * the method functions, even if they appear generic */ + /* The following members are handled by the method functions, + * even if they appear generic */ BIGNUM field; /* Field specification. - * For curves over GF(p), this is the modulus. */ + * For curves over GF(p), this is the modulus; + * for curves over GF(2^m), this is the + * irreducible polynomial defining the field. + */ BIGNUM a, b; /* Curve coefficients. * (Here the assumption is that BIGNUMs can be used @@ -163,13 +162,12 @@ struct ec_group_st { * For characteristic > 3, the curve is defined * by a Weierstrass equation of the form * y^2 = x^3 + a*x + b. + * For characteristic 2, the curve is defined by + * an equation of the form + * y^2 + x*y = x^3 + a*x^2 + b. */ - int a_is_minus3; /* enable optimized point arithmetics for special case */ - - EC_POINT *generator; /* optional */ - BIGNUM order, cofactor; - int nid; + int a_is_minus3; /* enable optimized point arithmetics for special case */ void *field_data1; /* method-specific (e.g., Montgomery structure) */ void *field_data2; /* method-specific */ @@ -213,11 +211,6 @@ void ec_GFp_simple_group_clear_finish(EC_GROUP *); int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); int ec_GFp_simple_group_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int ec_GFp_simple_group_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); -int ec_GFp_simple_group_set_generator(EC_GROUP *, const EC_POINT *generator, - const BIGNUM *order, const BIGNUM *cofactor); -EC_POINT *ec_GFp_simple_group_get0_generator(const EC_GROUP *); -int ec_GFp_simple_group_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *); -int ec_GFp_simple_group_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *); int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); int ec_GFp_simple_point_init(EC_POINT *); void ec_GFp_simple_point_finish(EC_POINT *); diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index a5153cd4bf..0597087cb7 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -94,6 +94,10 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) ret->extra_data_free_func = 0; ret->extra_data_clear_free_func = 0; + ret->generator = NULL; + BN_init(&ret->order); + BN_init(&ret->cofactor); + ret->nid = 0; if (!meth->group_init(ret)) @@ -113,6 +117,11 @@ void EC_GROUP_free(EC_GROUP *group) EC_GROUP_free_extra_data(group); + if (group->generator != NULL) + EC_POINT_free(group->generator); + BN_free(&group->order); + BN_free(&group->cofactor); + OPENSSL_free(group); } @@ -126,6 +135,11 @@ void EC_GROUP_clear_free(EC_GROUP *group) EC_GROUP_clear_free_extra_data(group); + if (group->generator != NULL) + EC_POINT_clear_free(group->generator); + BN_clear_free(&group->order); + BN_clear_free(&group->cofactor); + memset(group, 0, sizeof *group); OPENSSL_free(group); } @@ -161,6 +175,30 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) dest->extra_data_clear_free_func = src->extra_data_clear_free_func; } + if (src->generator != NULL) + { + if (dest->generator == NULL) + { + dest->generator = EC_POINT_new(dest); + if (dest->generator == NULL) return 0; + } + if (!EC_POINT_copy(dest->generator, src->generator)) return 0; + } + else + { + /* src->generator == NULL */ + if (dest->generator != NULL) + { + EC_POINT_clear_free(dest->generator); + dest->generator = NULL; + } + } + + if (!BN_copy(&dest->order, &src->order)) return 0; + if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0; + + dest->nid = src->nid; + return dest->meth->group_copy(dest, src); } @@ -171,69 +209,90 @@ const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) } -int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor) { - if (group->meth->group_set_curve_GFp == 0) + if (generator == NULL) { - ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); + return 0 ; } - return group->meth->group_set_curve_GFp(group, p, a, b, ctx); + + if (group->generator == NULL) + { + group->generator = EC_POINT_new(group); + if (group->generator == NULL) return 0; + } + if (!EC_POINT_copy(group->generator, generator)) return 0; + + if (order != NULL) + { if (!BN_copy(&group->order, order)) return 0; } + else + { if (!BN_zero(&group->order)) return 0; } + + if (cofactor != NULL) + { if (!BN_copy(&group->cofactor, cofactor)) return 0; } + else + { if (!BN_zero(&group->cofactor)) return 0; } + + return 1; } -int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) +EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) { - if (group->meth->group_get_curve_GFp == 0) - { - ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - return group->meth->group_get_curve_GFp(group, p, a, b, ctx); + return group->generator; } -int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor) +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { - if (group->meth->group_set_generator == 0) - { - ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + if (!BN_copy(order, &group->order)) return 0; - } - return group->meth->group_set_generator(group, generator, order, cofactor); + + return !BN_is_zero(order); } -EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) { - if (group->meth->group_get0_generator == 0) - { - ECerr(EC_F_EC_GROUP_GET0_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + if (!BN_copy(cofactor, &group->cofactor)) return 0; - } - return group->meth->group_get0_generator(group); + + return !BN_is_zero(&group->cofactor); } -int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) +void EC_GROUP_set_nid(EC_GROUP *group, int nid) + { + group->nid = nid; + } + + +int EC_GROUP_get_nid(const EC_GROUP *group) + { + return group->nid; + } + + +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { - if (group->meth->group_get_order == 0) + if (group->meth->group_set_curve_GFp == 0) { - ECerr(EC_F_EC_GROUP_GET_ORDER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - return group->meth->group_get_order(group, order, ctx); + return group->meth->group_set_curve_GFp(group, p, a, b, ctx); } -int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) { - if (group->meth->group_get_cofactor == 0) + if (group->meth->group_get_curve_GFp == 0) { - ECerr(EC_F_EC_GROUP_GET_COFACTOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - return group->meth->group_get_cofactor(group, cofactor, ctx); + return group->meth->group_get_curve_GFp(group, p, a, b, ctx); } @@ -248,18 +307,6 @@ int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) } -void EC_GROUP_set_nid(EC_GROUP *group, int nid) - { - group->nid = nid; - } - - -int EC_GROUP_get_nid(const EC_GROUP *group) - { - return group->nid; - } - - /* this has 'package' visibility */ int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *), void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *)) diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c index bad0a13614..6f1eaa497b 100644 --- a/crypto/ec/ecp_mont.c +++ b/crypto/ec/ecp_mont.c @@ -67,10 +67,6 @@ const EC_METHOD *EC_GFp_mont_method(void) ec_GFp_mont_group_copy, ec_GFp_mont_group_set_curve_GFp, ec_GFp_simple_group_get_curve_GFp, - ec_GFp_simple_group_set_generator, - ec_GFp_simple_group_get0_generator, - ec_GFp_simple_group_get_order, - ec_GFp_simple_group_get_cofactor, ec_GFp_simple_group_check_discriminant, ec_GFp_simple_point_init, ec_GFp_simple_point_finish, diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c index 911a4e4760..5adc907d60 100644 --- a/crypto/ec/ecp_smpl.c +++ b/crypto/ec/ecp_smpl.c @@ -69,10 +69,6 @@ const EC_METHOD *EC_GFp_simple_method(void) ec_GFp_simple_group_copy, ec_GFp_simple_group_set_curve_GFp, ec_GFp_simple_group_get_curve_GFp, - ec_GFp_simple_group_set_generator, - ec_GFp_simple_group_get0_generator, - ec_GFp_simple_group_get_order, - ec_GFp_simple_group_get_cofactor, ec_GFp_simple_group_check_discriminant, ec_GFp_simple_point_init, ec_GFp_simple_point_finish, @@ -110,9 +106,6 @@ int ec_GFp_simple_group_init(EC_GROUP *group) BN_init(&group->a); BN_init(&group->b); group->a_is_minus3 = 0; - group->generator = NULL; - BN_init(&group->order); - BN_init(&group->cofactor); return 1; } @@ -122,10 +115,6 @@ void ec_GFp_simple_group_finish(EC_GROUP *group) BN_free(&group->field); BN_free(&group->a); BN_free(&group->b); - if (group->generator != NULL) - EC_POINT_free(group->generator); - BN_free(&group->order); - BN_free(&group->cofactor); } @@ -134,13 +123,6 @@ void ec_GFp_simple_group_clear_finish(EC_GROUP *group) BN_clear_free(&group->field); BN_clear_free(&group->a); BN_clear_free(&group->b); - if (group->generator != NULL) - { - EC_POINT_clear_free(group->generator); - group->generator = NULL; - } - BN_clear_free(&group->order); - BN_clear_free(&group->cofactor); } @@ -152,28 +134,6 @@ int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) dest->a_is_minus3 = src->a_is_minus3; - if (src->generator != NULL) - { - if (dest->generator == NULL) - { - dest->generator = EC_POINT_new(dest); - if (dest->generator == NULL) return 0; - } - if (!EC_POINT_copy(dest->generator, src->generator)) return 0; - } - else - { - /* src->generator == NULL */ - if (dest->generator != NULL) - { - EC_POINT_clear_free(dest->generator); - dest->generator = NULL; - } - } - - if (!BN_copy(&dest->order, &src->order)) return 0; - if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0; - return 1; } @@ -284,61 +244,6 @@ int ec_GFp_simple_group_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM * } - -int ec_GFp_simple_group_set_generator(EC_GROUP *group, const EC_POINT *generator, - const BIGNUM *order, const BIGNUM *cofactor) - { - if (generator == NULL) - { - ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); - return 0 ; - } - - if (group->generator == NULL) - { - group->generator = EC_POINT_new(group); - if (group->generator == NULL) return 0; - } - if (!EC_POINT_copy(group->generator, generator)) return 0; - - if (order != NULL) - { if (!BN_copy(&group->order, order)) return 0; } - else - { if (!BN_zero(&group->order)) return 0; } - - if (cofactor != NULL) - { if (!BN_copy(&group->cofactor, cofactor)) return 0; } - else - { if (!BN_zero(&group->cofactor)) return 0; } - - return 1; - } - - -EC_POINT *ec_GFp_simple_group_get0_generator(const EC_GROUP *group) - { - return group->generator; - } - - -int ec_GFp_simple_group_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) - { - if (!BN_copy(order, &group->order)) - return 0; - - return !BN_is_zero(&group->order); - } - - -int ec_GFp_simple_group_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) - { - if (!BN_copy(cofactor, &group->cofactor)) - return 0; - - return !BN_is_zero(&group->cofactor); - } - - int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) { int ret = 0;