Commit e5fb923b authored by Rusty Russell's avatar Rusty Russell

xtea: new module.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent c36444e0
#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;
}
#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();
}
/* 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;
}
/* 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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment