介绍XXTEA加密算法

简介:

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;
 }
   
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)
    local ca = bit.bxor(sum, y)

    local dia = bit.band(p, 3)
    local dib = bit.bxor(dia, e)
    local da = k[dib + 1]
    local db = bit.bxor(da, z)

    local ea = convertToUInt32(ca + db)
    local fa = convertToUInt32(ac + bc)
    local ga = bit.bxor(fa, ea)

     return ga
end

---------------------------------------------------------------------
-- Decryption
---------------------------------------------------------------------

function decryptIntArray(v, k)
    local n = table.getn(v)
    local z = v[n]
    local y = v[1]
    local e = 0
    local p = 0

    local q = 6 + math.floor(52 / n)
    local sum = convertToUInt32(q * delta)
     while sum ~= 0  do
        e = bit.band(bit.brshift(sum, 2), 3)
         for p=n,2,-1  do
            z = v[p - 1]
            v[p] = convertToUInt32(v[p] - mx(sum, y, z, (p-1), e, k))
            y = v[p]
        end

        z = v[n]
        v[1] = convertToUInt32(v[1] - mx(sum, y, z, p, e, k))
        y = v[1]

        local sumBefore = sum
        sum = convertToUInt32(sum - delta)
    end

     return v
end

function decrypt(data, key)
    local dataLength =  string.len(data)
    local keyLength =  string.len(key)

     if keyLength == 0 then
         return data
    end

    local keyBytes = convertStringToBytes(key)
    local encryptedBytes = convertHexStringToBytes(data)

    local dataIntArray = convertBytesToUIntArray(encryptedBytes,  false)
    local keyIntArray = convertBytesToUIntArray(keyBytes,  false)

    local decryptedIntArray = decryptIntArray(dataIntArray, keyIntArray)
    local decryptedBytes = convertUIntArrayToBytes(decryptedIntArray,  true)
    local decryptedString = convertBytesToString(decryptedBytes)

     return decryptedString
end

---------------------------------------------------------------------
-- Encryption
---------------------------------------------------------------------

function encryptIntArray(v, k)

    n = table.getn(v)
     if n < 2 then
         return v
    end

    local z = v[n]
    local y = v[1]
    local sum = 0
    local e = 0
    local p = 0
    local initQ = 6 + math.floor(52 / n)

     for q=initQ,1,-1  do
        sum = convertToUInt32(sum + delta);
        e = bit.band(bit.brshift(sum, 2), 3);
         for p=1,(n-1)  do
            y = v[p + 1];
            v[p] = convertToUInt32(v[p] + mx(sum, y, z, (p-1), e, k));
            z = v[p]
        end
        y = v[1];
        v[n] = convertToUInt32(v[n] + mx(sum, y, z, (n-1), e, k));
        z = v[n]
    end

     return v;

end

function encrypt(data, key)
    local dataLength =  string.len(data)
    local keyLength =  string.len(key)

     if (keyLength == 0) then
         return data
    end

    local dataBytes = convertStringToBytes(data)
    local keyBytes = convertStringToBytes(key)

    local dataIntArray = convertBytesToUIntArray(dataBytes,  true)
    local keyIntArray = convertBytesToUIntArray(keyBytes,  false)

    local encryptedIntArray = encryptIntArray(dataIntArray, keyIntArray)
    local encryptedBytes = convertUIntArrayToBytes(encryptedIntArray,  false)
    local encryptedString = convertBytesToHexString(encryptedBytes)

     return encryptedString
end

---------------------------------------------------------------------
-- Program: replace
---------------------------------------------------------------------

unencryptedInput = "This is a test"
encryptionKeyInput = "xxxxxxxxxxxxxxxxxxxx"   -- Place your encryption key here

encryptedOutput = encrypt(unencryptedInput, encryptionKeyInput)
print(encryptedOutput)

decryptedEncryptedOutput = decrypt(encryptedOutput, encryptionKeyInput)
print(decryptedEncryptedOutput)

