xtea: new module.
[ccan] / ccan / crypto / xtea / xtea.c
1 /* CC0 license (public domain) - see LICENSE file for details */
2 #include "xtea.h"
3
4 /* Based on http://www.cix.co.uk/~klockstone/xtea.pdf, and the modernized
5  * source at https://en.wikipedia.org/wiki/XTEA */
6
7 /* Each round below represents two rounds, so we usee 32 not 64 here */
8 #define NUM_DOUBLE_ROUNDS 32
9
10 uint64_t xtea_encipher(const struct xtea_secret *secret, uint64_t v)
11 {
12         const uint32_t delta=0x9E3779B9;
13         uint32_t v0=(v>>32), v1=v, sum=0;
14
15         for (int i=0; i < NUM_DOUBLE_ROUNDS; i++) {
16                 v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + secret->u.u32[sum & 3]);
17                 sum += delta;
18                 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + secret->u.u32[(sum>>11) & 3]);
19         }
20         return ((uint64_t)v0 << 32) | v1;
21 }
22
23 uint64_t xtea_decipher(const struct xtea_secret *secret, uint64_t e)
24 {
25         const uint32_t delta=0x9E3779B9;
26         uint32_t v0=(e>>32), v1=e, sum=delta*NUM_DOUBLE_ROUNDS;
27
28         for (int i=0; i < NUM_DOUBLE_ROUNDS; i++) {
29                 v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + secret->u.u32[(sum>>11) & 3]);
30                 sum -= delta;
31                 v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + secret->u.u32[sum & 3]);
32         }
33         return ((uint64_t)v0 << 32) | v1;
34 }