add support for elliptic curves over binary fields
[openssl.git] / crypto / ec / ecp_smpl.c
index 8e062dc95126e9c5e610855d4fb004f898172dc8..27b4472b71700eea505633f229797475f9907e30 100644 (file)
  * Hudson (tjh@cryptsoft.com).
  *
  */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
 
 #include <openssl/err.h>
+#include <openssl/symhacks.h>
 
 #include "ec_lcl.h"
 
-
 const EC_METHOD *EC_GFp_simple_method(void)
        {
        static const EC_METHOD ret = {
+               NID_X9_62_prime_field,
                ec_GFp_simple_group_init,
                ec_GFp_simple_group_finish,
                ec_GFp_simple_group_clear_finish,
                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,
+               ec_GFp_simple_group_get_degree,
+               ec_GFp_simple_group_check_discriminant,
                ec_GFp_simple_point_init,
                ec_GFp_simple_point_finish,
                ec_GFp_simple_point_clear_finish,
@@ -89,6 +92,8 @@ const EC_METHOD *EC_GFp_simple_method(void)
                ec_GFp_simple_add,
                ec_GFp_simple_dbl,
                ec_GFp_simple_invert,
+               0 /* mul */,
+               0 /* precompute_mult */,
                ec_GFp_simple_is_at_infinity,
                ec_GFp_simple_is_on_curve,
                ec_GFp_simple_cmp,
@@ -96,6 +101,7 @@ const EC_METHOD *EC_GFp_simple_method(void)
                ec_GFp_simple_points_make_affine,
                ec_GFp_simple_field_mul,
                ec_GFp_simple_field_sqr,
+               0 /* field_div */,
                0 /* field_encode */,
                0 /* field_decode */,
                0 /* field_set_to_one */ };
@@ -110,9 +116,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 +125,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 +133,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 +144,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,75 +254,25 @@ 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)
+int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
        {
-       if (!BN_copy(order, &group->order))
-               return 0;
-
-       return !BN_is_zero(&group->order);
+       return BN_num_bits(&group->field);
        }
 
 
-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(const EC_GROUP *group, BN_CTX *ctx)
+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
        {
        int ret = 0;
        BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
        const BIGNUM *p = &group->field;
        BN_CTX *new_ctx = NULL;
-       EC_POINT *point = NULL;
 
        if (ctx == NULL)
                {
                ctx = new_ctx = BN_CTX_new();
                if (ctx == NULL)
                        {
-                       ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
+                       ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
                        goto err;
                        }
                }
@@ -380,11 +300,7 @@ int ec_GFp_simple_group_check(const EC_GROUP *group, BN_CTX *ctx)
          * 0 =< a, b < p */
        if (BN_is_zero(a))
                {
-               if (BN_is_zero(b))
-                       {
-                       ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
-                       goto err;
-                       }
+               if (BN_is_zero(b)) goto err;
                }
        else if (!BN_is_zero(b))
                {
@@ -398,49 +314,14 @@ int ec_GFp_simple_group_check(const EC_GROUP *group, BN_CTX *ctx)
                /* tmp_2 = 27*b^2 */
 
                if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
-               if (BN_is_zero(a))
-                       {
-                       ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
-                       goto err;
-                       }
+               if (BN_is_zero(a)) goto err;
                }
-       
-       /* check the generator */
-       if (group->generator == NULL)
-               {
-               ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
-               goto err;
-               }
-       if (!ec_GFp_simple_is_on_curve(group, group->generator, ctx))
-               {
-               ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
-               goto err;
-               }
-
-       /* check the order of the generator */
-       if ((point = EC_POINT_new(group)) == NULL) goto err;
-       if (!EC_GROUP_get_order(group, order, ctx)) goto err; 
-       if (BN_is_zero(order))
-               {
-               ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
-               goto err;
-               }
-       
-       if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) goto err;
-       if (!EC_POINT_is_at_infinity(group, point))
-               {
-               ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
-               goto err;
-               }
-
        ret = 1;
 
 err:
        BN_CTX_end(ctx);
        if (new_ctx != NULL)
                BN_CTX_free(new_ctx);
-       if (point)
-               EC_POINT_free(point);
        return ret;
        }