]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Unify handing of message hash for dsa and ecdsa, using mpn interface.
authorNiels Möller <nisse@lysator.liu.se>
Sat, 1 Jun 2024 16:26:56 +0000 (18:26 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Sat, 1 Jun 2024 16:26:56 +0000 (18:26 +0200)
13 files changed:
ChangeLog
Makefile.in
dsa-hash.c
dsa-internal.h
dsa-sign.c
dsa-verify.c
ecc-ecdsa-sign.c
ecc-ecdsa-verify.c
ecc-gostdsa-sign.c
ecc-gostdsa-verify.c
ecc-hash.c [deleted file]
ecc-internal.h
gmp-glue.h

index 2357137754eae95aba3370b6031bb030444594f1..4440af5f0f52cdc6723f820fc8eab7454a498b86 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,24 @@
 
        * eddsa-hash.c (_eddsa_hash): Use NETTLE_OCTET_SIZE_TO_LIMB_SIZE.
 
+       * ecc-hash.c (ecc_hash, gost_hash): Deleted file, moved functions to...
+       * dsa-hash.c (_nettle_dsa_hash): Change to use mpn interface
+       instead of mpz, replacing ecc_hash.
+       (_nettle_gostdsa_hash): Moved here, renamed from gost_hash.
+       * dsa-internal.h (_nettle_dsa_hash): Update declaration.
+       (_nettle_gostdsa_hash): Moved declaration here.
+       * ecc-internal.h (ecc_hash, gost_hash): Delete old declarations.
+       * gmp-glue.h (NETTLE_BIT_SIZE_TO_LIMB_SIZE): New macro.
+
+       * dsa-sign.c (dsa_sign): Adapt to _nettle_dsa_hash change.
+       * dsa-verify.c (dsa_verify): Likewise.
+       * ecc-ecdsa-sign.c (ecc_ecdsa_sign): Use _nettle_dsa_hash.
+       * ecc-ecdsa-verify.c (ecc_ecdsa_verify): Likewise.
+       * ecc-gostdsa-sign.c (ecc_gostdsa_sign): Use _nettle_gostdsa_hash.
+       * ecc-gostdsa-verify.c (ecc_gostdsa_verify): Likewise.
+
+       * Makefile.in (hogweed_SOURCES): Delete ecc-hash.c
+
 2024-05-15  Niels Möller  <nisse@lysator.liu.se>
 
        * powerpc64/p8/gcm-aes-encrypt.asm: Reduce register usage.
index cfc83e0b46bca9b1fcb944a49004c169fa8cc83d..2bf7f1e814a62f0e953234daac022323048d0c10 100644 (file)
@@ -212,7 +212,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
                  ecc-dup-eh.c ecc-add-eh.c ecc-add-ehh.c \
                  ecc-dup-th.c ecc-add-th.c ecc-add-thh.c \
                  ecc-mul-g-eh.c ecc-mul-a-eh.c ecc-mul-m.c \
-                 ecc-mul-g.c ecc-mul-a.c ecc-hash.c ecc-random.c \
+                 ecc-mul-g.c ecc-mul-a.c ecc-random.c \
                  ecc-point.c ecc-scalar.c ecc-point-mul.c ecc-point-mul-g.c \
                  ecc-ecdsa-sign.c ecdsa-sign.c \
                  ecc-ecdsa-verify.c ecdsa-verify.c ecdsa-keygen.c \
index aab3c838c60c236fbc386a19a87f7d3f92f50c91..77d89583126bfd15d8f1a6b121a01367872846a3 100644 (file)
 #include "dsa.h"
 #include "dsa-internal.h"
 
-#include "bignum.h"
+#include "gmp-glue.h"
 
 /* Convert hash value to an integer. The general description of DSA in
-   FIPS186-3 allows both larger and smaller q; in the the latter case,
-   the hash must be truncated to the right number of bits. */
+   FIPS186-3 allows both larger and smaller q; in the the former case
+   the hash is zero-padded at the left, in the latter case, the hash
+   is truncated at the right.
+
+   NOTE: We don't considered the hash value to be secret, so it's ok
+   if the running time of this conversion depends on h.
+
+   Output size is ceil(bit_size / GMP_NUMB_BITS).
+*/
+
 void
-_nettle_dsa_hash (mpz_t h, unsigned bit_size,
+_nettle_dsa_hash (mp_limb_t *hp, unsigned bit_size,
                  size_t length, const uint8_t *digest)
 {
-  
-  if (length > (bit_size + 7) / 8)
-    length = (bit_size + 7) / 8;
+  unsigned octet_size = (bit_size + 7) / 8;
+  unsigned limb_size = NETTLE_BIT_SIZE_TO_LIMB_SIZE (bit_size);
+
+  if (length > octet_size)
+    length = octet_size;
 
-  nettle_mpz_set_str_256_u(h, length, digest);
+  mpn_set_base256(hp, limb_size, digest, length);
 
   if (8 * length > bit_size)
     /* We got a few extra bits, at the low end. Discard them. */
-    mpz_tdiv_q_2exp (h, h, 8*length - bit_size);
+    mpn_rshift (hp, hp, limb_size, 8*length - bit_size);
+}
+
+/* Uses little-endian order, and no trimming of left-over bits in the
+   last byte (bits will instead be reduced mod q later). */
+void
+_nettle_gostdsa_hash (mp_limb_t *hp, unsigned bit_size,
+                     size_t length, const uint8_t *digest)
+{
+  unsigned octet_size = (bit_size + 7) / 8;
+  unsigned limb_size = NETTLE_BIT_SIZE_TO_LIMB_SIZE (bit_size);
+
+  if (length > octet_size)
+    length = octet_size;
+
+  mpn_set_base256_le(hp, limb_size, digest, length);
 }
index ce57c72a3c44d6014980b8cb901ee4e82b53ab38..7baa6ba0cfbdf24eb9799375e2451912578460bf 100644 (file)
 
 /* Internal functions. */
 void
-_nettle_dsa_hash (mpz_t h, unsigned bit_size,
+_nettle_dsa_hash (mp_limb_t *hp, unsigned bit_size,
                  size_t length, const uint8_t *digest);
 
+void
+_nettle_gostdsa_hash (mp_limb_t *hp, unsigned bit_size,
+                     size_t length, const uint8_t *digest);
+
 
 #endif /* NETTLE_DSA_INTERNAL_H_INCLUDED */
index 42a0a581150daa129057a3ecd29661d9969de2c4..ff66a0a686918f003d0f3203a8412575e3acee6a 100644 (file)
@@ -42,7 +42,7 @@
 #include "dsa-internal.h"
 
 #include "bignum.h"
-
+#include "gmp-glue.h"
 
 int
 dsa_sign(const struct dsa_params *params,
@@ -55,8 +55,11 @@ dsa_sign(const struct dsa_params *params,
   mpz_t k;
   mpz_t h;
   mpz_t tmp;
+  unsigned bit_size;
+  unsigned limb_size;
+
   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))
@@ -75,8 +78,11 @@ dsa_sign(const struct dsa_params *params,
   mpz_fdiv_r(signature->r, tmp, params->q);
 
   /* Compute hash */
+  bit_size = mpz_sizeinbase(params->q, 2);
+  limb_size = NETTLE_BIT_SIZE_TO_LIMB_SIZE(bit_size);
   mpz_init(h);
-  _nettle_dsa_hash (h, mpz_sizeinbase(params->q, 2), digest_size, digest);
+  _nettle_dsa_hash (mpz_limbs_write (h, limb_size), bit_size, digest_size, digest);
+  mpz_limbs_finish (h, limb_size);
 
   /* Compute k^-1 (mod q) */
   if (mpz_invert(k, k, params->q))
index eb573fe351513415d453dffe3d83c362645b6c69..adc12c7fe65b7a144ed107ae3a80bca633b5e888 100644 (file)
@@ -40,7 +40,7 @@
 #include "dsa.h"
 #include "dsa-internal.h"
 
-#include "bignum.h"
+#include "gmp-glue.h"
 
 int
 dsa_verify(const struct dsa_params *params,
@@ -52,6 +52,8 @@ dsa_verify(const struct dsa_params *params,
   mpz_t w;
   mpz_t tmp;
   mpz_t v;
+  unsigned bit_size;
+  unsigned limb_size;
 
   int res;
 
@@ -78,7 +80,10 @@ dsa_verify(const struct dsa_params *params,
   mpz_init(v);
 
   /* The message digest */
-  _nettle_dsa_hash (tmp, mpz_sizeinbase (params->q, 2), digest_size, digest);
+  bit_size = mpz_sizeinbase(params->q, 2);
+  limb_size = NETTLE_BIT_SIZE_TO_LIMB_SIZE(bit_size);
+  _nettle_dsa_hash (mpz_limbs_write (tmp, limb_size), bit_size, digest_size, digest);
+  mpz_limbs_finish (tmp, limb_size);
   
   /* v = g^{w * h (mod q)} (mod p)  */
   mpz_mul(tmp, tmp, w);
index 6a41c14c611f542c5e804a220581ac2e5684b70f..522a04d49b6421496b2b8086ce9cba74b5575ea7 100644 (file)
@@ -40,6 +40,7 @@
 
 #include "ecdsa.h"
 #include "ecc-internal.h"
+#include "dsa-internal.h"
 
 /* Low-level ECDSA signing */
 
@@ -87,7 +88,7 @@ ecc_ecdsa_sign (const struct ecc_curve *ecc,
   ecc->q.invert (&ecc->q, kinv, kp, tp);
   
   /* Process hash digest */
-  ecc_hash (&ecc->q, hp, length, digest);
+  _nettle_dsa_hash (hp, ecc->q.bit_size, length, digest);
 
   ecc_mod_mul (&ecc->q, tp, zp, rp, tp);
   ecc_mod_add (&ecc->q, hp, hp, tp);
index 9e324ea2cdcce59e514cbadf5522f93f9e9a84cf..6481b6c3356f6699454cbb1ee79f0124821efffa 100644 (file)
@@ -40,6 +40,7 @@
 
 #include "ecdsa.h"
 #include "ecc-internal.h"
+#include "dsa-internal.h"
 
 /* Low-level ECDSA verify */
 
@@ -101,7 +102,7 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
   ecc->q.invert (&ecc->q, sinv, sp, sinv + ecc->p.size);
 
   /* u1 = h / s, P1 = u1 * G */
-  ecc_hash (&ecc->q, hp, length, digest);
+  _nettle_dsa_hash (hp, ecc->q.bit_size, length, digest);
   ecc_mod_mul_canonical (&ecc->q, u1, hp, sinv, u1);
 
   /* u2 = r / s, P2 = u2 * Y */
index c811c87ef43234382cae86f4d9b2c725ef5b316e..ea63a2225011eaf729ecc2169e54e758a86bbe27 100644 (file)
@@ -38,6 +38,7 @@
 #include <stdlib.h>
 
 #include "gostdsa.h"
+#include "dsa-internal.h"
 #include "ecc-internal.h"
 
 /* Low-level GOST DSA signing */
@@ -79,7 +80,7 @@ ecc_gostdsa_sign (const struct ecc_curve *ecc,
   ecc_j_to_a (ecc, 2, rp, P, P + 3*ecc->p.size);
 
   /* Process hash digest */
-  gost_hash (&ecc->q, hp, length, digest);
+  _nettle_gostdsa_hash (hp, ecc->q.bit_size, length, digest);
   if (mpn_zero_p (hp, ecc->p.size))
     mpn_add_1 (hp, hp, ecc->p.size, 1);
 
index 0570af7e1982eec57d59ce85dfd43ea87ceab40d..2865ad63a37647e96e118a961d353150c9188d79 100644 (file)
@@ -38,6 +38,7 @@
 #include <stdlib.h>
 
 #include "gostdsa.h"
+#include "dsa-internal.h"
 #include "ecc-internal.h"
 
 /* Low-level GOST DSA verify */
@@ -93,7 +94,7 @@ ecc_gostdsa_verify (const struct ecc_curve *ecc,
         && ecdsa_in_range (ecc, sp)))
     return 0;
 
-  gost_hash (&ecc->q, hp, length, digest);
+  _nettle_gostdsa_hash (hp, ecc->q.bit_size, length, digest);
 
   if (mpn_zero_p (hp, ecc->p.size))
     mpn_add_1 (hp, hp, ecc->p.size, 1);
diff --git a/ecc-hash.c b/ecc-hash.c
deleted file mode 100644 (file)
index 0787711..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ecdsa-hash.c
-
-   Copyright (C) 2013 Niels Möller
-
-   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 "ecc-internal.h"
-
-/* Convert hash value to an integer. If the digest is larger than
-   the ecc bit size, then we must truncate it and use the leftmost
-   bits. */
-
-/* NOTE: We don't considered the hash value to be secret, so it's ok
-   if the running time of this conversion depends on h.
-
-   Requires m->size + 1 limbs, the extra limb may be needed for
-   unusual limb sizes.
-*/
-
-void
-ecc_hash (const struct ecc_modulo *m,
-         mp_limb_t *hp,
-         size_t length, const uint8_t *digest)
-{
-  if (length > ((size_t) m->bit_size + 7) / 8)
-    length = (m->bit_size + 7) / 8;
-
-  mpn_set_base256 (hp, m->size + 1, digest, length);
-
-  if (8 * length > m->bit_size)
-    /* We got a few extra bits, at the low end. Discard them. */
-    mpn_rshift (hp, hp, m->size + 1, 8*length - m->bit_size);
-}
-
-void
-gost_hash (const struct ecc_modulo *m,
-          mp_limb_t *hp,
-          size_t length, const uint8_t *digest)
-{
-  if (length > ((size_t) m->bit_size + 7) / 8)
-    length = (m->bit_size + 7) / 8;
-
-  mpn_set_base256_le (hp, m->size + 1, digest, length);
-}
index 4323304311dc0cd8edcbb4776537ae3d70e7aa58..7c3b83968de4738fc2a5228721f658eb67c6599b 100644 (file)
@@ -58,8 +58,6 @@
 #define ecc_mod_random _nettle_ecc_mod_random
 #define ecc_mod _nettle_ecc_mod
 #define ecc_mod_inv _nettle_ecc_mod_inv
-#define ecc_hash _nettle_ecc_hash
-#define gost_hash _nettle_gost_hash
 #define ecc_a_to_j _nettle_ecc_a_to_j
 #define ecc_j_to_a _nettle_ecc_j_to_a
 #define ecc_eh_to_a _nettle_ecc_eh_to_a
@@ -339,16 +337,6 @@ void
 ecc_mod_random (const struct ecc_modulo *m, mp_limb_t *xp,
                void *ctx, nettle_random_func *random, mp_limb_t *scratch);
 
-void
-ecc_hash (const struct ecc_modulo *m,
-         mp_limb_t *hp,
-         size_t length, const uint8_t *digest);
-
-void
-gost_hash (const struct ecc_modulo *m,
-         mp_limb_t *hp,
-         size_t length, const uint8_t *digest);
-
 /* Converts a point P in affine coordinates into a point R in jacobian
    coordinates. */
 void
index afe946355032851575621b293b2d58b69dc8ccc1..321cb4488a29a217b977c8d5e85b9916a22bec71 100644 (file)
@@ -85,8 +85,11 @@ is_zero_limb (mp_limb_t x)
 int
 sec_zero_p (const mp_limb_t *ap, mp_size_t n);
 
+#define NETTLE_BIT_SIZE_TO_LIMB_SIZE(n) \
+  (((n) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
+
 #define NETTLE_OCTET_SIZE_TO_LIMB_SIZE(n) \
-  (((n) * 8 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
+  (NETTLE_BIT_SIZE_TO_LIMB_SIZE((n) * 8))
 
 /* Convenience functions */