* 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)
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;
.id = GNUTLS_ECC_CURVE_SECP192R1,
.tls_id = 19,
.size = 24,
- .prime = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
- .A = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
- .B = "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
- .order = "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
- .Gx = "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
- .Gy = "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"
},
{
.name = "SECP224R1",
.id = GNUTLS_ECC_CURVE_SECP224R1,
.tls_id = 21,
.size = 28,
- .prime = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
- .A = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
- .B = "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
- .order = "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
- .Gx = "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
- .Gy = "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
},
{
.name = "SECP256R1",
.id = GNUTLS_ECC_CURVE_SECP256R1,
.tls_id = 23,
.size = 32,
- .prime = "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
- .A = "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
- .B = "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
- .order = "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
- .Gx = "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
- .Gy = "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
},
{
.name = "SECP384R1",
.id = GNUTLS_ECC_CURVE_SECP384R1,
.tls_id = 24,
.size = 48,
- .prime = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
- .A = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
- .B = "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
- .order = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
- .Gx = "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
- .Gy = "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"
},
{
.name = "SECP521R1",
.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}
};
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;
ret = _gnutls_set_psk_session_key (session, psk_key, &tmp_dh_key);
_gnutls_free_datum (&tmp_dh_key);
}
-
if (ret < 0)
{
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);
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);
/* 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 */
/* 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
* [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
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;
-
-}
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
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;
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 ();
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
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-#include <gmp.h>
-#include <nettle/nettle-types.h>
-#include <nettle/dsa.h>
-#include <nettle/bignum.h>
-#include <gnutls_int.h>
-
-/* 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, ...);
-
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-/* 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 $ */
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-/* 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 $ */
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-/* 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 $ */
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-#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;
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-/* needed for gnutls_* types */
-#include <gnutls_int.h>
-#include <algorithms.h>
-
-#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);
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-/* 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 $ */
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-#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;
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-#include "ecc.h"
-#include <gnutls_errors.h>
-
-#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
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-/* 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 $ */
-
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-#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;
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-#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;
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-/* Based on public domain code of LibTomCrypt by Tom St Denis.
- * Adapted to gmp and nettle by Nikos Mavrogiannopoulos.
- */
-
-#include "ecc.h"
-#include <string.h>
-
-/*
- @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 $ */
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-/* Based on public domain code of LibTomCrypt by Tom St Denis.
- * Adapted to gmp and nettle by Nikos Mavrogiannopoulos.
- */
-
-#include "ecc.h"
-#include <nettle/dsa.h>
-
-/*
- @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 $ */
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-/* 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 $ */
#include <gnutls_errors.h>
#include <gnutls_num.h>
#include <gnutls_mpi.h>
-#include "ecc.h"
/* Functions that refer to the initialization of the nettle library.
*/
int
gnutls_crypto_init (void)
{
- return ecc_wmnaf_cache_init();
+ return 0;
}
/* Functions that refer to the deinitialization of the nettle library.
void
gnutls_crypto_deinit (void)
{
- ecc_wmnaf_cache_free();
}
+++ /dev/null
-/* 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 <gmp.h>
-#include <stdarg.h>
-#include <ecc.h>
-
-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$ */
/*
* Copyright (C) 2010-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Nikos Mavrogiannopoulos
*
* Author: Nikos Mavrogiannopoulos
*
#include <gnutls_pk.h>
#include <nettle/dsa.h>
#include <nettle/rsa.h>
-#include <random.h>
#include <gnutls/crypto.h>
-#include "ecc.h"
+#include <nettle/bignum.h>
+#include <nettle/ecc.h>
+#include <nettle/ecdsa.h>
+#include <nettle/ecc-curve.h>
#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)
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,
{
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:
{
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);
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)
{
{
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));
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;
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:
else
ret = 0;
- _gnutls_mpi_release (&tmp[0]);
- _gnutls_mpi_release (&tmp[1]);
break;
}
case GNUTLS_PK_RSA:
ret = gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
else ret = 0;
- _gnutls_mpi_release (&tmp[0]);
break;
}
default:
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;
+ }
}
}
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:
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;
ret = 0;
ecc_cleanup:
- _ecc_params_clear(&ecc_priv);
- ecc_del_point(R);
+ ecc_scalar_clear(&priv);
+ ecc_point_clear(&pub);
}
break;
default:
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <gmp.h>
-
-#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;
-}
goto cleanup;
}
- ret = _gnutls_ecc_curve_fill_params(params->flags, params);
- if (ret < 0)
- {
- gnutls_assert();
- goto cleanup;
- }
-
ret = 0;
cleanup:
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)
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 ();