| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- -- require("lockbox").insecure();
- local Bit = require("lockbox.util.bit");
- local AND = Bit.band;
- local OR = Bit.bor;
- local XOR = Bit.bxor;
- local LSHIFT = Bit.lshift;
- local RSHIFT = Bit.rshift;
- --NOTE: XTEA is endian-dependent!
- --The spec does not seem to specify which to use.
- --It looks like most implementations use big-endian
- local bytes2word = function(b0, b1, b2, b3)
- local i = b0; i = LSHIFT(i, 8);
- i = OR(i, b1); i = LSHIFT(i, 8);
- i = OR(i, b2); i = LSHIFT(i, 8);
- i = OR(i, b3);
- return i;
- end
- local word2bytes = function(word)
- local b0, b1, b2, b3;
- b3 = AND(word, 0xFF); word = RSHIFT(word, 8);
- b2 = AND(word, 0xFF); word = RSHIFT(word, 8);
- b1 = AND(word, 0xFF); word = RSHIFT(word, 8);
- b0 = AND(word, 0xFF);
- return b0, b1, b2, b3;
- end
- local XTEA = {};
- XTEA.blockSize = 8;
- XTEA.encrypt = function(key, data)
- local y = bytes2word(data[1], data[2], data[3], data[4]);
- local z = bytes2word(data[5], data[6], data[7], data[8]);
- local delta = 0x9e3779b9;
- local sum = 0;
- local k0 = bytes2word(key[ 1], key[ 2], key[ 3], key[ 4]);
- local k1 = bytes2word(key[ 5], key[ 6], key[ 7], key[ 8]);
- local k2 = bytes2word(key[ 9], key[10], key[11], key[12]);
- local k3 = bytes2word(key[13], key[14], key[15], key[16]);
- local k = {[0] = k0, k1, k2, k3};
- for _ = 1, 32 do
- local temp;
- temp = XOR(LSHIFT(z, 4), RSHIFT(z, 5)) + z
- temp = XOR(temp, sum + k[ AND(sum, 0x3) ])
- y = AND(y + temp, 0xFFFFFFFF);
- sum = AND(sum + delta, 0xFFFFFFFF);
- temp = XOR(LSHIFT(y, 4), RSHIFT(y, 5)) + y
- temp = XOR(temp, sum + k[ AND(RSHIFT(sum, 11), 0x3) ])
- z = AND( z + temp, 0xFFFFFFFF);
- end
- local out = {};
- out[1], out[2], out[3], out[4] = word2bytes(y);
- out[5], out[6], out[7], out[8] = word2bytes(z);
- return out;
- end
- XTEA.decrypt = function(key, data)
- local y = bytes2word(data[1], data[2], data[3], data[4]);
- local z = bytes2word(data[5], data[6], data[7], data[8]);
- local delta = 0x9e3779b9;
- local sum = 0xc6ef3720; --AND(delta*32,0xFFFFFFFF);
- local k0 = bytes2word(key[ 1], key[ 2], key[ 3], key[ 4]);
- local k1 = bytes2word(key[ 5], key[ 6], key[ 7], key[ 8]);
- local k2 = bytes2word(key[ 9], key[10], key[11], key[12]);
- local k3 = bytes2word(key[13], key[14], key[15], key[16]);
- local k = {[0] = k0, k1, k2, k3};
- for _ = 1, 32 do
- local temp;
- temp = XOR(LSHIFT(y, 4), RSHIFT(y, 5)) + y
- temp = XOR(temp, sum + k[ AND(RSHIFT(sum, 11), 0x3) ])
- z = AND(z + 0x100000000 - temp, 0xFFFFFFFF);
- sum = AND(sum + 0x100000000 - delta, 0xFFFFFFFF);
- temp = XOR(LSHIFT(z, 4), RSHIFT(z, 5)) + z
- temp = XOR(temp, sum + k[ AND(sum, 0x3) ])
- y = AND(y + 0x100000000 - temp, 0xFFFFFFFF);
- end
- local out = {};
- out[1], out[2], out[3], out[4] = word2bytes(y);
- out[5], out[6], out[7], out[8] = word2bytes(z);
- return out;
- end
- return XTEA;
|