From: Daiki Ueno dueno@redhat.com
It turned out that the initial version of _dsa_compute_k was not constant time with the input message. In this version it is checked with a valgrind-based check.
Also the ecdsa-sign-deterministic test has been reorganized using a similar abstraction to struct nettle_mac in testutils.h.
Daiki Ueno (3): dsa: Add a function to find k deterministically ecdsa: Add support for deterministic signature generation dsa: Add support for deterministic signature generation
Makefile.in | 6 +- dsa-compute-k.c | 179 +++++++++++++++++ dsa-compute-k.h | 63 ++++++ dsa-sign-deterministic.c | 107 ++++++++++ dsa.h | 12 ++ ecdsa-sign-deterministic.c | 74 +++++++ ecdsa.h | 11 ++ testsuite/.gitignore | 2 + testsuite/.test-rules.make | 6 + testsuite/Makefile.in | 4 +- testsuite/dsa-compute-k-test.c | 127 ++++++++++++ testsuite/dsa-test.c | 148 +++++++++++++- testsuite/ecdsa-sign-deterministic-test.c | 230 ++++++++++++++++++++++ 13 files changed, 965 insertions(+), 4 deletions(-) create mode 100644 dsa-compute-k.c create mode 100644 dsa-compute-k.h create mode 100644 dsa-sign-deterministic.c create mode 100644 ecdsa-sign-deterministic.c create mode 100644 testsuite/dsa-compute-k-test.c create mode 100644 testsuite/ecdsa-sign-deterministic-test.c
From: Daiki Ueno dueno@redhat.com
This adds the _dsa_compute_k function that generates DSA/ECDSA k value from the private key and the hashed message, according to RFC 6979.
Signed-off-by: Daiki Ueno dueno@redhat.com --- Makefile.in | 5 +- dsa-compute-k.c | 179 +++++++++++++++++++++++++++++++++ dsa-compute-k.h | 63 ++++++++++++ testsuite/.gitignore | 1 + testsuite/.test-rules.make | 3 + testsuite/Makefile.in | 3 +- testsuite/dsa-compute-k-test.c | 127 +++++++++++++++++++++++ 7 files changed, 378 insertions(+), 3 deletions(-) create mode 100644 dsa-compute-k.c create mode 100644 dsa-compute-k.h create mode 100644 testsuite/dsa-compute-k-test.c
diff --git a/Makefile.in b/Makefile.in index b54e64b0..36b2a182 100644 --- a/Makefile.in +++ b/Makefile.in @@ -187,7 +187,8 @@ hogweed_SOURCES = sexp.c sexp-format.c \ eddsa-compress.c eddsa-decompress.c eddsa-expand.c \ eddsa-hash.c eddsa-pubkey.c eddsa-sign.c eddsa-verify.c \ ed25519-sha512-pubkey.c \ - ed25519-sha512-sign.c ed25519-sha512-verify.c + ed25519-sha512-sign.c ed25519-sha512-verify.c \ + dsa-compute-k.c
OPT_SOURCES = fat-x86_64.c fat-arm.c mini-gmp.c
@@ -237,7 +238,7 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \ ctr-internal.h chacha-internal.h sha3-internal.h \ salsa20-internal.h umac-internal.h hogweed-internal.h \ rsa-internal.h pkcs1-internal.h dsa-internal.h eddsa-internal.h \ - gmp-glue.h ecc-internal.h fat-setup.h \ + gmp-glue.h ecc-internal.h fat-setup.h dsa-compute-k.h \ mini-gmp.h asm.m4 \ nettle.texinfo nettle.info nettle.html nettle.pdf sha-example.c
diff --git a/dsa-compute-k.c b/dsa-compute-k.c new file mode 100644 index 00000000..105c500b --- /dev/null +++ b/dsa-compute-k.c @@ -0,0 +1,179 @@ +/* dsa-compute-k.c + + Deterministically find k value for ECDSA/DSA (RFC-6979). + + Copyright (C) 2019 Red Hat, Inc. + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle 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 + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa-compute-k.h" + +#include "gmp-glue.h" +#include "nettle-internal.h" +#include <string.h> +#include <stdio.h> + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) + +void +_dsa_compute_k (mp_limb_t *k, + mp_size_t qn, + const mp_limb_t *q, + const mp_limb_t *x, + void *mac_ctx, + nettle_hash_update_func *set_key, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_length, + const uint8_t *digest_message) +{ + TMP_DECL(V, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + TMP_DECL(K, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + TMP_GMP_DECL(xp, uint8_t); + TMP_GMP_DECL(hp, uint8_t); + TMP_GMP_DECL(tp, uint8_t); + TMP_GMP_DECL(h, mp_limb_t); + mp_size_t hn = (digest_length + sizeof(mp_limb_t) - 1) / sizeof(mp_limb_t); + mp_bitcnt_t q_bits = mpn_sizeinbase (q, qn, 2); + mp_bitcnt_t h_bits = digest_length * 8; + size_t nbytes = (q_bits + 7) / 8; + const uint8_t c0 = 0x00; + const uint8_t c1 = 0x01; + mp_limb_t cy; + + TMP_ALLOC(V, digest_length); + TMP_ALLOC(K, digest_length); + TMP_GMP_ALLOC(xp, nbytes); + TMP_GMP_ALLOC(hp, nbytes); + TMP_GMP_ALLOC(tp, nbytes); + TMP_GMP_ALLOC(h, MAX (qn, hn) * sizeof(mp_limb_t)); + + /* int2octets(x) */ + mpn_get_base256 (xp, nbytes, x, qn); + + /* bits2octets(h) */ + mpn_set_base256 (h, hn, digest_message, digest_length); + + if (hn < qn) + /* qlen > blen: add zero bits to the left */ + mpn_zero (&h[hn], qn - hn); + else if (h_bits > q_bits) + { + /* qlen < blen: keep the leftmost qlen bits. We do this in 2 + * steps because mpn_rshift only accepts shift count in the + * range 1 to mp_bits_per_limb-1. + */ + mp_bitcnt_t shift = h_bits - q_bits; + + if (shift / GMP_LIMB_BITS > 0) + { + mpn_copyi (h, &h[shift / GMP_LIMB_BITS], qn); + hn -= shift / GMP_LIMB_BITS; + } + + if (shift % GMP_LIMB_BITS > 0) + mpn_rshift (h, h, hn, shift % GMP_LIMB_BITS); + } + + cy = mpn_sub_n (h, h, q, qn); + cy = cnd_add_n (cy, h, q, qn); + mpn_get_base256 (hp, nbytes, h, qn); + + /* Step b */ + memset (V, c1, digest_length); + + /* Step c */ + memset (K, c0, digest_length); + set_key (mac_ctx, digest_length, K); + + /* Step d */ + update (mac_ctx, digest_length, V); + update (mac_ctx, 1, &c0); + update (mac_ctx, nbytes, xp); + update (mac_ctx, nbytes, hp); + digest (mac_ctx, digest_length, K); + set_key (mac_ctx, digest_length, K); + + /* Step e */ + update (mac_ctx, digest_length, V); + digest (mac_ctx, digest_length, V); + + /* Step f */ + update (mac_ctx, digest_length, V); + update (mac_ctx, 1, &c1); + update (mac_ctx, nbytes, xp); + update (mac_ctx, nbytes, hp); + digest (mac_ctx, digest_length, K); + set_key (mac_ctx, digest_length, K); + + /* Step g */ + update (mac_ctx, digest_length, V); + digest (mac_ctx, digest_length, V); + + /* Step h */ + for (;;) + { + /* Step 1 */ + size_t tlen = 0; + + /* Step 2 */ + while (tlen < nbytes) + { + size_t remaining = MIN(nbytes - tlen, digest_length); + update (mac_ctx, digest_length, V); + digest (mac_ctx, digest_length, V); + memcpy (&tp[tlen], V, remaining); + tlen += remaining; + } + + /* Step 3 */ + mpn_set_base256 (k, qn, tp, tlen); + if (tlen * 8 > q_bits) + mpn_rshift (k, k, qn, tlen * 8 - q_bits); + /* Check if k is in [1,q-1] */ + if (!mpn_zero_p (k, qn) && mpn_cmp (k, q, qn) < 0) + break; + + update (mac_ctx, digest_length, V); + update (mac_ctx, 1, &c0); + digest (mac_ctx, digest_length, K); + set_key (mac_ctx, digest_length, K); + update (mac_ctx, digest_length, V); + digest (mac_ctx, digest_length, V); + } + + TMP_GMP_FREE(xp); + TMP_GMP_FREE(hp); + TMP_GMP_FREE(tp); + TMP_GMP_FREE(h); +} diff --git a/dsa-compute-k.h b/dsa-compute-k.h new file mode 100644 index 00000000..3433e2fb --- /dev/null +++ b/dsa-compute-k.h @@ -0,0 +1,63 @@ +/* dsa-compute-k.h + + Deterministically find k value for ECDSA/DSA (RFC-6979). + + Copyright (C) 2019 Red Hat, Inc. + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle 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 + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_DSA_COMPUTE_K_H_INCLUDED +#define NETTLE_DSA_COMPUTE_K_H_INCLUDED + +#include "nettle-types.h" +#include "bignum.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Namespace mangling */ +#define _dsa_compute_k _nettle_dsa_compute_k + +void +_dsa_compute_k (mp_limb_t *k, + mp_size_t qn, + const mp_limb_t *q, + const mp_limb_t *x, + void *mac_ctx, + nettle_hash_update_func *set_key, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_length, + const uint8_t *digest_message); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_DSA_COMPUTE_K_H_INCLUDED */ diff --git a/testsuite/.gitignore b/testsuite/.gitignore index 066bcee2..40fbe046 100644 --- a/testsuite/.gitignore +++ b/testsuite/.gitignore @@ -22,6 +22,7 @@ /des-test /des3-test /dlopen-test +/dsa-compute-k-test /dsa-keygen-test /dsa-test /eax-test diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make index efb7df3c..61080010 100644 --- a/testsuite/.test-rules.make +++ b/testsuite/.test-rules.make @@ -280,6 +280,9 @@ eddsa-verify-test$(EXEEXT): eddsa-verify-test.$(OBJEXT) ed25519-test$(EXEEXT): ed25519-test.$(OBJEXT) $(LINK) ed25519-test.$(OBJEXT) $(TEST_OBJS) -o ed25519-test$(EXEEXT)
+dsa-compute-k-test$(EXEEXT): dsa-compute-k-test.$(OBJEXT) + $(LINK) dsa-compute-k-test.$(OBJEXT) $(TEST_OBJS) -o dsa-compute-k-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 f8f85701..e6acd788 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -52,7 +52,8 @@ TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \ ecdsa-sign-test.c ecdsa-verify-test.c \ ecdsa-keygen-test.c ecdh-test.c \ eddsa-compress-test.c eddsa-sign-test.c \ - eddsa-verify-test.c ed25519-test.c + eddsa-verify-test.c ed25519-test.c \ + dsa-compute-k-test.c
TS_SOURCES = $(TS_NETTLE_SOURCES) $(TS_HOGWEED_SOURCES) CXX_SOURCES = cxx-test.cxx diff --git a/testsuite/dsa-compute-k-test.c b/testsuite/dsa-compute-k-test.c new file mode 100644 index 00000000..3df9b2e8 --- /dev/null +++ b/testsuite/dsa-compute-k-test.c @@ -0,0 +1,127 @@ +#include "testutils.h" +#include "dsa-compute-k.h" +#include "hmac.h" + +#if HAVE_VALGRIND_MEMCHECK_H +# include <valgrind/memcheck.h> + +static nettle_hash_digest_func *digest_func; + +static void +digest_func_for_test(void *ctx, + size_t length, uint8_t *dst) +{ + digest_func (ctx, length, dst); + VALGRIND_MAKE_MEM_DEFINED (dst, length); +} + +static void +_dsa_compute_k_for_test (mp_limb_t *k, + mp_size_t qn, + const mp_limb_t *q, + const mp_limb_t *x, + void *mac_ctx, + nettle_hash_update_func *set_key, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_length, + const uint8_t *digest_message) +{ + /* Makes valgrind trigger on any branches depending on the input + data. */ + VALGRIND_MAKE_MEM_UNDEFINED (x, qn * sizeof(mp_limb_t)); + VALGRIND_MAKE_MEM_UNDEFINED (digest_message, digest_length); + + digest_func = digest; + _dsa_compute_k (k, qn, q, x, mac_ctx, set_key, update, digest_func_for_test, + digest_length, digest_message); + + VALGRIND_MAKE_MEM_DEFINED (x, qn * sizeof(mp_limb_t)); + VALGRIND_MAKE_MEM_DEFINED (digest_message, digest_length); + VALGRIND_MAKE_MEM_DEFINED (k, qn * sizeof(mp_limb_t)); +} +#else +#define _dsa_compute_k_test _dsa_compute_k +#endif + +static void +test_dsa_compute_k(const char *sq, + /* Private key */ + const char *sx, + /* HMAC */ + void *mac_ctx, + nettle_hash_update_func *set_key, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + /* Hash */ + const struct tstring *h, + /* Expected k */ + const char *sk) +{ + mpz_t k; + mpz_t q; + mpz_t x; + mpz_t e; + + mpz_init (k); + mpz_init_set_str (q, sq, 16); + mpz_init_set_str (x, sx, 16); + mpz_init_set_str (e, sk, 16); + + _dsa_compute_k_for_test (mpz_limbs_write (k, mpz_size (q)), + mpz_size (q), mpz_limbs_read (q), mpz_limbs_read (x), + mac_ctx, set_key, update, digest, + h->length, h->data); + + mpz_limbs_finish (k, mpz_size (q)); + + if (mpz_cmp (e, k) != 0) + { + fprintf (stderr, "k = "); + mpz_out_str (stderr, 16, k); + fprintf (stderr, "\n"); + fprintf (stderr, "e = "); + mpz_out_str (stderr, 16, e); + fprintf (stderr, "\n"); + abort (); + } + + mpz_clear (q); + mpz_clear (x); + mpz_clear (k); + mpz_clear (e); +} + +void +test_main (void) +{ + struct hmac_sha256_ctx hmac; + struct sha256_ctx hash; + uint8_t digest[SHA256_DIGEST_SIZE]; + + sha256_init (&hash); + sha256_update (&hash, 6, (const uint8_t *)"sample"); + sha256_digest (&hash, sizeof(digest), digest); + + /* Test vectors from RFC 6979 */ + test_dsa_compute_k ("996f967f6c8e388d9e28d01e205fba957a5698b1", + "411602cb19a6ccc34494d79d98ef1e7ed5af25f7", + &hmac, + (nettle_hash_update_func *)hmac_sha256_set_key, + (nettle_hash_update_func *)hmac_sha256_update, + (nettle_hash_digest_func *)hmac_sha256_digest, + tstring_data (SHA256_DIGEST_SIZE, digest), + "519ba0546d0c39202a7d34d7dfa5e760b318bcfb"); + + test_dsa_compute_k ("f2c3119374ce76c9356990b465374a17f23f9ed3" + "5089bd969f61c6dde9998c1f", + "69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f1" + "80316e5bcab92c933f0e4dbc", + &hmac, + (nettle_hash_update_func *)hmac_sha256_set_key, + (nettle_hash_update_func *)hmac_sha256_update, + (nettle_hash_digest_func *)hmac_sha256_digest, + tstring_data (SHA256_DIGEST_SIZE, digest), + "8926a27c40484216f052f4427cfd5647338b7b39" + "39bc6573af4333569d597c52"); +}
From: Daiki Ueno dueno@redhat.com
This adds the ecdsa_sign_deterministic function that calculates signature without requiring entropy source. Instead, it uses the deterministic construction described in RFC 6979, through _dsa_compute_k.
Signed-off-by: Daiki Ueno dueno@redhat.com --- Makefile.in | 2 +- ecdsa-sign-deterministic.c | 74 +++++++ ecdsa.h | 11 ++ testsuite/.gitignore | 1 + testsuite/.test-rules.make | 3 + testsuite/Makefile.in | 3 +- testsuite/ecdsa-sign-deterministic-test.c | 230 ++++++++++++++++++++++ 7 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 ecdsa-sign-deterministic.c create mode 100644 testsuite/ecdsa-sign-deterministic-test.c
diff --git a/Makefile.in b/Makefile.in index 36b2a182..27cbf93f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -188,7 +188,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ eddsa-hash.c eddsa-pubkey.c eddsa-sign.c eddsa-verify.c \ ed25519-sha512-pubkey.c \ ed25519-sha512-sign.c ed25519-sha512-verify.c \ - dsa-compute-k.c + dsa-compute-k.c ecdsa-sign-deterministic.c
OPT_SOURCES = fat-x86_64.c fat-arm.c mini-gmp.c
diff --git a/ecdsa-sign-deterministic.c b/ecdsa-sign-deterministic.c new file mode 100644 index 00000000..11eef5f6 --- /dev/null +++ b/ecdsa-sign-deterministic.c @@ -0,0 +1,74 @@ +/* ecdsa-sign-deterministic.c + + Copyright (C) 2013 Niels Möller + Copyright (C) 2019 Red Hat, Inc. + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle 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 + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#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" +#include "dsa-compute-k.h" + +void +ecdsa_sign_deterministic (const struct ecc_scalar *key, + void *mac_ctx, + nettle_hash_update_func *set_key, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_length, + const uint8_t *digest_message, + struct dsa_signature *signature) +{ + /* At most 936 bytes. */ + TMP_DECL(k, mp_limb_t, ECC_MAX_SIZE + ECC_ECDSA_SIGN_ITCH (ECC_MAX_SIZE)); + mp_limb_t size = key->ecc->p.size; + mp_limb_t *rp = mpz_limbs_write (signature->r, size); + mp_limb_t *sp = mpz_limbs_write (signature->s, size); + + TMP_ALLOC (k, size + ECC_ECDSA_SIGN_ITCH (size)); + + _dsa_compute_k (k, key->ecc->q.size, key->ecc->q.m, key->p, + mac_ctx, set_key, update, digest, + digest_length, digest_message); + ecc_ecdsa_sign (key->ecc, key->p, k, digest_length, digest_message, + rp, sp, k + size); + mpz_limbs_finish (signature->r, size); + mpz_limbs_finish (signature->s, size); + + assert (!(mpz_sgn (signature->r) == 0 || mpz_sgn (signature->s) == 0)); +} diff --git a/ecdsa.h b/ecdsa.h index 693aca8b..7d590367 100644 --- a/ecdsa.h +++ b/ecdsa.h @@ -43,6 +43,7 @@ extern "C" {
/* Name mangling */ #define ecdsa_sign nettle_ecdsa_sign +#define ecdsa_sign_deterministic nettle_ecdsa_sign_deterministic #define ecdsa_verify nettle_ecdsa_verify #define ecdsa_generate_keypair nettle_ecdsa_generate_keypair #define ecc_ecdsa_sign nettle_ecc_ecdsa_sign @@ -61,6 +62,16 @@ ecdsa_sign (const struct ecc_scalar *key, const uint8_t *digest, struct dsa_signature *signature);
+void +ecdsa_sign_deterministic (const struct ecc_scalar *key, + void *mac_ctx, + nettle_hash_update_func *set_key, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_length, + const uint8_t *digest_message, + struct dsa_signature *signature); + int ecdsa_verify (const struct ecc_point *pub, size_t length, const uint8_t *digest, diff --git a/testsuite/.gitignore b/testsuite/.gitignore index 40fbe046..fb2800e8 100644 --- a/testsuite/.gitignore +++ b/testsuite/.gitignore @@ -36,6 +36,7 @@ /ecc-sqrt-test /ecdh-test /ecdsa-keygen-test +/ecdsa-sign-deterministic-test /ecdsa-sign-test /ecdsa-verify-test /ed25519-test diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make index 61080010..8f796efd 100644 --- a/testsuite/.test-rules.make +++ b/testsuite/.test-rules.make @@ -283,6 +283,9 @@ ed25519-test$(EXEEXT): ed25519-test.$(OBJEXT) dsa-compute-k-test$(EXEEXT): dsa-compute-k-test.$(OBJEXT) $(LINK) dsa-compute-k-test.$(OBJEXT) $(TEST_OBJS) -o dsa-compute-k-test$(EXEEXT)
+ecdsa-sign-deterministic-test$(EXEEXT): ecdsa-sign-deterministic-test.$(OBJEXT) + $(LINK) ecdsa-sign-deterministic-test.$(OBJEXT) $(TEST_OBJS) -o ecdsa-sign-deterministic-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 e6acd788..8bdb8ea6 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -53,7 +53,8 @@ TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \ ecdsa-keygen-test.c ecdh-test.c \ eddsa-compress-test.c eddsa-sign-test.c \ eddsa-verify-test.c ed25519-test.c \ - dsa-compute-k-test.c + dsa-compute-k-test.c \ + ecdsa-sign-deterministic-test.c
TS_SOURCES = $(TS_NETTLE_SOURCES) $(TS_HOGWEED_SOURCES) CXX_SOURCES = cxx-test.cxx diff --git a/testsuite/ecdsa-sign-deterministic-test.c b/testsuite/ecdsa-sign-deterministic-test.c new file mode 100644 index 00000000..6e5e441e --- /dev/null +++ b/testsuite/ecdsa-sign-deterministic-test.c @@ -0,0 +1,230 @@ +#include "testutils.h" +#include "hmac.h" +#include "nettle-internal.h" + +/* This is a identical to struct nettle_mac defined in testutils.h, + * except that set_key is defined as a different type. */ +struct nettle_hmac +{ + const char *name; + + /* Size of the context struct */ + unsigned context_size; + + /* Size of digests */ + unsigned digest_size; + + /* Suggested key size; other sizes are sometimes possible. */ + unsigned key_size; + + /* HMAC require an additional key_length argument to set_key, which + * makes the type incompatible with nettle_set_key_func. */ + nettle_hash_update_func *set_key; + nettle_hash_update_func *update; + nettle_hash_digest_func *digest; +}; + +#undef _NETTLE_HMAC +#define _NETTLE_HMAC(name, NAME) { \ + #name, \ + sizeof(struct hmac_##name##_ctx), \ + NAME##_DIGEST_SIZE, \ + NAME##_DIGEST_SIZE, \ + (nettle_hash_update_func *)hmac_##name##_set_key, \ + (nettle_hash_update_func *)hmac_##name##_update, \ + (nettle_hash_digest_func *)hmac_##name##_digest, \ +} + +static void +test_ecdsa (const struct ecc_curve *ecc, + /* Private key */ + const char *sz, + /* HMAC */ + void *hmac_ctx, + const struct nettle_hmac *hmac, + /* Hash */ + const struct tstring *h, + /* Expected signature */ + const char *r, const char *s) +{ + struct ecc_scalar key; + struct dsa_signature ref; + struct dsa_signature signature; + mpz_t z; + + dsa_signature_init (&ref); + dsa_signature_init (&signature); + + mpz_init_set_str (z, sz, 16); + + ecc_scalar_init (&key, ecc); + ecc_scalar_set (&key, z); + + ecdsa_sign_deterministic (&key, + hmac_ctx, + hmac->set_key, + hmac->update, + hmac->digest, + h->length, h->data, &signature); + + mpz_set_str (ref.r, r, 16); + mpz_set_str (ref.s, s, 16); + + if (mpz_limbs_cmp (ref.r, mpz_limbs_read (signature.r), ecc->p.size) != 0 + || mpz_limbs_cmp (ref.s, mpz_limbs_read (signature.s), ecc->p.size) != 0) + { + fprintf (stderr, "_ecdsa_sign failed, bit_size = %u, hmac_%s\n", + ecc->p.bit_size, hmac->name); + fprintf (stderr, "r = "); + write_mpn (stderr, 16, mpz_limbs_read (signature.r), ecc->p.size); + fprintf (stderr, "\ns = "); + write_mpn (stderr, 16, mpz_limbs_read (signature.s), ecc->p.size); + fprintf (stderr, "\nref.r = "); + mpz_out_str (stderr, 16, ref.r); + fprintf (stderr, "\nref.s = "); + mpz_out_str (stderr, 16, ref.s); + fprintf (stderr, "\n"); + abort(); + } + + dsa_signature_clear (&ref); + dsa_signature_clear (&signature); + ecc_scalar_clear (&key); + mpz_clear (z); +} + +static const struct nettle_hmac hmac_sha1 = _NETTLE_HMAC(sha1, SHA1); +static const struct nettle_hmac hmac_sha224 = _NETTLE_HMAC(sha224, SHA224); +static const struct nettle_hmac hmac_sha256 = _NETTLE_HMAC(sha256, SHA256); +static const struct nettle_hmac hmac_sha384 = _NETTLE_HMAC(sha384, SHA384); +static const struct nettle_hmac hmac_sha512 = _NETTLE_HMAC(sha512, SHA512); + +static struct +{ + const struct ecc_curve *ecc; + const struct nettle_hash *hash; + const struct nettle_hmac *hmac; + const char *m; + const char *z; + const char *r; + const char *s; +} tests[] = { + /* Test vectors from RFC6979 */ + { &_nettle_secp_192r1, &nettle_sha1, &hmac_sha1, + "sample", + "6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4", + "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", + "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64" }, + { &_nettle_secp_192r1, &nettle_sha224, &hmac_sha224, + "sample", + "6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4", + "a1f00dad97aeec91c95585f36200c65f3c01812aa60378f5", + "e07ec1304c7c6c9debbe980b9692668f81d4de7922a0f97a" }, + { &_nettle_secp_192r1, &nettle_sha256, &hmac_sha256, + "sample", + "6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4", + "4b0b8ce98a92866a2820e20aa6b75b56382e0f9bfd5ecb55", + "ccdb006926ea9565cbadc840829d8c384e06de1f1e381b85" }, + { &_nettle_secp_192r1, &nettle_sha384, &hmac_sha384, + "sample", + "6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4", + "da63bf0b9abcf948fbb1e9167f136145f7a20426dcc287d5", + "c3aa2c960972bd7a2003a57e1c4c77f0578f8ae95e31ec5e" }, + { &_nettle_secp_192r1, &nettle_sha512, &hmac_sha512, + "sample", + "6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4", + "4d60c5ab1996bd848343b31c00850205e2ea6922dac2e4b8", + "3f6e837448f027a1bf4b34e796e32a811cbb4050908d8f67" }, + { &_nettle_secp_224r1, &nettle_sha1, &hmac_sha1, + "sample", + "f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1", + "22226f9d40a96e19c4a301ce5b74b115303c0f3a4fd30fc257fb57ac", + "66d1cdd83e3af75605dd6e2feff196d30aa7ed7a2edf7af475403d69" }, + { &_nettle_secp_224r1, &nettle_sha224, &hmac_sha224, + "sample", + "f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1", + "1cdfe6662dde1e4a1ec4cdedf6a1f5a2fb7fbd9145c12113e6abfd3e", + "a6694fd7718a21053f225d3f46197ca699d45006c06f871808f43ebc" }, + { &_nettle_secp_224r1, &nettle_sha256, &hmac_sha256, + "sample", + "f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1", + "61aa3da010e8e8406c656bc477a7a7189895e7e840cdfe8ff42307ba", + "bc814050dab5d23770879494f9e0a680dc1af7161991bde692b10101" }, + { &_nettle_secp_224r1, &nettle_sha384, &hmac_sha384, + "sample", + "f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1", + "0b115e5e36f0f9ec81f1325a5952878d745e19d7bb3eabfaba77e953", + "830f34ccdfe826ccfdc81eb4129772e20e122348a2bbd889a1b1af1d" }, + { &_nettle_secp_224r1, &nettle_sha512, &hmac_sha512, + "sample", + "f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1", + "074bd1d979d5f32bf958ddc61e4fb4872adcafeb2256497cdac30397", + "a4ceca196c3d5a1ff31027b33185dc8ee43f288b21ab342e5d8eb084" }, + { &_nettle_secp_256r1, &nettle_sha1, &hmac_sha1, + "sample", + "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721", + "61340c88c3aaebeb4f6d667f672ca9759a6ccaa9fa8811313039ee4a35471d32", + "6d7f147dac089441bb2e2fe8f7a3fa264b9c475098fdcf6e00d7c996e1b8b7eb" }, + { &_nettle_secp_256r1, &nettle_sha224, &hmac_sha224, + "sample", + "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721", + "53b2fff5d1752b2c689df257c04c40a587fababb3f6fc2702f1343af7ca9aa3f", + "b9afb64fdc03dc1a131c7d2386d11e349f070aa432a4acc918bea988bf75c74c" }, + { &_nettle_secp_256r1, &nettle_sha256, &hmac_sha256, + "sample", + "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721", + "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716", + "f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8" }, + { &_nettle_secp_256r1, &nettle_sha512, &hmac_sha512, + "sample", + "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721", + "8496a60b5e9b47c825488827e0495b0e3fa109ec4568fd3f8d1097678eb97f00", + "2362ab1adbe2b8adf9cb9edab740ea6049c028114f2460f96554f61fae3302fe" }, + { &_nettle_secp_384r1, &nettle_sha256, &hmac_sha256, + "sample", + "6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8" + "96d5724e4c70a825f872c9ea60d2edf5", + "21b13d1e013c7fa1392d03c5f99af8b30c570c6f98d4ea8e354b63a21d3daa33" + "bde1e888e63355d92fa2b3c36d8fb2cd", + "f3aa443fb107745bf4bd77cb3891674632068a10ca67e3d45db2266fa7d1feeb" + "efdc63eccd1ac42ec0cb8668a4fa0ab0" }, + { &_nettle_secp_521r1, &nettle_sha256, &hmac_sha256, + "sample", + "0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c" + "aa896eb32f1f47c70855836a6d16fcc1466f6d8fbec67db89ec0c08b0e996b83" + "538", + "1511bb4d675114fe266fc4372b87682baecc01d3cc62cf2303c92b3526012659" + "d16876e25c7c1e57648f23b73564d67f61c6f14d527d54972810421e7d87589e" + "1a7", + "04a171143a83163d6df460aaf61522695f207a58b95c0644d87e52aa1a347916" + "e4f7a72930b1bc06dbe22ce3f58264afd23704cbb63b29b931f7de6c9d949a7e" + "cfc" } +}; + +void +test_main (void) +{ + size_t i; + + for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) + { + void *hash_ctx; + uint8_t digest[NETTLE_MAX_HASH_DIGEST_SIZE]; + void *hmac_ctx; + + hash_ctx = xalloc (tests[i].hash->context_size); + tests[i].hash->init (hash_ctx); + tests[i].hash->update (hash_ctx, 6, (const uint8_t *)tests[i].m); + tests[i].hash->digest (hash_ctx, tests[i].hash->digest_size, digest); + + hmac_ctx = xalloc (tests[i].hmac->context_size); + test_ecdsa (tests[i].ecc, + tests[i].z, + hmac_ctx, + tests[i].hmac, + tstring_data (tests[i].hash->digest_size, digest), + tests[i].r, + tests[i].s); + free (hmac_ctx); + } +}
From: Daiki Ueno dueno@redhat.com
This adds the dsa_sign_deterministic function that calculates signature without requiring entropy source. Instead, it uses the deterministic construction described in RFC 6979, through _dsa_compute_k.
Signed-off-by: Daiki Ueno dueno@redhat.com --- Makefile.in | 3 +- dsa-sign-deterministic.c | 107 ++++++++++++++++++++++++++++ dsa.h | 12 ++++ testsuite/dsa-test.c | 148 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 dsa-sign-deterministic.c
diff --git a/Makefile.in b/Makefile.in index 27cbf93f..38b2a9a6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -188,7 +188,8 @@ hogweed_SOURCES = sexp.c sexp-format.c \ eddsa-hash.c eddsa-pubkey.c eddsa-sign.c eddsa-verify.c \ ed25519-sha512-pubkey.c \ ed25519-sha512-sign.c ed25519-sha512-verify.c \ - dsa-compute-k.c ecdsa-sign-deterministic.c + dsa-compute-k.c ecdsa-sign-deterministic.c \ + dsa-sign-deterministic.c
OPT_SOURCES = fat-x86_64.c fat-arm.c mini-gmp.c
diff --git a/dsa-sign-deterministic.c b/dsa-sign-deterministic.c new file mode 100644 index 00000000..8c75b80f --- /dev/null +++ b/dsa-sign-deterministic.c @@ -0,0 +1,107 @@ +/* dsa-sign-deterministic.c + + Copyright (C) 2002, 2010 Niels Möller + Copyright (C) 2019 Red Hat, Inc. + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle 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 + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <stdlib.h> + +#include "dsa.h" +#include "dsa-internal.h" +#include "dsa-compute-k.h" + +#include "bignum.h" + + +int +dsa_sign_deterministic (const struct dsa_params *params, + const mpz_t x, + void *mac_ctx, + nettle_hash_update_func *set_key, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_length, + const uint8_t *digest_message, + struct dsa_signature *signature) +{ + mpz_t k; + mpz_t h; + mpz_t tmp; + int res; + + /* Check that p is odd, so that invalid keys don't result in a crash + inside mpz_powm_sec. */ + if (mpz_even_p (params->p)) + return 0; + + /* Select k, 0<k<q, deterministically */ + mpz_init(k); + _dsa_compute_k (mpz_limbs_write (k, mpz_size (params->q)), + mpz_size (params->q), + mpz_limbs_read (params->q), + mpz_limbs_read (x), + mac_ctx, set_key, update, digest, + digest_length, digest_message); + mpz_limbs_finish (k, mpz_size (params->q)); + + /* Compute r = (g^k (mod p)) (mod q) */ + mpz_init (tmp); + mpz_powm_sec(tmp, params->g, k, params->p); + mpz_fdiv_r(signature->r, tmp, params->q); + + /* Compute hash */ + mpz_init(h); + _dsa_hash (h, mpz_sizeinbase(params->q, 2), digest_length, digest_message); + + /* Compute k^-1 (mod q) */ + if (mpz_invert(k, k, params->q)) + { + /* Compute signature s = k^-1 (h + xr) (mod q) */ + mpz_mul(tmp, signature->r, x); + mpz_fdiv_r(tmp, tmp, params->q); + mpz_add(tmp, tmp, h); + mpz_mul(tmp, tmp, k); + mpz_fdiv_r(signature->s, tmp, params->q); + res = 1; + } + else + /* What do we do now? The key is invalid. */ + res = 0; + + mpz_clear(k); + mpz_clear(h); + mpz_clear(tmp); + + return res; +} diff --git a/dsa.h b/dsa.h index 553ef327..fddaea9d 100644 --- a/dsa.h +++ b/dsa.h @@ -47,6 +47,7 @@ extern "C" { #define dsa_signature_init nettle_dsa_signature_init #define dsa_signature_clear nettle_dsa_signature_clear #define dsa_sign nettle_dsa_sign +#define dsa_sign_deterministic nettle_dsa_sign_deterministic #define dsa_verify nettle_dsa_verify #define dsa_generate_params nettle_dsa_generate_params #define dsa_generate_keypair nettle_dsa_generate_keypair @@ -109,6 +110,17 @@ dsa_sign(const struct dsa_params *params, const uint8_t *digest, struct dsa_signature *signature);
+int +dsa_sign_deterministic (const struct dsa_params *params, + const mpz_t x, + void *mac_ctx, + nettle_hash_update_func *set_key, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_length, + const uint8_t *digest_message, + struct dsa_signature *signature); + int dsa_verify(const struct dsa_params *params, const mpz_t y, diff --git a/testsuite/dsa-test.c b/testsuite/dsa-test.c index 9a80c967..dbc8d063 100644 --- a/testsuite/dsa-test.c +++ b/testsuite/dsa-test.c @@ -1,4 +1,57 @@ #include "testutils.h" +#include "hmac.h" +#include "nettle-internal.h" + +static void +test_dsa_sign_deterministic(const struct dsa_params *params, + /* Private key */ + const char *sz, + /* HMAC */ + void *mac_ctx, + nettle_hash_update_func *set_key, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + /* Hash */ + const struct tstring *h, + /* Expected signature */ + const char *r, const char *s) +{ + struct dsa_signature ref; + struct dsa_signature signature; + mpz_t z; + + dsa_signature_init (&ref); + dsa_signature_init(&signature); + + mpz_init_set_str (z, sz, 16); + + ASSERT (dsa_sign_deterministic (params, z, + mac_ctx, set_key, update, digest, + h->length, h->data, &signature)); + + mpz_set_str (ref.r, r, 16); + mpz_set_str (ref.s, s, 16); + + if (mpz_cmp (signature.r, ref.r) != 0 + || mpz_cmp (signature.s, ref.s) != 0) + { + fprintf (stderr, "_dsa_sign failed\n"); + fprintf (stderr, "r = "); + mpz_out_str (stderr, 16, signature.r); + fprintf (stderr, "\ns = "); + mpz_out_str (stderr, 16, signature.s); + fprintf (stderr, "\nref.r = "); + mpz_out_str (stderr, 16, ref.r); + fprintf (stderr, "\nref.s = "); + mpz_out_str (stderr, 16, ref.s); + fprintf (stderr, "\n"); + abort(); + } + + dsa_signature_clear (&ref); + dsa_signature_clear (&signature); + mpz_clear (z); +}
void test_main(void) @@ -7,6 +60,13 @@ test_main(void) struct dsa_private_key key; struct dsa_signature signature; struct dsa_params *params = (struct dsa_params *) &pub; + struct hmac_sha256_ctx hmac_sha256; + struct sha256_ctx hash_sha256; + uint8_t digest[NETTLE_MAX_HASH_DIGEST_SIZE]; + + sha256_init (&hash_sha256); + sha256_update (&hash_sha256, 6, (const uint8_t *)"sample"); + sha256_digest (&hash_sha256, SHA256_DIGEST_SIZE, digest);
dsa_public_key_init(&pub); dsa_private_key_init(&key); @@ -877,7 +937,93 @@ test_main(void) "bb7441c122f1dc2f9d0b0bc07f26ba29a35cdf0da846a9d8" "eab405cbf8c8e77f"), &signature); - + + /* Test vectors from RFC 6979 */ + mpz_set_str(pub.p, + "86f5ca03dcfeb225063ff830a0c769b9dd9d6153ad91d7ce" + "27f787c43278b447e6533b86b18bed6e8a48b784a14c252c" + "5be0dbf60b86d6385bd2f12fb763ed8873abfd3f5ba2e0a8" + "c0a59082eac056935e529daf7c610467899c77adedfc846c" + "881870b7b19b2b58f9be0521a17002e3bdd6b86685ee90b3" + "d9a1b02b782b1779", 16); + mpz_set_str(pub.q, + "996f967f6c8e388d9e28d01e205fba957a5698b1", 16); + mpz_set_str(pub.g, + "07b0f92546150b62514bb771e2a0c0ce387f03bda6c56b50" + "5209ff25fd3c133d89bbcd97e904e09114d9a7defdeadfc9" + "078ea544d2e401aeecc40bb9fbbf78fd87995a10a1c27cb7" + "789b594ba7efb5c4326a9fe59a070e136db77175464adca4" + "17be5dce2f40d10a46a3a3943f26ab7fd9c0398ff8c76ee0" + "a56826a8a88f1dbd", 16); + mpz_set_str(pub.y, + "5df5e01ded31d0297e274e1691c192fe5868fef9e19a8477" + "6454b100cf16f65392195a38b90523e2542ee61871c0440c" + "b87c322fc4b4d2ec5e1e7ec766e1be8d4ce935437dc11c3c" + "8fd426338933ebfe739cb3465f4d3668c5e473508253b1e6" + "82f65cbdc4fae93c2ea212390e54905a86e2223170b44eaa" + "7da5dd9ffcfb7f3b", 16); + test_dsa_sign_deterministic (params, + "411602cb19a6ccc34494d79d98ef1e7ed5af25f7", + &hmac_sha256, + (nettle_hash_update_func *)hmac_sha256_set_key, + (nettle_hash_update_func *)hmac_sha256_update, + (nettle_hash_digest_func *)hmac_sha256_digest, + tstring_data (SHA256_DIGEST_SIZE, digest), /* h */ + "81f2f5850be5bc123c43f71a3033e9384611c545", + "4cdd914b65eb6c66a8aaad27299bee6b035f5e89"); + + mpz_set_str(pub.p, + "9db6fb5951b66bb6fe1e140f1d2ce5502374161fd6538df1" + "648218642f0b5c48c8f7a41aadfa187324b87674fa1822b0" + "0f1ecf8136943d7c55757264e5a1a44ffe012e9936e00c1d" + "3e9310b01c7d179805d3058b2a9f4bb6f9716bfe6117c6b5" + "b3cc4d9be341104ad4a80ad6c94e005f4b993e14f091eb51" + "743bf33050c38de235567e1b34c3d6a5c0ceaa1a0f368213" + "c3d19843d0b4b09dcb9fc72d39c8de41f1bf14d4bb4563ca" + "28371621cad3324b6a2d392145bebfac748805236f5ca2fe" + "92b871cd8f9c36d3292b5509ca8caa77a2adfc7bfd77dda6" + "f71125a7456fea153e433256a2261c6a06ed3693797e7995" + "fad5aabbcfbe3eda2741e375404ae25b", 16); + mpz_set_str(pub.q, + "f2c3119374ce76c9356990b465374a17f23f9ed35089bd96" + "9f61c6dde9998c1f", 16); + mpz_set_str(pub.g, + "5c7ff6b06f8f143fe8288433493e4769c4d988ace5be25a0" + "e24809670716c613d7b0cee6932f8faa7c44d2cb24523da5" + "3fbe4f6ec3595892d1aa58c4328a06c46a15662e7eaa703a" + "1decf8bbb2d05dbe2eb956c142a338661d10461c0d135472" + "085057f3494309ffa73c611f78b32adbb5740c361c9f35be" + "90997db2014e2ef5aa61782f52abeb8bd6432c4dd097bc54" + "23b285dafb60dc364e8161f4a2a35aca3a10b1c4d203cc76" + "a470a33afdcbdd92959859abd8b56e1725252d78eac66e71" + "ba9ae3f1dd2487199874393cd4d832186800654760e1e34c" + "09e4d155179f9ec0dc4473f996bdce6eed1cabed8b6f116f" + "7ad9cf505df0f998e34ab27514b0ffe7", 16); + mpz_set_str(pub.y, + "667098c654426c78d7f8201eac6c203ef030d43605032c2f" + "1fa937e5237dbd949f34a0a2564fe126dc8b715c5141802c" + "e0979c8246463c40e6b6bdaa2513fa611728716c2e4fd53b" + "c95b89e69949d96512e873b9c8f8dfd499cc312882561ade" + "cb31f658e934c0c197f2c4d96b05cbad67381e7b768891e4" + "da3843d24d94cdfb5126e9b8bf21e8358ee0e0a30ef13fd6" + "a664c0dce3731f7fb49a4845a4fd8254687972a2d382599c" + "9bac4e0ed7998193078913032558134976410b89d2c171d1" + "23ac35fd977219597aa7d15c1a9a428e59194f75c721ebcb" + "cfae44696a499afa74e04299f132026601638cb87ab79190" + "d4a0986315da8eec6561c938996beadf", 16); + test_dsa_sign_deterministic (params, + "69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f1" + "80316e5bcab92c933f0e4dbc", + &hmac_sha256, + (nettle_hash_update_func *)hmac_sha256_set_key, + (nettle_hash_update_func *)hmac_sha256_update, + (nettle_hash_digest_func *)hmac_sha256_digest, + tstring_data (SHA256_DIGEST_SIZE, digest), /* h */ + "eace8bdbbe353c432a795d9ec556c6d021f7a03f" + "42c36e9bc87e4ac7932cc809", + "7081e175455f9247b812b74583e9e94f9ea79bd6" + "40dc962533b0680793a38d53"); + dsa_public_key_clear(&pub); dsa_private_key_clear(&key); dsa_signature_clear(&signature);
nettle-bugs@lists.lysator.liu.se