Implemented eddsa signature internals.
authorNiels Möller <nisse@lysator.liu.se>
Sat, 4 Oct 2014 19:21:48 +0000 (21:21 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Sat, 4 Oct 2014 19:21:48 +0000 (21:21 +0200)
ChangeLog
Makefile.in
eddsa-hash.c [new file with mode: 0644]
eddsa-sign.c [new file with mode: 0644]
eddsa.h

index 5dab6273a452b2a9372a3b94a1fa5bf93e45efcb..82ad092d47584148a86f0f311176b33585704762 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2014-10-04  Niels Möller  <nisse@lysator.liu.se>
+
+       * eddsa-sign.c (_eddsa_sign, _eddsa_sign_itch): New file, new
+       functions.
+       * eddsa-hash.c (_eddsa_hash): New file and function.
+       * eddsa.h: Declare new functions.
+       * Makefile.in (hogweed_SOURCES): Added eddsa-hash.c and
+       eddsa-sign.c.
+
 2014-10-03  Niels Möller  <nisse@lysator.liu.se>
 
        * testsuite/ecc-redc-test.c [NETTLE_USE_MINI_GMP]: Enable test.
index 1cc423dfac8c7dc9fe2ca8127bb0bfaecc3f1350..666155149f7d1095f3a90afa9361546c4544e403 100644 (file)
@@ -176,7 +176,8 @@ hogweed_SOURCES = sexp.c sexp-format.c \
                  ecc-ecdsa-sign.c ecdsa-sign.c \
                  ecc-ecdsa-verify.c ecdsa-verify.c ecdsa-keygen.c \
                  curve25519-mul-g.c curve25519-mul.c curve25519-eh-to-x.c \
-                 eddsa-compress.c eddsa-decompress.c \
+                 eddsa-compress.c eddsa-decompress.c eddsa-hash.c \
+                 eddsa-sign.c \
                  $(OPT_HOGWEED_SOURCES)
 
 HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \
diff --git a/eddsa-hash.c b/eddsa-hash.c
new file mode 100644 (file)
index 0000000..4fb79f1
--- /dev/null
@@ -0,0 +1,51 @@
+/* eddsa-hash.c
+
+   Copyright (C) 2014 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/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "eddsa.h"
+
+#include "ecc.h"
+#include "ecc-internal.h"
+#include "nettle-internal.h"
+
+void
+_eddsa_hash (const struct ecc_modulo *m,
+            mp_limb_t *rp, const uint8_t *digest)
+{
+  size_t nbytes = 1 + m->bit_size / 8;
+  mpn_set_base256_le (rp, 2*m->size, digest, 2*nbytes);
+  m->mod (m, rp);
+}
diff --git a/eddsa-sign.c b/eddsa-sign.c
new file mode 100644 (file)
index 0000000..9b0c9d5
--- /dev/null
@@ -0,0 +1,108 @@
+/* eddsa-sign.c
+
+   Copyright (C) 2014 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/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "eddsa.h"
+
+#include "ecc.h"
+#include "ecc-internal.h"
+#include "nettle-internal.h"
+#include "nettle-meta.h"
+
+mp_size_t
+_eddsa_sign_itch (const struct ecc_curve *ecc)
+{
+  return 5*ecc->p.size + ecc->mul_g_itch;
+}
+
+void
+_eddsa_sign (const struct ecc_curve *ecc,
+            const struct nettle_hash *H,
+            const uint8_t *pub,
+            void *ctx,
+            const mp_limb_t *k2,
+            size_t length,
+            const uint8_t *msg,
+            uint8_t *signature,
+            mp_limb_t *scratch)
+{
+  mp_size_t size;
+  size_t nbytes;
+#define rp scratch
+#define hp (scratch + size)
+#define P (scratch + 2*size)
+#define sp (scratch + 2*size)
+#define hash ((uint8_t *) (scratch + 3*size))
+#define scratch_out (scratch + 5*size)
+
+  size = ecc->p.size;
+  nbytes = 1 + ecc->p.bit_size / 8;
+
+  assert (H->digest_size >= 2 * nbytes);
+
+  H->update (ctx, length, msg);
+  H->digest (ctx, 2*nbytes, hash);
+  _eddsa_hash (&ecc->q, rp, hash);
+  ecc->mul_g (ecc, P, rp, scratch_out);
+  _eddsa_compress (ecc, signature, P, scratch_out);
+
+  H->update (ctx, nbytes, signature);
+  H->update (ctx, nbytes, pub);
+  H->update (ctx, length, msg);
+  H->digest (ctx, 2*nbytes, hash);
+  _eddsa_hash (&ecc->q, hp, hash);
+
+  ecc_modq_mul (ecc, sp, hp, k2);
+  ecc_modq_add (ecc, sp, sp, rp); /* FIXME: Can be plain add */
+  /* FIXME: Special code duplicated in ecc_25519_modq and ecc_eh_to_a.
+     Define a suitable method? */
+  {
+    unsigned shift;
+    mp_limb_t cy;
+    assert (ecc->p.bit_size == 255);
+    shift = 252 - GMP_NUMB_BITS * (ecc->p.size - 1);
+    cy = mpn_submul_1 (sp, ecc->q.m, ecc->p.size,
+                      sp[ecc->p.size-1] >> shift);
+    assert (cy < 2);
+    cnd_add_n (cy, sp, ecc->q.m, ecc->p.size);
+  }
+  mpn_get_base256_le (signature + nbytes, nbytes, sp, ecc->q.size);
+#undef rp
+#undef hp
+#undef P
+#undef sp
+#undef hash
+}
diff --git a/eddsa.h b/eddsa.h
index 7152b0773ff41b3c1316fbf6248f308bdcb85432..551c73554150d3b9f21d3267fba634c358bd2b44 100644 (file)
--- a/eddsa.h
+++ b/eddsa.h
@@ -45,10 +45,14 @@ extern "C" {
 #define _eddsa_compress_itch _nettle_eddsa_compress_itch
 #define _eddsa_decompress _nettle_eddsa_decompress
 #define _eddsa_decompress_itch _nettle_eddsa_decompress_itch
+#define _eddsa_hash _nettle_eddsa_hash
+#define _eddsa_sign _nettle_eddsa_sign
+#define _eddsa_sign_itch _nettle_eddsa_sign_itch
 
 #define ED25519_KEY_SIZE 32
 
 struct ecc_curve;
+struct ecc_modulo;
 
 mp_size_t
 _eddsa_compress_itch (const struct ecc_curve *ecc);
@@ -63,6 +67,24 @@ _eddsa_decompress (const struct ecc_curve *ecc, mp_limb_t *p,
                   const uint8_t *cp,
                   mp_limb_t *scratch);
 
+void
+_eddsa_hash (const struct ecc_modulo *m,
+            mp_limb_t *rp, const uint8_t *digest);
+
+mp_size_t
+_eddsa_sign_itch (const struct ecc_curve *ecc);
+
+void
+_eddsa_sign (const struct ecc_curve *ecc,
+            const struct nettle_hash *H,
+            const uint8_t *pub,
+            void *ctx,
+            const mp_limb_t *k2,
+            size_t length,
+            const uint8_t *msg,
+            uint8_t *signature,
+            mp_limb_t *scratch);
+
 #ifdef __cplusplus
 }
 #endif