diff --git a/ChangeLog b/ChangeLog
index ee6afd1c0b66d20091ce82fabf41f99abd4b6e39..cee70a0a3772ae9078699012b0459f12dc2fc0e6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2014-01-27  Niels Möller  <nisse@lysator.liu.se>
+
+	Chacha implementation, based on contribution by Joachim
+	Strömbergson.
+	* chacha.h: New file.
+	* chacha256-set-key.c (chacha256_set_key): New file and function.
+	* chacha128-set-key.c (chacha128_set_key): New file and function.
+	* chacha-set-key.c (chacha_set_key): New file and function.
+	* chacha-set-iv.c (chacha_set_iv): New file and function.
+	* chacha-core-internal.c (_chacha_core): New file and function.
+	* chacha-crypt.c (chacha_crypt): New file and function.
+	* Makefile.in (nettle_SOURCES): Added chacha files.
+	(HEADERS): Added chacha.h.
+	* testsuite/chacha-test.c: New file.
+	* testsuite/Makefile.in (TS_NETTLE_SOURCES): Added chacha-test.c.
+
 2014-01-26  Niels Möller  <nisse@lysator.liu.se>
 
 	* nettle-internal.h (_NETTLE_AEAD_FIX): Renamed to...
diff --git a/Makefile.in b/Makefile.in
index 7292ea26b783058c60cebfbedf2c29c6d15b6917..1d339acea0f5189a7387d79aef8edc0ad2adcbe6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -86,8 +86,11 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
 		 camellia256-set-decrypt-key.c \
 		 camellia256-meta.c \
 		 cast128.c cast128-meta.c \
-		 blowfish.c \
-		 cbc.c ctr.c gcm.c \
+		 blowfish.c cbc.c \
+		 chacha-crypt.c chacha-core-internal.c \
+		 chacha-set-iv.c chacha-set-key.c \
+		 chacha128-set-key.c chacha256-set-key.c \
+		 ctr.c gcm.c \
 		 gcm-aes.c gcm-aes128.c gcm-aes192.c gcm-aes256.c \
 		 des.c des3.c des-compat.c eax.c \
 		 hmac.c hmac-md5.c hmac-ripemd160.c hmac-sha1.c \
@@ -159,7 +162,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
 
 HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \
 	  base16.h base64.h buffer.h camellia.h cast128.h \
-	  cbc.h ctr.h \
+	  cbc.h chacha.h ctr.h \
 	  des.h des-compat.h dsa.h eax.h ecc-curve.h ecc.h ecdsa.h \
 	  gcm.h gosthash94.h hmac.h \
 	  knuth-lfib.h \
