Joachim Strömbergson <[email protected]> writes:

> Here is the patch to add build chacha in Nettle.

Nice. I've tried this, together with your code at
https://github.com/secworks/nettle/tree/master/chacha (is that your
latest code? It was slightly inconsistent, with some function still
expecting nrounds in the context struct).

I edited it a bit, to take out support for rounds != 20 for now (except
for the _chacha_core_internal function), and I split the set key
function into two functions for the two available key sizes, 128 and 256
bits.

Resulting patch below. I think I'll check this in soon. Next steps would
be:

1. Add it to the benchmark (probably easiest to do it the same way as
   salsa20, with a struct in nettle-internal.c).

2. Adapt the test program to nettle conventions. Possibly convert the
   round != 20 test cases to tests of the chacha_core function?

3. Write some assembly.

Regards,
/Niels

diff --git a/Makefile.in b/Makefile.in
index 10715b2..092c217 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,8 +80,10 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
                 camellia-crypt.c camellia-crypt-internal.c \
                 camellia-set-encrypt-key.c camellia-set-decrypt-key.c \
                 camellia-table.c camellia-meta.c \
-                cast128.c cast128-meta.c \
-                cbc.c ctr.c \
+                cast128.c cast128-meta.c cbc.c \
+                chacha-crypt.c chacha-core-internal.c chacha-set-iv.c \
+                chacha128-set-key.c chacha256-set-key.c \
+                ctr.c \
                 des.c des3.c des-compat.c eax.c \
                 gcm.c gcm-aes.c gosthash94.c \
                 hmac.c hmac-md5.c hmac-ripemd160.c hmac-sha1.c \