AS3语言实现
/* *********************************************************\
|                                                          |
| The implementation of PHPRPC Protocol 3.0                |
|                                                          |
| XXTEA.as                                                 |
|                                                          |
| Release 3.0.0                                            |
| Copyright (c) 2005-2007 by Team-PHPRPC                   |
|                                                          |
| WebSite:  http://www.phprpc.org/                         |
|           http://www.phprpc.net/                         |
|           http://www.phprpc.com/                         |
|           http://sourceforge.net/projects/php-rpc/       |
|                                                          |
| Authors:  Ma Bingyao <andot@ujn.edu.cn>                  |
|                                                          |
| This file may be distributed and/or modified under the   |
| terms of the GNU Lesser General Public License (LGPL)    |
| version 3.0 as published by the Free Software Foundation |
| and appearing in the included file LICENSE.              |
|                                                          |
\*********************************************************
*/
/*  XXTEA encryption arithmetic library.
 *
 * Copyright (C) 2006-2007 Ma Bingyao <andot@ujn.edu.cn>
 * Version: 1.7
 * LastModified: Nov 5, 2007
 * This library is free.  You can redistribute it and/or modify it.
 
*/
 
package org.phprpc.util {
    import flash.utils.ByteArray;
    import flash.utils.Endian;
    public class XXTEA {
        private static const delta:uint = uint(0x9E3779B9);
        private static  function LongArrayToByteArray(data:Array, includeLength:Boolean):ByteArray {
             var length:uint = data.length;
             var n:uint = (length - 1) << 2;
             if (includeLength) {
                 var m:uint = data[length - 1];
                 if ((m < n - 3) || (m > n)) {
                     return  null;
                }
                n = m;
            }
             var result:ByteArray =  new ByteArray();
            result.endian = Endian.LITTLE_ENDIAN;
             for ( var i:uint = 0; i < length; i++) {
                result.writeUnsignedInt(data[i]);
            }
             if (includeLength) {
                result.length = n;
                 return result;
            }
             else {
                 return result;
            }
        }
        private static  function ByteArrayToLongArray(data:ByteArray, includeLength:Boolean):Array {
             var length:uint = data.length;
             var n:uint = length >> 2;
             if (length % 4 > 0) {
                n++;
                data.length += (4 - (length % 4));
            }
            data.endian = Endian.LITTLE_ENDIAN;
            data.position = 0;
             var result:Array = [];
             for ( var i:uint = 0; i < n; i++) {
                result[i] = data.readUnsignedInt();
            }
             if (includeLength) {
                result[n] = length;
            }
            data.length = length;
             return result;
        }
        public static  function encrypt(data:ByteArray, key:ByteArray):ByteArray {
             if (data.length == 0) {
                 return  new ByteArray();
            }
             var v:Array = ByteArrayToLongArray(data,  true);
             var k:Array = ByteArrayToLongArray(key,  false);
             if (k.length < 4) {
                k.length = 4;
            }
             var n:uint = v.length - 1;
             var z:uint = v[n];
             var y:uint = v[0];
             var mx:uint;
             var e:uint;
             var p:uint;
             var q:uint = uint(6 + 52 / (n + 1));
             var sum:uint = 0;
             while (0 < q--) {
                sum = sum + delta;
                e = sum >>> 2 & 3;
                 for (p = 0; p < n; p++) {
                    y = v[p + 1];
                    mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                    z = v[p] = v[p] + mx;
                }
                y = v[0];
                mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                z = v[n] = v[n] + mx;
            }
             return LongArrayToByteArray(v,  false);
        }
        public static  function decrypt(data:ByteArray, key:ByteArray):ByteArray {
             if (data.length == 0) {
                 return  new ByteArray();
            }
             var v:Array = ByteArrayToLongArray(data,  false);
             var k:Array = ByteArrayToLongArray(key,  false);
             if (k.length < 4) {
                k.length = 4;
            }
             var n:uint = v.length - 1;
             var z:uint = v[n - 1];
             var y:uint = v[0];
             var mx:uint;
             var e:uint;
             var p:uint;
             var q:uint = uint(6 + 52 / (n + 1));
             var sum:uint = q * delta;
             while (sum != 0) {
                e = sum >>> 2 & 3;
                 for (p = n; p > 0; p--) {
                    z = v[p - 1];
                    mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                    y = v[p] = v[p] - mx;
                }
                z = v[n];
                mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                y = v[0] = v[0] - mx;
                sum = sum - delta;
            }
             return LongArrayToByteArray(v,  true);
        }
    }
}


