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 -- [email protected]
To unsubscribe send an email to [email protected]