diff options
author | Niels Möller <nisse@lysator.liu.se> | 2020-01-02 19:36:17 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2020-01-02 19:36:17 +0100 |
commit | 42e410bf0c084b1352b235e7e190fa6406a11441 (patch) | |
tree | 51db6a2dba6c6e437f3718d6089efd5b9590be1b /eddsa-hash.c | |
parent | bbc64730490afbb7d6c14813a2d0944b8d6d7c19 (diff) | |
download | nettle-42e410bf0c084b1352b235e7e190fa6406a11441.tar.gz |
Update eddsa internals to support ed448.
Diffstat (limited to 'eddsa-hash.c')
-rw-r--r-- | eddsa-hash.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/eddsa-hash.c b/eddsa-hash.c index 46f6ca34..e05f6ac1 100644 --- a/eddsa-hash.c +++ b/eddsa-hash.c @@ -1,6 +1,8 @@ /* eddsa-hash.c - Copyright (C) 2014 Niels Möller + Copyright (C) 2014, 2019 Niels Möller + Copyright (C) 2017 Daiki Ueno + Copyright (C) 2017 Red Hat, Inc. This file is part of GNU Nettle. @@ -42,11 +44,35 @@ #include "ecc-internal.h" #include "nettle-internal.h" +/* Convert hash digest to integer, and reduce modulo q, to m->size + limbs. Needs space for 2*m->size + 1 at rp. */ void _eddsa_hash (const struct ecc_modulo *m, - mp_limb_t *rp, const uint8_t *digest) + mp_limb_t *rp, size_t digest_size, const uint8_t *digest) { - size_t nbytes = 1 + m->bit_size / 8; - mpn_set_base256_le (rp, 2*m->size, digest, 2*nbytes); + mp_size_t nlimbs = (8*digest_size + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS; + + mpn_set_base256_le (rp, nlimbs, digest, digest_size); + + if (nlimbs > 2*m->size) + { + /* Special case for Ed448: reduce rp to 2*m->size limbs. + After decoding rp from a hash of size 2*rn: + + rp = r2 || r1 || r0 + + where r0 and r1 have m->size limbs. Reduce this to: + + rp = r1' || r0 + + where r1' has m->size limbs. */ + mp_limb_t hi = rp[2*m->size]; + assert (nlimbs == 2*m->size + 1); + + hi = mpn_addmul_1 (rp + m->size, m->B, m->size, hi); + assert (hi <= 1); + hi = cnd_add_n (hi, rp + m->size, m->B, m->size); + assert (hi == 0); + } m->mod (m, rp); } |