Re: Deterministic (EC)DSA
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 + #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 */
Re: Deterministic (EC)DSA
Niels Möller writes: > Daiki Ueno writes: > >> I agree, that's a valid use-case. Perhaps this might suffice: >> >> /* Sign DIGEST with KEY using deterministic nonce generation. >>* >>* DIGEST must be of the same length of SHA-256 output, that is 32 >>* octets long. */ >> void >> ecdsa_sha256_sign_deterministic (const struct ecc_scalar *key, >>const uint8_t *digest, >>struct dsa_signature *signature); > > Looks good to me. Underlying more general helper functions > (however they are organized) can be internal only. I've updated the MR along these lines. Regards, -- Daiki Ueno ___ nettle-bugs mailing list -- nettle-bugs@lists.lysator.liu.se To unsubscribe send an email to nettle-bugs-le...@lists.lysator.liu.se
Re: Deterministic (EC)DSA
Daiki Ueno writes: > I agree, that's a valid use-case. Perhaps this might suffice: > > /* Sign DIGEST with KEY using deterministic nonce generation. >* >* DIGEST must be of the same length of SHA-256 output, that is 32 >* octets long. */ > void > ecdsa_sha256_sign_deterministic (const struct ecc_scalar *key, >const uint8_t *digest, >struct dsa_signature *signature); Looks good to me. Underlying more general helper functions (however they are organized) can be internal only. Regards, /Niels -- 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
Re: Deterministic (EC)DSA
Niels Möller writes: > Daiki Ueno writes: > >> I have a slight feeling that the current API is not easy to use, as the >> caller needs to instantiate both hash and HMAC contexts, as there are no >> correlations between the two: > > On a more abstract level, are there any reasonable usecases for having > one hash function for processing the message, and a different underlying > hash function for the hmac used to produce the deterministic nonce? Not that I know of. The RFC mandates the same hash function to be used in both for processing the message and generating a nonce. >> What would you say to introducing a specialized API, something like the >> following? >> >> void >> ecdsa_sha256_sign_deterministic (const struct ecc_scalar *key, >>size_t length, >>const uint8_t *message, >>struct dsa_signature *signature); > > I think that could sense, but we also need an advertised api function > that takes the digest as input, for applications that want to process > the message using multiple _update calls. I agree, that's a valid use-case. Perhaps this might suffice: /* Sign DIGEST with KEY using deterministic nonce generation. * * DIGEST must be of the same length of SHA-256 output, that is 32 * octets long. */ void ecdsa_sha256_sign_deterministic (const struct ecc_scalar *key, const uint8_t *digest, struct dsa_signature *signature); Regards, -- Daiki Ueno ___ nettle-bugs mailing list -- nettle-bugs@lists.lysator.liu.se To unsubscribe send an email to nettle-bugs-le...@lists.lysator.liu.se
Re: Deterministic (EC)DSA
Daiki Ueno writes: > I have a slight feeling that the current API is not easy to use, as the > caller needs to instantiate both hash and HMAC contexts, as there are no > correlations between the two: On a more abstract level, are there any reasonable usecases for having one hash function for processing the message, and a different underlying hash function for the hmac used to produce the deterministic nonce? > What would you say to introducing a specialized API, something like the > following? > > void > ecdsa_sha256_sign_deterministic (const struct ecc_scalar *key, >size_t length, >const uint8_t *message, >struct dsa_signature *signature); I think that could sense, but we also need an advertised api function that takes the digest as input, for applications that want to process the message using multiple _update calls. Regards, /Niels -- 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
Re: Deterministic (EC)DSA
Niels Möller writes: > Daiki Ueno writes: > >> The attached patch adds support for the deterministic DSA and ECDSA, as >> defined in RFC 6979, which enables us to use the signing function >> without randomness. > > Thanks, I've had a first read, and added some comments on your MR > (https://git.lysator.liu.se/nettle/nettle/-/merge_requests/64). Thank you; I updated the MR to address those comments. I have a slight feeling that the current API is not easy to use, as the caller needs to instantiate both hash and HMAC contexts, as there are no correlations between the two: struct sha256_ctx sha256; sha256_init (); sha256_update (, length, message); sha256_digest (, SHA256_DIGEST_SIZE, digest); struct hmac_sha256_ctx hmac_sha256; ecdsa_sign_deterministic (, _sha256, _hmac_sha256, digest, ); What would you say to introducing a specialized API, something like the following? void ecdsa_sha256_sign_deterministic (const struct ecc_scalar *key, size_t length, const uint8_t *message, struct dsa_signature *signature); Regards, -- Daiki Ueno ___ nettle-bugs mailing list -- nettle-bugs@lists.lysator.liu.se To unsubscribe send an email to nettle-bugs-le...@lists.lysator.liu.se
Re: Deterministic (EC)DSA
Daiki Ueno writes: > The attached patch adds support for the deterministic DSA and ECDSA, as > defined in RFC 6979, which enables us to use the signing function > without randomness. Thanks, I've had a first read, and added some comments on your MR (https://git.lysator.liu.se/nettle/nettle/-/merge_requests/64). Regards, /Niels -- 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