]> git.ozlabs.org Git - ccan/blobdiff - ccan/crypto/xtea/xtea.c
xtea: new module.
[ccan] / ccan / crypto / xtea / xtea.c
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;
+}