diff --git a/chacha-core-internal.c b/chacha-core-internal.c
new file mode 100644
index 0000000000000000000000000000000000000000..fb695ff566254547cb3ffc3fc91aa85ef38fd78e
--- /dev/null
+++ b/chacha-core-internal.c
@@ -0,0 +1,120 @@
+/* chacha-core-internal.c
+ *
+ * Core functionality of the ChaCha stream cipher.
+ * Heavily based on the Salsa20 implementation in Nettle.
+ *
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Joachim Strömbergson
+ * Copyright (C) 2012 Simon Josefsson, Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+/* Based on:
+   chacha-ref.c version 2008.01.20.
+   D. J. Bernstein
+   Public domain.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "chacha.h"
+
+#include "macros.h"
+
+#ifndef CHACHA_DEBUG
+# define CHACHA_DEBUG 0
+#endif
+
+#if CHACHA_DEBUG
+# include <stdio.h>
+# define DEBUG(i) do {				\
+    unsigned debug_j;				\
+    for (debug_j = 0; debug_j < 16; debug_j++)	\
+      {						\
+	if (debug_j == 0)			\
+	  fprintf(stderr, "%2d:", (i));		\
+	else if (debug_j % 4 == 0)		\
+	  fprintf(stderr, "\n   ");		\
+	fprintf(stderr, " %8x", x[debug_j]);	\
+      }						\
+    fprintf(stderr, "\n");			\
+  } while (0)
+#else
+# define DEBUG(i)
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define LE_SWAP32(v)				\
+  ((ROTL32(8,  v) & 0x00FF00FFUL) |		\
+   (ROTL32(24, v) & 0xFF00FF00UL))
+#else
+#define LE_SWAP32(v) (v)
+#endif
+
+#define QROUND(x0, x1, x2, x3) do { \
+  x0 = x0 + x1; x3 = ROTL32(16, (x0 ^ x3)); \
+  x2 = x2 + x3; x1 = ROTL32(12, (x1 ^ x2)); \
+  x0 = x0 + x1; x3 = ROTL32(8,  (x0 ^ x3)); \
+  x2 = x2 + x3; x1 = ROTL32(7,  (x1 ^ x2)); \
+  } while(0)
+
+void
+_chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds)
+{
+  uint32_t x[_CHACHA_STATE_LENGTH];
+  unsigned i;
+
+  assert ( (rounds & 1) == 0);
+
+  memcpy (x, src, sizeof(x));
+  for (i = 0; i < rounds;i += 2)
+    {
+      DEBUG (i);
+      QROUND(x[0], x[4], x[8],  x[12]);
+      QROUND(x[1], x[5], x[9],  x[13]);
+      QROUND(x[2], x[6], x[10], x[14]);
+      QROUND(x[3], x[7], x[11], x[15]);
+
+      DEBUG (i+1);
+      QROUND(x[0], x[5], x[10], x[15]);
+      QROUND(x[1], x[6], x[11], x[12]);
+      QROUND(x[2], x[7], x[8],  x[13]);
+      QROUND(x[3], x[4], x[9],  x[14]);
+    }
+  DEBUG (i);
+
+  for (i = 0; i < _CHACHA_STATE_LENGTH; i++)
+    {
+      uint32_t t = x[i] + src[i];
+      dst[i] = LE_SWAP32 (t);
+    }
+}
+
+
+
+
+
+
+
diff --git a/chacha-crypt.c b/chacha-crypt.c
new file mode 100644
index 0000000000000000000000000000000000000000..2fb77777b8ce07fb9dadd3314a5f5016cb9a6d55
--- /dev/null
+++ b/chacha-crypt.c
@@ -0,0 +1,78 @@
+/* chacha-crypt.c
+ *
+ * The crypt function in the ChaCha stream cipher.
+ * Heavily based on the Salsa20 implementation in Nettle.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2014 Niels Möller
+ * Copyright (C) 2013 Joachim Strömbergson
+ * Copyright (C) 2012 Simon Josefsson
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+/* Based on:
+   chacha-ref.c version 2008.01.20.
+   D. J. Bernstein
+   Public domain.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "chacha.h"
+
+#include "macros.h"
+#include "memxor.h"
+
+#define CHACHA_ROUNDS 20
+
+void
+chacha_crypt(struct chacha_ctx *ctx,
+	      size_t length,
+	      uint8_t *c,
+	      const uint8_t *m)
+{
+  if (!length)
+    return;
+  
+  for (;;)
+    {
+      uint32_t x[_CHACHA_STATE_LENGTH];
+
+      _chacha_core (x, ctx->state, CHACHA_ROUNDS);
+
+      ctx->state[9] += (++ctx->state[8] == 0);
+
+      /* stopping at 2^70 length per nonce is user's responsibility */
+      
+      if (length <= CHACHA_BLOCK_SIZE)
+	{
+	  memxor3 (c, m, x, length);
+	  return;
+	}
+      memxor3 (c, m, x, CHACHA_BLOCK_SIZE);
+
+      length -= CHACHA_BLOCK_SIZE;
+      c += CHACHA_BLOCK_SIZE;
+      m += CHACHA_BLOCK_SIZE;
+  }
+}
diff --git a/chacha-set-iv.c b/chacha-set-iv.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab872bbea85599ee558b0f48ee7bc3b6734c5fed
--- /dev/null
+++ b/chacha-set-iv.c
@@ -0,0 +1,53 @@
+/* chacha-set-iv.c
+ *
+ * Setting the IV the ChaCha stream cipher.
+ * Based on the Salsa20 implementation in Nettle.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Joachim Strömbergon
+ * Copyright (C) 2012 Simon Josefsson
+ * Copyright (C) 2012, 2014 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+/* Based on:
+   ChaCha specification (doc id: 4027b5256e17b9796842e6d0f68b0b5e) and reference 
+   implementation dated 2008.01.20
+   D. J. Bernstein
+   Public domain.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "chacha.h"
+
+#include "macros.h"
+
+void
+chacha_set_iv(struct chacha_ctx *ctx, const uint8_t *iv)
+{
+  ctx->state[12] = 0;
+  ctx->state[13] = 0;
+  ctx->state[14] = LE_READ_UINT32(iv + 0);
+  ctx->state[15] = LE_READ_UINT32(iv + 4);
+}
diff --git a/chacha-set-key.c b/chacha-set-key.c
new file mode 100644
index 0000000000000000000000000000000000000000..18c6109e344da3931762de5ef100f05583cb76de
--- /dev/null
+++ b/chacha-set-key.c
@@ -0,0 +1,43 @@
+/* chacha-set-key.c
+ *
+ * Copyright (C) 2014 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "chacha.h"
+
+void
+chacha_set_key(struct chacha_ctx *ctx, size_t length, const uint8_t *key)
+{
+  switch (length)
+    {
+    default:
+      abort ();
+    case CHACHA128_KEY_SIZE:
+      chacha128_set_key (ctx, key);
+      break;
+    case CHACHA256_KEY_SIZE:
+      chacha256_set_key (ctx, key);
+      break;
+    }
+}
diff --git a/chacha.h b/chacha.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8ec92b07c0cb11acf94cd3cda7f1d383ef9ee34
--- /dev/null
+++ b/chacha.h
@@ -0,0 +1,97 @@
+/* chacha.h
+ *
+ * The ChaCha stream cipher.
+ * Heavily based on the Salsa20 source code in Nettle.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Joachim Strömbergson
+ * Copyright (C) 2012 Simon Josefsson
+ * Copyright (C) 2014 Niels Möller
+ *
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#ifndef NETTLE_CHACHA_H_INCLUDED
+#define NETTLE_CHACHA_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define chacha_set_key nettle_chacha_set_key
+#define chacha128_set_key nettle_chacha128_set_key
+#define chacha256_set_key nettle_chacha256_set_key
+#define chacha_set_iv nettle_chacha_set_iv
+#define chacha_crypt nettle_chacha_crypt
+#define _chacha_core _nettle_chacha_core
+
+/* Possible keysizes, and a reasonable default. In octets. */
+#define CHACHA128_KEY_SIZE 16
+#define CHACHA256_KEY_SIZE 32
+#define CHACHA_KEY_SIZE 32
+
+#define CHACHA_BLOCK_SIZE 64
+
+#define CHACHA_IV_SIZE 8
+
+#define _CHACHA_STATE_LENGTH 16
+
+struct chacha_ctx
+{
+  /* Indices 0-3 holds a constant (SIGMA or TAU).
+     Indices 4-11 holds the key.
+     Indices 12-13 holds the block counter.
+     Indices 14-15 holds the IV:
+
+     This creates the state matrix:
+     C C C C
+     K K K K
+     K K K K
+     B B I I
+  */
+  uint32_t state[_CHACHA_STATE_LENGTH];
+};
+
+void
+chacha128_set_key(struct chacha_ctx *ctx, const uint8_t *key);
+
+void
+chacha256_set_key(struct chacha_ctx *ctx, const uint8_t *key);
+
+void
+chacha_set_key(struct chacha_ctx *ctx,
+	       size_t length, const uint8_t *key);
+
+void
+chacha_set_iv(struct chacha_ctx *ctx, const uint8_t *iv);
+
+void
+chacha_crypt(struct chacha_ctx *ctx, size_t length, 
+             uint8_t *dst, const uint8_t *src);
+
+void
+_chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_CHACHA_H_INCLUDED */
diff --git a/chacha128-set-key.c b/chacha128-set-key.c
new file mode 100644
index 0000000000000000000000000000000000000000..569e801c17669bdeab24caacfef1fb0d12fd3dc5
--- /dev/null
+++ b/chacha128-set-key.c
@@ -0,0 +1,61 @@
+/* chacha128-set-key.c
+ *
+ * ChaCha key setup for 128-bit keys.
+ * Based on the Salsa20 implementation in Nettle.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Joachim Strömbergon
+ * Copyright (C) 2012 Simon Josefsson
+ * Copyright (C) 2012, 2014 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+/* Based on:
+   ChaCha specification (doc id: 4027b5256e17b9796842e6d0f68b0b5e) and reference 
+   implementation dated 2008.01.20
+   D. J. Bernstein
+   Public domain.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "chacha.h"
+
+#include "macros.h"
+
+void
+chacha128_set_key(struct chacha_ctx *ctx, const uint8_t *key)
+{
+  static const uint32_t tau[4] = {
+    /* "expand 16-byte k" */
+    0x61707865, 0x3120646e, 0x79622d36, 0x6b206574
+  };
+
+  ctx->state[8]  = ctx->state[4] = LE_READ_UINT32(key + 0);
+  ctx->state[9]  = ctx->state[5] = LE_READ_UINT32(key + 4);
+  ctx->state[10] = ctx->state[6] = LE_READ_UINT32(key + 8);
+  ctx->state[11] = ctx->state[7] = LE_READ_UINT32(key + 12);
+
+  memcpy (ctx->state, tau, sizeof(tau));
+}
diff --git a/chacha256-set-key.c b/chacha256-set-key.c
new file mode 100644
index 0000000000000000000000000000000000000000..66e314b04adf3e1eedafc199d6a80a2c2e153e53
--- /dev/null
+++ b/chacha256-set-key.c
@@ -0,0 +1,65 @@
+/* chacha256-set-key.c
+ *
+ * ChaCha key setup for 256-bit keys.
+ * Based on the Salsa20 implementation in Nettle.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Joachim Strömbergon
+ * Copyright (C) 2012 Simon Josefsson
+ * Copyright (C) 2012, 2014 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+/* Based on:
+   ChaCha specification (doc id: 4027b5256e17b9796842e6d0f68b0b5e) and reference 
+   implementation dated 2008.01.20
+   D. J. Bernstein
+   Public domain.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "chacha.h"
+
+#include "macros.h"
+
+void
+chacha256_set_key(struct chacha_ctx *ctx, const uint8_t *key)
+{
+  static const uint32_t sigma[4] = {
+    /* "expand 32-byte k" */
+    0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
+  };
+  ctx->state[4] = LE_READ_UINT32(key + 0);
+  ctx->state[5] = LE_READ_UINT32(key + 4);
+  ctx->state[6] = LE_READ_UINT32(key + 8);
+  ctx->state[7] = LE_READ_UINT32(key + 12);
+
+  ctx->state[8]  = LE_READ_UINT32(key + 16);
+  ctx->state[9]  = LE_READ_UINT32(key + 20);
+  ctx->state[10] = LE_READ_UINT32(key + 24);
+  ctx->state[11] = LE_READ_UINT32(key + 28);
+
+  memcpy (ctx->state, sigma, sizeof(sigma));
+}
diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make
index 2900468b5df15a0c2a7e5bc35a0f30ca9cad7633..ccd8e5a9871e590f0a89daed18615f79ec1c6fb5 100644
--- a/testsuite/.test-rules.make
+++ b/testsuite/.test-rules.make
@@ -22,6 +22,9 @@ base64-test$(EXEEXT): base64-test.$(OBJEXT)
 camellia-test$(EXEEXT): camellia-test.$(OBJEXT)
 	$(LINK) camellia-test.$(OBJEXT) $(TEST_OBJS) -o camellia-test$(EXEEXT)
 
