Commit b6db386f authored by Bodo Möller's avatar Bodo Möller
Browse files

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.
parent 2c975b50
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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).
+7 −7
Original line number Diff line number Diff line
@@ -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
+15 −22
Original line number Diff line number Diff line
@@ -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 *);
+91 −44
Original line number Diff line number Diff line
@@ -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);
		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; }	

int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
	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)
	{
	if (group->meth->group_get_curve_GFp == 0)
	return group->generator;
	}


int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
	{
		ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
	if (!BN_copy(order, &group->order))
		return 0;
		}
	return group->meth->group_get_curve_GFp(group, p, a, b, ctx);

	return !BN_is_zero(order);
	}


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)
int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
	{
		ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
	if (!BN_copy(cofactor, &group->cofactor))
		return 0;
		}
	return group->meth->group_set_generator(group, generator, order, cofactor);

	return !BN_is_zero(&group->cofactor);
	}


EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
	{
	if (group->meth->group_get0_generator == 0)
void EC_GROUP_set_nid(EC_GROUP *group, int nid)
	{
		ECerr(EC_F_EC_GROUP_GET0_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		return 0;
	group->nid = nid;
	}
	return group->meth->group_get0_generator(group);


int EC_GROUP_get_nid(const EC_GROUP *group)
	{
	return group->nid;
	}


int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, 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_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 *))
+0 −4
Original line number Diff line number Diff line
@@ -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,
Loading