Added SAFER block cipher.
authormdw <mdw>
Sun, 29 Apr 2001 17:40:25 +0000 (17:40 +0000)
committermdw <mdw>
Sun, 29 Apr 2001 17:40:25 +0000 (17:40 +0000)
.cvsignore
Makefile.m4
safer.c [new file with mode: 0644]
safer.h [new file with mode: 0644]
safersk.c [new file with mode: 0644]
safersk.h [new file with mode: 0644]
tests/safer [new file with mode: 0644]
tests/safersk [new file with mode: 0644]

index f1f30ef..b9e1dcf 100644 (file)
@@ -138,6 +138,27 @@ rmd320-hmac.c
 rmd320-hmac.h
 rmd320-mgf.c
 rmd320-mgf.h
+safer-cbc.c
+safer-cbc.h
+safer-cfb.c
+safer-cfb.h
+safer-counter.c
+safer-counter.h
+safer-ecb.c
+safer-ecb.h
+safer-mktab.c
+safer-ofb.c
+safer-ofb.h
+safersk-cbc.c
+safersk-cbc.h
+safersk-cfb.c
+safersk-cfb.h
+safersk-counter.c
+safersk-counter.h
+safersk-ecb.c
+safersk-ecb.h
+safersk-ofb.c
+safersk-ofb.h
 serpent-cbc.c
 serpent-cbc.h
 serpent-cfb.c
index d1d55cd..e7110a1 100644 (file)
@@ -1,6 +1,6 @@
 ## -*-makefile-*-
 ##
-## $Id: Makefile.m4,v 1.51 2001/04/19 18:26:32 mdw Exp $
+## $Id: Makefile.m4,v 1.52 2001/04/29 17:37:35 mdw Exp $
 ##
 ## Makefile for Catacomb
 ##
@@ -29,6 +29,9 @@
 ##----- Revision history ----------------------------------------------------
 ##
 ## $Log: Makefile.m4,v $
+## Revision 1.52  2001/04/29 17:37:35  mdw
+## Added SAFER block cipher.
+##
 ## Revision 1.51  2001/04/19 18:26:32  mdw
 ## Add CRC as another hash function.
 ##
