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) |
{ |