From e5fb923ba3735c758ef795eb69d5ee1c6f0a94e9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 4 Feb 2020 13:08:02 +1030 Subject: [PATCH] xtea: new module. Signed-off-by: Rusty Russell --- ccan/crypto/xtea/_info | 25 +++++++++++++++++++++ ccan/crypto/xtea/test/run.c | 37 ++++++++++++++++++++++++++++++ ccan/crypto/xtea/xtea.c | 34 ++++++++++++++++++++++++++++ ccan/crypto/xtea/xtea.h | 45 +++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 ccan/crypto/xtea/_info create mode 100644 ccan/crypto/xtea/test/run.c create mode 100644 ccan/crypto/xtea/xtea.c create mode 100644 ccan/crypto/xtea/xtea.h diff --git a/ccan/crypto/xtea/_info b/ccan/crypto/xtea/_info new file mode 100644 index 00000000..5932d667 --- /dev/null +++ b/ccan/crypto/xtea/_info @@ -0,0 +1,25 @@ +#include "config.h" +#include +#include + +/** + * 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 index 00000000..35231f28 --- /dev/null +++ b/ccan/crypto/xtea/test/run.c @@ -0,0 +1,37 @@ +#include +/* Include the C files directly. */ +#include +#include +#include + +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 index 00000000..28435d6a --- /dev/null +++ b/ccan/crypto/xtea/xtea.c @@ -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 index 00000000..a3e971ad --- /dev/null +++ b/ccan/crypto/xtea/xtea.h @@ -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 + +/** + * 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 */ -- 2.39.2