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

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.
上级 2c975b50
......@@ -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).
......
......@@ -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
......
......@@ -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 *);
......
......@@ -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 *))
......
......@@ -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,
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册