diff options
author | Niels Möller <nisse@lysator.liu.se> | 2013-02-20 11:27:24 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2013-02-20 11:27:24 +0100 |
commit | bf913c733da8b5e5d9f9e4cca5ed81b92237774d (patch) | |
tree | c24a14d4a0996b207d8f388ba18d5199a7308e6a | |
parent | aaf431459847561bc8df7e31bfb62fe95cfc3382 (diff) | |
download | nettle-bf913c733da8b5e5d9f9e4cca5ed81b92237774d.tar.gz |
Implemented ECDSA key generation.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | ecdsa-keygen.c | 51 | ||||
-rw-r--r-- | testsuite/.gitignore | 1 | ||||
-rw-r--r-- | testsuite/.test-rules.make | 3 | ||||
-rw-r--r-- | testsuite/Makefile.in | 2 | ||||
-rw-r--r-- | testsuite/ecdsa-keygen-test.c | 113 |
7 files changed, 176 insertions, 2 deletions
@@ -1,5 +1,11 @@ 2013-02-20 Niels Möller <nisse@lysator.liu.se> + * ecdsa-keygen.c (ecdsa_generate_keypair): New file and function. + * Makefile.in (hogweed_SOURCES): Added ecdsa-keygen.c. + * testsuite/ecdsa-keygen-test.c: New testcase. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + ecdsa-keygen-test.c. + * nettle-internal.h (TMP_ALLOC): Added missing parentheses. 2013-02-18 Niels Möller <nisse@lysator.liu.se> diff --git a/Makefile.in b/Makefile.in index 958278df..a327b0bf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -133,7 +133,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ ecc-mul-g.c ecc-mul-a.c ecc-hash.c ecc-random.c \ ecc-point.c ecc-scalar.c \ ecc-ecdsa-sign.c ecdsa-sign.c \ - ecc-ecdsa-verify.c ecdsa-verify.c + ecc-ecdsa-verify.c ecdsa-verify.c ecdsa-keygen.c HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \ base16.h base64.h buffer.h camellia.h cast128.h \ diff --git a/ecdsa-keygen.c b/ecdsa-keygen.c new file mode 100644 index 00000000..7f8a37f1 --- /dev/null +++ b/ecdsa-keygen.c @@ -0,0 +1,51 @@ +/* ecdsa-keygen.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Niels Möller + * + * The nettle 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. + * + * The nettle 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 the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +/* Development of Nettle's ECC support was funded by Internetfonden. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <stdlib.h> + +#include "ecdsa.h" +#include "ecc-internal.h" +#include "nettle-internal.h" + +void +ecdsa_generate_keypair (struct ecc_point *pub, + struct ecc_scalar *key, + void *random_ctx, nettle_random_func *random) +{ + TMP_DECL(p, mp_limb_t, 3*ECC_MAX_SIZE + ECC_MUL_G_ITCH (ECC_MAX_SIZE)); + mp_size_t itch = 3*pub->ecc->size + ECC_MUL_G_ITCH (pub->ecc->size); + + assert (key->ecc == pub->ecc); + + TMP_ALLOC (p, itch); + + ecc_modq_random (key->ecc, key->p, random_ctx, random, p); + ecc_mul_g (pub->ecc, p, key->p, p + 3*pub->ecc->size); + ecc_j_to_a (pub->ecc, 1, pub->p, p, p + 3*pub->ecc->size); +} diff --git a/testsuite/.gitignore b/testsuite/.gitignore index a5b83b51..642d8c42 100644 --- a/testsuite/.gitignore +++ b/testsuite/.gitignore @@ -23,6 +23,7 @@ /ecc-mul-a-test /ecc-mul-g-test /ecc-redc-test +/ecdsa-keygen-test /ecdsa-sign-test /ecdsa-verify-test /gcm-test diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make index f23f2515..a935171d 100644 --- a/testsuite/.test-rules.make +++ b/testsuite/.test-rules.make @@ -181,6 +181,9 @@ ecdsa-sign-test$(EXEEXT): ecdsa-sign-test.$(OBJEXT) ecdsa-verify-test$(EXEEXT): ecdsa-verify-test.$(OBJEXT) $(LINK) ecdsa-verify-test.$(OBJEXT) $(TEST_OBJS) -o ecdsa-verify-test$(EXEEXT) +ecdsa-keygen-test$(EXEEXT): ecdsa-keygen-test.$(OBJEXT) + $(LINK) ecdsa-keygen-test.$(OBJEXT) $(TEST_OBJS) -o ecdsa-keygen-test$(EXEEXT) + sha1-huge-test$(EXEEXT): sha1-huge-test.$(OBJEXT) $(LINK) sha1-huge-test.$(OBJEXT) $(TEST_OBJS) -o sha1-huge-test$(EXEEXT) diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index 847c01d7..a155b447 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -37,7 +37,7 @@ TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \ dsa-test.c dsa-keygen-test.c \ ecc-mod-test.c ecc-modinv-test.c ecc-redc-test.c \ ecc-mul-g-test.c ecc-mul-a-test.c \ - ecdsa-sign-test.c ecdsa-verify-test.c + ecdsa-sign-test.c ecdsa-verify-test.c ecdsa-keygen-test.c TS_SOURCES = $(TS_NETTLE_SOURCES) $(TS_HOGWEED_SOURCES) CXX_SOURCES = cxx-test.cxx diff --git a/testsuite/ecdsa-keygen-test.c b/testsuite/ecdsa-keygen-test.c new file mode 100644 index 00000000..375820c7 --- /dev/null +++ b/testsuite/ecdsa-keygen-test.c @@ -0,0 +1,113 @@ +#include "testutils.h" +#include <nettle/knuth-lfib.h> + +/* Check if y^2 = x^3 - 3x + b */ +static int +ecc_valid_p (struct ecc_point *pub) +{ + mpz_t t, x, y; + mpz_t lhs, rhs; + int res; + mp_size_t size; + + size = pub->ecc->size; + + /* First check range */ + if (mpn_cmp (pub->p, pub->ecc->p, size) >= 0 + || mpn_cmp (pub->p + size, pub->ecc->p, size) >= 0) + return 0; + + mpz_init (lhs); + mpz_init (rhs); + + _mpz_init_mpn (x, pub->p, size); + _mpz_init_mpn (y, pub->p + size, size); + + mpz_mul (lhs, y, y); + mpz_mul (rhs, x, x); + mpz_sub_ui (rhs, rhs, 3); + mpz_mul (rhs, rhs, x); + mpz_add (rhs, rhs, _mpz_init_mpn (t, pub->ecc->b, size)); + + res = mpz_congruent_p (lhs, rhs, _mpz_init_mpn (t, pub->ecc->p, size)); + + mpz_clear (lhs); + mpz_clear (rhs); + + return res; +} + +void +test_main (void) +{ + unsigned i; + struct knuth_lfib_ctx rctx; + struct dsa_signature signature; + + struct tstring *digest; + + knuth_lfib_init (&rctx, 4711); + dsa_signature_init (&signature); + + digest = SHEX (/* sha256("abc") */ + "BA7816BF 8F01CFEA 414140DE 5DAE2223" + "B00361A3 96177A9C B410FF61 F20015AD"); + + for (i = 0; ecc_curves[i]; i++) + { + const struct ecc_curve *ecc = ecc_curves[i]; + struct ecc_point pub; + struct ecc_scalar key; + + if (verbose) + fprintf (stderr, "Curve %d\n", ecc->bit_size); + + ecc_point_init (&pub, ecc); + ecc_scalar_init (&key, ecc); + + ecdsa_generate_keypair (&pub, &key, + &rctx, + (nettle_random_func *) knuth_lfib_random); + + if (verbose) + { + gmp_fprintf (stderr, + "Public key:\nx = %Nx\ny = %Nx\n", + pub.p, ecc->size, pub.p + ecc->size, ecc->size); + gmp_fprintf (stderr, + "Private key: %Nx\n", key.p, ecc->size); + } + if (!ecc_valid_p (&pub)) + die ("ecdsa_generate_keypair produced an invalid point.\n"); + + ecdsa_sign (&key, + &rctx, (nettle_random_func *) knuth_lfib_random, + digest->length, digest->data, + &signature); + + if (!ecdsa_verify (&pub, digest->length, digest->data, + &signature)) + die ("ecdsa_verify failed.\n"); + + digest->data[3] ^= 17; + if (ecdsa_verify (&pub, digest->length, digest->data, + &signature)) + die ("ecdsa_verify returned success with invalid digest.\n"); + digest->data[3] ^= 17; + + mpz_combit (signature.r, 117); + if (ecdsa_verify (&pub, digest->length, digest->data, + &signature)) + die ("ecdsa_verify returned success with invalid signature.r.\n"); + + mpz_combit (signature.r, 117); + mpz_combit (signature.s, 93); + if (ecdsa_verify (&pub, digest->length, digest->data, + &signature)) + die ("ecdsa_verify returned success with invalid signature.s.\n"); + + ecc_point_clear (&pub); + ecc_scalar_clear (&key); + } + dsa_signature_clear (&signature); +} |