From f0e2f36e44930a0fde3b694409fdb127bb0e4794 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Niels=20M=C3=B6ller?= Date: Sat, 1 Jun 2024 18:26:56 +0200 Subject: [PATCH] Unify handing of message hash for dsa and ecdsa, using mpn interface. --- ChangeLog | 18 +++++++++++ Makefile.in | 2 +- dsa-hash.c | 43 +++++++++++++++++++------ dsa-internal.h | 6 +++- dsa-sign.c | 12 +++++-- dsa-verify.c | 9 ++++-- ecc-ecdsa-sign.c | 3 +- ecc-ecdsa-verify.c | 3 +- ecc-gostdsa-sign.c | 3 +- ecc-gostdsa-verify.c | 3 +- ecc-hash.c | 75 -------------------------------------------- ecc-internal.h | 12 ------- gmp-glue.h | 5 ++- 13 files changed, 86 insertions(+), 108 deletions(-) delete mode 100644 ecc-hash.c diff --git a/ChangeLog b/ChangeLog index 23571377..4440af5f 100644 --- 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 * powerpc64/p8/gcm-aes-encrypt.asm: Reduce register usage. 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..77d89583 100644 --- a/dsa-hash.c +++ b/dsa-hash.c @@ -36,22 +36,47 @@ #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); } 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..adc12c7f 100644 --- a/dsa-verify.c +++ b/dsa-verify.c @@ -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); 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..ea63a222 100644 --- a/ecc-gostdsa-sign.c +++ b/ecc-gostdsa-sign.c @@ -38,6 +38,7 @@ #include #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); diff --git a/ecc-gostdsa-verify.c b/ecc-gostdsa-verify.c index 0570af7e..2865ad63 100644 --- a/ecc-gostdsa-verify.c +++ b/ecc-gostdsa-verify.c @@ -38,6 +38,7 @@ #include #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 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..7c3b8396 100644 --- a/ecc-internal.h +++ b/ecc-internal.h @@ -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 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 */ -- 2.47.2