Initial support for pluggable public key ASN1 support. Process most public
[openssl.git] / crypto / ec / ecp_smpl.c
index 7325abf52055b4b2e5b9a6e3fc721d9df6b422c8..4d26f8bdf6921f4ae9a9e5be06fbde3f54b55628 100644 (file)
@@ -94,13 +94,14 @@ 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,
                ec_GFp_simple_make_affine,
                ec_GFp_simple_points_make_affine,
+               0 /* mul */,
+               0 /* precompute_mult */,
+               0 /* have_precompute_mult */,   
                ec_GFp_simple_field_mul,
                ec_GFp_simple_field_sqr,
                0 /* field_div */,
@@ -112,6 +113,20 @@ const EC_METHOD *EC_GFp_simple_method(void)
        }
 
 
+/* Most method functions in this file are designed to work with
+ * non-trivial representations of field elements if necessary
+ * (see ecp_mont.c): while standard modular addition and subtraction
+ * are used, the field_mul and field_sqr methods will be used for
+ * multiplication, and field_encode and field_decode (if defined)
+ * will be used for converting between representations.
+
+ * Functions ec_GFp_simple_points_make_affine() and
+ * ec_GFp_simple_point_get_affine_coordinates() specifically assume
+ * that if a non-trivial representation is used, it is a Montgomery
+ * representation (i.e. 'encoding' means multiplying by some factor R).
+ */
+
+
 int ec_GFp_simple_group_init(EC_GROUP *group)
        {
        BN_init(&group->field);
@@ -177,7 +192,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group,
 
        /* group->field */
        if (!BN_copy(&group->field, p)) goto err;
-       BN_set_sign(&group->field, 0);
+       BN_set_negative(&group->field, 0);
 
        /* group->a */
        if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
@@ -321,7 +336,8 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
        ret = 1;
 
 err:
-       BN_CTX_end(ctx);
+       if (ctx != NULL)
+               BN_CTX_end(ctx);
        if (new_ctx != NULL)
                BN_CTX_free(new_ctx);
        return ret;
@@ -370,7 +386,8 @@ int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
 int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
        {
        point->Z_is_one = 0;
-       return (BN_zero(&point->Z));
+       BN_zero(&point->Z);
+       return 1;
        }
 
 
@@ -624,6 +641,9 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *po
        BIGNUM *tmp1, *tmp2, *x, *y;
        int ret = 0;
 
+       /* clear error queue*/
+       ERR_clear_error();
+
        if (ctx == NULL)
                {
                ctx = new_ctx = BN_CTX_new();
@@ -695,11 +715,11 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *po
        
        if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
                {
-               unsigned long err = ERR_peek_error();
+               unsigned long err = ERR_peek_last_error();
                
                if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
                        {
-                       (void)ERR_get_error();
+                       ERR_clear_error();
                        ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
                        }
                else
@@ -886,7 +906,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
                }
        form = buf[0];
        y_bit = form & 1;
-       form = form & ~1;
+       form = form & ~1U;
        if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
                && (form != POINT_CONVERSION_UNCOMPRESSED)
                && (form != POINT_CONVERSION_HYBRID))
@@ -1078,7 +1098,7 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, con
                else
                        {
                        /* a is the inverse of b */
-                       if (!BN_zero(&r->Z)) goto end;
+                       BN_zero(&r->Z);
                        r->Z_is_one = 0;
                        ret = 1;
                        goto end;
@@ -1154,7 +1174,7 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_
        
        if (EC_POINT_is_at_infinity(group, a))
                {
-               if (!BN_zero(&r->Z)) return 0;
+               BN_zero(&r->Z);
                r->Z_is_one = 0;
                return 1;
                }
@@ -1282,7 +1302,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C
        int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
        const BIGNUM *p;
        BN_CTX *new_ctx = NULL;
-       BIGNUM *rh, *tmp1, *tmp2, *Z4, *Z6;
+       BIGNUM *rh, *tmp, *Z4, *Z6;
        int ret = -1;
 
        if (EC_POINT_is_at_infinity(group, point))
@@ -1301,8 +1321,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C
 
        BN_CTX_start(ctx);
        rh = BN_CTX_get(ctx);
-       tmp1 = BN_CTX_get(ctx);
-       tmp2 = BN_CTX_get(ctx);
+       tmp = BN_CTX_get(ctx);
        Z4 = BN_CTX_get(ctx);
        Z6 = BN_CTX_get(ctx);
        if (Z6 == NULL) goto err;
@@ -1316,59 +1335,49 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C
         * To test this, we add up the right-hand side in 'rh'.
         */
 
-       /* rh := X^3 */
+       /* rh := X^2 */
        if (!field_sqr(group, rh, &point->X, ctx)) goto err;
-       if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
 
        if (!point->Z_is_one)
                {
-               if (!field_sqr(group, tmp1, &point->Z, ctx)) goto err;
-               if (!field_sqr(group, Z4, tmp1, ctx)) goto err;
-               if (!field_mul(group, Z6, Z4, tmp1, ctx)) goto err;
+               if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;
+               if (!field_sqr(group, Z4, tmp, ctx)) goto err;
+               if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;
 
-               /* rh := rh + a*X*Z^4 */
-               if (!field_mul(group, tmp1, &point->X, Z4, ctx)) goto err;
+               /* rh := (rh + a*Z^4)*X */
                if (group->a_is_minus3)
                        {
-                       if (!BN_mod_lshift1_quick(tmp2, tmp1, p)) goto err;
-                       if (!BN_mod_add_quick(tmp2, tmp2, tmp1, p)) goto err;
-                       if (!BN_mod_sub_quick(rh, rh, tmp2, p)) goto err;
+                       if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;
+                       if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;
+                       if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;
+                       if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
                        }
                else
                        {
-                       if (!field_mul(group, tmp2, tmp1, &group->a, ctx)) goto err;
-                       if (!BN_mod_add_quick(rh, rh, tmp2, p)) goto err;
+                       if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;
+                       if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
+                       if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
                        }
 
                /* rh := rh + b*Z^6 */
-               if (!field_mul(group, tmp1, &group->b, Z6, ctx)) goto err;
-               if (!BN_mod_add_quick(rh, rh, tmp1, p)) goto err;
+               if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;
+               if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
                }
        else
                {
                /* point->Z_is_one */
 
-               /* rh := rh + a*X */
-               if (group->a_is_minus3)
-                       {
-                       if (!BN_mod_lshift1_quick(tmp2, &point->X, p)) goto err;
-                       if (!BN_mod_add_quick(tmp2, tmp2, &point->X, p)) goto err;
-                       if (!BN_mod_sub_quick(rh, rh, tmp2, p)) goto err;
-                       }
-               else
-                       {
-                       if (!field_mul(group, tmp2, &point->X, &group->a, ctx)) goto err;
-                       if (!BN_mod_add_quick(rh, rh, tmp2, p)) goto err;
-                       }
-
+               /* rh := (rh + a)*X */
+               if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;
+               if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
                /* rh := rh + b */
                if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
                }
 
        /* 'lh' := Y^2 */
-       if (!field_sqr(group, tmp1, &point->Y, ctx)) goto err;
+       if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;
 
-       ret = (0 == BN_cmp(tmp1, rh));
+       ret = (0 == BN_ucmp(tmp, rh));
 
  err:
        BN_CTX_end(ctx);