X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fec%2Fec2_smpl.c;h=01d8483c3af1036a3222183854ab7cd9b2332724;hb=ea71ec1b11e585b3cd704af1930c09c0c1606916;hp=d34e97d676d859f64675c25c4c31080d2b13b6ca;hpb=560f7abb7e12d09b5e1dd2e9c8e3c6a04fc901d3;p=oweals%2Fopenssl.git diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c index d34e97d676..01d8483c3a 100644 --- a/crypto/ec/ec2_smpl.c +++ b/crypto/ec/ec2_smpl.c @@ -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 @@ void ec_GF2m_simple_group_clear_finish(EC_GROUP *group) group->poly[2] = 0; group->poly[3] = 0; group->poly[4] = 0; + group->poly[5] = -1; } @@ -174,6 +175,7 @@ int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) dest->poly[2] = src->poly[2]; dest->poly[3] = src->poly[3]; dest->poly[4] = src->poly[4]; + dest->poly[5] = src->poly[5]; bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2); bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2); for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0; @@ -190,7 +192,7 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group, /* 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); @@ -281,7 +283,8 @@ int ec_GF2m_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; @@ -354,11 +357,11 @@ int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT } if (!BN_copy(&point->X, x)) goto err; - BN_set_sign(&point->X, 0); + BN_set_negative(&point->X, 0); if (!BN_copy(&point->Y, y)) goto err; - BN_set_sign(&point->Y, 0); + BN_set_negative(&point->Y, 0); if (!BN_copy(&point->Z, BN_value_one())) goto err; - BN_set_sign(&point->Z, 0); + BN_set_negative(&point->Z, 0); point->Z_is_one = 1; ret = 1; @@ -389,12 +392,12 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_ if (x != NULL) { if (!BN_copy(x, &point->X)) goto err; - BN_set_sign(x, 0); + BN_set_negative(x, 0); } if (y != NULL) { if (!BN_copy(y, &point->Y)) goto err; - BN_set_sign(y, 0); + BN_set_negative(y, 0); } ret = 1; @@ -403,18 +406,94 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_ } -/* 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) @@ -425,14 +504,6 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, po 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)) @@ -487,13 +558,11 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, po 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; @@ -805,13 +874,18 @@ int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) */ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; - BIGNUM *rh, *lh, *tmp1; int ret = -1; + BN_CTX *new_ctx = NULL; + BIGNUM *lh, *y2; + int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); if (EC_POINT_is_at_infinity(group, point)) return 1; - + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + /* only support affine coordinates */ if (!point->Z_is_one) goto err; @@ -823,37 +897,23 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_ } BN_CTX_start(ctx); - rh = BN_CTX_get(ctx); + y2 = BN_CTX_get(ctx); lh = BN_CTX_get(ctx); - tmp1 = BN_CTX_get(ctx); - if (tmp1 == NULL) goto err; + if (lh == NULL) goto err; /* We have a curve defined by a Weierstrass equation * y^2 + x*y = x^3 + a*x^2 + b. - * To test this, we add up the right-hand side in 'rh' - * and the left-hand side in 'lh'. + * <=> x^3 + a*x^2 + x*y + b + y^2 = 0 + * <=> ((x + a) * x + y ) * x + b + y^2 = 0 */ - - /* rh := X^3 */ - if (!group->meth->field_sqr(group, tmp1, &point->X, ctx)) goto err; - if (!group->meth->field_mul(group, rh, tmp1, &point->X, ctx)) goto err; - - /* rh := rh + a*X^2 */ - if (!group->meth->field_mul(group, tmp1, tmp1, &group->a, ctx)) goto err; - if (!BN_GF2m_add(rh, rh, tmp1)) goto err; - - /* rh := rh + b */ - if (!BN_GF2m_add(rh, rh, &group->b)) goto err; - - /* lh := Y^2 */ - if (!group->meth->field_sqr(group, lh, &point->Y, ctx)) goto err; - - /* lh := lh + x*y */ - if (!group->meth->field_mul(group, tmp1, &point->X, &point->Y, ctx)) goto err; - if (!BN_GF2m_add(lh, lh, tmp1)) goto err; - - ret = (0 == BN_GF2m_cmp(lh, rh)); - + if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err; + if (!field_mul(group, lh, lh, &point->X, ctx)) goto err; + if (!BN_GF2m_add(lh, lh, &point->Y)) goto err; + if (!field_mul(group, lh, lh, &point->X, ctx)) goto err; + if (!BN_GF2m_add(lh, lh, &group->b)) goto err; + if (!field_sqr(group, y2, &point->Y, ctx)) goto err; + if (!BN_GF2m_add(lh, lh, y2)) goto err; + ret = BN_is_zero(lh); err: if (ctx) BN_CTX_end(ctx); if (new_ctx) BN_CTX_free(new_ctx);