JS语言实现
/*  XXTEA encryption arithmetic library.
*
* Copyright (C) 2006 Ma Bingyao <andot@ujn.edu.cn>
* Version:      1.5
* LastModified: Dec 9, 2006
* This library is free.  You can redistribute it and/or modify it.
*/
 
function long2str(v, w) {
     var vl = v.length;
     var n = (vl - 1) << 2;
     if (w) {
         var m = v[vl - 1];
         if ((m < n - 3) || (m > n))  return  null;
        n = m;
    }
     for ( var i = 0; i < vl; i++) {
        v[i] = String.fromCharCode(v[i] & 0xff,
                                   v[i] >>> 8 & 0xff,
                                   v[i] >>> 16 & 0xff,
                                   v[i] >>> 24 & 0xff);
    }
     if (w) {
         return v.join('').substring(0, n);
    }
     else {
         return v.join('');
    }
}
 
function str2long(s, w) {
     var len = s.length;
     var v = [];
     for ( var i = 0; i < len; i += 4) {
        v[i >> 2] = s.charCodeAt(i)
                  | s.charCodeAt(i + 1) << 8
                  | s.charCodeAt(i + 2) << 16
                  | s.charCodeAt(i + 3) << 24;
    }
     if (w) {
        v[v.length] = len;
    }
     return v;
}
 
function xxtea_encrypt(str, key) {
     if (str == "") {
         return "";
    }
     var v = str2long(str,  true);
     var k = str2long(key,  false);
     if (k.length < 4) {
        k.length = 4;
    }
     var n = v.length - 1;
 
     var z = v[n], y = v[0], delta = 0x9E3779B9;
     var mx, e, p, q = Math.floor(6 + 52 / (n + 1)), sum = 0;
     while (0 < q--) {
        sum = sum + delta & 0xffffffff;
        e = sum >>> 2 & 3;
         for (p = 0; p < n; p++) {
            y = v[p + 1];
            mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
            z = v[p] = v[p] + mx & 0xffffffff;
        }
        y = v[0];
        mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
        z = v[n] = v[n] + mx & 0xffffffff;
    }
 
     return long2str(v,  false);
}
 
function xxtea_decrypt(str, key) {
     if (str == "") {
         return "";
    }
     var v = str2long(str,  false);
     var k = str2long(key,  false);
     if (k.length < 4) {
        k.length = 4;
    }
     var n = v.length - 1;
 
     var z = v[n - 1], y = v[0], delta = 0x9E3779B9;
     var mx, e, p, q = Math.floor(6 + 52 / (n + 1)), sum = q * delta & 0xffffffff;
     while (sum != 0) {
        e = sum >>> 2 & 3;
         for (p = n; p > 0; p--) {
            z = v[p - 1];
            mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
            y = v[p] = v[p] - mx & 0xffffffff;
        }
        z = v[n];
        mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
        y = v[0] = v[0] - mx & 0xffffffff;
        sum = sum - delta & 0xffffffff;
    }
 
     return long2str(v,  true);
}

PHP语言实现
<?php
/*  XXTEA encryption arithmetic library.
*
* Copyright (C) 2006 Ma Bingyao <andot@ujn.edu.cn>
* Version:      1.5
* LastModified: Dec 5, 2006
* This library is free.  You can redistribute it and/or modify it.
*/
 
function long2str( $v$w) {
     $len =  count( $v);
     $n = ( $len - 1) << 2;
     if ( $w) {
         $m =  $v[ $len - 1];
         if (( $m <  $n - 3) || ( $m >  $n))  return  false;
         $n =  $m;
    }
     $s =  array();
     for ( $i = 0;  $i <  $len$i++) {
         $s[ $i] =  pack("V",  $v[ $i]);
    }
     if ( $w) {
         return  substr( join('',  $s), 0,  $n);
    }
     else {
         return  join('',  $s);
    }
}
 
function str2long( $s$w) {
     $v =  unpack("V*",  $sstr_repeat("\0", (4 -  strlen( $s) % 4) & 3));
     $v =  array_values( $v);
     if ( $w) {
         $v[ count( $v)] =  strlen( $s);
    }
     return  $v;
}
 
function int32( $n) {
     while ( $n >= 2147483648)  $n -= 4294967296;
     while ( $n <= -2147483649)  $n += 4294967296;
     return (int) $n;
}
 
