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.
This commit is contained in:
Bodo Möller 2002-05-08 11:54:24 +00:00
parent 2c975b501d
commit b6db386ffd
6 changed files with 135 additions and 184 deletions

10
CHANGES
View File

@ -4,6 +4,16 @@
Changes between 0.9.7 and 0.9.8 [xx XXX 2002] 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 *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM
arithmetic, and such that modified wNAFs are generated arithmetic, and such that modified wNAFs are generated
(which avoid length expansion in many cases). (which avoid length expansion in many cases).

View File

@ -107,11 +107,16 @@ void EC_GROUP_free(EC_GROUP *);
void EC_GROUP_clear_free(EC_GROUP *); void EC_GROUP_clear_free(EC_GROUP *);
int EC_GROUP_copy(EC_GROUP *, const 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); void EC_GROUP_set_nid(EC_GROUP *, int);
int EC_GROUP_get_nid(const EC_GROUP *); 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. /* We don't have types for field specifications and field elements in general.
* Otherwise we could declare * 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_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_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 */ /* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */
int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
/* EC_GROUP_check_discriminant() returns 1 if the discriminant of the /* EC_GROUP_check_discriminant() returns 1 if the discriminant of the

View File

@ -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_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 *); 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: */ /* used by EC_GROUP_check: */
int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *); int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
@ -146,16 +137,24 @@ struct ec_method_st {
struct ec_group_st { struct ec_group_st {
const EC_METHOD *meth; const EC_METHOD *meth;
EC_POINT *generator; /* optional */
BIGNUM order, cofactor;
int nid; /* optional NID for named curve */
void *extra_data; void *extra_data;
void *(*extra_data_dup_func)(void *); void *(*extra_data_dup_func)(void *);
void (*extra_data_free_func)(void *); void (*extra_data_free_func)(void *);
void (*extra_data_clear_free_func)(void *); void (*extra_data_clear_free_func)(void *);
/* All members except 'meth' and 'extra_data...' are handled by /* The following members are handled by the method functions,
* the method functions, even if they appear generic */ * even if they appear generic */
BIGNUM field; /* Field specification. 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. BIGNUM a, b; /* Curve coefficients.
* (Here the assumption is that BIGNUMs can be used * (Here the assumption is that BIGNUMs can be used
@ -163,14 +162,13 @@ struct ec_group_st {
* For characteristic > 3, the curve is defined * For characteristic > 3, the curve is defined
* by a Weierstrass equation of the form * by a Weierstrass equation of the form
* y^2 = x^3 + a*x + b. * 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 */ int a_is_minus3; /* enable optimized point arithmetics for special case */
EC_POINT *generator; /* optional */
BIGNUM order, cofactor;
int nid;
void *field_data1; /* method-specific (e.g., Montgomery structure) */ void *field_data1; /* method-specific (e.g., Montgomery structure) */
void *field_data2; /* method-specific */ void *field_data2; /* method-specific */
} /* EC_GROUP */; } /* EC_GROUP */;
@ -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_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_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_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_group_check_discriminant(const EC_GROUP *, BN_CTX *);
int ec_GFp_simple_point_init(EC_POINT *); int ec_GFp_simple_point_init(EC_POINT *);
void ec_GFp_simple_point_finish(EC_POINT *); void ec_GFp_simple_point_finish(EC_POINT *);

View File

@ -94,6 +94,10 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
ret->extra_data_free_func = 0; ret->extra_data_free_func = 0;
ret->extra_data_clear_free_func = 0; ret->extra_data_clear_free_func = 0;
ret->generator = NULL;
BN_init(&ret->order);
BN_init(&ret->cofactor);
ret->nid = 0; ret->nid = 0;
if (!meth->group_init(ret)) if (!meth->group_init(ret))
@ -113,6 +117,11 @@ void EC_GROUP_free(EC_GROUP *group)
EC_GROUP_free_extra_data(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); OPENSSL_free(group);
} }
@ -126,6 +135,11 @@ void EC_GROUP_clear_free(EC_GROUP *group)
EC_GROUP_clear_free_extra_data(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); memset(group, 0, sizeof *group);
OPENSSL_free(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; 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); return dest->meth->group_copy(dest, src);
} }
@ -171,6 +209,71 @@ const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
} }
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
{
if (generator == NULL)
{
ECerr(EC_F_EC_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_GROUP_get0_generator(const EC_GROUP *group)
{
return group->generator;
}
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
{
if (!BN_copy(order, &group->order))
return 0;
return !BN_is_zero(order);
}
int EC_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);
}
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) 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_set_curve_GFp == 0) if (group->meth->group_set_curve_GFp == 0)
@ -193,50 +296,6 @@ int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *
} }
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
{
if (group->meth->group_set_generator == 0)
{
ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_set_generator(group, generator, order, cofactor);
}
EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
{
if (group->meth->group_get0_generator == 0)
{
ECerr(EC_F_EC_GROUP_GET0_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_get0_generator(group);
}
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
{
if (group->meth->group_get_order == 0)
{
ECerr(EC_F_EC_GROUP_GET_ORDER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_get_order(group, order, ctx);
}
int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
{
if (group->meth->group_get_cofactor == 0)
{
ECerr(EC_F_EC_GROUP_GET_COFACTOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_get_cofactor(group, cofactor, ctx);
}
int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
{ {
if (group->meth->group_check_discriminant == 0) if (group->meth->group_check_discriminant == 0)
@ -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 */ /* this has 'package' visibility */
int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *), 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 *)) void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))

View File

@ -67,10 +67,6 @@ const EC_METHOD *EC_GFp_mont_method(void)
ec_GFp_mont_group_copy, ec_GFp_mont_group_copy,
ec_GFp_mont_group_set_curve_GFp, ec_GFp_mont_group_set_curve_GFp,
ec_GFp_simple_group_get_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_group_check_discriminant,
ec_GFp_simple_point_init, ec_GFp_simple_point_init,
ec_GFp_simple_point_finish, ec_GFp_simple_point_finish,

View File

@ -69,10 +69,6 @@ const EC_METHOD *EC_GFp_simple_method(void)
ec_GFp_simple_group_copy, ec_GFp_simple_group_copy,
ec_GFp_simple_group_set_curve_GFp, ec_GFp_simple_group_set_curve_GFp,
ec_GFp_simple_group_get_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_group_check_discriminant,
ec_GFp_simple_point_init, ec_GFp_simple_point_init,
ec_GFp_simple_point_finish, 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->a);
BN_init(&group->b); BN_init(&group->b);
group->a_is_minus3 = 0; group->a_is_minus3 = 0;
group->generator = NULL;
BN_init(&group->order);
BN_init(&group->cofactor);
return 1; return 1;
} }
@ -122,10 +115,6 @@ void ec_GFp_simple_group_finish(EC_GROUP *group)
BN_free(&group->field); BN_free(&group->field);
BN_free(&group->a); BN_free(&group->a);
BN_free(&group->b); 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->field);
BN_clear_free(&group->a); BN_clear_free(&group->a);
BN_clear_free(&group->b); 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; 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; 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 ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
{ {
int ret = 0; int ret = 0;