xtea: new module.
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 4 Feb 2020 02:38:02 +0000 (13:08 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 4 Feb 2020 02:52:43 +0000 (13:22 +1030)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ccan/crypto/xtea/_info [new file with mode: 0644]
ccan/crypto/xtea/test/run.c [new file with mode: 0644]
ccan/crypto/xtea/xtea.c [new file with mode: 0644]
ccan/crypto/xtea/xtea.h [new file with mode: 0644]

diff --git a/ccan/crypto/xtea/_info b/ccan/crypto/xtea/_info
new file mode 100644 (file)
index 0000000..5932d66
--- /dev/null
@@ -0,0 +1,25 @@
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * crypto/xtea - implementation of xtea algorithm.
+ *
+ * This code is an implementation of the simple xtea encryption/decryption
+ * algorithm.  You probably don't want to use this; try AES or chacha20
+ * from libsodium for modern encryption routines.
+ *
+ * License: CC0 (Public Domain)
+ */
+int main(int argc, char *argv[])
+{
+       /* Expect exactly one argument */
+       if (argc != 2)
+               return 1;
+
+       if (strcmp(argv[1], "depends") == 0) {
+               return 0;
+       }
+
+       return 1;
+}
diff --git a/ccan/crypto/xtea/test/run.c b/ccan/crypto/xtea/test/run.c
new file mode 100644 (file)
index 0000000..35231f2
--- /dev/null
@@ -0,0 +1,37 @@
+#include <ccan/crypto/xtea/xtea.h>
+/* Include the C files directly. */
+#include <ccan/crypto/xtea/xtea.c>
+#include <ccan/tap/tap.h>
+#include <string.h>
+
+int main(void)
+{
+       uint64_t v, e;  
+       struct xtea_secret s;
+
+       /* This is how many tests you plan to run */
+       plan_tests(66);
+
+       memset(&s, 1, sizeof(s));
+
+       for (v = 1; v; v <<= 1) {
+               e = xtea_encipher(&s, v);
+               ok1(xtea_decipher(&s, e) == v);
+       }
+
+       /* The only 32-iteration from the "test vectors" at
+        * http://www.cix.co.uk/~klockstone/teavect.htm:
+        * in=af20a390547571aa, N=32, k=27f917b1c1da899360e2acaaa6eb923d, out=d26428af0a202283
+        */
+       v = 0xaf20a390547571aaULL;
+       s.u.u32[0] = 0x27f917b1;
+       s.u.u32[1] = 0xc1da8993;
+       s.u.u32[2] = 0x60e2acaa;
+       s.u.u32[3] = 0xa6eb923d;
+       e = xtea_encipher(&s, v);
+       ok1(e == 0xd26428af0a202283ULL);
+       ok1(xtea_decipher(&s, e) == v);
+
+       /* This exits depending on whether all tests passed */
+       return exit_status();
+}
diff --git a/ccan/crypto/xtea/xtea.c b/ccan/crypto/xtea/xtea.c
new file mode 100644 (file)
index 0000000..28435d6
--- /dev/null
@@ -0,0 +1,34 @@
+/* CC0 license (public domain) - see LICENSE file for details */
+#include "xtea.h"
+
+/* Based on http://www.cix.co.uk/~klockstone/xtea.pdf, and the modernized
+ * source at https://en.wikipedia.org/wiki/XTEA */
+
+/* Each round below represents two rounds, so we usee 32 not 64 here */
+#define NUM_DOUBLE_ROUNDS 32
+
+uint64_t xtea_encipher(const struct xtea_secret *secret, uint64_t v)
+{
+       const uint32_t delta=0x9E3779B9;
+       uint32_t v0=(v>>32), v1=v, sum=0;
+
+       for (int i=0; i < NUM_DOUBLE_ROUNDS; i++) {
+               v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + secret->u.u32[sum & 3]);
+               sum += delta;
+               v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + secret->u.u32[(sum>>11) & 3]);
+       }
+       return ((uint64_t)v0 << 32) | v1;
+}
+
+uint64_t xtea_decipher(const struct xtea_secret *secret, uint64_t e)
+{
+       const uint32_t delta=0x9E3779B9;
+       uint32_t v0=(e>>32), v1=e, sum=delta*NUM_DOUBLE_ROUNDS;
+
+       for (int i=0; i < NUM_DOUBLE_ROUNDS; i++) {
+               v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + secret->u.u32[(sum>>11) & 3]);
+               sum -= delta;
+               v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + secret->u.u32[sum & 3]);
+       }
+       return ((uint64_t)v0 << 32) | v1;
+}
diff --git a/ccan/crypto/xtea/xtea.h b/ccan/crypto/xtea/xtea.h
new file mode 100644 (file)
index 0000000..a3e971a
--- /dev/null
@@ -0,0 +1,45 @@
+/* CC0 license (public domain) - see LICENSE file for details */
+#ifndef CCAN_CRYPTO_XTEA_H
+#define CCAN_CRYPTO_XTEA_H
+/* Public domain - see LICENSE file for details */
+#include "config.h"
+#include <stdint.h>
+
+/**
+ * struct xtea_secret - secret to use for xtea encryption
+ * @u.u8: an unsigned char array.
+ * @u.u32: a 32-bit integer array.
+ * @u.u64: a 64-bit integer array.
+ *
+ * Other fields may be added to the union in future.
+ */
+struct xtea_secret {
+       union {
+               /* Array of chars */
+               unsigned char u8[16];
+               /* Array of uint32_t */
+               uint32_t u32[4];
+               /* Array of uint64_t */
+               uint64_t u64[2];
+       } u;
+};
+
+/**
+ * xtea_encipher - encrypt a 64-bit value.
+ * @secret: the xtea secret
+ * @v: the 64 bit value
+ *
+ * Returns the 64-bit encrypted value: use xtea_decipher to decrypt.
+ */
+uint64_t xtea_encipher(const struct xtea_secret *secret, uint64_t v);
+
+/**
+ * xtea_decipher - decrypt a 64-bit value.
+ * @secret: the xtea secret
+ * @e: the 64 bit encrypted value
+ *
+ * Returns the 64-bit decryptted value.
+ */
+uint64_t xtea_decipher(const struct xtea_secret *secret, uint64_t e);
+
+#endif /* CCAN_CRYPTO_SIPHASH24_H */