function xxtea_encrypt( $str$key) {
     if ( $str == "") {
         return "";
    }
     $v = str2long( $strtrue);
     $k = str2long( $keyfalse);
     if ( count( $k) < 4) {
         for ( $i =  count( $k);  $i < 4;  $i++) {
             $k[ $i] = 0;
        }
    }
     $n =  count( $v) - 1;
 
     $z =  $v[ $n];
     $y =  $v[0];
     $delta = 0x9E3779B9;
     $q =  floor(6 + 52 / ( $n + 1));
     $sum = 0;
     while (0 <  $q--) {
         $sum = int32( $sum +  $delta);
         $e =  $sum >> 2 & 3;
         for ( $p = 0;  $p <  $n$p++) {
             $y =  $v[ $p + 1];
             $mx = int32((( $z >> 5 & 0x07ffffff) ^  $y << 2) + (( $y >> 3 & 0x1fffffff) ^  $z << 4)) ^ int32(( $sum ^  $y) + ( $k[ $p & 3 ^  $e] ^  $z));
             $z =  $v[ $p] = int32( $v[ $p] +  $mx);
        }
         $y =  $v[0];
         $mx = int32((( $z >> 5 & 0x07ffffff) ^  $y << 2) + (( $y >> 3 & 0x1fffffff) ^  $z << 4)) ^ int32(( $sum ^  $y) + ( $k[ $p & 3 ^  $e] ^  $z));
         $z =  $v[ $n] = int32( $v[ $n] +  $mx);
    }
     return long2str( $vfalse);
}
 
function xxtea_decrypt( $str$key) {
     if ( $str == "") {
         return "";
    }
     $v = str2long( $strfalse);
     $k = str2long( $keyfalse);
     if ( count( $k) < 4) {
         for ( $i =  count( $k);  $i < 4;  $i++) {
             $k[ $i] = 0;
        }
    }
     $n =  count( $v) - 1;
 
     $z =  $v[ $n];
     $y =  $v[0];
     $delta = 0x9E3779B9;
     $q =  floor(6 + 52 / ( $n + 1));
     $sum = int32( $q *  $delta);
     while ( $sum != 0) {
         $e =  $sum >> 2 & 3;
         for ( $p =  $n$p > 0;  $p--) {
             $z =  $v[ $p - 1];
             $mx = int32((( $z >> 5 & 0x07ffffff) ^  $y << 2) + (( $y >> 3 & 0x1fffffff) ^  $z << 4)) ^ int32(( $sum ^  $y) + ( $k[ $p & 3 ^  $e] ^  $z));
             $y =  $v[ $p] = int32( $v[ $p] -  $mx);
        }
         $z =  $v[ $n];
         $mx = int32((( $z >> 5 & 0x07ffffff) ^  $y << 2) + (( $y >> 3 & 0x1fffffff) ^  $z << 4)) ^ int32(( $sum ^  $y) + ( $k[ $p & 3 ^  $e] ^  $z));
         $y =  $v[0] = int32( $v[0] -  $mx);
         $sum = int32( $sum -  $delta);
    }
     return long2str( $vtrue);
}
?>
目录
相关文章
|
6月前
|
算法 数据安全/隐私保护 C语言
XXTEA加密算法
XXTEA加密算法
163 0
|
9月前
|
存储 算法 安全
几种加密算法
几种加密算法
|
9月前
|
算法 安全 Unix
常见加密算法介绍及比较
常见加密算法介绍及比较
227 0
|
9月前
|
存储 算法 安全
5种常用加密算法!
5种常用加密算法!
|
10月前
|
算法 搜索推荐 小程序
AES加密
AES加密
481 0
|
数据安全/隐私保护
对称加密及AES加密算法
对称加密及AES加密算法
253 0
|
算法 安全 数据安全/隐私保护
浅谈加密算法 aes
浅谈加密算法 aes
浅谈加密算法 aes
|
缓存 算法 BI
密码学系列之:Argon2加密算法详解
密码学系列之:Argon2加密算法详解
密码学系列之:Argon2加密算法详解
|
算法 架构师 Java
那些常用的加密算法
本文主要讲解一下C#常用的那些加密算法。
那些常用的加密算法
|
机器学习/深度学习 编解码 人工智能
密码学之常见加密方式(01)
密码学之常见加密方式
417 0
密码学之常见加密方式(01)