summaryrefslogtreecommitdiff
path: root/eddsa-hash.c
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2020-01-02 19:36:17 +0100
committerNiels Möller <nisse@lysator.liu.se>2020-01-02 19:36:17 +0100
commit42e410bf0c084b1352b235e7e190fa6406a11441 (patch)
tree51db6a2dba6c6e437f3718d6089efd5b9590be1b /eddsa-hash.c
parentbbc64730490afbb7d6c14813a2d0944b8d6d7c19 (diff)
downloadnettle-42e410bf0c084b1352b235e7e190fa6406a11441.tar.gz
Update eddsa internals to support ed448.
Diffstat (limited to 'eddsa-hash.c')
-rw-r--r--eddsa-hash.c34
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);
}