@@ -149,7 +151,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
index e69de29..fb695ff 100644
--- a/chacha-core-internal.c
+++ 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
index e69de29..1aed643 100644
--- a/chacha-crypt.c
+++ b/chacha-crypt.c
@@ -0,0 +1,77 @@
+/* salsa20-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) 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
index e69de29..50d9835 100644
--- a/chacha-set-iv.c
+++ b/chacha-set-iv.c
@@ -0,0 +1,52 @@
+/* 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.h b/chacha.h
index e69de29..e965234 100644
--- a/chacha.h
+++ b/chacha.h
@@ -0,0 +1,91 @@
+/* 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) 2001 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 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
+
+/* Minimum and maximum keysizes, and a reasonable default. 
+   In octets. */
+#define CHACHA128_KEY_SIZE 16
+#define CHACHA256_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 *ct, const uint8_t *key);
+
+void
+chacha256_set_key(struct chacha_ctx *ct, 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
index e69de29..569e801 100644
--- a/chacha128-set-key.c
+++ 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
index e69de29..66e314b 100644
--- a/chacha256-set-key.c
+++ 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 5549fc0..3d6137f 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 0ad950d..8838bef 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
index e69de29..f1ed0ea 100644
--- a/testsuite/chacha-test.c
+++ b/testsuite/chacha-test.c
@@ -0,0 +1,251 @@
+/* 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 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
+print_block(uint8_t block[64])
+{
+  uint8_t i;
+
+  for (i = 0 ; i < 64 ; i++) {
+    printf("0x%02x ", block[i]);
+    if (((i + 1) % 8) == 0) {
+      printf("\n");
+    }
+  }
+  printf("\n");
+}
+
+
+static void
+test_chacha(const uint8_t *key, const uint8_t *iv, uint8_t *expected, 
+           uint8_t keylength)
+{
+    uint8_t cipher_data[64] =  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00};
+
+    uint8_t cipher_result[64] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
+                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
+                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
+                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
+                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
+                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
+                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
+                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00};
+    
+    struct chacha_ctx cipher_ctx;
+
+    unsigned i, errors;
+
+    switch (keylength)
+      {
+      default:
+       abort ();
+      case 16:
+       chacha128_set_key(&cipher_ctx, key);
+       break;
+      case 32:
+       chacha256_set_key(&cipher_ctx, key);
+       break;
+      }
+
+    chacha_set_iv(&cipher_ctx, iv);
+    chacha_crypt(&cipher_ctx, 64, &cipher_result[0], &cipher_data[0]);
+
+    if (verbose)
+      {
+        printf("Result after encryption:\n");
+        print_block(cipher_result);
+      }
+
+    errors = 0;
+    for (i = 0 ; i < 64 ; i++)
+      if (cipher_result[i] != expected[i])
+        errors++;
+    
+    if (errors > 0)
+      {
+       printf("Error, expected:\n");
+       print_block(&expected[0]);
+       printf("Got:\n");
+       print_block(cipher_result);
+      }
+    else
+      printf("Success, result matched expected.\n");
+}
+
+
+void
+test_main(void)
+{
+  printf("Test of chacha nettle implementation\n");
+  printf("------------------------------------\n");
+
+  /* Test vectors from draft-strombergson-chacha-test-vectors */
+
+#if 0
+  // TC1: All zero key and IV. 128 bit key and 8 rounds.
+  uint8_t tc1_key[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  uint8_t tc1_keylength = 16;
+
+  uint8_t tc1_iv[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+  uint8_t tc1_rounds = 8;
+
+  uint8_t tc1_expected[64] = {0xe2, 0x8a, 0x5f, 0xa4, 0xa6, 0x7f, 0x8c, 0x5d,
+                              0xef, 0xed, 0x3e, 0x6f, 0xb7, 0x30, 0x34, 0x86,
+                              0xaa, 0x84, 0x27, 0xd3, 0x14, 0x19, 0xa7, 0x29,
+                              0x57, 0x2d, 0x77, 0x79, 0x53, 0x49, 0x11, 0x20,
+                              0xb6, 0x4a, 0xb8, 0xe7, 0x2b, 0x8d, 0xeb, 0x85,
+                              0xcd, 0x6a, 0xea, 0x7c, 0xb6, 0x08, 0x9a, 0x10,
+                              0x18, 0x24, 0xbe, 0xeb, 0x08, 0x81, 0x4a, 0x42,
+                              0x8a, 0xab, 0x1f, 0xa2, 0xc8, 0x16, 0x08, 0x1b};
+
+  test_chacha(&tc1_key[0], &tc1_iv[0], &tc1_expected[0], tc1_keylength, 
tc1_rounds); 
+
+  
+  // TC2: All zero key and IV. 128 bit key and 12 rounds.
+  uint8_t tc2_key[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  uint8_t tc2_keylength = 16;
+
+  uint8_t tc2_iv[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+  uint8_t tc2_rounds = 12;
+
+  uint8_t tc2_expected[64] = {0xe1, 0x04, 0x7b, 0xa9, 0x47, 0x6b, 0xf8, 0xff,
+                              0x31, 0x2c, 0x01, 0xb4, 0x34, 0x5a, 0x7d, 0x8c,
+                              0xa5, 0x79, 0x2b, 0x0a, 0xd4, 0x67, 0x31, 0x3f,
+                              0x1d, 0xc4, 0x12, 0xb5, 0xfd, 0xce, 0x32, 0x41,
+                              0x0d, 0xea, 0x8b, 0x68, 0xbd, 0x77, 0x4c, 0x36,
+                              0xa9, 0x20, 0xf0, 0x92, 0xa0, 0x4d, 0x3f, 0x95,
+                              0x27, 0x4f, 0xbe, 0xff, 0x97, 0xbc, 0x84, 0x91,
+                              0xfc, 0xef, 0x37, 0xf8, 0x59, 0x70, 0xb4, 0x50};
+
+  test_chacha(&tc2_key[0], &tc2_iv[0], &tc2_expected[0], tc2_keylength, 
tc2_rounds); 
+
+#endif
+  // TC3: All zero key and IV. 128 bit key and 20 rounds.
+  uint8_t tc3_key[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  uint8_t tc3_keylength = 16;
+
+  uint8_t tc3_iv[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+  uint8_t tc3_expected[64] = {0x89, 0x67, 0x09, 0x52, 0x60, 0x83, 0x64, 0xfd,
+                              0x00, 0xb2, 0xf9, 0x09, 0x36, 0xf0, 0x31, 0xc8,
+                              0xe7, 0x56, 0xe1, 0x5d, 0xba, 0x04, 0xb8, 0x49,
+                              0x3d, 0x00, 0x42, 0x92, 0x59, 0xb2, 0x0f, 0x46,
+                              0xcc, 0x04, 0xf1, 0x11, 0x24, 0x6b, 0x6c, 0x2c,
+                              0xe0, 0x66, 0xbe, 0x3b, 0xfb, 0x32, 0xd9, 0xaa,
+                              0x0f, 0xdd, 0xfb, 0xc1, 0x21, 0x23, 0xd4, 0xb9,
+                              0xe4, 0x4f, 0x34, 0xdc, 0xa0, 0x5a, 0x10, 0x3f};
+
+  test_chacha(&tc3_key[0], &tc3_iv[0], &tc3_expected[0], tc3_keylength); 
+
+#if 0
+  // TC4: Sequence patterns in key and IV. 256 bit key and 8 rounds.
+  uint8_t tc4_key[32] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+                         0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
+                         0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00};
+  uint8_t tc4_keylength = 32;
+
+  uint8_t tc4_iv[8] = {0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x59, 0x68, 0x77};
+
+  uint8_t tc4_rounds = 8;
+
+  uint8_t tc4_expected[64] = {0x60, 0xfd, 0xed, 0xbd, 0x1a, 0x28, 0x0c, 0xb7,
+                              0x41, 0xd0, 0x59, 0x3b, 0x6e, 0xa0, 0x30, 0x90,
+                              0x10, 0xac, 0xf1, 0x8e, 0x14, 0x71, 0xf6, 0x89,
+                              0x68, 0xf4, 0xc9, 0xe3, 0x11, 0xdc, 0xa1, 0x49,
+                              0xb8, 0xe0, 0x27, 0xb4, 0x7c, 0x81, 0xe0, 0x35,
+                              0x3d, 0xb0, 0x13, 0x89, 0x1a, 0xa5, 0xf6, 0x8e,
+                              0xa3, 0xb1, 0x3d, 0xd2, 0xf3, 0xb8, 0xdd, 0x08,
+                              0x73, 0xbf, 0x37, 0x46, 0xe7, 0xd6, 0xc5, 0x67};
+
+  test_chacha(&tc4_key[0], &tc4_iv[0], &tc4_expected[0], tc4_keylength, 
tc4_rounds); 
+
+  
+  // TC5: Sequence patterns in key and IV. 256 bit key and 12 rounds.
+  uint8_t tc5_key[32] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+                         0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
+                         0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00};
+  uint8_t tc5_keylength = 32;
+
+  uint8_t tc5_iv[8] = {0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x59, 0x68, 0x77};
+
+  uint8_t tc5_rounds = 12;
+
+  uint8_t tc5_expected[64] = {0x6e, 0x93, 0xf2, 0x58, 0x16, 0xed, 0x81, 0x51,
+                              0xdb, 0xab, 0x6c, 0x9a, 0x50, 0x0d, 0x56, 0x2e,
+                              0xf3, 0xac, 0x3c, 0xfd, 0x18, 0x99, 0x70, 0x8c,
+                              0x15, 0x74, 0xb9, 0x12, 0xf7, 0x1b, 0x13, 0x12,
+                              0x11, 0x49, 0x85, 0x21, 0x70, 0xbd, 0x0f, 0x45,
+                              0x43, 0xf0, 0xb7, 0x3f, 0x9f, 0x27, 0xc3, 0x63,
+                              0x77, 0x36, 0x32, 0xe9, 0xe2, 0xaa, 0x63, 0x24,
+                              0xf6, 0xbe, 0xd8, 0x7a, 0xb0, 0xd0, 0x30, 0x5e};
+  
+  test_chacha(&tc5_key[0], &tc5_iv[0], &tc5_expected[0], tc5_keylength, 
tc5_rounds); 
+
+#endif
+  // TC6: Sequence patterns in key and IV. 256 bit key and 20 rounds.
+  uint8_t tc6_key[32] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+                         0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
+                         0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00};
+  uint8_t tc6_keylength = 32;
+
+  uint8_t tc6_iv[8] = {0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x59, 0x68, 0x77};
+
+  uint8_t tc6_expected[64] = {0x87, 0xfa, 0x92, 0x06, 0x10, 0x43, 0xca, 0x5e,
+                              0x63, 0x1f, 0xed, 0xd8, 0x8e, 0x8b, 0xfb, 0x84,
+                              0xad, 0x6b, 0x21, 0x3b, 0xde, 0xe4, 0xbc, 0x80,
+                              0x6e, 0x27, 0x64, 0x93, 0x5f, 0xb8, 0x90, 0x97,
+                              0x21, 0x8a, 0x89, 0x7b, 0x7a, 0xea, 0xd1, 0x0e,
+                              0x1b, 0x17, 0xf6, 0x80, 0x2b, 0x2a, 0xbd, 0xd9,
+                              0x55, 0x94, 0x90, 0x30, 0x83, 0x73, 0x56, 0x13,
+                              0xd6, 0xb3, 0x53, 0x1b, 0x9e, 0x0d, 0x1b, 0x67};
+
+  test_chacha(&tc6_key[0], &tc6_iv[0], &tc6_expected[0], tc6_keylength); 
+}

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.
_______________________________________________
nettle-bugs mailing list
[email protected]
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to