From: Nikos Mavrogiannopoulos Date: Tue, 2 Apr 2013 19:48:39 +0000 (+0200) Subject: Removed elliptic curve code from gnutls. Use nettle's implementation. X-Git-Tag: gnutls_3_2_0~87 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fed208e129ccd61b19b0036d1ff5f55b62b496c2;p=thirdparty%2Fgnutls.git Removed elliptic curve code from gnutls. Use nettle's implementation. --- diff --git a/NEWS b/NEWS index 830afeba4f..ba3a5bda02 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ See the end for copying conditions. * Version 3.2.0 (unreleased) +** libgnutls: Use nettle's elliptic curve implementation. + ** libgnutls: Added Salsa20 cipher (experimental) ** libgnutls: Added UMAC-96 and UMAC-128 MACs (experimental) diff --git a/lib/algorithms.h b/lib/algorithms.h index e37d23ccef..752ee617c2 100644 --- a/lib/algorithms.h +++ b/lib/algorithms.h @@ -143,19 +143,6 @@ struct gnutls_ecc_curve_entry_st gnutls_ecc_curve_t id; int tls_id; /* The RFC4492 namedCurve ID */ int size; /* the size in bytes */ - - /** The prime that defines the field the curve is in (encoded in hex) */ - const char *prime; - /** The fields A param (hex) */ - const char *A; - /** The fields B param (hex) */ - const char *B; - /** The order of the curve (hex) */ - const char *order; - /** The x co-ordinate of the base point on the curve (hex) */ - const char *Gx; - /** The y co-ordinate of the base point on the curve (hex) */ - const char *Gy; }; typedef struct gnutls_ecc_curve_entry_st gnutls_ecc_curve_entry_st; diff --git a/lib/algorithms/ecc.c b/lib/algorithms/ecc.c index cc2e14f613..c574036ae9 100644 --- a/lib/algorithms/ecc.c +++ b/lib/algorithms/ecc.c @@ -36,12 +36,6 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { .id = GNUTLS_ECC_CURVE_SECP192R1, .tls_id = 19, .size = 24, - .prime = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - .A = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - .B = "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", - .order = "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", - .Gx = "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", - .Gy = "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811" }, { .name = "SECP224R1", @@ -49,12 +43,6 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { .id = GNUTLS_ECC_CURVE_SECP224R1, .tls_id = 21, .size = 28, - .prime = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", - .A = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", - .B = "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", - .order = "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", - .Gx = "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", - .Gy = "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", }, { .name = "SECP256R1", @@ -62,12 +50,6 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { .id = GNUTLS_ECC_CURVE_SECP256R1, .tls_id = 23, .size = 32, - .prime = "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - .A = "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - .B = "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - .order = "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", - .Gx = "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", - .Gy = "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", }, { .name = "SECP384R1", @@ -75,12 +57,6 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { .id = GNUTLS_ECC_CURVE_SECP384R1, .tls_id = 24, .size = 48, - .prime = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", - .A = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", - .B = "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", - .order = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", - .Gx = "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", - .Gy = "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F" }, { .name = "SECP521R1", @@ -88,12 +64,6 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { .id = GNUTLS_ECC_CURVE_SECP521R1, .tls_id = 25, .size = 66, - .prime = "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - .A = "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", - .B = "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", - .order = "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", - .Gx = "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", - .Gy = "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", }, {0, 0, 0} }; diff --git a/lib/auth/ecdhe.c b/lib/auth/ecdhe.c index 0c75caa9a4..0a7c03ea9c 100644 --- a/lib/auth/ecdhe.c +++ b/lib/auth/ecdhe.c @@ -91,12 +91,6 @@ gnutls_pk_params_st pub; int ret; memset(&pub,0,sizeof(pub)); - pub.params[ECC_PRIME] = session->key.ecdh_params.params[ECC_PRIME]; - pub.params[ECC_ORDER] = session->key.ecdh_params.params[ECC_ORDER]; - pub.params[ECC_A] = session->key.ecdh_params.params[ECC_A]; - pub.params[ECC_B] = session->key.ecdh_params.params[ECC_B]; - pub.params[ECC_GX] = session->key.ecdh_params.params[ECC_GX]; - pub.params[ECC_GY] = session->key.ecdh_params.params[ECC_GY]; pub.params[ECC_X] = session->key.ecdh_x; pub.params[ECC_Y] = session->key.ecdh_y; @@ -116,7 +110,6 @@ int ret; ret = _gnutls_set_psk_session_key (session, psk_key, &tmp_dh_key); _gnutls_free_datum (&tmp_dh_key); } - if (ret < 0) { @@ -202,8 +195,8 @@ _gnutls_gen_ecdh_common_client_kx_int (gnutls_session_t session, if (ret < 0) return gnutls_assert_val(ret); - ret = _gnutls_ecc_ansi_x963_export(curve, session->key.ecdh_params.params[6] /* x */, - session->key.ecdh_params.params[7] /* y */, &out); + ret = _gnutls_ecc_ansi_x963_export(curve, session->key.ecdh_params.params[ECC_X] /* x */, + session->key.ecdh_params.params[ECC_Y] /* y */, &out); if (ret < 0) return gnutls_assert_val(ret); @@ -304,8 +297,8 @@ int _gnutls_ecdh_common_print_server_kx (gnutls_session_t session, gnutls_buffer if (ret < 0) return gnutls_assert_val(ret); - ret = _gnutls_ecc_ansi_x963_export(curve, session->key.ecdh_params.params[6] /* x */, - session->key.ecdh_params.params[7] /* y */, &out); + ret = _gnutls_ecc_ansi_x963_export(curve, session->key.ecdh_params.params[ECC_X] /* x */, + session->key.ecdh_params.params[ECC_Y] /* y */, &out); if (ret < 0) return gnutls_assert_val(ret); diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h index 4975f4a005..955e4bd1e8 100644 --- a/lib/crypto-backend.h +++ b/lib/crypto-backend.h @@ -206,7 +206,7 @@ /* parameters should not be larger than this limit */ #define DSA_PUBLIC_PARAMS 4 #define RSA_PUBLIC_PARAMS 2 -#define ECC_PUBLIC_PARAMS 8 +#define ECC_PUBLIC_PARAMS 2 #define MAX_PRIV_PARAMS_SIZE GNUTLS_MAX_PK_PARAMS /* ok for RSA and DSA */ @@ -214,7 +214,7 @@ /* parameters should not be larger than this limit */ #define DSA_PRIVATE_PARAMS 5 #define RSA_PRIVATE_PARAMS 8 -#define ECC_PRIVATE_PARAMS 9 +#define ECC_PRIVATE_PARAMS 3 #if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0 #error INCREASE MAX_PRIV_PARAMS @@ -262,15 +262,9 @@ * [8] is k (private key) */ -#define ECC_PRIME 0 -#define ECC_ORDER 1 -#define ECC_A 2 -#define ECC_B 3 -#define ECC_GX 4 -#define ECC_GY 5 -#define ECC_X 6 -#define ECC_Y 7 -#define ECC_K 8 +#define ECC_X 0 +#define ECC_Y 1 +#define ECC_K 2 #define DSA_P 0 #define DSA_Q 1 diff --git a/lib/gnutls_ecc.c b/lib/gnutls_ecc.c index 51abe7b425..da02aecc05 100644 --- a/lib/gnutls_ecc.c +++ b/lib/gnutls_ecc.c @@ -103,117 +103,3 @@ _gnutls_ecc_ansi_x963_import (const uint8_t * in, return 0; } -int _gnutls_ecc_curve_fill_params(gnutls_ecc_curve_t curve, gnutls_pk_params_st* params) -{ -const gnutls_ecc_curve_entry_st *st; -uint8_t val[MAX_ECC_CURVE_SIZE]; -size_t val_size; -int ret; - - st = _gnutls_ecc_curve_get_params(curve); - if (st == NULL) - return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); - - val_size = sizeof(val); - ret = _gnutls_hex2bin(st->prime, strlen(st->prime), val, &val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_mpi_scan_nz(¶ms->params[ECC_PRIME], val, val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - params->params_nr++; - - val_size = sizeof(val); - ret = _gnutls_hex2bin(st->order, strlen(st->order), val, &val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_mpi_scan_nz(¶ms->params[ECC_ORDER], val, val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - params->params_nr++; - - val_size = sizeof(val); - ret = _gnutls_hex2bin(st->A, strlen(st->A), val, &val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_mpi_scan_nz(¶ms->params[ECC_A], val, val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - params->params_nr++; - - val_size = sizeof(val); - ret = _gnutls_hex2bin(st->B, strlen(st->B), val, &val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_mpi_scan_nz(¶ms->params[ECC_B], val, val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - params->params_nr++; - - val_size = sizeof(val); - ret = _gnutls_hex2bin(st->Gx, strlen(st->Gx), val, &val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_mpi_scan_nz(¶ms->params[ECC_GX], val, val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - params->params_nr++; - - val_size = sizeof(val); - ret = _gnutls_hex2bin(st->Gy, strlen(st->Gy), val, &val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_mpi_scan_nz(¶ms->params[ECC_GY], val, val_size); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - params->params_nr++; - - return 0; - -cleanup: - gnutls_pk_params_release(params); - return ret; - -} diff --git a/lib/gnutls_ecc.h b/lib/gnutls_ecc.h index b0f2bf657f..10104c743a 100644 --- a/lib/gnutls_ecc.h +++ b/lib/gnutls_ecc.h @@ -25,5 +25,4 @@ int _gnutls_ecc_ansi_x963_import(const uint8_t *in, unsigned long inlen, bigint_t* x, bigint_t* y); int _gnutls_ecc_ansi_x963_export(gnutls_ecc_curve_t curve, bigint_t x, bigint_t y, gnutls_datum_t * out); -int _gnutls_ecc_curve_fill_params(gnutls_ecc_curve_t curve, gnutls_pk_params_st* params); #endif diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index 1a42d50f38..8e4965e352 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -135,22 +135,13 @@ privkey_to_pubkey (gnutls_pk_algorithm_t pk, break; case GNUTLS_PK_EC: - pub->params[0] = _gnutls_mpi_copy (priv->params[0]); - pub->params[1] = _gnutls_mpi_copy (priv->params[1]); - pub->params[2] = _gnutls_mpi_copy (priv->params[2]); - pub->params[3] = _gnutls_mpi_copy (priv->params[3]); - pub->params[4] = _gnutls_mpi_copy (priv->params[4]); - pub->params[5] = _gnutls_mpi_copy (priv->params[5]); - pub->params[6] = _gnutls_mpi_copy (priv->params[6]); - pub->params[7] = _gnutls_mpi_copy (priv->params[7]); + pub->params[ECC_X] = _gnutls_mpi_copy (priv->params[ECC_X]); + pub->params[ECC_Y] = _gnutls_mpi_copy (priv->params[ECC_Y]); pub->params_nr = ECC_PUBLIC_PARAMS; pub->flags = priv->flags; - if (pub->params[0] == NULL || pub->params[1] == NULL || - pub->params[2] == NULL || pub->params[3] == NULL || - pub->params[4] == NULL || pub->params[5] == NULL || - pub->params[6] == NULL || pub->params[7] == NULL) + if (pub->params[ECC_X] == NULL || pub->params[ECC_Y] == NULL) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index 019704f7c8..d3c10bf2aa 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -1373,10 +1373,6 @@ gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key, key->params.flags = curve; - ret = _gnutls_ecc_curve_fill_params(curve, &key->params); - if (ret < 0) - return gnutls_assert_val(ret); - if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X], x->data, x->size)) { gnutls_assert (); diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am index add6baa852..e2b704e9ce 100644 --- a/lib/nettle/Makefile.am +++ b/lib/nettle/Makefile.am @@ -34,8 +34,4 @@ endif noinst_LTLIBRARIES = libcrypto.la libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c rnd.c init.c egd.c egd.h \ - multi.c wmnaf.c ecc_free.c ecc.h ecc_make_key.c ecc_shared_secret.c \ - ecc_map.c ecc_mulmod.c ecc_mulmod_cached.c \ - ecc_points.c ecc_projective_dbl_point_3.c ecc_projective_isneutral.c \ - ecc_projective_check_point.c ecc_projective_negate_point.c \ - ecc_projective_add_point_ng.c ecc_sign_hash.c ecc_verify_hash.c gnettle.h + gnettle.h diff --git a/lib/nettle/ecc.h b/lib/nettle/ecc.h deleted file mode 100644 index ececd95390..0000000000 --- a/lib/nettle/ecc.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -#include -#include -#include -#include -#include - -/* assume y^2 = x^3 - 3x + b - * instead of the generic y^2 = x^3 + ax + b - * - * (XXX: the generic case has been tested only - * with the SECG curves.) - */ -#define ECC_SECP_CURVES_ONLY - -#define PK_PRIVATE 1 -#define PK_PUBLIC 2 - -/* ---- ECC Routines ---- */ -/* size of our temp buffers for exported keys */ -#define ECC_BUF_SIZE 512 - -/* max private key size */ -#define ECC_MAXSIZE 66 - -/* wMNAF window size */ -#define WMNAF_WINSIZE 4 - -/* length of a single array of precomputed values for wMNAF - * we have two such arrays for positive and negative multipliers */ -#define WMNAF_PRECOMPUTED_LENGTH (1 << (WMNAF_WINSIZE - 1)) - -/** Structure defines a NIST GF(p) curve */ -typedef struct { - /** The size of the curve in octets */ - int size; - - /** name of curve */ - const char *name; - - /** The prime that defines the field the curve is in (encoded in hex) */ - const char *prime; - - /** The fields A param (hex) */ - const char *A; - - /** The fields B param (hex) */ - const char *B; - - /** The order of the curve (hex) */ - const char *order; - - /** The x co-ordinate of the base point on the curve (hex) */ - const char *Gx; - - /** The y co-ordinate of the base point on the curve (hex) */ - const char *Gy; -} ecc_set_type; - -/** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */ -typedef struct { - /** The x co-ordinate */ - mpz_t x; - - /** The y co-ordinate */ - mpz_t y; - - /** The z co-ordinate */ - mpz_t z; -} ecc_point; - -/** An ECC key */ -typedef struct { - /** Type of key, PK_PRIVATE or PK_PUBLIC */ - int type; - - mpz_t prime; - mpz_t order; - mpz_t A; - mpz_t B; - mpz_t Gx; - mpz_t Gy; - - /** The public key */ - ecc_point pubkey; - - /** The private key */ - mpz_t k; -} ecc_key; - -void ecc_sizes(int *low, int *high); -int ecc_get_size(ecc_key *key); - -int ecc_make_key(void *random_ctx, nettle_random_func random, ecc_key *key, const ecc_set_type *dp, gnutls_ecc_curve_t id); -int ecc_make_key_ex(void *random_ctx, nettle_random_func random, ecc_key *key, mpz_t prime, mpz_t order, mpz_t A, mpz_t B, mpz_t Gx, mpz_t Gy, gnutls_ecc_curve_t id, int timing_res); -void ecc_free(ecc_key *key); - -int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, - unsigned char *out, unsigned long *outlen); - -int ecc_sign_hash(const unsigned char *in, unsigned long inlen, - struct dsa_signature *signature, - void *random_ctx, nettle_random_func random, - ecc_key *key, gnutls_ecc_curve_t id); - -int ecc_verify_hash(struct dsa_signature * signature, - const unsigned char *hash, unsigned long hashlen, - int *stat, ecc_key *key, gnutls_ecc_curve_t id); - -/* low level functions */ -ecc_point *ecc_new_point(void); -void ecc_del_point(ecc_point *p); - -/* point ops (mp == montgomery digit) */ -/* R = -P */ -int ecc_projective_negate_point(ecc_point *P, ecc_point *R, mpz_t modulus); - -/* R = 2P */ -int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mpz_t a, mpz_t modulus); - -/* R = P + Q */ -int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mpz_t A, mpz_t modulus); -int ecc_projective_madd (ecc_point* P, ecc_point* Q, ecc_point* R, mpz_t a, mpz_t modulus); - -/* R = kG */ -/* wMNAF-based mulmod */ -signed char* ecc_wMNAF(mpz_t x, size_t *ret_len); -int ecc_mulmod(mpz_t k, ecc_point *G, ecc_point *R, mpz_t a, mpz_t modulus, int map); - -/* cache-enabled wMNAF-based mulmod */ -int ecc_wmnaf_cache_init(void); -void ecc_wmnaf_cache_free(void); -int ecc_mulmod_cached (mpz_t k, gnutls_ecc_curve_t id, ecc_point * R, mpz_t a, mpz_t modulus, int map); -int ecc_mulmod_cached_timing (mpz_t k, gnutls_ecc_curve_t id, ecc_point * R, mpz_t a, mpz_t modulus, int map); -int ecc_mulmod_cached_lookup (mpz_t k, ecc_point *G, ecc_point *R, mpz_t a, mpz_t modulus, int map); - -/* check if the given point is neutral point */ -int ecc_projective_isneutral(ecc_point *P, mpz_t modulus); - -/* map P to affine from projective */ -int ecc_map(ecc_point *P, mpz_t modulus); - -/* check whether a point lies on the curve */ -int ecc_projective_check_point (ecc_point * P, mpz_t b, mpz_t modulus); - -/* helper functions */ -int mp_init_multi(mpz_t *a, ...); -void mp_clear_multi(mpz_t *a, ...); - diff --git a/lib/nettle/ecc_free.c b/lib/nettle/ecc_free.c deleted file mode 100644 index 6d6fb23410..0000000000 --- a/lib/nettle/ecc_free.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -/* Based on public domain code of LibTomCrypt by Tom St Denis. - * Adapted to gmp and nettle by Nikos Mavrogiannopoulos. - */ - -#include "ecc.h" - -/* - @file ecc_free.c - ECC Crypto, Tom St Denis -*/ - -/* - Free an ECC key from memory - @param key The key you wish to free -*/ -void -ecc_free (ecc_key * key) -{ - mp_clear_multi (&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, - &key->prime, &key->order, &key->Gx, &key->Gy, &key->A, &key->B, NULL); -} - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_free.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/lib/nettle/ecc_make_key.c b/lib/nettle/ecc_make_key.c deleted file mode 100644 index 0df9df0008..0000000000 --- a/lib/nettle/ecc_make_key.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -/* Based on public domain code of LibTomCrypt by Tom St Denis. - * Adapted to gmp and nettle by Nikos Mavrogiannopoulos. - */ - -#include "ecc.h" - -/* - @file ecc_make_key.c - ECC Crypto, Tom St Denis -*/ - -/* - Make a new ECC key - @param prng An active PRNG state - @param wprng The index of the PRNG you wish to use - @param prime The prime of curve's field - @param order The order of the G point - @param A The "a" parameter of the curve - @param Gx The x coordinate of the base point - @param Gy The y coordinate of the base point - @param curve_id The id of the curve we are working with - @timing_res If non zero the function will try to return in constant time. - @return 0 if successful, upon error all allocated memory will be freed -*/ - -int -ecc_make_key_ex (void *random_ctx, nettle_random_func random, ecc_key * key, - mpz_t prime, mpz_t order, mpz_t A, mpz_t B, mpz_t Gx, mpz_t Gy, - gnutls_ecc_curve_t curve_id, int timing_res) -{ - int err; - ecc_point *base; - unsigned char *buf; - int keysize; - - if (key == NULL || random == NULL) - return -1; - - keysize = nettle_mpz_sizeinbase_256_u (order); - - /* allocate ram */ - base = NULL; - buf = malloc (keysize); - if (buf == NULL) - return -1; - - /* make up random string */ - random (random_ctx, keysize, buf); - - /* setup the key variables */ - if ((err = - mp_init_multi (&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, - &key->prime, &key->order, &key->A, &key->B, &key->Gx, &key->Gy, - NULL)) != 0) - { - goto ERR_BUF; - } - base = ecc_new_point (); - if (base == NULL) - { - err = -1; - goto errkey; - } - - /* read in the specs for this key */ - mpz_set (key->prime, prime); - mpz_set (key->order, order); - mpz_set (key->Gx, Gx); - mpz_set (key->Gy, Gy); - mpz_set (key->A, A); - mpz_set (key->B, B); - - mpz_set (base->x, key->Gx); - mpz_set (base->y, key->Gy); - mpz_set_ui (base->z, 1); - - nettle_mpz_set_str_256_u (key->k, keysize, buf); - - /* the key should be smaller than the order of base point */ - if (mpz_cmp (key->k, key->order) >= 0) - { - mpz_mod (key->k, key->k, key->order); - } - /* make the public key */ - if (timing_res) - err = ecc_mulmod_cached_timing (key->k, curve_id, &key->pubkey, key->A, key->prime, 1); - else - err = ecc_mulmod_cached (key->k, curve_id, &key->pubkey, key->A, key->prime, 1); - - if (err != 0) - goto errkey; - - key->type = PK_PRIVATE; - - /* free up ram */ - err = 0; - goto cleanup; -errkey: - mp_clear_multi (&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, - &key->order, &key->prime, &key->Gx, &key->Gy, &key->A, &key->B, - NULL); -cleanup: - ecc_del_point (base); -ERR_BUF: - free (buf); - return err; -} - -int -ecc_make_key (void *random_ctx, nettle_random_func random, ecc_key * key, - const ecc_set_type * dp, gnutls_ecc_curve_t curve_id) -{ - mpz_t prime, order, Gx, Gy, A, B; - int err; - - /* setup the key variables */ - if ((err = mp_init_multi (&prime, &order, &A, &B, &Gx, &Gy, NULL)) != 0) - { - goto cleanup; - } - - /* read in the specs for this key */ - mpz_set_str (prime, (char *) dp->prime, 16); - mpz_set_str (order, (char *) dp->order, 16); - mpz_set_str (Gx, (char *) dp->Gx, 16); - mpz_set_str (Gy, (char *) dp->Gy, 16); - mpz_set_str (A, (char *) dp->A, 16); - mpz_set_str (B, (char *) dp->B, 16); - - err = ecc_make_key_ex (random_ctx, random, key, prime, order, A, B, Gx, Gy, curve_id, 0); - - mp_clear_multi (&prime, &order, &A, &B, &Gx, &Gy, NULL); -cleanup: - return err; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_make_key.c,v $ */ -/* $Revision: 1.13 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/lib/nettle/ecc_map.c b/lib/nettle/ecc_map.c deleted file mode 100644 index 077f2fa262..0000000000 --- a/lib/nettle/ecc_map.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -/* Based on public domain code of LibTomCrypt by Tom St Denis. - * Adapted to gmp and nettle by Nikos Mavrogiannopoulos. - */ - -#include "ecc.h" - -/* - @file ecc_map.c - ECC Crypto, Tom St Denis -*/ - -/* - Map a projective jacobian point back to affine space - @param P [in/out] The point to map - @param modulus The modulus of the field the ECC curve is in - @param mp The "b" value from montgomery_setup() - @return 0 on success -*/ -int -ecc_map (ecc_point * P, mpz_t modulus) -{ - mpz_t t1, t2; - int err; - - if (P == NULL) - return -1; - - if ((err = mp_init_multi (&t1, &t2, NULL)) != 0) - { - return -1; - } - - mpz_mod (P->z, P->z, modulus); - - /* get 1/z */ - mpz_invert (t1, P->z, modulus); - - /* get 1/z^2 and 1/z^3 */ - mpz_mul (t2, t1, t1); - mpz_mod (t2, t2, modulus); - mpz_mul (t1, t1, t2); - mpz_mod (t1, t1, modulus); - - /* multiply against x/y */ - mpz_mul (P->x, P->x, t2); - mpz_mod (P->x, P->x, modulus); - mpz_mul (P->y, P->y, t1); - mpz_mod (P->y, P->y, modulus); - mpz_set_ui (P->z, 1); - - err = 0; - - mp_clear_multi (&t1, &t2, NULL); - return err; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_map.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/lib/nettle/ecc_mulmod.c b/lib/nettle/ecc_mulmod.c deleted file mode 100644 index 79e70ca8d4..0000000000 --- a/lib/nettle/ecc_mulmod.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * Author: Ilya Tumaykin - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -#include "ecc.h" - - -/* - Perform a point multiplication using wMNAF representation - @param k The scalar to multiply by - @param G The base point - @param R [out] Destination for kG - @param a The curve's A value - @param modulus The modulus of the field the ECC curve is in - @param map Boolean whether to map back to affine or not (1 == map, 0 == leave in projective) - @return GNUTLS_E_SUCCESS on success -*/ -int -ecc_mulmod (mpz_t k, ecc_point * G, ecc_point * R, mpz_t a, - mpz_t modulus, int map) -{ - ecc_point *pos[WMNAF_PRECOMPUTED_LENGTH], *neg[WMNAF_PRECOMPUTED_LENGTH]; - int i, j, err; - - signed char *wmnaf = NULL; - size_t wmnaf_len; - signed char digit; - - if (k == NULL || G == NULL || R == NULL || modulus == NULL) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - /* alloc ram for precomputed values */ - for (i = 0; i < WMNAF_PRECOMPUTED_LENGTH; ++i) - { - pos[i] = ecc_new_point (); - neg[i] = ecc_new_point (); - if (pos[i] == NULL || neg[i] == NULL) - { - for (j = 0; j < i; ++j) - { - ecc_del_point (pos[j]); - ecc_del_point (neg[j]); - } - - return GNUTLS_E_MEMORY_ERROR; - } - } - - /* fill in pos and neg arrays with precomputed values - * pos holds kG for k == 1, 3, 5, ..., (2^w - 1) - * neg holds kG for k == -1,-3,-5, ...,-(2^w - 1) - */ - - /* pos[0] == 2G for a while, later it will be set to the expected 1G */ - if ((err = ecc_projective_dbl_point (G, pos[0], a, modulus)) != 0) - goto done; - - /* pos[1] == 3G */ - if ((err = - ecc_projective_add_point (pos[0], G, pos[1], a, modulus)) != 0) - goto done; - - /* fill in kG for k = 5, 7, ..., (2^w - 1) */ - for (j = 2; j < WMNAF_PRECOMPUTED_LENGTH; ++j) - { - if ((err = - ecc_projective_add_point (pos[j - 1], pos[0], pos[j], a, - modulus)) != 0) - goto done; - } - - /* set pos[0] == 1G as expected - * after this step we don't need G at all - * and can change it without worries even if R == G */ - mpz_set (pos[0]->x, G->x); - mpz_set (pos[0]->y, G->y); - mpz_set (pos[0]->z, G->z); - - /* neg[i] == -pos[i] */ - for (j = 0; j < WMNAF_PRECOMPUTED_LENGTH; ++j) - { - if ((err = ecc_projective_negate_point (pos[j], neg[j], modulus)) != 0) - goto done; - } - - /* calculate wMNAF */ - wmnaf = ecc_wMNAF (k, &wmnaf_len); - if (!wmnaf) - { - err = GNUTLS_E_INTERNAL_ERROR; - goto done; - } - - /* actual point computation */ - - /* set R to neutral */ - mpz_set_ui (R->x, 1); - mpz_set_ui (R->y, 1); - mpz_set_ui (R->z, 0); - - /* perform ops */ - for (j = wmnaf_len - 1; j >= 0; --j) - { - if ((err = ecc_projective_dbl_point (R, R, a, modulus)) != 0) - goto done; - - digit = wmnaf[j]; - - if (digit) - { - if (digit > 0) - { - if ((err = - ecc_projective_add_point (R, pos[(digit / 2)], R, a, - modulus)) != 0) - goto done; - } - else - { - if ((err = - ecc_projective_add_point (R, neg[(-digit / 2)], R, a, - modulus)) != 0) - goto done; - } - } - } - - - /* map R back from projective space */ - if (map) - { - err = ecc_map (R, modulus); - } - else - { - err = GNUTLS_E_SUCCESS; - } -done: - for (i = 0; i < WMNAF_PRECOMPUTED_LENGTH; ++i) - { - ecc_del_point (pos[i]); - ecc_del_point (neg[i]); - } - if (wmnaf) - free (wmnaf); - return err; -} diff --git a/lib/nettle/ecc_mulmod_cached.c b/lib/nettle/ecc_mulmod_cached.c deleted file mode 100644 index fa40476fc4..0000000000 --- a/lib/nettle/ecc_mulmod_cached.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * Author: Ilya Tumaykin - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -/* needed for gnutls_* types */ -#include -#include - -#include "ecc.h" - - -/* per-curve cache structure */ -typedef struct -{ - /* curve's id */ - gnutls_ecc_curve_t id; - - /** The array of positive multipliers of G */ - ecc_point *pos[WMNAF_PRECOMPUTED_LENGTH]; - - /** The array of negative multipliers of G */ - ecc_point *neg[WMNAF_PRECOMPUTED_LENGTH]; -} gnutls_ecc_curve_cache_entry_t; - -/* global cache */ -static gnutls_ecc_curve_cache_entry_t *ecc_wmnaf_cache = NULL; - -/* free single cache entry */ -static void -_ecc_wmnaf_cache_entry_free (gnutls_ecc_curve_cache_entry_t * p) -{ - int i; - - for (i = 0; i < WMNAF_PRECOMPUTED_LENGTH; ++i) - { - ecc_del_point (p->pos[i]); - ecc_del_point (p->neg[i]); - } -} - -/* free curves caches */ -void -ecc_wmnaf_cache_free (void) -{ - gnutls_ecc_curve_cache_entry_t *p = ecc_wmnaf_cache; - if (p) - { - for (; p->id != GNUTLS_ECC_CURVE_INVALID; ++p) - { - _ecc_wmnaf_cache_entry_free (p); - } - - free (ecc_wmnaf_cache); - ecc_wmnaf_cache = NULL; - } -} - -/* initialize single cache entry - * for a curve with the given id */ -static int -_ecc_wmnaf_cache_entry_init (gnutls_ecc_curve_cache_entry_t * p, - gnutls_ecc_curve_t id) -{ - int i, j, err; - ecc_point *G; - mpz_t a, modulus; - - const gnutls_ecc_curve_entry_st *st = NULL; - - if (p == NULL || id == 0) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - G = ecc_new_point (); - if (G == NULL) - { - return GNUTLS_E_MEMORY_ERROR; - } - - st = _gnutls_ecc_curve_get_params (id); - if (st == NULL) - { - err = GNUTLS_E_INTERNAL_ERROR; - goto done; - } - - if ((err = mp_init_multi (&a, &modulus, NULL) != 0)) - return err; - - /* set id */ - p->id = id; - - /* set modulus */ - mpz_set_str (modulus, st->prime, 16); - - /* get generator point */ - mpz_set_str (G->x, st->Gx, 16); - mpz_set_str (G->y, st->Gy, 16); - mpz_set_ui (G->z, 1); - - /* set A */ - mpz_set_str (a, st->A, 16); - - /* alloc ram for precomputed values */ - for (i = 0; i < WMNAF_PRECOMPUTED_LENGTH; ++i) - { - p->pos[i] = ecc_new_point (); - p->neg[i] = ecc_new_point (); - if (p->pos[i] == NULL || p->neg[i] == NULL) - { - for (j = 0; j < i; ++j) - { - ecc_del_point (p->pos[j]); - ecc_del_point (p->neg[j]); - } - - err = GNUTLS_E_MEMORY_ERROR; - goto done; - } - } - - /* fill in pos and neg arrays with precomputed values - * pos holds kG for k == 1, 3, 5, ..., (2^w - 1) - * neg holds kG for k == -1,-3,-5, ...,-(2^w - 1) - */ - - /* pos[0] == 2G for a while, later it will be set to the expected 1G */ - if ((err = ecc_projective_dbl_point (G, p->pos[0], a, modulus)) != 0) - goto done; - - /* pos[1] == 3G */ - if ((err = - ecc_projective_add_point (p->pos[0], G, p->pos[1], a, - modulus)) != 0) - goto done; - - /* fill in kG for k = 5, 7, ..., (2^w - 1) */ - for (j = 2; j < WMNAF_PRECOMPUTED_LENGTH; ++j) - { - if ((err = - ecc_projective_add_point (p->pos[j - 1], p->pos[0], p->pos[j], - a, modulus)) != 0) - goto done; - } - - /* set pos[0] == 1G as expected - * after this step we don't need G at all */ - mpz_set (p->pos[0]->x, G->x); - mpz_set (p->pos[0]->y, G->y); - mpz_set (p->pos[0]->z, G->z); - - /* map to affine all elements in pos - * this will allow to use ecc_projective_madd later - * set neg[i] == -pos[i] */ - for (j = 0; j < WMNAF_PRECOMPUTED_LENGTH; ++j) - { - if ((err = ecc_map (p->pos[j], modulus)) != 0) - goto done; - - if ((err = - ecc_projective_negate_point (p->pos[j], p->neg[j], modulus)) != 0) - goto done; - } - - err = 0; -done: - ecc_del_point (G); - mp_clear_multi (&a, &modulus, NULL); - - return err; -} - -/* initialize curves caches */ -int -ecc_wmnaf_cache_init (void) -{ - int j, err; - - gnutls_ecc_curve_cache_entry_t *ret; - - const gnutls_ecc_curve_t *p; - - ret = (gnutls_ecc_curve_cache_entry_t *) - malloc (MAX_ALGOS * sizeof (gnutls_ecc_curve_cache_entry_t)); - if (ret == NULL) - return GNUTLS_E_MEMORY_ERROR; - - /* get supported curves' ids */ - p = gnutls_ecc_curve_list (); - - for (j = 0; *p; ++p, ++j) - { - if ((err = _ecc_wmnaf_cache_entry_init (ret + *p - 1, *p)) != 0) - goto done; - } - - /* nullify last cache entry id */ - ret[j].id = GNUTLS_ECC_CURVE_INVALID; - - err = GNUTLS_E_SUCCESS; - - ecc_wmnaf_cache = ret; -done: - if (err) - { - int i; - for (i = 0; i < j; ++i) - { - _ecc_wmnaf_cache_entry_free (ret + i); - } - - free (ret); - ecc_wmnaf_cache = NULL; - } - return err; -} - - -/* - Perform a point wMNAF-multiplication utilizing cache - @param k The scalar to multiply by - @param id The curve's id - @param R [out] Destination for kG - @param a The curve's A value - @param modulus The modulus of the field the ECC curve is in - @param map Boolean whether to map back to affine or not (1 == map, 0 == leave in projective) - @return GNUTLS_E_SUCCESS on success -*/ -int -ecc_mulmod_cached (mpz_t k, gnutls_ecc_curve_t id, ecc_point * R, - mpz_t a, mpz_t modulus, int map) -{ - int j, err; - - gnutls_ecc_curve_cache_entry_t *cache = NULL; - signed char *wmnaf = NULL; - size_t wmnaf_len; - signed char digit; - - if (k == NULL || R == NULL || modulus == NULL || id == 0) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - /* calculate wMNAF */ - wmnaf = ecc_wMNAF (k, &wmnaf_len); - if (!wmnaf) - { - err = GNUTLS_E_INTERNAL_ERROR; - goto done; - } - - /* set R to neutral */ - mpz_set_ui (R->x, 1); - mpz_set_ui (R->y, 1); - mpz_set_ui (R->z, 0); - - /* do cache lookup */ - cache = ecc_wmnaf_cache + id - 1; - - /* perform ops */ - for (j = wmnaf_len - 1; j >= 0; --j) - { - if ((err = ecc_projective_dbl_point (R, R, a, modulus)) != 0) - goto done; - - digit = wmnaf[j]; - - if (digit) - { - if (digit > 0) - { - if ((err = - ecc_projective_madd (R, cache->pos[(digit / 2)], R, a, - modulus)) != 0) - goto done; - } - else - { - if ((err = - ecc_projective_madd (R, cache->neg[(-digit / 2)], R, a, - modulus)) != 0) - goto done; - } - } - } - - - /* map R back from projective space */ - if (map) - { - err = ecc_map (R, modulus); - } - else - { - err = GNUTLS_E_SUCCESS; - } -done: - if (wmnaf) - free (wmnaf); - return err; -} - -/* - Perform a point wMNAF-multiplication utilizing cache - This version tries to be timing resistant - @param k The scalar to multiply by - @param id The curve's id - @param R [out] Destination for kG - @param a The curve's A value - @param modulus The modulus of the field the ECC curve is in - @param map Boolean whether to map back to affine or not (1 == map, 0 == leave in projective) - @return GNUTLS_E_SUCCESS on success -*/ -int -ecc_mulmod_cached_timing (mpz_t k, gnutls_ecc_curve_t id, ecc_point * R, - mpz_t a, mpz_t modulus, int map) -{ - int j, err; - - gnutls_ecc_curve_cache_entry_t *cache = NULL; - signed char *wmnaf = NULL; - size_t wmnaf_len; - signed char digit; - /* point for throttle */ - ecc_point *T; - - if (k == NULL || R == NULL || modulus == NULL || id == 0) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - /* prepare T point */ - T = ecc_new_point (); - if (T == NULL) - return GNUTLS_E_MEMORY_ERROR; - - /* calculate wMNAF */ - wmnaf = ecc_wMNAF (k, &wmnaf_len); - if (!wmnaf) - { - err = GNUTLS_E_INTERNAL_ERROR; - goto done; - } - - /* set R to neutral */ - mpz_set_ui (R->x, 1); - mpz_set_ui (R->y, 1); - mpz_set_ui (R->z, 0); - - /* set T to neutral */ - mpz_set_ui (T->x, 1); - mpz_set_ui (T->y, 1); - mpz_set_ui (T->z, 0); - - /* do cache lookup */ - cache = ecc_wmnaf_cache + id - 1; - - /* perform ops */ - for (j = wmnaf_len - 1; j >= 0; --j) - { - if ((err = ecc_projective_dbl_point (R, R, a, modulus)) != 0) - goto done; - - digit = wmnaf[j]; - - if (digit) - { - if (digit > 0) - { - if ((err = - ecc_projective_madd (R, cache->pos[(digit / 2)], R, a, - modulus)) != 0) - goto done; - } - else - { - if ((err = - ecc_projective_madd (R, cache->neg[(-digit / 2)], R, a, - modulus)) != 0) - goto done; - } - } - else - { - /* we add middle element of pos array as a general case - * there is no real difference between using pos and neg */ - if ((err = - ecc_projective_madd (R, - cache-> - pos[(WMNAF_PRECOMPUTED_LENGTH / 2)], T, a, - modulus)) != 0) - goto done; - } - } - - - /* map R back from projective space */ - if (map) - { - err = ecc_map (R, modulus); - } - else - { - err = GNUTLS_E_SUCCESS; - } -done: - ecc_del_point (T); - if (wmnaf) - free (wmnaf); - return err; -} - -/* - Perform a point wMNAF-multiplication utilizing cache - This function will lookup for an apropriate curve first - This function's definition allows in-place substitution instead of ecc_mulmod - @param k The scalar to multiply by - @param id The curve's id - @param R [out] Destination for kG - @param a The curve's A value - @param modulus The modulus of the field the ECC curve is in - @param map Boolean whether to map back to affine or not (1 == map, 0 == leave in projective) - @return GNUTLS_E_SUCCESS on success -*/ -int -ecc_mulmod_cached_lookup (mpz_t k, ecc_point * G, ecc_point * R, - mpz_t a, mpz_t modulus, int map) -{ - int i, id; - - if (k == NULL || G == NULL || R == NULL || modulus == NULL) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - for (i = 0; (id = ecc_wmnaf_cache[i].id); ++i) - { - if (!(mpz_cmp (G->x, ecc_wmnaf_cache[i].pos[0]->x)) && - !(mpz_cmp (G->y, ecc_wmnaf_cache[i].pos[0]->y))) - { - break; - } - } - - return ecc_mulmod_cached (k, id, R, a, modulus, map); -} diff --git a/lib/nettle/ecc_points.c b/lib/nettle/ecc_points.c deleted file mode 100644 index c1dc7c0fe6..0000000000 --- a/lib/nettle/ecc_points.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -/* Based on public domain code of LibTomCrypt by Tom St Denis. - * Adapted to gmp and nettle by Nikos Mavrogiannopoulos. - */ - -#include "ecc.h" - -/* - @file ecc_points.c - ECC Crypto, Tom St Denis -*/ - -/* - Allocate a new ECC point - @return A newly allocated point or NULL on error -*/ -ecc_point * -ecc_new_point (void) -{ - ecc_point *p; - p = calloc (1, sizeof (*p)); - if (p == NULL) - { - return NULL; - } - if (mp_init_multi (&p->x, &p->y, &p->z, NULL) != 0) - { - free (p); - return NULL; - } - return p; -} - -/* Free an ECC point from memory - @param p The point to free -*/ -void -ecc_del_point (ecc_point * p) -{ - /* prevents free'ing null arguments */ - if (p != NULL) - { - mp_clear_multi (&p->x, &p->y, &p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */ - free (p); - } -} - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_points.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/lib/nettle/ecc_projective_add_point_ng.c b/lib/nettle/ecc_projective_add_point_ng.c deleted file mode 100644 index 9bf370050a..0000000000 --- a/lib/nettle/ecc_projective_add_point_ng.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * Author: Ilya Tumaykin - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -#include "ecc.h" - -/* We use two algorithms for different cases. - * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html - * - * The algorithm used for general case is "add-1998-cmo-2" - * It costs 12M + 4S. - * - * If Z2 = 1 we use "madd". It costs 8M + 3S. - * - * The original versions use a lot of vars: - * Z1Z1, Z2Z2, U1, U2, S1, S2, H, I, HHH, r, V, etc. - * We use only the needed minimum: - * S1, H, HHH(J), r, V. - * The rest of the vars are not needed for final - * computation, so we calculate them, but don't store. - * Follow the comments. - */ - - -#define __WITH_EXTENDED_CHECKS -/* Check if H == 0 - * In this case P + Q = neutral element. - * - * In all of the cases below when H == 0 then Z == 0 - * and the resulting point lies at infinity. - * - * And the only point on the curve with Z == 0 MUST be - * the neutral point. - * - * Of course, if there wasn't a mistake somewhere before. - * We will be gullible and won't do any checks and simply - * return neutral point in that case. - */ - - -/* - Add two ECC points - @param P The point to add - @param Q The point to add - @param R [out] The destination of the double - @param a Curve's a value - @param modulus The modulus of the field the ECC curve is in - @return GNUTLS_E_SUCCESS on success - - Note: this function WILL work when a != -3. - It will work in general case without a change. -*/ -int -ecc_projective_add_point (ecc_point * P, ecc_point * Q, ecc_point * R, - mpz_t a, mpz_t modulus) -{ - mpz_t t0, t1, S1, H, HHH, r, V; - int err; - - if (P == NULL || Q == NULL || R == NULL || modulus == NULL) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - /* check all special cases first */ - - /* check for neutral points */ - if ((err = ecc_projective_isneutral (Q, modulus)) == 0) - { - /* P + Q = P + neutral = P */ - - mpz_set (R->x, P->x); - mpz_set (R->y, P->y); - mpz_set (R->z, P->z); - - return GNUTLS_E_SUCCESS; - } - else if (err < 0) - { - return err; - } - - if ((err = ecc_projective_isneutral (P, modulus)) == 0) - { - /* P + Q = neutral + Q = Q */ - - mpz_set (R->x, Q->x); - mpz_set (R->y, Q->y); - mpz_set (R->z, Q->z); - - return GNUTLS_E_SUCCESS; - } - else if (err < 0) - { - return err; - } - - if ((err = mp_init_multi (&S1, &H, &HHH, &r, &V, &t0, &t1, NULL)) != 0) - return err; - - /* Check if P == Q and do doubling in that case - * If Q == -P then P + Q = neutral element */ - if ((mpz_cmp (P->x, Q->x) == 0) && (mpz_cmp (P->z, Q->z) == 0)) - { - - /* x and z coordinates match. - * Check if P->y = Q->y, or P->y = -Q->y */ - - if (mpz_cmp (P->y, Q->y) == 0) - { - mp_clear_multi (&S1, &H, &HHH, &r, &V, &t0, &t1, NULL); - return ecc_projective_dbl_point (P, R, a, modulus); - } - - mpz_sub (t1, modulus, Q->y); - if (mpz_cmp (P->y, t1) == 0) - { - mp_clear_multi (&S1, &H, &HHH, &r, &V, &t0, &t1, NULL); - mpz_set_ui (R->x, 1); - mpz_set_ui (R->y, 1); - mpz_set_ui (R->z, 0); - return GNUTLS_E_SUCCESS; - } - } - - - /* check if Z2 == 1 and do "madd" in that case */ - if ((mpz_cmp_ui (Q->z, 1) == 0)) - { - mp_clear_multi (&S1, &H, &HHH, &r, &V, &t0, &t1, NULL); - return ecc_projective_madd (P, Q, R, a, modulus); - } - - /* no special cases occured - * do general routine */ - - /* t1 = Z1 * Z1 */ - /* it is the original Z1Z1 */ - mpz_mul (t1, P->z, P->z); - mpz_mod (t1, t1, modulus); - - /* t0 = Z1 * Z1Z1 */ - mpz_mul (t0, t1, P->z); - mpz_mod (t0, t0, modulus); - - /* H = X2 * Z1Z1 */ - /* it is the original U2 */ - mpz_mul (H, t1, Q->x); - mpz_mod (H, H, modulus); - - /* r = Y2 * Z1 * Z1Z1 */ - /* it is the original S2 */ - mpz_mul (r, t0, Q->y); - mpz_mod (r, r, modulus); - - /* S1 = Z2 * Z2 */ - /* it is the original Z2Z2 */ - mpz_mul (S1, Q->z, Q->z); - mpz_mod (S1, S1, modulus); - - /* t0 = X1 * Z2Z2 */ - /* it is the original U1 */ - mpz_mul (t0, S1, P->x); - mpz_mod (t0, t0, modulus); - - /* H = U2 - U1 = H - t0 */ - mpz_sub (H, H, t0); -#ifdef __WITH_EXTENDED_CHECKS - err = mpz_cmp_ui (H, 0); - if (err < 0) - { - mpz_add (H, H, modulus); - } - else if (!err) - { - mpz_set_ui (R->x, 1); - mpz_set_ui (R->y, 1); - mpz_set_ui (R->z, 0); - mp_clear_multi (&S1, &H, &HHH, &r, &V, &t0, &t1, NULL); - - return GNUTLS_E_SUCCESS; - } -#else - if (mpz_cmp_ui (H, 0) < 0) - mpz_add (H, H, modulus); -#endif - /* t1 = H^2 */ - /* it is the original HH */ - mpz_mul (t1, H, H); - mpz_mod (t1, t1, modulus); - /* HHH = H * HH */ - mpz_mul (HHH, t1, H); - mpz_mod (HHH, HHH, modulus); - - /* V = U1 * HH = t0 * t1 */ - mpz_mul (V, t1, t0); - mpz_mod (V, V, modulus); - - /* t0 = Z2 * Z2Z2 */ - mpz_mul (t0, S1, Q->z); - mpz_mod (t0, t0, modulus); - /* S1 = Y1 * Z2 * Z2Z2 */ - mpz_mul (S1, t0, P->y); - mpz_mod (S1, S1, modulus); - - /* r = S2 - S1 = r - S1 */ - mpz_sub (r, r, S1); - if (mpz_cmp_ui (r, 0) < 0) - mpz_add (r, r, modulus); - - /* we've calculated all needed vars: - * S1, H, HHH, r, V - * now, we will calculate the coordinates */ - - /* t0 = (r)^2 */ - mpz_mul (t0, r, r); - mpz_mod (t0, t0, modulus); - /* t0 = t0 - HHH */ - mpz_sub (t0, t0, HHH); - if (mpz_cmp_ui (t0, 0) < 0) - mpz_add (t0, t0, modulus); - /* t1 = 2V */ - mpz_add (t1, V, V); - if (mpz_cmp (t1, modulus) >= 0) - mpz_sub (t1, t1, modulus); - /* X = r^2 - HHH - 2V = t0 - t1 */ - mpz_sub (R->x, t0, t1); - if (mpz_cmp_ui (R->x, 0) < 0) - mpz_add (R->x, R->x, modulus); - - - /* t1 = V - X */ - mpz_sub (t1, V, R->x); - if (mpz_cmp_ui (t1, 0) < 0) - mpz_add (t1, t1, modulus); - /* t0 = r * t1 */ - mpz_mul (t0, r, t1); - mpz_mod (t0, t0, modulus); - /* t1 = S1 * HHH */ - mpz_mul (t1, S1, HHH); - mpz_mod (t1, t1, modulus); - /* Y = r*(V - X) - S1*HHH = t0 - t1 */ - mpz_sub (R->y, t0, t1); - if (mpz_cmp_ui (R->y, 0) < 0) - mpz_add (R->y, R->y, modulus); - - - /* t1 = Z1 * Z2 */ - mpz_mul (t1, P->z, Q->z); - mpz_mod (t1, t1, modulus); - /* Z = Z1 * Z2 * H = t1 * H */ - mpz_mul (R->z, t1, H); - mpz_mod (R->z, R->z, modulus); - - mp_clear_multi (&S1, &H, &HHH, &r, &V, &t0, &t1, NULL); - - return GNUTLS_E_SUCCESS; -} - -/* - Add two ECC points, when it is known that Z2 == 1 - @param P The point to add - @param Q The point with Z == 1 to add - @param R [out] The destination of the double - @param a Curve's a value - @param modulus The modulus of the field the ECC curve is in - @return GNUTLS_E_SUCCESS on success - - Note: this function will work when a != -3. - It will work in general case without a change. -*/ -int -ecc_projective_madd (ecc_point * P, ecc_point * Q, ecc_point * R, - mpz_t a, mpz_t modulus) -{ - mpz_t t0, t1, H, J, r, V; - int err; - - if (P == NULL || Q == NULL || R == NULL || modulus == NULL) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - /* check all special cases first */ - - /* check for neutral points */ - /* Q is guaranteed not to be neutral since it has Z == 1 */ - if ((err = ecc_projective_isneutral (P, modulus)) == 0) - { - /* P + Q = neutral + Q = Q */ - - mpz_set (R->x, Q->x); - mpz_set (R->y, Q->y); - mpz_set (R->z, Q->z); - - return GNUTLS_E_SUCCESS; - } - else if (err < 0) - { - return err; - } - - if ((err = mp_init_multi (&H, &J, &r, &V, &t0, &t1, NULL)) != 0) - return err; - - /* Check if P == Q and do doubling in that case - * If Q == -P then P + Q = neutral element */ - if ((mpz_cmp (P->x, Q->x) == 0) && (mpz_cmp (P->z, Q->z) == 0)) - { - - /* x and z coordinates match. - * Check if P->y = Q->y, or P->y = -Q->y */ - - if (mpz_cmp (P->y, Q->y) == 0) - { - mp_clear_multi (&H, &J, &r, &V, &t0, &t1, NULL); - return ecc_projective_dbl_point (P, R, a, modulus); - } - - mpz_sub (t1, modulus, Q->y); - if (mpz_cmp (P->y, t1) == 0) - { - mp_clear_multi (&H, &J, &r, &V, &t0, &t1, NULL); - mpz_set_ui (R->x, 1); - mpz_set_ui (R->y, 1); - mpz_set_ui (R->z, 0); - return GNUTLS_E_SUCCESS; - } - } - - /* no special cases occured - * do madd */ - - /* t1 = Z1 * Z1 */ - /* it is the original Z1Z1 */ - mpz_mul (t1, P->z, P->z); - mpz_mod (t1, t1, modulus); - - /* t0 = Z1 * Z1Z1 */ - mpz_mul (t0, t1, P->z); - mpz_mod (t0, t0, modulus); - - /* r = Y2 * Z1 * Z1Z1 */ - /* it is the original S2 */ - mpz_mul (r, t0, Q->y); - mpz_mod (r, r, modulus); - /* r = S2 - Y1 = r - Y1 */ - mpz_sub (r, r, P->y); - if (mpz_cmp_ui (r, 0) < 0) - mpz_add (r, r, modulus); - /* r = 2 * (S2 - Y1) */ - mpz_add (r, r, r); - if (mpz_cmp (r, modulus) >= 0) - mpz_sub (r, r, modulus); - - /* H = X2 * Z1Z1 */ - /* it is the original U2 */ - mpz_mul (H, t1, Q->x); - mpz_mod (H, H, modulus); - /* H = U2 - X1 = H - X1 */ - mpz_sub (H, H, P->x); -#ifdef __WITH_EXTENDED_CHECKS - err = mpz_cmp_ui (H, 0); - if (err < 0) - { - mpz_add (H, H, modulus); - } - else if (!err) - { - mpz_set_ui (R->x, 1); - mpz_set_ui (R->y, 1); - mpz_set_ui (R->z, 0); - mp_clear_multi (&H, &J, &r, &V, &t0, &t1, NULL); - - return GNUTLS_E_SUCCESS; - } -#else - if (mpz_cmp_ui (H, 0) < 0) - mpz_add (H, H, modulus); -#endif - - /* t0 = 2H */ - mpz_add (t0, H, H); - if (mpz_cmp (t0, modulus) >= 0) - mpz_sub (t0, t0, modulus); - /* t1 = (2H)^2 */ - /* it is the original I */ - mpz_mul (t1, t0, t0); - mpz_mod (t1, t1, modulus); - - /* J = H * I = H * t1 */ - mpz_mul (J, t1, H); - mpz_mod (J, J, modulus); - - /* V = X1 * I = X1 * t1 */ - mpz_mul (V, t1, P->x); - mpz_mod (V, V, modulus); - - /* we've calculated all needed vars: - * H, J, r, V - * now, we will calculate the coordinates */ - - /* Z = 2 * Z1 * H = Z1 * t0 */ - mpz_mul (R->z, P->z, t0); - mpz_mod (R->z, R->z, modulus); - - - /* t0 = (r)^2 */ - mpz_mul (t0, r, r); - mpz_mod (t0, t0, modulus); - /* t0 = t0 - J */ - mpz_sub (t0, t0, J); - if (mpz_cmp_ui (t0, 0) < 0) - mpz_add (t0, t0, modulus); - /* t1 = 2V */ - mpz_add (t1, V, V); - if (mpz_cmp (t1, modulus) >= 0) - mpz_sub (t1, t1, modulus); - /* X = r^2 - J - 2V = t0 - t1 */ - mpz_sub (R->x, t0, t1); - if (mpz_cmp_ui (R->x, 0) < 0) - mpz_add (R->x, R->x, modulus); - - - /* t1 = V - X */ - mpz_sub (t1, V, R->x); - if (mpz_cmp_ui (t1, 0) < 0) - mpz_add (t1, t1, modulus); - /* t0 = r * t1 */ - mpz_mul (t0, r, t1); - mpz_mod (t0, t0, modulus); - /* t1 = Y1 * J */ - mpz_mul (t1, J, P->y); - mpz_mod (t1, t1, modulus); - /* t1 = 2 * t1 */ - mpz_add (t1, t1, t1); - if (mpz_cmp (t1, modulus) >= 0) - mpz_sub (t1, t1, modulus); - /* Y = r * (V - X) - 2 * Y1 * J = t0 - t1 */ - mpz_sub (R->y, t0, t1); - if (mpz_cmp_ui (R->y, 0) < 0) - mpz_add (R->y, R->y, modulus); - - - mp_clear_multi (&H, &J, &r, &V, &t0, &t1, NULL); - - return GNUTLS_E_SUCCESS; -} diff --git a/lib/nettle/ecc_projective_check_point.c b/lib/nettle/ecc_projective_check_point.c deleted file mode 100644 index 69e1953617..0000000000 --- a/lib/nettle/ecc_projective_check_point.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -#include "ecc.h" -#include - -#ifdef ECC_SECP_CURVES_ONLY - -/* - @file ecc_projective_check_point.c -*/ - -/* - Checks whether a point lies on the curve y^2 = x^3 - 3x + b - @param P The point to check - @param modulus The modulus of the field the ECC curve is in - @param b The "B" value of the curve - @return 0 on success -*/ -int ecc_projective_check_point (ecc_point * P, mpz_t b, mpz_t modulus) -{ - mpz_t t1, t2, t3; - int err; - - if (P == NULL || b == NULL || modulus == NULL) - return -1; - - if (mpz_cmp_ui (P->z, 1) != 0) - { - gnutls_assert (); - return -1; - } - - if ((err = mp_init_multi (&t1, &t2, &t3, NULL)) != 0) - { - return err; - } - - /* t1 = Z * Z */ - mpz_mul (t1, P->y, P->y); - mpz_mod (t1, t1, modulus); /* t1 = y^2 */ - - mpz_mul (t2, P->x, P->x); - mpz_mod (t2, t2, modulus); - - mpz_mul (t2, P->x, t2); - mpz_mod (t2, t2, modulus); /* t2 = x^3 */ - - mpz_add (t3, P->x, P->x); - if (mpz_cmp (t3, modulus) >= 0) - { - mpz_sub (t3, t3, modulus); - } - - mpz_add (t3, t3, P->x); /* t3 = 3x */ - if (mpz_cmp (t3, modulus) >= 0) - { - mpz_sub (t3, t3, modulus); - } - - mpz_sub (t1, t1, t2); /* t1 = y^2 - x^3 */ - if (mpz_cmp_ui (t1, 0) < 0) - { - mpz_add (t1, t1, modulus); - } - - mpz_add (t1, t1, t3); /* t1 = y^2 - x^3 + 3x */ - if (mpz_cmp (t1, modulus) >= 0) - { - mpz_sub (t1, t1, modulus); - } - - mpz_sub (t1, t1, b); /* t1 = y^2 - x^3 + 3x - b */ - if (mpz_cmp_ui (t1, 0) < 0) - { - mpz_add (t1, t1, modulus); - } - - if (mpz_cmp_ui (t1, 0) != 0) - { - err = -1; - } - else - { - err = 0; - } - - mp_clear_multi(&t1, &t2, &t3, NULL); - - return err; -} - -#endif diff --git a/lib/nettle/ecc_projective_dbl_point_3.c b/lib/nettle/ecc_projective_dbl_point_3.c deleted file mode 100644 index 4331829fe2..0000000000 --- a/lib/nettle/ecc_projective_dbl_point_3.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -/* Based on public domain code of LibTomCrypt by Tom St Denis. - * Adapted to gmp and nettle by Nikos Mavrogiannopoulos. - */ - -#include "ecc.h" - -/* - @file ecc_projective_dbl_point.c - ECC Crypto, Tom St Denis -*/ - -#ifdef ECC_SECP_CURVES_ONLY - -/* - Double an ECC point - @param P The point to double - @param R [out] The destination of the double - @param a Curve's a value - @param modulus The modulus of the field the ECC curve is in - @return GNUTLS_E_SUCCESS on success -*/ -int -ecc_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a, - mpz_t modulus) -{ - /* Using "dbl-2004-hmv" algorithm. - * It costs 4M + 4S + half. */ - mpz_t t1, t2; - int err; - - if (P == NULL || R == NULL || modulus == NULL) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - if ( (err = ecc_projective_isneutral(P, modulus)) == 1 ) { - - if ((err = mp_init_multi(&t1, &t2, NULL)) != 0) { - return err; - } - - if (P != R) { - mpz_set(R->x, P->x); - mpz_set(R->y, P->y); - mpz_set(R->z, P->z); - } - - if (mpz_cmp_ui (P->z, 1) != 0) { - /* t1 = Z * Z */ - mpz_mul(t1, R->z, R->z); - mpz_mod(t1, t1, modulus); - /* Z = Y * Z */ - mpz_mul(R->z, R->y, R->z); - mpz_mod(R->z, R->z, modulus); - /* Z = 2Z */ - mpz_add(R->z, R->z, R->z); - if (mpz_cmp(R->z, modulus) >= 0) { - mpz_sub(R->z, R->z, modulus); - } - } else { - /* t1 = 1 */ - mpz_set(t1, P->z); - /* Z = 2Y */ - mpz_add(R->z, R->y, R->y); - if (mpz_cmp(R->z, modulus) >= 0) { - mpz_sub(R->z, R->z, modulus); - } - } - - /* T2 = X - T1 */ - mpz_sub(t2, R->x, t1); - if (mpz_cmp_ui(t2, 0) < 0) { - mpz_add(t2, t2, modulus); - } - /* T1 = X + T1 */ - mpz_add(t1, t1, R->x); - if (mpz_cmp(t1, modulus) >= 0) { - mpz_sub(t1, t1, modulus); - } - /* T2 = T1 * T2 */ - mpz_mul(t2, t1, t2); - mpz_mod(t2, t2, modulus); - /* T1 = 2T2 */ - mpz_add(t1, t2, t2); - if (mpz_cmp(t1, modulus) >= 0) { - mpz_sub(t1, t1, modulus); - } - /* T1 = T1 + T2 */ - mpz_add(t1, t1, t2); - if (mpz_cmp(t1, modulus) >= 0) { - mpz_sub(t1, t1, modulus); - } - - /* Y = 2Y */ - mpz_add(R->y, R->y, R->y); - if (mpz_cmp(R->y, modulus) >= 0) { - mpz_sub(R->y, R->y, modulus); - } - /* Y = Y * Y */ - mpz_mul(R->y, R->y, R->y); - mpz_mod(R->y, R->y, modulus); - /* T2 = Y * Y */ - mpz_mul(t2, R->y, R->y); - mpz_mod(t2, t2, modulus); - /* T2 = T2/2 */ - if (mpz_odd_p(t2)) { - mpz_add(t2, t2, modulus); - } - mpz_divexact_ui(t2, t2, 2); - /* Y = Y * X */ - mpz_mul(R->y, R->y, R->x); - mpz_mod(R->y, R->y, modulus); - - /* X = T1 * T1 */ - mpz_mul(R->x, t1, t1); - mpz_mod(R->x, R->x, modulus); - /* X = X - Y */ - mpz_sub(R->x, R->x, R->y); - if (mpz_cmp_ui(R->x, 0) < 0) { - mpz_add(R->x, R->x, modulus); - } - /* X = X - Y */ - mpz_sub(R->x, R->x, R->y); - if (mpz_cmp_ui(R->x, 0) < 0) { - mpz_add(R->x, R->x, modulus); - } - - /* Y = Y - X */ - mpz_sub(R->y, R->y, R->x); - if (mpz_cmp_ui(R->y, 0) < 0) { - mpz_add(R->y, R->y, modulus); - } - /* Y = Y * T1 */ - mpz_mul(R->y, R->y, t1); - mpz_mod(R->y, R->y, modulus); - /* Y = Y - T2 */ - mpz_sub(R->y, R->y, t2); - if (mpz_cmp_ui(R->y, 0) < 0) { - mpz_add( R->y, R->y, modulus); - } - - err = GNUTLS_E_SUCCESS; - - mp_clear_multi(&t1, &t2, NULL); - return err; - } else if (err == 0) { - /* 2*neutral = neutral */ - mpz_set_ui(R->x, 1); - mpz_set_ui(R->y, 1); - mpz_set_ui(R->z, 0); - - return GNUTLS_E_SUCCESS; - } else { - return err; - } -} -#endif -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_projective_dbl_point.c,v $ */ -/* $Revision: 1.11 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ - diff --git a/lib/nettle/ecc_projective_isneutral.c b/lib/nettle/ecc_projective_isneutral.c deleted file mode 100644 index da2d7ca929..0000000000 --- a/lib/nettle/ecc_projective_isneutral.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * Author: Ilya Tumaykin - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -#include "ecc.h" - -/* - Check if the given point is the neutral point - @param P The point to check - @param modulus The modulus of the field the ECC curve is in - @return 0 if given point is a neutral point - @return 1 if given point is not a neutral point - @return negative value in case of error -*/ -int -ecc_projective_isneutral (ecc_point * P, mpz_t modulus) -{ - mpz_t t1, t2; - int err; - - if (P == NULL || modulus == NULL) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - /* - * neutral point is a point with projective - * coordinates (x,y,0) such that y^2 == x^3 - * excluding point (0,0,0) - */ - if (mpz_sgn (P->z)) - /* Z != 0 */ - return 1; - - if ((err = mp_init_multi (&t1, &t2, NULL)) != 0) - { - return err; - } - - /* t1 == x^3 */ - mpz_mul (t1, P->x, P->x); - mpz_mod (t1, t1, modulus); - mpz_mul (t1, t1, P->x); - mpz_mod (t1, t1, modulus); - /* t2 == y^2 */ - mpz_mul (t2, P->y, P->y); - mpz_mod (t2, t2, modulus); - - if ((!mpz_cmp (t1, t2)) && (mpz_sgn (t1))) - { - /* Z == 0 and X^3 == Y^2 != 0 - * it is neutral */ - err = 0; - goto done; - } - - /* Z == 0 and X^3 != Y^2 or - * Z == X == Y == 0 - * this should never happen */ - err = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - goto done; -done: - mp_clear_multi (&t1, &t2, NULL); - return err; -} diff --git a/lib/nettle/ecc_projective_negate_point.c b/lib/nettle/ecc_projective_negate_point.c deleted file mode 100644 index 440d926a81..0000000000 --- a/lib/nettle/ecc_projective_negate_point.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * Author: Ilya Tumaykin - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -#include "ecc.h" - -/* - Negate an ECC point - @param P The point to negate - @param R [out] The destination of the negate - @param modulus The modulus of the field the ECC curve is in - @return GNUTLS_E_SUCCESS on success -*/ -int -ecc_projective_negate_point (ecc_point * P, ecc_point * R, mpz_t modulus) -{ - - if (P == NULL || R == NULL) - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - - if (ecc_projective_isneutral (P, modulus)) - { - /* we set R.y to (modulus - P.y) to avoid negative coordinates */ - mpz_set (R->x, P->x); - mpz_sub (R->y, modulus, P->y); - mpz_mod (R->y, R->y, modulus); - mpz_set (R->z, P->z); - } - else - { - /* -neutral = neutral */ - mpz_set_ui (R->x, 1); - mpz_set_ui (R->y, 1); - mpz_set_ui (R->z, 0); - } - - return GNUTLS_E_SUCCESS; -} diff --git a/lib/nettle/ecc_shared_secret.c b/lib/nettle/ecc_shared_secret.c deleted file mode 100644 index 58d3b31c99..0000000000 --- a/lib/nettle/ecc_shared_secret.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -/* Based on public domain code of LibTomCrypt by Tom St Denis. - * Adapted to gmp and nettle by Nikos Mavrogiannopoulos. - */ - -#include "ecc.h" -#include - -/* - @file ecc_shared_secret.c - ECC Crypto, Tom St Denis -*/ - -/* - Create an ECC shared secret between two keys - @param private_key The private ECC key - @param public_key The public key - @param out [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63) - @param outlen [in/out] The max size and resulting size of the shared secret - @return 0 if successful -*/ -int -ecc_shared_secret (ecc_key * private_key, ecc_key * public_key, - unsigned char *out, unsigned long *outlen) -{ - unsigned long x; - ecc_point *result; - int err; - - if (private_key == NULL || public_key == NULL || out == NULL || outlen == NULL) - return -1; - - /* type valid? */ - if (private_key->type != PK_PRIVATE) - { - return -1; - } - - /* make new point */ - result = ecc_new_point (); - if (result == NULL) - { - return -1; - } - - if ((err = - ecc_mulmod (private_key->k, &public_key->pubkey, result, - private_key->A, private_key->prime, 1)) != 0) - { - goto done; - } - - x = nettle_mpz_sizeinbase_256_u (private_key->prime); - if (*outlen < x) - { - *outlen = x; - err = -1; - goto done; - } - nettle_mpz_get_str_256(x, out, result->x); - - err = 0; - *outlen = x; -done: - ecc_del_point (result); - return err; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_shared_secret.c,v $ */ -/* $Revision: 1.10 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/lib/nettle/ecc_sign_hash.c b/lib/nettle/ecc_sign_hash.c deleted file mode 100644 index f1ae27af3d..0000000000 --- a/lib/nettle/ecc_sign_hash.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -/* Based on public domain code of LibTomCrypt by Tom St Denis. - * Adapted to gmp and nettle by Nikos Mavrogiannopoulos. - */ - -#include "ecc.h" -#include - -/* - @file ecc_sign_hash.c - ECC Crypto, Tom St Denis -*/ - -/* - Sign a message digest - @param in The message digest to sign - @param inlen The length of the digest - @param sign The destination for the signature - @param prng An active PRNG state - @param wprng The index of the PRNG you wish to use - @param key A private ECC key - @param curve_id The id of the curve we are working with - @return 0 if successful -*/ -int -ecc_sign_hash (const unsigned char *in, unsigned long inlen, - struct dsa_signature *sig, - void *random_ctx, nettle_random_func random, - ecc_key * key, gnutls_ecc_curve_t curve_id) -{ - ecc_key pubkey; - mpz_t e; - int err; - - if (in == NULL || sig == NULL || key == NULL) - return -1; - - /* is this a private key? */ - if (key->type != PK_PRIVATE) - { - return -1; - } - - /* get the hash and load it as a bignum into 'e' */ - /* init the bignums */ - if ((err = mp_init_multi (&e, NULL)) != 0) - { - return err; - } - - nettle_mpz_set_str_256_u (e, inlen, in); - - /* make up a key and export the public copy */ - for (;;) - { - if ((err = - ecc_make_key_ex (random_ctx, random, &pubkey, key->prime, - key->order, key->A, key->B, key->Gx, key->Gy, curve_id, 1)) != 0) - { - goto errnokey; - } - - /* find r = x1 mod n */ - mpz_mod (sig->r, pubkey.pubkey.x, pubkey.order); - - if (mpz_cmp_ui (sig->r, 0) == 0) - { - ecc_free (&pubkey); - } - else - { - /* find s = (e + xr)/k */ - mpz_invert (pubkey.k, pubkey.k, pubkey.order); - - /* mulmod */ - mpz_mul (sig->s, key->k, sig->r); - mpz_mod (sig->s, sig->s, pubkey.order); - mpz_add (sig->s, e, sig->s); - mpz_mod (sig->s, sig->s, pubkey.order); - - mpz_mul (sig->s, sig->s, pubkey.k); - mpz_mod (sig->s, sig->s, pubkey.order); - ecc_free (&pubkey); - if (mpz_cmp_ui (sig->s, 0) != 0) - { - break; - } - } - } - -errnokey: - mp_clear_multi (&e, NULL); - return err; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sign_hash.c,v $ */ -/* $Revision: 1.11 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/lib/nettle/ecc_verify_hash.c b/lib/nettle/ecc_verify_hash.c deleted file mode 100644 index 63075b7f3a..0000000000 --- a/lib/nettle/ecc_verify_hash.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -/* Based on public domain code of LibTomCrypt by Tom St Denis. - * Adapted to gmp and nettle by Nikos Mavrogiannopoulos. - */ - -#include "ecc.h" - -/* - @file ecc_verify_hash.c - ECC Crypto, Tom St Denis -*/ - -/* verify - * - * w = s^-1 mod n - * u1 = xw - * u2 = rw - * X = u1*G + u2*Q - * v = X_x1 mod n - * accept if v == r - */ - -/* - Verify an ECC signature - @param signature The signature to verify - @param hash The hash (message digest) that was signed - @param hashlen The length of the hash (octets) - @param stat Result of signature, 1==valid, 0==invalid - @param key The corresponding public ECC key - @param curve_id The id of the curve we are working with - @return 0 if successful (even if the signature is not valid) -*/ -int -ecc_verify_hash (struct dsa_signature *signature, - const unsigned char *hash, unsigned long hashlen, - int *stat, ecc_key * key, gnutls_ecc_curve_t curve_id) -{ - ecc_point *mG, *mQ; - mpz_t v, w, u1, u2, e; - int err; - - if (signature == NULL || hash == NULL || stat == NULL || key == NULL) - return -1; - - /* default to invalid signature */ - *stat = 0; - - /* allocate ints */ - if ((err = mp_init_multi (&v, &w, &u1, &u2, &e, NULL)) != 0) - { - return -1; - } - - /* allocate points */ - mG = ecc_new_point (); - mQ = ecc_new_point (); - if (mQ == NULL || mG == NULL) - { - err = -1; - goto error; - } - - /* check for (0) */ - if (mpz_cmp_ui (signature->r, 0) == 0 || mpz_cmp_ui (signature->s, 0) == 0 - || mpz_cmp (signature->r, key->order) >= 0 - || mpz_cmp (signature->s, key->order) >= 0) - { - err = -1; - goto error; - } - - /* read hash */ - nettle_mpz_set_str_256_u (e, hashlen, hash); - - /* w = s^-1 mod n */ - mpz_invert (w, signature->s, key->order); - - /* u1 = ew */ - mpz_mul (u1, e, w); - mpz_mod (u1, u1, key->order); - - /* u2 = rw */ - mpz_mul (u2, signature->r, w); - mpz_mod (u2, u2, key->order); - - /* find mG and mQ */ - mpz_set (mG->x, key->Gx); - mpz_set (mG->y, key->Gy); - mpz_set_ui (mG->z, 1); - - mpz_set (mQ->x, key->pubkey.x); - mpz_set (mQ->y, key->pubkey.y); - mpz_set (mQ->z, key->pubkey.z); - - /* compute u1*mG + u2*mQ = mG */ - if ((err = ecc_mulmod_cached (u1, curve_id, mG, key->A, key->prime, 0)) != 0) - { - goto error; - } - if ((err = ecc_mulmod (u2, mQ, mQ, key->A, key->prime, 0)) != 0) - { - goto error; - } - - /* add them */ - if ((err = - ecc_projective_add_point (mQ, mG, mG, key->A, key->prime)) != 0) - { - goto error; - } - - /* reduce */ - if ((err = ecc_map (mG, key->prime)) != 0) - { - goto error; - } - - /* v = X_x1 mod n */ - mpz_mod (v, mG->x, key->order); - - /* does v == r */ - if (mpz_cmp (v, signature->r) == 0) - { - *stat = 1; - } - - /* clear up and return */ - err = 0; -error: - ecc_del_point (mG); - ecc_del_point (mQ); - mp_clear_multi (&v, &w, &u1, &u2, &e, NULL); - return err; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_verify_hash.c,v $ */ -/* $Revision: 1.14 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/lib/nettle/init.c b/lib/nettle/init.c index 7982347bf0..0799d33bfc 100644 --- a/lib/nettle/init.c +++ b/lib/nettle/init.c @@ -24,7 +24,6 @@ #include #include #include -#include "ecc.h" /* Functions that refer to the initialization of the nettle library. */ @@ -32,7 +31,7 @@ int gnutls_crypto_init (void) { - return ecc_wmnaf_cache_init(); + return 0; } /* Functions that refer to the deinitialization of the nettle library. @@ -41,5 +40,4 @@ gnutls_crypto_init (void) void gnutls_crypto_deinit (void) { - ecc_wmnaf_cache_free(); } diff --git a/lib/nettle/multi.c b/lib/nettle/multi.c deleted file mode 100644 index 788c8e9a00..0000000000 --- a/lib/nettle/multi.c +++ /dev/null @@ -1,46 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include -#include -#include - -int mp_init_multi(mpz_t *a, ...) -{ - mpz_t *cur = a; - int np = 0; - va_list args; - - va_start(args, a); - while (cur != NULL) { - mpz_init(*cur); - ++np; - cur = va_arg(args, mpz_t*); - } - va_end(args); - return 0; -} - -void mp_clear_multi(mpz_t *a, ...) -{ - mpz_t *cur = a; - va_list args; - - va_start(args, a); - while (cur != NULL) { - mpz_clear(*cur); - cur = va_arg(args, mpz_t*); - } - va_end(args); -} - -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 50be724753..b2862229e1 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2010-2012 Free Software Foundation, Inc. + * Copyright (C) 2013 Nikos Mavrogiannopoulos * * Author: Nikos Mavrogiannopoulos * @@ -38,13 +39,15 @@ #include #include #include -#include #include -#include "ecc.h" +#include +#include +#include +#include #define TOMPZ(x) (*((mpz_t*)(x))) -static inline int is_supported_curve(int curve); +static inline const struct ecc_curve *get_supported_curve(int curve); static void rnd_func (void *_ctx, unsigned length, uint8_t * data) @@ -91,42 +94,50 @@ _rsa_params_to_pubkey (const gnutls_pk_params_st * pk_params, pub->size = nettle_mpz_sizeinbase_256_u(pub->n); } -static void +static int _ecc_params_to_privkey(const gnutls_pk_params_st * pk_params, - ecc_key * priv) + struct ecc_scalar * priv, const struct ecc_curve *curve) { - priv->type = PK_PRIVATE; - memcpy(&priv->prime, pk_params->params[ECC_PRIME], sizeof(mpz_t)); - memcpy(&priv->order, pk_params->params[ECC_ORDER], sizeof(mpz_t)); - memcpy(&priv->A, pk_params->params[ECC_A], sizeof(mpz_t)); - memcpy(&priv->B, pk_params->params[ECC_B], sizeof(mpz_t)); - memcpy(&priv->Gx, pk_params->params[ECC_GX], sizeof(mpz_t)); - memcpy(&priv->Gy, pk_params->params[ECC_GY], sizeof(mpz_t)); - memcpy(&priv->pubkey.x, pk_params->params[ECC_X], sizeof(mpz_t)); - memcpy(&priv->pubkey.y, pk_params->params[ECC_Y], sizeof(mpz_t)); - memcpy(&priv->k, pk_params->params[ECC_K], sizeof(mpz_t)); - mpz_init_set_ui(priv->pubkey.z, 1); + ecc_scalar_init(priv, curve); + if (ecc_scalar_set(priv, pk_params->params[ECC_K]) == 0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + return 0; } -static void _ecc_params_clear(ecc_key * key) +static int +_ecc_params_to_pubkey(const gnutls_pk_params_st * pk_params, + struct ecc_point * pub, const struct ecc_curve *curve) { - mpz_clear(key->pubkey.z); + ecc_point_init(pub, curve); + if (ecc_point_set(pub, pk_params->params[ECC_X], pk_params->params[ECC_Y]) == 0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + return 0; } -static void -_ecc_params_to_pubkey(const gnutls_pk_params_st * pk_params, - ecc_key * pub) +static void +ecc_shared_secret (struct ecc_scalar * private_key, + struct ecc_point * public_key, + void *out, unsigned size) { - pub->type = PK_PUBLIC; - memcpy(&pub->prime, pk_params->params[ECC_PRIME], sizeof(mpz_t)); - memcpy(&pub->order, pk_params->params[ECC_ORDER], sizeof(mpz_t)); - memcpy(&pub->A, pk_params->params[ECC_A], sizeof(mpz_t)); - memcpy(&pub->B, pk_params->params[ECC_B], sizeof(mpz_t)); - memcpy(&pub->Gx, pk_params->params[ECC_GX], sizeof(mpz_t)); - memcpy(&pub->Gy, pk_params->params[ECC_GY], sizeof(mpz_t)); - memcpy(&pub->pubkey.x, pk_params->params[ECC_X], sizeof(mpz_t)); - memcpy(&pub->pubkey.y, pk_params->params[ECC_Y], sizeof(mpz_t)); - mpz_init_set_ui(pub->pubkey.z, 1); +struct ecc_point r; +mpz_t x, y; + + mpz_init(x); + mpz_init(y); + ecc_point_init(&r, public_key->ecc); + + ecc_point_mul(&r, private_key, public_key); + + ecc_point_get(&r, x, y); + nettle_mpz_get_str_256(size, out, x); + + mpz_clear(x); + mpz_clear(y); + ecc_point_clear(&r); + + return; } static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, gnutls_datum_t * out, @@ -139,47 +150,42 @@ static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, gnutls_datum_t * o { case GNUTLS_PK_EC: { - ecc_key ecc_pub, ecc_priv; - int curve = priv->flags; - unsigned long sz; + struct ecc_scalar ecc_priv; + struct ecc_point ecc_pub; + const struct ecc_curve * curve; out->data = NULL; - if (is_supported_curve(curve) == 0) + curve = get_supported_curve(priv->flags); + if (curve == NULL) return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); - _ecc_params_to_pubkey(pub, &ecc_pub); - _ecc_params_to_privkey(priv, &ecc_priv); - sz = ECC_BUF_SIZE; - - if (ecc_projective_check_point(&ecc_pub.pubkey, pub->params[ECC_B], pub->params[ECC_PRIME]) != 0) + ret = _ecc_params_to_pubkey(pub, &ecc_pub, curve); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _ecc_params_to_privkey(priv, &ecc_priv, curve); + if (ret < 0) { - ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); - goto ecc_cleanup; + ecc_point_clear(&ecc_pub); + return gnutls_assert_val(ret); } - out->data = gnutls_malloc(sz); + out->size = gnutls_ecc_curve_get_size(priv->flags); + /*ecc_size(curve)*sizeof(mp_limb_t);*/ + out->data = gnutls_malloc(out->size); if (out->data == NULL) { ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); goto ecc_cleanup; } - ret = ecc_shared_secret(&ecc_priv, &ecc_pub, out->data, &sz); - if (ret != 0) - ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + ecc_shared_secret(&ecc_priv, &ecc_pub, out->data, out->size); ecc_cleanup: - _ecc_params_clear(&ecc_pub); - _ecc_params_clear(&ecc_priv); + ecc_point_clear(&ecc_pub); + ecc_scalar_clear(&ecc_priv); - if (ret < 0) - { - gnutls_free(out->data); - return ret; - } - - out->size = sz; break; } default: @@ -328,14 +334,18 @@ _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo, { case GNUTLS_PK_EC: /* we do ECDSA */ { - ecc_key priv; + struct ecc_scalar priv; struct dsa_signature sig; int curve_id = pk_params->flags; + const struct ecc_curve * curve; - if (is_supported_curve(curve_id) == 0) + curve = get_supported_curve(curve_id); + if (curve == NULL) return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); - _ecc_params_to_privkey(pk_params, &priv); + ret = _ecc_params_to_privkey(pk_params, &priv, curve); + if (ret < 0) + return gnutls_assert_val(ret); dsa_signature_init (&sig); @@ -347,20 +357,12 @@ _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo, hash_len = vdata->size; } - ret = ecc_sign_hash(vdata->data, hash_len, - &sig, NULL, rnd_func, &priv, curve_id); - if (ret != 0) - { - gnutls_assert (); - ret = GNUTLS_E_PK_SIGN_FAILED; - goto ecdsa_fail; - } + ecdsa_sign(&priv, NULL, rnd_func, hash_len, vdata->data, &sig); ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s); - ecdsa_fail: dsa_signature_clear (&sig); - _ecc_params_clear( &priv); + ecc_scalar_clear( &priv); if (ret < 0) { @@ -472,22 +474,26 @@ _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo, { case GNUTLS_PK_EC: /* ECDSA */ { - ecc_key pub; + struct ecc_point pub; struct dsa_signature sig; - int stat; int curve_id = pk_params->flags; + const struct ecc_curve * curve; - if (is_supported_curve(curve_id) == 0) + curve = get_supported_curve(curve_id); + if (curve == NULL) return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _ecc_params_to_pubkey(pk_params, &pub, curve); if (ret < 0) { - gnutls_assert (); + gnutls_assert(); goto cleanup; } - - _ecc_params_to_pubkey(pk_params, &pub); + memcpy (&sig.r, tmp[0], sizeof (sig.r)); memcpy (&sig.s, tmp[1], sizeof (sig.s)); @@ -495,8 +501,8 @@ _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo, if (hash_len > vdata->size) hash_len = vdata->size; - ret = ecc_verify_hash(&sig, vdata->data, hash_len, &stat, &pub, curve_id); - if (ret != 0 || stat != 1) + ret = ecdsa_verify(&pub, hash_len, vdata->data, &sig); + if (ret == 0) { gnutls_assert(); ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; @@ -504,9 +510,7 @@ _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo, else ret = 0; - _gnutls_mpi_release (&tmp[0]); - _gnutls_mpi_release (&tmp[1]); - _ecc_params_clear( &pub); + ecc_point_clear( &pub); break; } case GNUTLS_PK_DSA: @@ -538,8 +542,6 @@ _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo, else ret = 0; - _gnutls_mpi_release (&tmp[0]); - _gnutls_mpi_release (&tmp[1]); break; } case GNUTLS_PK_RSA: @@ -563,7 +565,6 @@ _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo, ret = gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED); else ret = 0; - _gnutls_mpi_release (&tmp[0]); break; } default: @@ -574,15 +575,28 @@ _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo, cleanup: + _gnutls_mpi_release (&tmp[0]); + _gnutls_mpi_release (&tmp[1]); return ret; } -static inline int is_supported_curve(int curve) +static inline const struct ecc_curve *get_supported_curve(int curve) { - if (gnutls_ecc_curve_get_name(curve) != NULL) - return 1; - else - return 0; + switch(curve) + { + case GNUTLS_ECC_CURVE_SECP192R1: + return &nettle_secp_192r1; + case GNUTLS_ECC_CURVE_SECP224R1: + return &nettle_secp_224r1; + case GNUTLS_ECC_CURVE_SECP256R1: + return &nettle_secp_256r1; + case GNUTLS_ECC_CURVE_SECP384R1: + return &nettle_secp_384r1; + case GNUTLS_ECC_CURVE_SECP521R1: + return &nettle_secp_521r1; + default: + return NULL; + } } @@ -707,55 +721,42 @@ rsa_fail: } case GNUTLS_PK_EC: { - ecc_key key; - ecc_set_type tls_ecc_set; - const gnutls_ecc_curve_entry_st *st; + struct ecc_scalar key; + struct ecc_point pub; + const struct ecc_curve* curve; - st = _gnutls_ecc_curve_get_params(level); - if (st == NULL) + curve = get_supported_curve(level); + if (curve == NULL) return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); - tls_ecc_set.size = st->size; - tls_ecc_set.prime = st->prime; - tls_ecc_set.order = st->order; - tls_ecc_set.Gx = st->Gx; - tls_ecc_set.Gy = st->Gy; - tls_ecc_set.A = st->A; - tls_ecc_set.B = st->B; - - ret = ecc_make_key(NULL, rnd_func, &key, &tls_ecc_set, st->id); - if (ret != 0) - return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + ecc_scalar_init(&key, curve); + ecc_point_init(&pub, curve); + + ecdsa_generate_keypair(&pub, &key, NULL, rnd_func); + + params->params[ECC_X] = _gnutls_mpi_new (0); + params->params[ECC_Y] = _gnutls_mpi_new (0); + params->params[ECC_K] = _gnutls_mpi_new (0); + + if (params->params[ECC_X] == NULL || params->params[ECC_Y] == NULL || + params->params[ECC_K] == NULL) + { + _gnutls_mpi_release(¶ms->params[ECC_X]); + _gnutls_mpi_release(¶ms->params[ECC_Y]); + _gnutls_mpi_release(¶ms->params[ECC_K]); + goto ecc_cleanup; + } - params->params_nr = 0; - for (i = 0; i < ECC_PRIVATE_PARAMS; i++) - { - params->params[i] = _gnutls_mpi_alloc_like(&key.prime); - if (params->params[i] == NULL) - { - ret = GNUTLS_E_MEMORY_ERROR; - goto ecc_fail; - } - params->params_nr++; - } params->flags = level; + params->params_nr = ECC_PRIVATE_PARAMS; - mpz_set(TOMPZ(params->params[ECC_PRIME]), key.prime); - mpz_set(TOMPZ(params->params[ECC_ORDER]), key.order); - mpz_set(TOMPZ(params->params[ECC_A]), key.A); - mpz_set(TOMPZ(params->params[ECC_B]), key.B); - mpz_set(TOMPZ(params->params[ECC_GX]), key.Gx); - mpz_set(TOMPZ(params->params[ECC_GY]), key.Gy); - mpz_set(TOMPZ(params->params[ECC_X]), key.pubkey.x); - mpz_set(TOMPZ(params->params[ECC_Y]), key.pubkey.y); - mpz_set(TOMPZ(params->params[ECC_K]), key.k); - -ecc_fail: - ecc_free(&key); - - if (ret < 0) - goto fail; + ecc_point_get(&pub, TOMPZ(params->params[ECC_X]), TOMPZ(params->params[ECC_Y])); + ecc_scalar_get(&key, TOMPZ(params->params[ECC_K])); +ecc_cleanup: + ecc_point_clear(&pub); + ecc_scalar_clear(&key); + break; } default: @@ -876,41 +877,53 @@ dsa_cleanup: break; case GNUTLS_PK_EC: { - int curve = params->flags; - ecc_key ecc_priv; - ecc_point *R; - ecc_point zero; - + struct ecc_point r, pub; + struct ecc_scalar priv; + mpz_t x1, y1, x2, y2; + const struct ecc_curve * curve; + if (params->params_nr != ECC_PRIVATE_PARAMS) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - if (is_supported_curve(curve) == 0) + curve = get_supported_curve(params->flags); + if (curve == NULL) return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); - _ecc_params_to_privkey(params, &ecc_priv); - R = ecc_new_point(); + ret = _ecc_params_to_pubkey(params, &pub, curve); + if (ret < 0) + return gnutls_assert_val(ret); - /* verify that x,y lie on the curve */ - ret = ecc_projective_check_point(&ecc_priv.pubkey, TOMPZ(params->params[ECC_B]), params->params[ECC_PRIME]); - if (ret != 0) + ret = _ecc_params_to_privkey(params, &priv, curve); + if (ret < 0) { - ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); - goto ecc_cleanup; + ecc_point_clear(&pub); + return gnutls_assert_val(ret); } - memcpy(&zero.x, ecc_priv.Gx, sizeof(mpz_t)); - memcpy(&zero.y, ecc_priv.Gy, sizeof(mpz_t)); - memcpy(&zero.z, ecc_priv.pubkey.z, sizeof(mpz_t)); /* z = 1 */ - - /* verify that k*(Gx,Gy)=(x,y) */ - ret = ecc_mulmod_cached(ecc_priv.k, curve, R, TOMPZ(params->params[ECC_A]), TOMPZ(params->params[ECC_PRIME]), 1); - if (ret != 0) + ecc_point_init(&r, curve); + /* verify that x,y lie on the curve */ + ret = ecc_point_set(&r, TOMPZ(params->params[ECC_X]), TOMPZ(params->params[ECC_Y])); + if (ret == 0) { ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); goto ecc_cleanup; } + ecc_point_clear(&r); - if (mpz_cmp(ecc_priv.pubkey.x, R->x) != 0 || mpz_cmp(ecc_priv.pubkey.y, R->y) != 0) + ecc_point_init(&r, curve); + ecc_point_mul_g(&r, &priv); + + mpz_init(x1); + mpz_init(y1); + ecc_point_get(&r, x1, y1); + ecc_point_clear(&r); + + mpz_init(x2); + mpz_init(y2); + ecc_point_get(&pub, x2, y2); + + /* verify that k*(Gx,Gy)=(x,y) */ + if (mpz_cmp(x1, x2) != 0 || mpz_cmp(y1, y2) != 0) { ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); goto ecc_cleanup; @@ -919,8 +932,8 @@ dsa_cleanup: ret = 0; ecc_cleanup: - _ecc_params_clear(&ecc_priv); - ecc_del_point(R); + ecc_scalar_clear(&priv); + ecc_point_clear(&pub); } break; default: diff --git a/lib/nettle/wmnaf.c b/lib/nettle/wmnaf.c deleted file mode 100644 index d29c901768..0000000000 --- a/lib/nettle/wmnaf.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2011-2012 Free Software Foundation, Inc. - * - * Author: Ilya Tumaykin - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - */ - -#include - -#include -#include -#include - -#include "ecc.h" - -/* needed constants */ -#define BASEW (1 << WMNAF_WINSIZE) /* 2^w */ -#define BASEWW (1 << (WMNAF_WINSIZE + 1)) /* 2^(w+1) */ -#define WBITS (BASEWW - 1) - -#define ABS(x) ((x) >= 0 ? (x) : -(x)) - -/* GMP lacks this typedef in versions prior to 5 */ -#if __GNU_MP__ < 5 -typedef unsigned long int mp_bitcnt_t; -#endif - -/* - * A local replacement for mpz_tstbit. - * It is needed because original mpz_tstbit process negative numbers - * in a two-complement manner and we don't want it. - * This function mimics mpz_tstbit behavior for positive numbers in both cases. - */ -static int -mpz_unitstbit (mpz_t u, mp_bitcnt_t bit_index) - __GMP_NOTHROW -{ - mp_srcptr u_ptr = u->_mp_d; - mp_size_t size = u->_mp_size; - mp_size_t abs_size = ABS (size); - mp_size_t limb_index = bit_index / GMP_NUMB_BITS; - mp_srcptr p = u_ptr + limb_index; - mp_limb_t limb; - - if (limb_index >= abs_size) - return (size < 0); - - limb = *p; - - return (limb >> (bit_index % GMP_NUMB_BITS)) & 1; -} - -/* - * Return an array with wMNAF representation together with its length. - * The result is the array with elements from the set {0, +-1, +-3, +-5, ..., +-(2^w - 1)} - * such that at most one of any (w + 1) consecutive digits is non-zero - * with exception for the the most significant (w + 1) bits. - * With the last property it is modified version of wNAF. - * Overview of this algorithm can be found, for exmaple, in - * Bodo Moller, Improved Techniques for Fast Exponentiation. - * Information Security and Cryptology – ICISC 2002, Springer-Verlag LNCS 2587, pp. 298–312 - */ -/* - @param x The number to get wMNAF for - @param len [out] Destination for the length of wMNAF - @return array with wMNAF representation - @return NULL in case of errors - */ -signed char * -ecc_wMNAF (mpz_t x, size_t * wmnaf_len) -{ - int b, c; - char sign = 1; - size_t i, len; - - signed char *ret = NULL; - - if (!(sign = mpz_sgn (x))) - { - /* x == 0 */ - ret = malloc (1); - if (ret == NULL) - goto done; - - ret[0] = 0; - *wmnaf_len = 1; - goto done; - } - - /* total number of bits */ - len = mpz_sizeinbase (x, 2); - - /* wMNAF is at most (len + 1) bits long */ - ret = malloc (len + 1); - if (ret == NULL) - goto done; - - /* get (w + 1) Least Significant Bits */ - c = (mpz_getlimbn (x, 0)) & WBITS; - - /* how many bits we've already processed */ - i = 0; - - while ((c != 0) || (i + WMNAF_WINSIZE + 1 < len)) - { - if (c & 1) - { - /* LSB == 1 */ - if (c >= BASEW) - { - b = c - BASEWW; - } - else - { - b = c; - } - - c -= b; - } - else - { - b = 0; - } - - ret[i++] = sign * b; - - /* fill c with next LSB */ - c >>= 1; - c += BASEW * mpz_unitstbit (x, i + WMNAF_WINSIZE); - } - - *wmnaf_len = i--; - - /* do modified wNAF - * check if wNAF starts with 1 and - * (w + 1)th bit is negative */ - if ((ret[i] == 1) && (ret[i - (WMNAF_WINSIZE + 1)] < 0)) - { - ret[i - (WMNAF_WINSIZE + 1)] += BASEW; - ret[i - 1] = 1; - *wmnaf_len = i; - } -done: - return ret; -} diff --git a/lib/x509/key_decode.c b/lib/x509/key_decode.c index 2a52ecf787..b2267af5da 100644 --- a/lib/x509/key_decode.c +++ b/lib/x509/key_decode.c @@ -221,13 +221,6 @@ _gnutls_x509_read_ecc_params (uint8_t * der, int dersize, gnutls_pk_params_st * goto cleanup; } - ret = _gnutls_ecc_curve_fill_params(params->flags, params); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - ret = 0; cleanup: diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index 61fd52304e..a755d888b8 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -294,13 +294,6 @@ _gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key, goto error; } - ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params); - if (ret < 0) - { - gnutls_assert(); - goto error; - } - /* read the public key */ ret = _gnutls_x509_read_value (pkey_asn, "publicKey", &out); if (ret < 0) @@ -974,10 +967,6 @@ gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key, key->params.flags = curve; - ret = _gnutls_ecc_curve_fill_params(curve, &key->params); - if (ret < 0) - return gnutls_assert_val(ret); - if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X], x->data, x->size)) { gnutls_assert ();