@@ -215,7 +218,7 @@ addsuffix(join(`$1', `-', `$2'), `$3')')
 
 define(`ciphers', `dnl
 _(des) _(desx) _(des3) dnl
-_(idea) dnl
+_(idea) _(safer) _(safersk) dnl
 _(blowfish) _(twofish) dnl
 _(tea) _(xtea) dnl
 _(rc2) _(rc5) dnl
@@ -244,7 +247,7 @@ modes-stamp: genmodes
        echo datestamp >modes-stamp
 
 define(`gen_tables', `dnl
-_(des) _(blowfish) _(twofish) _(square) _(rijndael) _(tiger) dnl
+_(des) _(blowfish) _(twofish) _(square) _(safer) _(rijndael) _(tiger) dnl
 _(gfshare) _(gfx-sqr)')
 
 autoheaders: addsuffix(`gen_tables', `-tab.h') primetab.h mptypes.h
diff --git a/safer.c b/safer.c
new file mode 100644 (file)
index 0000000..1c97eab
--- /dev/null
+++ b/safer.c
@@ -0,0 +1,333 @@
+/* -*-c-*-
+ *
+ * $Id: safer.c,v 1.1 2001/04/29 17:37:35 mdw Exp $
+ *
+ * The SAFER block cipher
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ * 
+ * Catacomb 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 Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: safer.c,v $
+ * Revision 1.1  2001/04/29 17:37:35  mdw
+ * Added SAFER block cipher.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <mLib/bits.h>
+
+#include "blkc.h"
+#include "gcipher.h"
+#include "paranoia.h"
+#include "safer.h"
+#include "safer-tab.h"
+
+/*----- Global variables --------------------------------------------------*/
+
+const octet safer_keysz[] = { KSZ_SET, 8, 16, 0 };
+
+/*----- Important tables --------------------------------------------------*/
+
+static const octet s[265] = SAFER_S, si[256] = SAFER_SI;
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @safer_setup@ --- *
+ *
+ * Arguments:  @safer_ctx *k@ = pointer to context to initialize
+ *             @unsigned r@ = number of rounds wanted
+ *             @unsigned f@ = various other flags
+ *             @const void *buf@ = pointer to key material
+ *             @size_t sz@ = size of key material in bytes
+ *
+ * Returns:    ---
+ *
+ * Use:                Initializes an SAFER expanded key.  A default number of
+ *             rounds is chosen, based on the key length.
+ */
+
+struct ksched {
+  unsigned i;
+  octet x[9];
+};
+
+static void init(struct ksched *t, const octet *k)
+{
+  memcpy(t->x, k, 8);
+  t->i = 1;
+}
+
+static void init_sk(struct ksched *t, const octet *k)
+{
+  unsigned i;
+  octet x;
+  memcpy(t->x, k, 8);
+  for (x = 0, i = 0; i < 8; x ^= k[i++])
+    ;
+  t->x[8] = x;
+  t->i = 1;
+}
+
+static void next(struct ksched *t, octet *k)
+{
+  unsigned i;
+  if (k) {
+    memcpy(k, t->x, 8);
+    if (t->i > 1) {
+      for (i = 0; i < 8; i++)
+       k[i] += s[s[U8(9*t->i + i + 1)]];
+    }
+  }
+  for (i = 0; i < 8; i++)
+    t->x[i] = ROL8(t->x[i], 3);
+  t->i++;
+}
+
+static void next_sk(struct ksched *t, octet *k)
+{
+  unsigned i;
+  i = (t->i - 1)%9;
+  if (k) {
+    if (i < 2)
+      memcpy(k, t->x + i, 8);
+    else {
+      memcpy(k, t->x + i, 9 - i);
+      memcpy(k + 9 - i, t->x, i - 1);
+    }
+    if (t->i > 1) {
+      for (i = 0; i < 8; i++)
+       k[i] += s[s[U8(9*t->i + i + 1)]];
+    }
+  }
+  for (i = 0; i < 9; i++)
+    t->x[i] = ROL8(t->x[i], 3);
+  t->i++;
+}
+
+void safer_setup(safer_ctx *k, unsigned r, unsigned f,
+                const void *buf, size_t sz)
+{
+  struct ksched ka, kb;
+  void (*in)(struct ksched *, const octet *);
+  void (*nx)(struct ksched *, octet *);
+  octet *kk;
+
+  assert(r <= SAFER_MAXROUNDS);
+  KSZ_ASSERT(safer, sz);
+
+  if (f & SAFER_SK) {
+    in = init_sk;
+    nx = next_sk;
+  } else {
+    in = init;
+    nx = next;
+  }
+
+  in(&kb, buf);
+  in(&ka, sz == 8 ? buf : (const octet *)buf + 8);
+
+  k->r = r;
+  kk = k->k;
+  while (r) {
+    nx(&ka, kk); nx(&kb, 0); kk += 8;
+    nx(&kb, kk); nx(&ka, 0); kk += 8;
+    r--;
+  }
+  nx(&ka, kk); kk += 8;
+}
+
+/* --- @safer_init@, @safersk_init@ --- *
+ *
+ * Arguments:  @safer_ctx *k@ = pointer to context to initialize
+ *             @const void *buf@ = pointer to key material
+ *             @size_t sz@ = size of key material in bytes
+ *
+ * Returns:    ---
+ *
+ * Use:                Initializes an SAFER expanded key.  A default number of
+ *             rounds is chosen, based on the key length.
+ */
+
+void safer_init(safer_ctx *k, const void *buf, size_t sz)
+{
+  safer_setup(k, sz == 8 ? 6 : 10, 0, buf, sz);
+}
+
+void safersk_init(safer_ctx *k, const void *buf, size_t sz)
+{
+  safer_setup(k, sz == 8 ? 8 : 10, SAFER_SK, buf, sz);
+}
+
+/* --- @safer_eblk@, @safer_dblk@ --- *
+ *
+ * Arguments:  @const safer_ctx *k@ = pointer to SAFER context
+ *             @const uint32 s[2]@ = pointer to source block
+ *             @const uint32 d[2]@ = pointer to destination block
+ *
+ * Returns:    ---
+ *
+ * Use:                Low-level block encryption and decryption.
+ */
+
+#define UNPACK(src, a, b, c, d, e, f, g, h) do {                       \
+  a = U8(src[0] >> 24); b = U8(src[0] >> 16);                          \
+  c = U8(src[0] >>  8); d = U8(src[0] >>  0);                          \
+  e = U8(src[1] >> 24); f = U8(src[1] >> 16);                          \
+  g = U8(src[1] >>  8); h = U8(src[1] >>  0);                          \
+} while (0)
+
+#define PACK(dst, a, b, c, d, e, f, g, h) do {                         \
+  dst[0] = (U8(a) << 24) | (U8(b) << 16) | (U8(c) << 8) | U8(d);       \
+  dst[1] = (U8(e) << 24) | (U8(f) << 16) | (U8(g) << 8) | U8(h);       \
+} while (0)
+
+#define F(x, y) y += x, x += y
+#define G(x, y) x -= y, y -= x
+
+#define PHT(a, b, c, d, e, f, g, h) do {                               \
+  F(a, b); F(c, d); F(e, f); F(g, h);                                  \
+  F(a, c); F(e, g); F(b, d); F(f, h);                                  \
+  F(a, e); F(b, f); F(c, g); F(d, h);                                  \
+} while (0)
+ #define IPHT(a, b, c, d, e, f, g, h) do {                             \
+  G(a, e); G(b, f); G(c, g); G(d, h);                                  \
+  G(a, c); G(e, g); G(b, d); G(f, h);                                  \
+  G(a, b); G(c, d); G(e, f); G(g, h);                                  \
+} while (0)
+
+#define KXA(k, a, b, c, d, e, f, g, h) do {                            \
+  a ^= *k++; b += *k++; c += *k++; d ^= *k++;                          \
+  e ^= *k++; f += *k++; g += *k++; h ^= *k++;                          \
+} while (0)
+#define SUB(a, b, c, d, e, f, g, h) do {                               \
+  a = s[U8(a)]; b = si[U8(b)]; c = si[U8(c)]; d = s[U8(d)];            \
+  e = s[U8(e)]; f = si[U8(f)]; g = si[U8(g)]; h = s[U8(h)];            \
+} while (0)
+#define KAX(k, a, b, c, d, e, f, g, h) do {                            \
+  a += *k++; b ^= *k++; c ^= *k++; d += *k++;                          \
+  e += *k++; f ^= *k++; g ^= *k++; h += *k++;                          \
+} while (0)
+
+#define KXS(k, a, b, c, d, e, f, g, h) do {                            \
+  h ^= *--k; g -= *--k; f -= *--k; e ^= *--k;                          \
+  d ^= *--k; c -= *--k; b -= *--k; a ^= *--k;                          \
+} while (0)
+#define ISUB(a, b, c, d, e, f, g, h) do {                              \
+  a = si[U8(a)]; b = s[U8(b)]; c = s[U8(c)]; d = si[U8(d)];            \
+  e = si[U8(e)]; f = s[U8(f)]; g = s[U8(g)]; h = si[U8(h)];            \
+} while (0)
+#define KSX(k, a, b, c, d, e, f, g, h) do {                            \
+  h -= *--k; g ^= *--k; f ^= *--k; e -= *--k;                          \
+  d -= *--k; c ^= *--k; b ^= *--k; a -= *--k;                          \
+} while (0)
+
+#define EROUND(k, a, b, c, d, e, f, g, h) do {                         \
+  KXA(k, a, b, c, d, e, f, g, h);                                      \
+  SUB(a, b, c, d, e, f, g, h);                                         \
+  KAX(k, a, b, c, d, e, f, g, h);                                      \
+  PHT(a, b, c, d, e, f, g, h);                                         \
+} while (0)
+
+#define DROUND(k, a, b, c, d, e, f, g, h) do {                         \
+  IPHT(a, b, c, d, e, f, g, h);                                                \
+  KSX(k, a, b, c, d, e, f, g, h);                                      \
+  ISUB(a, b, c, d, e, f, g, h);                                                \
+  KXS(k, a, b, c, d, e, f, g, h);                                      \
+} while (0)
+
+
+void safer_eblk(const safer_ctx *k, const uint32 *src, uint32 *dst)
+{
+  octet a, b, c, d, e, f, g, h;
+  unsigned r = k->r;
+  const octet *kk = k->k;
+
+  UNPACK(src, a, b, c, d, e, f, g, h);
+  while (r >= 3) {
+    EROUND(kk, a, b, c, d, e, f, g, h);
+    EROUND(kk, a, e, b, f, c, g, d, h);
+    EROUND(kk, a, c, e, g, b, d, f, h);
+    r -= 3;
+  }
+  switch (r) {
+    case 0:
+      KXA(kk, a, b, c, d, e, f, g, h);
+      PACK(dst, a, b, c, d, e, f, g ,h);
+      break;
+    case 1:
+      EROUND(kk, a, b, c, d, e, f, g, h);
+      KXA(kk, a, e, b, f, c, g, d, h);
+      PACK(dst, a, e, b, f, c, g, d, h);
+      break;
+    case 2:
+      EROUND(kk, a, b, c, d, e, f, g, h);
+      EROUND(kk, a, e, b, f, c, g, d, h);
+      KXA(kk, a, c, e, g, b, d, f, h);
+      PACK(dst, a, c, e, g, b, d, f, h);
+      break;
+  }
+}
+
+void safer_dblk(const safer_ctx *k, const uint32 *src, uint32 *dst)
+{
+  octet a, b, c, d, e, f, g, h;
+  unsigned r = k->r;
+  const octet *kk = k->k + 16 * r + 8;
+  switch (r%3) {
+    default:
+    case 0:
+      UNPACK(src, a, b, c, d, e, f, g, h);
+      KXS(kk, a, b, c, d, e, f, g, h);
+      break;
+    case 1:
+      UNPACK(src, a, e, b, f, c, g, d, h);
+      KXS(kk, a, e, b, f, c, g, d, h);
+      r--;
+      goto one_round;
+    case 2:
+      UNPACK(src, a, c, e, g, b, d, f, h);
+      KXS(kk, a, c, e, g, b, d, f, h);
+      r -= 2;
+      DROUND(kk, a, e, b, f, c, g, d, h);
+    one_round:
+      DROUND(kk, a, b, c, d, e, f, g, h);
+      break;
+  }
+  while (r) {
+    DROUND(kk, a, c, e, g, b, d, f, h);
+    DROUND(kk, a, e, b, f, c, g, d, h);
+    DROUND(kk, a, b, c, d, e, f, g, h);
+    r -= 3;
+  }
+  PACK(dst, a, b, c, d, e, f, g, h);
+}
+
+BLKC_TEST(SAFER, safer)
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/safer.h b/safer.h
new file mode 100644 (file)
index 0000000..f4d5516
--- /dev/null
+++ b/safer.h
@@ -0,0 +1,136 @@
+/* -*-c-*-
+ *
+ * $Id: safer.h,v 1.1 2001/04/29 17:37:35 mdw Exp $
+ *
+ * The SAFER block cipher
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ * 
+ * Catacomb 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 Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: safer.h,v $
+ * Revision 1.1  2001/04/29 17:37:35  mdw
+ * Added SAFER block cipher.
+ *
+ */
+
+#ifndef CATACOMB_SAFER_H
+#define CATACOMB_SAFER_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stddef.h>
+
+#include <mLib/bits.h>
+
+/*----- Magical numbers ---------------------------------------------------*/
+
+#define SAFER_BLKSZ 8
+#define SAFER_KEYSZ 8
+#define SAFER_CLASS (N, B, 64)
+
+#define SAFERSK_BLKSZ SAFER_BLKSZ
+#define SAFERSK_KEYSZ 16
+#define SAFERSK_CLASS SAFER_CLASS
+
+#define SAFER_MAXROUNDS 12
+
+extern const octet safer_keysz[];
+#define safersk_keysz safer_keysz
+
+/*----- Data structures ---------------------------------------------------*/
+
+typedef struct safer_ctx {
+  octet k[8 * (2 * SAFER_MAXROUNDS + 1)];
+  unsigned r;
+} safer_ctx, safersk_ctx;
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @safer_setup@ --- *
+ *
+ * Arguments:  @safer_ctx *k@ = pointer to context to initialize
+ *             @unsigned r@ = number of rounds wanted
+ *             @unsigned f@ = various other flags
+ *             @const void *buf@ = pointer to key material
+ *             @size_t sz@ = size of key material in bytes
+ *
+ * Returns:    ---
+ *
+ * Use:                Initializes an SAFER expanded key.  A default number of
+ *             rounds is chosen, based on the key length.
+ */
+
+#define SAFER_SK 1u
+
+extern void safer_setup(safer_ctx */*k*/, unsigned /*r*/, unsigned /*f*/,
+                       const void */*buf*/, size_t /*sz*/);
+
+/* --- @safer_init@, @safersk_init@ --- *
+ *
+ * Arguments:  @safer_ctx *k@ = pointer to context to initialize
+ *             @const void *buf@ = pointer to key material
+ *             @size_t sz@ = size of key material in bytes
+ *
+ * Returns:    ---
+ *
+ * Use:                Initializes an SAFER expanded key.  A default number of
+ *             rounds is chosen, based on the key length.
+ */
+
+extern void safer_init(safer_ctx */*k*/,
+                      const void */*buf*/, size_t /*sz*/);
+extern void safersk_init(safer_ctx */*k*/,
+                        const void */*buf*/, size_t /*sz*/);
+
+/* --- @safer_eblk@, @safer_dblk@ --- *
+ *
+ * Arguments:  @const safer_ctx *k@ = pointer to SAFER context
+ *             @const uint32 s[2]@ = pointer to source block
+ *             @const uint32 d[2]@ = pointer to destination block
+ *
+ * Returns:    ---
+ *
+ * Use:                Low-level block encryption and decryption.
+ */
+
+extern void safer_eblk(const safer_ctx */*k*/,
+                      const uint32 */*s*/, uint32 */*dst*/);
+extern void safer_dblk(const safer_ctx */*k*/,
+                      const uint32 */*s*/, uint32 */*dst*/);
+
+#define safersk_eblk safer_eblk
+#define safersk_dblk safer_dblk
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
diff --git a/safersk.c b/safersk.c
new file mode 100644 (file)
index 0000000..9305cdd
--- /dev/null
+++ b/safersk.c
@@ -0,0 +1,16 @@
+/* -*-c-*-
+ *
+ * $Id: safersk.c,v 1.1 2001/04/29 17:37:35 mdw Exp $
+ *
+ * Stub source for SAFER SK
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+#include "blkc.h"
+#include "safersk.h"
+
+const char *safersk_magic = "Compile this useless file";
+
+BLKC_TEST(SAFERSK, safersk)
+  
diff --git a/safersk.h b/safersk.h
new file mode 100644 (file)
index 0000000..7403de7
--- /dev/null
+++ b/safersk.h
@@ -0,0 +1,17 @@
+/* -*-c-*-
+ *
+ * $Id: safersk.h,v 1.1 2001/04/29 17:37:35 mdw Exp $
+ *
+ * Stub header for SAFER SK
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+#ifndef CATACOMB_SAFERSK_H
+#define CATACOMB_SAFERSK_H
+
+#include "safer.h"
+
+extern const char *safersk_magic;
+
+#endif
diff --git a/tests/safer b/tests/safer
new file mode 100644 (file)
index 0000000..36149a0
--- /dev/null
@@ -0,0 +1,10 @@
+# $Id: safer,v 1.1 2001/04/29 17:37:38 mdw Exp $
+#
+# Test vectors for SAFER
+
+# From HAC 7.114, and Richard de Moliner's implementation
+
+safer {
+  0807060504030201 0102030405060708 c8f29cdd87783ed9;
+  100f0e0d0c0b0a090807060504030201 0102030405060708 4a99b15cce9ada19;
+}
diff --git a/tests/safersk b/tests/safersk
new file mode 100644 (file)
index 0000000..d1ea05a
--- /dev/null
@@ -0,0 +1,10 @@
+# $Id: safersk,v 1.1 2001/04/29 17:37:38 mdw Exp $
+#
+# Test vectors for SAFER
+
+# From HAC 7.114, and Richard de Moliner's implementation
+
+safersk {
+  0102030405060708 0102030405060708 60d04ad7c49b8ded;
+  100f0e0d0c0b0a090807060504030201 0102030405060708 b260740f80d2445d;
+}