+chacha-test$(EXEEXT): chacha-test.$(OBJEXT)
+	$(LINK) chacha-test.$(OBJEXT) $(TEST_OBJS) -o chacha-test$(EXEEXT)
+
 des-test$(EXEEXT): des-test.$(OBJEXT)
 	$(LINK) des-test.$(OBJEXT) $(TEST_OBJS) -o des-test$(EXEEXT)
 
diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in
index ea85ef95929c0ff9780ef787f3997691f8378f05..8860ba5cd5e72a5abdfc2e1ef804e92a26e5f81b 100644
--- a/testsuite/Makefile.in
+++ b/testsuite/Makefile.in
@@ -13,7 +13,7 @@ PRE_LDFLAGS = -L..
 TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \
 		    blowfish-test.c cast128-test.c \
 	            base16-test.c base64-test.c \
-		    camellia-test.c \
+		    camellia-test.c chacha-test.c \
 		    des-test.c des3-test.c des-compat-test.c \
 		    md2-test.c md4-test.c md5-test.c md5-compat-test.c \
 		    memxor-test.c gosthash94-test.c \
diff --git a/testsuite/chacha-test.c b/testsuite/chacha-test.c
new file mode 100644
index 0000000000000000000000000000000000000000..e8732fa7e63eebedfe1dc8d5380ea5da4670c961
--- /dev/null
+++ b/testsuite/chacha-test.c
@@ -0,0 +1,344 @@
+/* chacha-test.c
+ *
+ * Test program for the ChaCha stream cipher implementation.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Joachim Strömbergson
+ * Copyright (C) 2012, 2014 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#include "testutils.h"
+
+#include "chacha.h"
+
+static void
+test_chacha(const struct tstring *key, const struct tstring *iv,
+	    const struct tstring *expected, unsigned rounds)
+{
+  /* Uses the _chacha_core function to be able to test different
+     numbers of rounds. */
+  /* FIXME: For rounds == 20, use crypt function, support more than
+     one block, and test various short lengths. */
+  uint32_t out[_CHACHA_STATE_LENGTH];
+  
+  struct chacha_ctx ctx;
+
+  ASSERT (expected->length == CHACHA_BLOCK_SIZE);
+
+  chacha_set_key (&ctx, key->length, key->data);
+  ASSERT (iv->length == CHACHA_IV_SIZE);
+  chacha_set_iv(&ctx, iv->data);
+
+  _chacha_core (out, ctx.state, rounds);
+
+  if (!MEMEQ(CHACHA_BLOCK_SIZE, out, expected->data))
+    {
+      printf("Error, expected:\n");
+      tstring_print_hex (expected);
+      printf("Got:\n");
+      print_hex(CHACHA_BLOCK_SIZE, (uint8_t *) out);
+      FAIL ();
+    }
+
+  if (verbose)
+    {
+      printf("Result after encryption:\n");
+      print_hex(CHACHA_BLOCK_SIZE, (uint8_t *) out);
+    }
+}
+
+void
+test_main(void)
+{
+  /* Test vectors from draft-strombergson-chacha-test-vectors */
+
+  /* TC1: All zero key and IV. 128 bit key and 8 rounds. */
+  test_chacha (SHEX("0000000000000000 0000000000000000"),
+	       SHEX("0000000000000000"),
+	       SHEX("e28a5fa4a67f8c5d efed3e6fb7303486"
+		    "aa8427d31419a729 572d777953491120"
+		    "b64ab8e72b8deb85 cd6aea7cb6089a10"
+		    "1824beeb08814a42 8aab1fa2c816081b"),
+	       8);
+  test_chacha (SHEX("0000000000000000 0000000000000000"),
+	       SHEX("0000000000000000"),
+	       SHEX("e1047ba9476bf8ff 312c01b4345a7d8c"
+		    "a5792b0ad467313f 1dc412b5fdce3241"
+		    "0dea8b68bd774c36 a920f092a04d3f95"
+		    "274fbeff97bc8491 fcef37f85970b450"),
+	       12);
+
+  test_chacha (SHEX("0000000000000000 0000000000000000"),
+	       SHEX("0000000000000000"),
+	       SHEX("89670952608364fd 00b2f90936f031c8"
+		    "e756e15dba04b849 3d00429259b20f46"
+		    "cc04f111246b6c2c e066be3bfb32d9aa"
+		    "0fddfbc12123d4b9 e44f34dca05a103f"),
+	       20);
+
+  test_chacha (SHEX("0000000000000000 0000000000000000"
+		    "0000000000000000 0000000000000000"),
+	       SHEX("0000000000000000"),
+	       SHEX("76b8e0ada0f13d90 405d6ae55386bd28"
+		    "bdd219b8a08ded1a a836efcc8b770dc7"
+		    "da41597c5157488d 7724e03fb8d84a37"
+		    "6a43b8f41518a11c c387b669b2ee6586"),
+	       20);
+
+
+  /* TC2: Single bit in key set. All zero IV */
+  test_chacha (SHEX("0100000000000000 0000000000000000"),
+	       SHEX("0000000000000000"),
+	       SHEX("03a7669888605a07 65e8357475e58673"
+		    "f94fc8161da76c2a 3aa2f3caf9fe5449"
+		    "e0fcf38eb882656a f83d430d410927d5"
+		    "5c972ac4c92ab9da 3713e19f761eaa14"),
+	       8);
+
+  test_chacha (SHEX("0100000000000000 0000000000000000"),
+	       SHEX("0000000000000000"),
+	       SHEX("2a865a3b8999fa83 ae8aacf33fc6be4f"
+		    "32c8aa9762738d26 963270052f4eef8b"
+		    "86af758f7867560a f6d0eeb973b5542b"
+		    "b24c8abceac8b1f3 6d026963d6c8a9b2"),
+	       12);
+
+  test_chacha (SHEX("0100000000000000 0000000000000000"),
+	       SHEX("0000000000000000"),
+	       SHEX("ae56060d04f5b597 897ff2af1388dbce"
+		    "ff5a2a4920335dc1 7a3cb1b1b10fbe70"
+		    "ece8f4864d8c7cdf 0076453a8291c7db"
+		    "eb3aa9c9d10e8ca3 6be4449376ed7c42"),
+	       20);
+
+  test_chacha (SHEX("0100000000000000 0000000000000000"
+		    "0000000000000000 0000000000000000"),
+	       SHEX("0000000000000000"),
+	       SHEX("c5d30a7ce1ec1193 78c84f487d775a85"
+		    "42f13ece238a9455 e8229e888de85bbd"
+		    "29eb63d0a17a5b99 9b52da22be4023eb"
+		    "07620a54f6fa6ad8 737b71eb0464dac0"),
+	       20);
+
+  /* TC3: Single bit in IV set. All zero key */
+  test_chacha (SHEX("0000000000000000 0000000000000000"),
+	       SHEX("0100000000000000"),
+	       SHEX("25f5bec6683916ff 44bccd12d102e692"
+		    "176663f4cac53e71 9509ca74b6b2eec8"
+		    "5da4236fb2990201 2adc8f0d86c8187d"
+		    "25cd1c486966930d 0204c4ee88a6ab35"),
+	       8);
+
+  test_chacha (SHEX("0000000000000000 0000000000000000"),
+	       SHEX("0100000000000000"),
+	       SHEX("91cdb2f180bc89cf e86b8b6871cd6b3a"
+		    "f61abf6eba01635d b619c40a0b2e19ed"
+		    "fa8ce5a9bd7f53cc 2c9bcfea181e9754"
+		    "a9e245731f658cc2 82c2ae1cab1ae02c"),
+	       12);
+
+  test_chacha (SHEX("0000000000000000 0000000000000000"),
+	       SHEX("0100000000000000"),
+	       SHEX("1663879eb3f2c994 9e2388caa343d361"
+		    "bb132771245ae6d0 27ca9cb010dc1fa7"
+		    "178dc41f8278bc1f 64b3f12769a24097"
+		    "f40d63a86366bdb3 6ac08abe60c07fe8"),
+	       20);
+
+  test_chacha (SHEX("0000000000000000 0000000000000000"
+		    "0000000000000000 0000000000000000"),
+	       SHEX("0100000000000000"),
+	       SHEX("ef3fdfd6c61578fb f5cf35bd3dd33b80"
+		    "09631634d21e42ac 33960bd138e50d32"
+		    "111e4caf237ee53c a8ad6426194a8854"
+		    "5ddc497a0b466e7d 6bbdb0041b2f586b"),
+	       20);
+
+  /* TC4: All bits in key and IV are set. */
+  test_chacha (SHEX("ffffffffffffffff ffffffffffffffff"),
+	       SHEX("ffffffffffffffff"),
+	       SHEX("2204d5b81ce66219 3e00966034f91302"
+		    "f14a3fb047f58b6e 6ef0d72113230416"
+		    "3e0fb640d76ff9c3 b9cd99996e6e38fa"
+		    "d13f0e31c82244d3 3abbc1b11e8bf12d"),
+	       8);
+	       
+  test_chacha (SHEX("ffffffffffffffff ffffffffffffffff"),
+	       SHEX("ffffffffffffffff"),
+	       SHEX("60e349e60c38b328 c4baab90d44a7c72"
+		    "7662770d36350d65 a1433bd92b00ecf4"
+		    "83d5597d7a616258 ec3c5d5b30e1c5c8"
+		    "5c5dfe2f92423b8e 36870f3185b6add9"),
+	       12);
+  
+  test_chacha (SHEX("ffffffffffffffff ffffffffffffffff"),
+	       SHEX("ffffffffffffffff"),
+	       SHEX("992947c3966126a0 e660a3e95db048de"
+		    "091fb9e0185b1e41 e41015bb7ee50150"
+		    "399e4760b262f9d5 3f26d8dd19e56f5c"
+		    "506ae0c3619fa67f b0c408106d0203ee"),
+	       20);
+  
+  test_chacha (SHEX("ffffffffffffffff ffffffffffffffff"
+		    "ffffffffffffffff ffffffffffffffff"),
+	       SHEX("ffffffffffffffff"),
+	       SHEX("d9bf3f6bce6ed0b5 4254557767fb5744"
+		    "3dd4778911b60605 5c39cc25e674b836"
+		    "3feabc57fde54f79 0c52c8ae43240b79"
+		    "d49042b777bfd6cb 80e931270b7f50eb"),
+	       20);
+
+  /* TC5: Every even bit set in key and IV. */
+  test_chacha (SHEX("5555555555555555 5555555555555555"),
+	       SHEX("5555555555555555"),
+	       SHEX("f0a23bc36270e18e d0691dc384374b9b"
+		    "2c5cb60110a03f56 fa48a9fbbad961aa"
+		    "6bab4d892e96261b 6f1a0919514ae56f"
+		    "86e066e17c71a417 6ac684af1c931996"),
+	       8);
+
+  test_chacha (SHEX("5555555555555555 5555555555555555"),
+	       SHEX("5555555555555555"),
+	       SHEX("90ec7a49ee0b20a8 08af3d463c1fac6c"
+		    "2a7c897ce8f6e60d 793b62ddbebcf980"
+		    "ac917f091e52952d b063b1d2b947de04"
+		    "aac087190ca99a35 b5ea501eb535d570"),
+	       12);
+
+  test_chacha (SHEX("5555555555555555 5555555555555555"),
+	       SHEX("5555555555555555"),
+	       SHEX("357d7d94f966778f 5815a2051dcb0413"
+		    "3b26b0ead9f57dd0 9927837bc3067e4b"
+		    "6bf299ad81f7f50c 8da83c7810bfc17b"
+		    "b6f4813ab6c32695 7045fd3fd5e19915"
+		    ),
+	       20);
+
+  test_chacha (SHEX("5555555555555555 5555555555555555"
+		    "5555555555555555 5555555555555555"),
+	       SHEX("5555555555555555"),
+	       SHEX("bea9411aa453c543 4a5ae8c92862f564"
+		    "396855a9ea6e22d6 d3b50ae1b3663311"
+		    "a4a3606c671d605c e16c3aece8e61ea1"
+		    "45c59775017bee2f a6f88afc758069f7"),
+	       20);
+
+  /* TC6: Every odd bit set in key and IV. */
+  test_chacha (SHEX("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+	       SHEX("aaaaaaaaaaaaaaaa"),
+	       SHEX("312d95c0bc38eff4 942db2d50bdc500a"
+		    "30641ef7132db1a8 ae838b3bea3a7ab0"
+		    "3815d7a4cc09dbf5 882a3433d743aced"
+		    "48136ebab7329950 6855c0f5437a36c6"),
+	       8);
+	       
+  test_chacha (SHEX("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+	       SHEX("aaaaaaaaaaaaaaaa"),
+	       SHEX("057fe84fead13c24 b76bb2a6fdde66f2"
+		    "688e8eb6268275c2 2c6bcb90b85616d7"
+		    "fe4d3193a1036b70 d7fb864f01453641"
+		    "851029ecdb60ac38 79f56496f16213f4"),
+	       12);
+	       
+  test_chacha (SHEX("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+	       SHEX("aaaaaaaaaaaaaaaa"),
+	       SHEX("fc79acbd58526103 862776aab20f3b7d"
+		    "8d3149b2fab65766 299316b6e5b16684"
+		    "de5de548c1b7d083 efd9e3052319e0c6"
+		    "254141da04a6586d f800f64d46b01c87"),
+	       20);
+	       
+  test_chacha (SHEX("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"
+		    "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"),
+	       SHEX("aaaaaaaaaaaaaaaa"),
+	       SHEX("9aa2a9f656efde5a a7591c5fed4b35ae"
+		    "a2895dec7cb4543b 9e9f21f5e7bcbcf3"
+		    "c43c748a970888f8 248393a09d43e0b7"
+		    "e164bc4d0b0fb240 a2d72115c4808906"),
+	       20);
+	       
+  /* TC7: Sequence patterns in key and IV. */
+  test_chacha (SHEX("0011223344556677 8899aabbccddeeff"),
+	       SHEX("0f1e2d3c4b5a6978"),
+	       SHEX("29560d280b452840 0a8f4b795369fb3a"
+		    "01105599e9f1ed58 279cfc9ece2dc5f9"
+		    "9f1c2e52c98238f5 42a5c0a881d850b6"
+		    "15d3acd9fbdb026e 9368565da50e0d49"),
+	       8);
+
+  test_chacha (SHEX("0011223344556677 8899aabbccddeeff"),
+	       SHEX("0f1e2d3c4b5a6978"),
+	       SHEX("5eddc2d9428fceee c50a52a964eae0ff"
+		    "b04b2de006a9b04c ff368ffa921116b2"
+		    "e8e264babd2efa0d e43ef2e3b6d065e8"
+		    "f7c0a17837b0a40e b0e2c7a3742c8753"),
+	       12);
+
+  test_chacha (SHEX("0011223344556677 8899aabbccddeeff"),
+	       SHEX("0f1e2d3c4b5a6978"),
+	       SHEX("d1abf630467eb4f6 7f1cfb47cd626aae"
+		    "8afedbbe4ff8fc5f e9cfae307e74ed45"
+		    "1f1404425ad2b545 69d5f18148939971"
+		    "abb8fafc88ce4ac7 fe1c3d1f7a1eb7ca"),
+	       20);
+
+  test_chacha (SHEX("0011223344556677 8899aabbccddeeff"
+		    "ffeeddccbbaa9988 7766554433221100"),
+	       SHEX("0f1e2d3c4b5a6978"),
+	       SHEX("db43ad9d1e842d12 72e4530e276b3f56"
+		    "8f8859b3f7cf6d9d 2c74fa53808cb515"
+		    "7a8ebf46ad3dcc4b 6c7dadde131784b0"
+		    "120e0e22f6d5f9ff a7407d4a21b695d9"),
+	       8);
+
+  /* TC8: hashed string patterns */
+  test_chacha(SHEX("c46ec1b18ce8a878 725a37e780dfb735"),
+	      SHEX("1ada31d5cf688221"),
+	      SHEX("6a870108859f6791 18f3e205e2a56a68"
+		   "26ef5a60a4102ac8 d4770059fcb7c7ba"
+		   "e02f5ce004a6bfbb ea53014dd82107c0"
+		   "aa1c7ce11b7d78f2 d50bd3602bbd2594"),
+	      8);
+
+  test_chacha(SHEX("c46ec1b18ce8a878 725a37e780dfb735"),
+	      SHEX("1ada31d5cf688221"),
+	      SHEX("b02bd81eb55c8f68 b5e9ca4e307079bc"
+		   "225bd22007eddc67 02801820709ce098"
+		   "07046a0d2aa552bf dbb49466176d56e3"
+		   "2d519e10f5ad5f27 46e241e09bdf9959"),
+	      12);
+
+  test_chacha(SHEX("c46ec1b18ce8a878 725a37e780dfb735"),
+	      SHEX("1ada31d5cf688221"),
+	      SHEX("826abdd84460e2e9 349f0ef4af5b179b"
+		   "426e4b2d109a9c5b b44000ae51bea90a"
+		   "496beeef62a76850 ff3f0402c4ddc99f"
+		   "6db07f151c1c0dfa c2e56565d6289625"),
+	      20);
+
+  test_chacha(SHEX("c46ec1b18ce8a878 725a37e780dfb735"
+		   "1f68ed2e194c79fb c6aebee1a667975d"),
+	      SHEX("1ada31d5cf688221"),
+	      SHEX("f63a89b75c2271f9 368816542ba52f06"
+		   "ed49241792302b00 b5e8f80ae9a473af"
+		   "c25b218f519af0fd d406362e8d69de7f"
+		   "54c604a6e00f353f 110f771bdca8ab92"),
+	      20);
+}