Somewhat related to RFC 6979, I've made a patch to unify the way digest
is converted to integer (bits2int, except that it doesn't produce
canonical representation mod q).

I think it would make sense to have a shared helper function for
signing, that takes integer representation of both h (hash) and k
(nonce) as input.

Regards,
/Niels

diff --git a/Makefile.in b/Makefile.in
index cfc83e0b..2bf7f1e8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -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 \
diff --git a/dsa-hash.c b/dsa-hash.c
index aab3c838..26aa4917 100644
--- a/dsa-hash.c
+++ b/dsa-hash.c
@@ -33,25 +33,50 @@
 # include "config.h"
 #endif
 
+#include <assert.h>
+
 #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);
+}
+
+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 = (bit_size + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
+
+  if (length > octet_size)
+    length = octet_size;
+
+  mpn_set_base256_le(hp, limb_size, digest, length);
 }
diff --git a/dsa-internal.h b/dsa-internal.h
index ce57c72a..7baa6ba0 100644
--- a/dsa-internal.h
+++ b/dsa-internal.h
@@ -38,8 +38,12 @@
 
 /* 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 */
diff --git a/dsa-sign.c b/dsa-sign.c
index 42a0a581..ff66a0a6 100644
--- a/dsa-sign.c
+++ b/dsa-sign.c
@@ -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))
diff --git a/dsa-verify.c b/dsa-verify.c
index eb573fe3..aec62fae 100644
--- a/dsa-verify.c
+++ b/dsa-verify.c
@@ -41,6 +41,7 @@
 #include "dsa-internal.h"
 
 #include "bignum.h"
+#include "gmp-glue.h"
 
 int
 dsa_verify(const struct dsa_params *params,
@@ -52,6 +53,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 +81,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);
diff --git a/ecc-ecdsa-sign.c b/ecc-ecdsa-sign.c
index 6a41c14c..522a04d4 100644
--- a/ecc-ecdsa-sign.c
+++ b/ecc-ecdsa-sign.c
@@ -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);
diff --git a/ecc-ecdsa-verify.c b/ecc-ecdsa-verify.c
index 9e324ea2..6481b6c3 100644
--- a/ecc-ecdsa-verify.c
+++ b/ecc-ecdsa-verify.c
@@ -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 */
diff --git a/ecc-gostdsa-sign.c b/ecc-gostdsa-sign.c
index c811c87e..f5a0cf7b 100644
--- a/ecc-gostdsa-sign.c
+++ b/ecc-gostdsa-sign.c
@@ -79,7 +79,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);
 
diff --git a/ecc-gostdsa-verify.c b/ecc-gostdsa-verify.c
index 0570af7e..14c12335 100644
--- a/ecc-gostdsa-verify.c
+++ b/ecc-gostdsa-verify.c
@@ -93,7 +93,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
index 07877110..00000000
--- a/ecc-hash.c
+++ /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);
-}
diff --git a/ecc-internal.h b/ecc-internal.h
index 43233043..b4b45bae 100644
--- a/ecc-internal.h
+++ b/ecc-internal.h
@@ -58,7 +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
@@ -339,16 +338,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
diff --git a/gmp-glue.h b/gmp-glue.h
index afe94635..321cb448 100644
--- a/gmp-glue.h
+++ b/gmp-glue.h
@@ -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 */
 

-- 
Niels Möller. PGP key CB4962D070D77D7FCB8BA36271D8F1FF368C6677.
Internet email is subject to wholesale government surveillance.
_______________________________________________
nettle-bugs mailing list -- nettle-bugs@lists.lysator.liu.se
To unsubscribe send an email to nettle-bugs-le...@lists.lysator.liu.se

Reply via email to