diff --git a/ChangeLog b/ChangeLog
index 4087cc56ef784833dc3e4848d3e20e9f8e3544d7..7be4706212c900be11a680bb4a1b31e66639ab0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2014-10-20  Niels Möller  <nisse@lysator.liu.se>
+
+	* eddsa.h (ED25519_KEY_SIZE): New constant.
+	(ED25519_SIGNATURE_SIZE): New constant.
+	(struct ed25519_private_key): New struct.
+	(struct ed25519_public_key): New struct.
+
+	* ed25519-sha512-sign.c (ed25519_sha512_set_private_key)
+	(ed25519_sha512_sign): New file and functions.
+	* ed25519-sha512-verify.c (ed25519_sha512_set_public_key)
+	(ed25519_sha512_verify): New file and functions.
+	* Makefile.in (hogweed_SOURCES): Added ed25519-sha512-sign.c and
+	ed25519-sha512-verify.c.
+
+
 2014-10-18  Niels Möller  <nisse@lysator.liu.se>
 
 	* eddsa-verify.c (_eddsa_verify): Change argument order, putting A
diff --git a/Makefile.in b/Makefile.in
index 7006211e1dfd70ac2710d36621295fc7401d977a..19269af978c9b5d6ffd65b9b389d0b2aaaaf055c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -178,6 +178,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
 		  curve25519-mul-g.c curve25519-mul.c curve25519-eh-to-x.c \
 		  eddsa-compress.c eddsa-decompress.c eddsa-expand.c \
 		  eddsa-hash.c eddsa-sign.c eddsa-verify.c \
+		  ed25519-sha512-sign.c ed25519-sha512-verify.c \
 		  $(OPT_HOGWEED_SOURCES)
 
 HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \
diff --git a/ed25519-sha512-sign.c b/ed25519-sha512-sign.c
new file mode 100644
index 0000000000000000000000000000000000000000..bbcd133b371f243548a17bafe2fd0a729e66eacd
--- /dev/null
+++ b/ed25519-sha512-sign.c
@@ -0,0 +1,70 @@
+/* ed25519-sha512-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 "eddsa.h"
+
+#include "ecc-internal.h"
+#include "sha2.h"
+
+void
+ed25519_sha512_set_private_key (struct ed25519_private_key *priv,
+				const uint8_t *key)
+{
+  mp_size_t itch = _eddsa_expand_key_itch (&nettle_curve25519);
+  mp_limb_t *scratch = gmp_alloc_limbs (itch);
+  struct sha512_ctx ctx;
+
+  _eddsa_expand_key (&nettle_curve25519, &nettle_sha512, &ctx,
+		     key, priv->pub, priv->k1, priv->k2, scratch);
+  gmp_free_limbs (scratch, itch);
+}
+
+void
+ed25519_sha512_sign (const struct ed25519_private_key *priv,
+		     size_t length, const uint8_t *msg,
+		     uint8_t *signature)
+{
+  mp_size_t itch = _eddsa_sign_itch (&nettle_curve25519);
+  mp_limb_t *scratch = gmp_alloc_limbs (itch);
+  struct sha512_ctx ctx;
+
+  sha512_init (&ctx);
+  sha512_update (&ctx, ED25519_KEY_SIZE, priv->k1);
+  _eddsa_sign (&nettle_curve25519, &nettle_sha512, priv->pub,
+	       &ctx,
+	       priv->k2, length, msg, signature, scratch);
+
+  gmp_free_limbs (scratch, itch);
+}
diff --git a/ed25519-sha512-verify.c b/ed25519-sha512-verify.c
new file mode 100644
index 0000000000000000000000000000000000000000..763a9b043f5b06ce455a020e92df1909e336f544
--- /dev/null
+++ b/ed25519-sha512-verify.c
@@ -0,0 +1,75 @@
+/* ed25519-sha512-verify.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 <string.h>
+
+#include "eddsa.h"
+
+#include "ecc-internal.h"
+#include "sha2.h"
+
+int
+ed25519_sha512_set_public_key (struct ed25519_public_key *pub,
+			       const uint8_t *key)
+{
+  mp_size_t itch = _eddsa_decompress_itch (&nettle_curve25519);
+  mp_limb_t *scratch = gmp_alloc_limbs (itch);
+  int res;
+
+  memcpy (pub->pub, key, sizeof(pub->pub));
+  res = _eddsa_decompress (&nettle_curve25519,
+			   pub->A, key, scratch);
+
+  gmp_free_limbs (scratch, itch);
+  return res;
+}
+
+int
+ed25519_sha512_verify (const struct ed25519_public_key *pub,
+		       size_t length, const uint8_t *msg,
+		       const uint8_t *signature)
+{
+  mp_size_t itch = _eddsa_verify_itch (&nettle_curve25519);
+  mp_limb_t *scratch = gmp_alloc_limbs (itch);
+  struct sha512_ctx ctx;
+  int res;
+
+  res = _eddsa_verify (&nettle_curve25519, &nettle_sha512,
+		       pub->pub, pub->A, &ctx,
+		       length, msg, signature,
+		       scratch);
+  gmp_free_limbs (scratch, itch);
+  return res;
+}
diff --git a/eddsa.h b/eddsa.h
index 50214862f7ca55aa940430ad7c9bbff39c5960cf..dffe5ececc21ca81c8f0f875341c9edc96d92953 100644
--- a/eddsa.h
+++ b/eddsa.h
@@ -41,6 +41,11 @@ extern "C" {
 #endif
 
 /* Name mangling */
+#define ed25519_sha512_set_private_key nettle_ed25519_sha512_set_private_key
+#define ed25519_sha512_sign nettle_ed25519_sha512_sign
+#define ed25519_sha512_set_public_key nettle_ed25519_sha512_set_public_key
+#define ed25519_sha512_verify nettle_ed25519_sha512_verify
+
 #define _eddsa_compress _nettle_eddsa_compress
 #define _eddsa_compress_itch _nettle_eddsa_compress_itch
 #define _eddsa_decompress _nettle_eddsa_decompress
@@ -54,6 +59,44 @@ extern "C" {
 #define _eddsa_verify_itch _nettle_eddsa_verify_itch
 
 #define ED25519_KEY_SIZE 32
+#define ED25519_SIGNATURE_SIZE 64
+
+/* Number of limbs needed to represent a point coordinate, or a secret
+   exponent (note that exponents are 254 bits, larger than q). */
+#define _ED25519_LIMB_SIZE ((255 + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS)
+
+struct ed25519_private_key
+{
+  uint8_t pub[ED25519_KEY_SIZE];
+  uint8_t k1[ED25519_KEY_SIZE];
+  mp_limb_t k2[_ED25519_LIMB_SIZE];
+};
+
+void
+ed25519_sha512_set_private_key (struct ed25519_private_key *priv,
+				const uint8_t *key);
+
+void
+ed25519_sha512_sign (const struct ed25519_private_key *priv,
+		     size_t length, const uint8_t *msg,
+		     uint8_t *signature);
+
+struct ed25519_public_key
+{
+  uint8_t pub[ED25519_KEY_SIZE];
+  mp_limb_t A[2*_ED25519_LIMB_SIZE];
+};
+
+int
+ed25519_sha512_set_public_key (struct ed25519_public_key *pub,
+			       const uint8_t *key);
+
+int
+ed25519_sha512_verify (const struct ed25519_public_key *pub,
+		       size_t length, const uint8_t *msg,
+		       const uint8_t *signature);
+
+/* Low-level internal functions */
 
 struct ecc_curve;
 struct ecc_modulo;