| Index: openssl/crypto/ec/ec2_smpl.c
|
| ===================================================================
|
| --- openssl/crypto/ec/ec2_smpl.c (revision 105093)
|
| +++ openssl/crypto/ec/ec2_smpl.c (working copy)
|
| @@ -14,7 +14,7 @@
|
| *
|
| */
|
| /* ====================================================================
|
| - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
|
| + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
|
| *
|
| * Redistribution and use in source and binary forms, with or without
|
| * modification, are permitted provided that the following conditions
|
| @@ -157,6 +157,7 @@
|
| group->poly[2] = 0;
|
| group->poly[3] = 0;
|
| group->poly[4] = 0;
|
| + group->poly[5] = -1;
|
| }
|
|
|
|
|
| @@ -174,10 +175,9 @@
|
| dest->poly[2] = src->poly[2];
|
| dest->poly[3] = src->poly[3];
|
| dest->poly[4] = src->poly[4];
|
| - if(bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
|
| - return 0;
|
| - if(bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
|
| - return 0;
|
| + dest->poly[5] = src->poly[5];
|
| + if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
|
| + if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
|
| for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
|
| for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
|
| return 1;
|
| @@ -192,7 +192,7 @@
|
|
|
| /* group->field */
|
| if (!BN_copy(&group->field, p)) goto err;
|
| - i = BN_GF2m_poly2arr(&group->field, group->poly, 5);
|
| + i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
|
| if ((i != 5) && (i != 3))
|
| {
|
| ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
|
| @@ -406,18 +406,94 @@
|
| }
|
|
|
|
|
| -/* Include patented algorithms. */
|
| -#include "ec2_smpt.c"
|
| +/* Calculates and sets the affine coordinates of an EC_POINT from the given
|
| + * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
|
| + * Note that the simple implementation only uses affine coordinates.
|
| + *
|
| + * The method is from the following publication:
|
| + *
|
| + * Harper, Menezes, Vanstone:
|
| + * "Public-Key Cryptosystems with Very Small Key Lengths",
|
| + * EUROCRYPT '92, Springer-Verlag LNCS 658,
|
| + * published February 1993
|
| + *
|
| + * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
|
| + * the same method, but claim no priority date earlier than July 29, 1994
|
| + * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
|
| + */
|
| +int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
|
| + const BIGNUM *x_, int y_bit, BN_CTX *ctx)
|
| + {
|
| + BN_CTX *new_ctx = NULL;
|
| + BIGNUM *tmp, *x, *y, *z;
|
| + int ret = 0, z0;
|
|
|
| + /* clear error queue */
|
| + ERR_clear_error();
|
|
|
| + if (ctx == NULL)
|
| + {
|
| + ctx = new_ctx = BN_CTX_new();
|
| + if (ctx == NULL)
|
| + return 0;
|
| + }
|
| +
|
| + y_bit = (y_bit != 0) ? 1 : 0;
|
| +
|
| + BN_CTX_start(ctx);
|
| + tmp = BN_CTX_get(ctx);
|
| + x = BN_CTX_get(ctx);
|
| + y = BN_CTX_get(ctx);
|
| + z = BN_CTX_get(ctx);
|
| + if (z == NULL) goto err;
|
| +
|
| + if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
|
| + if (BN_is_zero(x))
|
| + {
|
| + if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
|
| + }
|
| + else
|
| + {
|
| + if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
|
| + if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
|
| + if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
|
| + if (!BN_GF2m_add(tmp, x, tmp)) goto err;
|
| + if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
|
| + {
|
| + unsigned long err = ERR_peek_last_error();
|
| +
|
| + if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
|
| + {
|
| + ERR_clear_error();
|
| + ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
|
| + }
|
| + else
|
| + ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
|
| + goto err;
|
| + }
|
| + z0 = (BN_is_odd(z)) ? 1 : 0;
|
| + if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
|
| + if (z0 != y_bit)
|
| + {
|
| + if (!BN_GF2m_add(y, y, x)) goto err;
|
| + }
|
| + }
|
| +
|
| + if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
|
| +
|
| + ret = 1;
|
| +
|
| + err:
|
| + BN_CTX_end(ctx);
|
| + if (new_ctx != NULL)
|
| + BN_CTX_free(new_ctx);
|
| + return ret;
|
| + }
|
| +
|
| +
|
| /* Converts an EC_POINT to an octet string.
|
| * If buf is NULL, the encoded length will be returned.
|
| * If the length len of buf is smaller than required an error will be returned.
|
| - *
|
| - * The point compression section of this function is patented by Certicom Corp.
|
| - * under US Patent 6,141,420. Point compression is disabled by default and can
|
| - * be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at
|
| - * Configure-time.
|
| */
|
| size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
|
| unsigned char *buf, size_t len, BN_CTX *ctx)
|
| @@ -428,14 +504,6 @@
|
| BIGNUM *x, *y, *yxi;
|
| size_t field_len, i, skip;
|
|
|
| -#ifndef OPENSSL_EC_BIN_PT_COMP
|
| - if ((form == POINT_CONVERSION_COMPRESSED) || (form == POINT_CONVERSION_HYBRID))
|
| - {
|
| - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_DISABLED);
|
| - goto err;
|
| - }
|
| -#endif
|
| -
|
| if ((form != POINT_CONVERSION_COMPRESSED)
|
| && (form != POINT_CONVERSION_UNCOMPRESSED)
|
| && (form != POINT_CONVERSION_HYBRID))
|
| @@ -490,13 +558,11 @@
|
| if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
|
|
|
| buf[0] = form;
|
| -#ifdef OPENSSL_EC_BIN_PT_COMP
|
| if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
|
| {
|
| if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
|
| if (BN_is_odd(yxi)) buf[0]++;
|
| }
|
| -#endif
|
|
|
| i = 1;
|
|
|
| @@ -821,7 +887,7 @@
|
| field_sqr = group->meth->field_sqr;
|
|
|
| /* only support affine coordinates */
|
| - if (!point->Z_is_one) goto err;
|
| + if (!point->Z_is_one) return -1;
|
|
|
| if (ctx == NULL)
|
| {
|
| @@ -871,6 +937,9 @@
|
| {
|
| return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
|
| }
|
| +
|
| + if (EC_POINT_is_at_infinity(group, b))
|
| + return 1;
|
|
|
| if (a->Z_is_one && b->Z_is_one)
|
| {
|
|
|