From 1df2957f4b063d435e2bb6c5f822a61749548a4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Wed, 8 Oct 2014 22:44:49 +0200
Subject: [PATCH] New function _eddsa_expand_key.

---
 ChangeLog      |  4 +++
 Makefile.in    |  4 +--
 eddsa-expand.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++
 eddsa.h        | 16 +++++++++
 4 files changed, 117 insertions(+), 2 deletions(-)
 create mode 100644 eddsa-expand.c

diff --git a/ChangeLog b/ChangeLog
index f85a67ca..3de9be5e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2014-10-08  Niels Möller  <nisse@lysator.liu.se>
 
+	* eddsa-expand.c (_eddsa_expand_key): New file, new function.
+	* eddsa.h (_eddsa_expand_key): Declare it.
+	* Makefile.in (hogweed_SOURCES): Added eddsa-expand.c.
+
 	* eddsa-sign.c: Drop unneeded include of nettle-internal.h.
 
 2014-10-04  Niels Möller  <nisse@lysator.liu.se>
diff --git a/Makefile.in b/Makefile.in
index 66615514..f3f2b38c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -176,8 +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-hash.c \
-		  eddsa-sign.c \
+		  eddsa-compress.c eddsa-decompress.c eddsa-expand.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-expand.c b/eddsa-expand.c
new file mode 100644
index 00000000..9c0b0b23
--- /dev/null
+++ b/eddsa-expand.c
@@ -0,0 +1,95 @@
+/* eddsa-expand.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 <string.h>
+
+#include "eddsa.h"
+
+#include "ecc.h"
+#include "ecc-internal.h"
+#include "nettle-meta.h"
+
+mp_size_t
+_eddsa_expand_key_itch (const struct ecc_curve *ecc)
+{
+  assert (_eddsa_compress_itch (ecc) <= ecc->mul_g_itch);
+  return 3*ecc->p.size + ecc->mul_g_itch;
+}
+
+/* Expands a private key, generating the key K1 for nonce generation,
+   the secret scalar K2, and, if PUB is non-NULL, the corresponding
+   public key (in compressed form). */
+void
+_eddsa_expand_key (const struct ecc_curve *ecc,
+		   const struct nettle_hash *H,
+		   void *ctx,
+		   const uint8_t *key,
+		   uint8_t *pub,
+		   uint8_t *k1,
+		   mp_limb_t *k2,
+		   mp_limb_t *scratch)
+{
+  size_t nbytes = 1 + ecc->p.bit_size / 8;
+  uint8_t *digest = (uint8_t *) scratch;
+
+#define P scratch
+#define scratch_out (scratch + 3*ecc->p.size)
+
+  assert (H->digest_size >= 2*nbytes);
+
+  H->init (ctx);
+  H->update (ctx, nbytes, key);
+  H->digest (ctx, 2*nbytes, digest);
+  memcpy (k1, digest + nbytes, nbytes);
+
+  mpn_set_base256_le (k2, ecc->p.size, digest, nbytes);
+  /* Clear low 3 bits */
+  k2[0] &= ~(mp_limb_t) 7;
+  /* Set bit number bit_size - 1 (bit 254 for curve25519) */
+  k2[(ecc->p.bit_size - 1) / GMP_NUMB_BITS]
+    |= (mp_limb_t) 1 << ((ecc->p.bit_size - 1) % GMP_NUMB_BITS);
+  /* Clear any higher bits. */
+  k2[ecc->p.size - 1] &= ~(mp_limb_t) 0
+    >> (GMP_NUMB_BITS * ecc->p.size - ecc->p.bit_size);
+
+  if (pub)
+    {
+      ecc->mul_g (ecc, P, k2, scratch_out);
+      _eddsa_compress (ecc, pub, P, scratch_out);
+    }
+#undef P
+#undef scratch_out
+}
diff --git a/eddsa.h b/eddsa.h
index 551c7355..d368432b 100644
--- a/eddsa.h
+++ b/eddsa.h
@@ -46,6 +46,8 @@ extern "C" {
 #define _eddsa_decompress _nettle_eddsa_decompress
 #define _eddsa_decompress_itch _nettle_eddsa_decompress_itch
 #define _eddsa_hash _nettle_eddsa_hash
+#define _eddsa_expand_key_itch _nettle_eddsa_expand_key_itch
+#define _eddsa_expand_key _nettle_eddsa_expand_key
 #define _eddsa_sign _nettle_eddsa_sign
 #define _eddsa_sign_itch _nettle_eddsa_sign_itch
 
@@ -85,6 +87,20 @@ _eddsa_sign (const struct ecc_curve *ecc,
 	     uint8_t *signature,
 	     mp_limb_t *scratch);
 
+mp_size_t
+_eddsa_expand_key_itch (const struct ecc_curve *ecc);
+
+void
+_eddsa_expand_key (const struct ecc_curve *ecc,
+		   const struct nettle_hash *H,
+		   void *ctx,
+		   const uint8_t *key,
+		   uint8_t *pub,
+		   uint8_t *k1,
+		   mp_limb_t *k2,
+		   mp_limb_t *scratch);
+
+			   
 #ifdef __cplusplus
 }
 #endif
-- 
GitLab