Change internals of the EC library so that the functions
authorBodo Möller <bodo@openssl.org>
Wed, 8 May 2002 11:54:24 +0000 (11:54 +0000)
committerBodo Möller <bodo@openssl.org>
Wed, 8 May 2002 11:54:24 +0000 (11:54 +0000)
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.

CHANGES
crypto/ec/ec.h
crypto/ec/ec_lcl.h
crypto/ec/ec_lib.c
crypto/ec/ecp_mont.c
crypto/ec/ecp_smpl.c

diff --git a/CHANGES b/CHANGES
index d8b1b62..ed2bcea 100644 (file)
--- 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).
index 05b454c..6baf39c 100644 (file)
@@ -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
index ece0de8..79655e3 100644 (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_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 *);
index a5153cd..0597087 100644 (file)
@@ -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 *))
index bad0a13..6f1eaa4 100644 (file)
@@ -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,
index 911a4e4..5adc907 100644 (file)
@@ -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;