TEA算法是由剑桥大学计算机实验室的David Wheeler和Roger Needham于1994年发明,TEA是Tiny Encryption Algorithm的缩写,以加密解密速度快,实现简单著称。TEA算法每一次可以操作64bit(8byte),采用128bit(16byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。为解决TEA算法密钥表攻击的问题,TEA算法先后经历了几次改进,从XTEA到BLOCK TEA,直至最新的XXTEA。XTEA也称做TEAN,它使用与TEA相同的简单运算,但四个子密钥采取不正规的方式进行混合以阻止密钥表攻击。Block TEA算法可以对32位的任意整数倍长度的变量块进行加解密的操作,该算法将XTEA轮循函数依次应用于块中的每个字,并且将它附加于被应用字的邻字。XXTEA使用跟Block TEA相似的结构,但在处理块中每个字时利用了相邻字,且用拥有两个输入量的MX函数代替了XTEA轮循函数。本文所描述的安全机制采用的加密算法就是TEA算法中安全性能最佳的改进版本-XXTEA算法。
XXTEA算法的结构非常简单,只需要执行加法、异或和寄存的硬件即可,且软件实现的代码非常短小,具有可移植性,非常适合嵌入式系统应用。由于XXTEA算法的以上优点,可以很好地应用于嵌入式RFID系统当中。
C语言实现:
#define MX (z>>5^y<<2) + (y>>3^z<<4)^(sum^y) + (k[p&3^e]^z);
long btea( long* v, long n, long* k) {
unsigned long z=v[n-1], y=v[0], sum=0, e, DELTA=0x9e3779b9;
long p, q ;
if (n > 1) {
q = 6 + 52/n;
while (q-- > 0) {
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++) y = v[p+1], z = v[p] += MX;
y = v[0];
z = v[n-1] += MX;
}
return 0 ;
} else if (n < -1) {
n = -n;
q = 6 + 52/n;
sum = q*DELTA ;
while (sum != 0) {
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--) z = v[p-1], y = v[p] -= MX;
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
return 0;
}
return 1;
}
long btea( long* v, long n, long* k) {
unsigned long z=v[n-1], y=v[0], sum=0, e, DELTA=0x9e3779b9;
long p, q ;
if (n > 1) {
q = 6 + 52/n;
while (q-- > 0) {
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++) y = v[p+1], z = v[p] += MX;
y = v[0];
z = v[n-1] += MX;
}
return 0 ;
} else if (n < -1) {
n = -n;
q = 6 + 52/n;
sum = q*DELTA ;
while (sum != 0) {
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--) z = v[p-1], y = v[p] -= MX;
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
return 0;
}
return 1;
}
Lua语言实现
---------------------------------------------------------------------
-- Author: Jørn Skaarud Karlsen
---------------------------------------------------------------------
require("bit")
require("hex")
---------------------------------------------------------------------
-- Constants
---------------------------------------------------------------------
delta = 0x9E3779B9
---------------------------------------------------------------------
-- Conversion
---------------------------------------------------------------------
function convertStringToBytes(str)
local bytes = {}
local strLength = string.len(str)
for i=1,strLength do
table.insert(bytes, string. byte(str, i))
end
return bytes
end
function convertBytesToString(bytes)
local bytesLength = table.getn(bytes)
local str = ""
for i=1,bytesLength do
str = str .. string. char(bytes[i])
end
return str
end
function convertHexStringToBytes(str)
local bytes = {}
local strLength = string.len(str)
for k=2,strLength,2 do
local hexString = "0x" .. string.sub(str, (k - 1), k)
table.insert(bytes, hex.to_dec(hexString))
end
return bytes
end
function convertBytesToHexString(bytes)
local str = ""
local bytesLength = table.getn(bytes)
for i=1,bytesLength do
local hexString = string.sub(hex.to_hex(bytes[i]), 3)
if string.len(hexString) == 1 then
hexString = "0" .. hexString
end
str = str .. hexString
end
return str
end
function convertBytesToUIntArray(bytes, includeLength)
local bytesLength = table.getn(bytes)
local result = {}
if includeLength then
local n = bit.brshift(bytesLength, 2) + 1
if bit.band(bytesLength, 3) ~= 0 then
n = n + 1
end
result[n] = bytesLength;
end
for i=0,(bytesLength - 1) do
local resultIndex = bit.brshift(i, 2) + 1
if result[resultIndex] == nil then
result[resultIndex] = 0
end
local resultValue = bit.blshift(bit.band(0x000000ff, bytes[i+1]), bit.blshift(bit.band(i, 3), 3))
result[resultIndex] = bit.bor(result[resultIndex], resultValue);
end
return result
end
function convertUIntArrayToBytes(data, includeLength)
local dataLength = table.getn(data)
local n = bit.blshift(dataLength, 2)
local result = {}
if includeLength then
local m = data[dataLength]
if m > n then
return nil
end
n = m
end
for i=0,(n-1) do
local value = bit.band(bit.brshift(data[bit.brshift(i, 2) + 1], (bit.blshift(bit.band(i, 3), 3))), 0xff)
table.insert(result, value)
end
return result
end
function convertToUInt32(value)
if value < 0 then
local absValue = math.abs(value)
local a = math.floor(absValue / 0xFFFFFFFF)
local b = value + a * 0xFFFFFFFF
local c = 0xFFFFFFFF + b + 1
return c
end
return math.mod(value, 0xFFFFFFFF) - math.floor(value / 0xFFFFFFFF)
end
---------------------------------------------------------------------
-- Encryption/decryption common
---------------------------------------------------------------------
function mx(sum, y, z, p, e, k)
local aa = bit.brshift(z, 5)
local ab = convertToUInt32(bit.blshift(y, 2))
local ac = bit.bxor(aa, ab)
local ba = bit.brshift(y, 3)
local bb = convertToUInt32(bit.blshift(z, 4))
local bc = bit.bxor(ba, bb)
-- Author: Jørn Skaarud Karlsen
---------------------------------------------------------------------
require("bit")
require("hex")
---------------------------------------------------------------------
-- Constants
---------------------------------------------------------------------
delta = 0x9E3779B9
---------------------------------------------------------------------
-- Conversion
---------------------------------------------------------------------
function convertStringToBytes(str)
local bytes = {}
local strLength = string.len(str)
for i=1,strLength do
table.insert(bytes, string. byte(str, i))
end
return bytes
end
function convertBytesToString(bytes)
local bytesLength = table.getn(bytes)
local str = ""
for i=1,bytesLength do
str = str .. string. char(bytes[i])
end
return str
end
function convertHexStringToBytes(str)
local bytes = {}
local strLength = string.len(str)
for k=2,strLength,2 do
local hexString = "0x" .. string.sub(str, (k - 1), k)
table.insert(bytes, hex.to_dec(hexString))
end
return bytes
end
function convertBytesToHexString(bytes)
local str = ""
local bytesLength = table.getn(bytes)
for i=1,bytesLength do
local hexString = string.sub(hex.to_hex(bytes[i]), 3)
if string.len(hexString) == 1 then
hexString = "0" .. hexString
end
str = str .. hexString
end
return str
end
function convertBytesToUIntArray(bytes, includeLength)
local bytesLength = table.getn(bytes)
local result = {}
if includeLength then
local n = bit.brshift(bytesLength, 2) + 1
if bit.band(bytesLength, 3) ~= 0 then
n = n + 1
end
result[n] = bytesLength;
end
for i=0,(bytesLength - 1) do
local resultIndex = bit.brshift(i, 2) + 1
if result[resultIndex] == nil then
result[resultIndex] = 0
end
local resultValue = bit.blshift(bit.band(0x000000ff, bytes[i+1]), bit.blshift(bit.band(i, 3), 3))
result[resultIndex] = bit.bor(result[resultIndex], resultValue);
end
return result
end
function convertUIntArrayToBytes(data, includeLength)
local dataLength = table.getn(data)
local n = bit.blshift(dataLength, 2)
local result = {}
if includeLength then
local m = data[dataLength]
if m > n then
return nil
end
n = m
end
for i=0,(n-1) do
local value = bit.band(bit.brshift(data[bit.brshift(i, 2) + 1], (bit.blshift(bit.band(i, 3), 3))), 0xff)
table.insert(result, value)
end
return result
end
function convertToUInt32(value)
if value < 0 then
local absValue = math.abs(value)
local a = math.floor(absValue / 0xFFFFFFFF)
local b = value + a * 0xFFFFFFFF
local c = 0xFFFFFFFF + b + 1
return c
end
return math.mod(value, 0xFFFFFFFF) - math.floor(value / 0xFFFFFFFF)
end
---------------------------------------------------------------------
-- Encryption/decryption common
---------------------------------------------------------------------
function mx(sum, y, z, p, e, k)
local aa = bit.brshift(z, 5)
local ab = convertToUInt32(bit.blshift(y, 2))
local ac = bit.bxor(aa, ab)
local ba = bit.brshift(y, 3)
local bb = convertToUInt32(bit.blshift(z, 4))
local bc = bit.bxor(ba, bb)