new function EC_GROUP_cmp() (used by EVP_PKEY_cmp())
authorBodo Möller <bodo@openssl.org>
Mon, 21 Jul 2003 13:43:28 +0000 (13:43 +0000)
committerBodo Möller <bodo@openssl.org>
Mon, 21 Jul 2003 13:43:28 +0000 (13:43 +0000)
Submitted by: Nils Larsch

crypto/ec/ec.h
crypto/ec/ec_lib.c
crypto/evp/p_lib.c

index 431a28b38f9763608f8039566023430c5df40a9c..dcffc8c049049e077ae9cedd38d4fd26e9376746 100644 (file)
@@ -166,6 +166,9 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
  * elliptic curve is not zero, 0 otherwise */
 int EC_GROUP_check_discriminant(const EC_GROUP *, BN_CTX *);
 
+/* EC_GROUP_cmp() returns 0 if both groups are equal and 1 otherwise */
+int EC_GROUP_cmp(const EC_GROUP *, const EC_GROUP *, BN_CTX *);
+
 /* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
  * after choosing an appropriate EC_METHOD */
 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
index c00875cd73e9483ea3b0fc9cd2b827fdbdb502b0..b3ef05659ada196f0213ff1c4dcd7777e5a9429f 100644 (file)
@@ -470,6 +470,81 @@ int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
        }
 
 
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
+       {
+       int    r = 0;
+       BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
+       BN_CTX *ctx_new = NULL;
+
+       /* compare the field types*/
+       if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
+           EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
+               return 1;
+       /* compare the curve name (if present) */
+       if (EC_GROUP_get_nid(a) && EC_GROUP_get_nid(b) &&
+           EC_GROUP_get_nid(a) == EC_GROUP_get_nid(b))
+               return 0;
+
+       if (!ctx)
+               ctx_new = ctx = BN_CTX_new();
+       if (!ctx)
+               return -1;
+       
+       BN_CTX_start(ctx);
+       a1 = BN_CTX_get(ctx);
+       a2 = BN_CTX_get(ctx);
+       a3 = BN_CTX_get(ctx);
+       b1 = BN_CTX_get(ctx);
+       b2 = BN_CTX_get(ctx);
+       b3 = BN_CTX_get(ctx);
+       if (!b3)
+               {
+               BN_CTX_end(ctx);
+               if (ctx_new)
+                       BN_CTX_free(ctx);
+               return -1;
+               }
+
+       /* XXX This approach assumes that the external representation
+        * of curves over the same field type is the same.
+        */
+       if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
+           !b->meth->group_get_curve(b, b1, b2, b3, ctx))
+               r = 1;
+
+       if (r || BN_cmp(a1, b2) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
+               r = 1;
+
+       /* XXX EC_POINT_cmp() assumes that the methods are equal */
+       if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
+           EC_GROUP_get0_generator(b), ctx))
+               r = 1;
+
+       if (!r)
+               {
+               /* compare the order and cofactor */
+               if (!EC_GROUP_get_order(a, a1, ctx) ||
+                   !EC_GROUP_get_order(b, b1, ctx) ||
+                   !EC_GROUP_get_cofactor(a, a2, ctx) ||
+                   !EC_GROUP_get_cofactor(b, b2, ctx))
+                       {
+                       BN_CTX_end(ctx);
+                       if (ctx_new)
+                               BN_CTX_free(ctx);
+                       return -1;
+                       }
+               if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
+                       r = 1;
+               }
+
+       BN_CTX_end(ctx);
+       if (ctx_new)
+               BN_CTX_free(ctx);
+
+       return r;
+       }
+
+
 /* this has 'package' visibility */
 int EC_GROUP_set_extra_data(EC_GROUP *group, void *data,
        void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
index 730ef4d0a90470a33b525cfe5b76c3d0ec544ab3..d6d7234cd5d41b6c57d690692e63c68dc9155083 100644 (file)
@@ -233,6 +233,15 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
                else
                        return(1);
                }
+#endif
+#ifndef OPENSSL_NO_EC
+       if (a->type == EVP_PKEY_EC && b->type == EVP_PKEY_EC)
+               {
+               if (EC_GROUP_cmp(a->pkey.eckey->group, b->pkey.eckey->group, NULL))
+                       return 0;
+               else
+                       return 1;
+               }
 #endif
        return(-1);
        }