xtea.lua 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. -- require("lockbox").insecure();
  2. local Bit = require("lockbox.util.bit");
  3. local AND = Bit.band;
  4. local OR = Bit.bor;
  5. local XOR = Bit.bxor;
  6. local LSHIFT = Bit.lshift;
  7. local RSHIFT = Bit.rshift;
  8. --NOTE: XTEA is endian-dependent!
  9. --The spec does not seem to specify which to use.
  10. --It looks like most implementations use big-endian
  11. local bytes2word = function(b0, b1, b2, b3)
  12. local i = b0; i = LSHIFT(i, 8);
  13. i = OR(i, b1); i = LSHIFT(i, 8);
  14. i = OR(i, b2); i = LSHIFT(i, 8);
  15. i = OR(i, b3);
  16. return i;
  17. end
  18. local word2bytes = function(word)
  19. local b0, b1, b2, b3;
  20. b3 = AND(word, 0xFF); word = RSHIFT(word, 8);
  21. b2 = AND(word, 0xFF); word = RSHIFT(word, 8);
  22. b1 = AND(word, 0xFF); word = RSHIFT(word, 8);
  23. b0 = AND(word, 0xFF);
  24. return b0, b1, b2, b3;
  25. end
  26. local XTEA = {};
  27. XTEA.blockSize = 8;
  28. XTEA.encrypt = function(key, data)
  29. local y = bytes2word(data[1], data[2], data[3], data[4]);
  30. local z = bytes2word(data[5], data[6], data[7], data[8]);
  31. local delta = 0x9e3779b9;
  32. local sum = 0;
  33. local k0 = bytes2word(key[ 1], key[ 2], key[ 3], key[ 4]);
  34. local k1 = bytes2word(key[ 5], key[ 6], key[ 7], key[ 8]);
  35. local k2 = bytes2word(key[ 9], key[10], key[11], key[12]);
  36. local k3 = bytes2word(key[13], key[14], key[15], key[16]);
  37. local k = {[0] = k0, k1, k2, k3};
  38. for _ = 1, 32 do
  39. local temp;
  40. temp = XOR(LSHIFT(z, 4), RSHIFT(z, 5)) + z
  41. temp = XOR(temp, sum + k[ AND(sum, 0x3) ])
  42. y = AND(y + temp, 0xFFFFFFFF);
  43. sum = AND(sum + delta, 0xFFFFFFFF);
  44. temp = XOR(LSHIFT(y, 4), RSHIFT(y, 5)) + y
  45. temp = XOR(temp, sum + k[ AND(RSHIFT(sum, 11), 0x3) ])
  46. z = AND( z + temp, 0xFFFFFFFF);
  47. end
  48. local out = {};
  49. out[1], out[2], out[3], out[4] = word2bytes(y);
  50. out[5], out[6], out[7], out[8] = word2bytes(z);
  51. return out;
  52. end
  53. XTEA.decrypt = function(key, data)
  54. local y = bytes2word(data[1], data[2], data[3], data[4]);
  55. local z = bytes2word(data[5], data[6], data[7], data[8]);
  56. local delta = 0x9e3779b9;
  57. local sum = 0xc6ef3720; --AND(delta*32,0xFFFFFFFF);
  58. local k0 = bytes2word(key[ 1], key[ 2], key[ 3], key[ 4]);
  59. local k1 = bytes2word(key[ 5], key[ 6], key[ 7], key[ 8]);
  60. local k2 = bytes2word(key[ 9], key[10], key[11], key[12]);
  61. local k3 = bytes2word(key[13], key[14], key[15], key[16]);
  62. local k = {[0] = k0, k1, k2, k3};
  63. for _ = 1, 32 do
  64. local temp;
  65. temp = XOR(LSHIFT(y, 4), RSHIFT(y, 5)) + y
  66. temp = XOR(temp, sum + k[ AND(RSHIFT(sum, 11), 0x3) ])
  67. z = AND(z + 0x100000000 - temp, 0xFFFFFFFF);
  68. sum = AND(sum + 0x100000000 - delta, 0xFFFFFFFF);
  69. temp = XOR(LSHIFT(z, 4), RSHIFT(z, 5)) + z
  70. temp = XOR(temp, sum + k[ AND(sum, 0x3) ])
  71. y = AND(y + 0x100000000 - temp, 0xFFFFFFFF);
  72. end
  73. local out = {};
  74. out[1], out[2], out[3], out[4] = word2bytes(y);
  75. out[5], out[6], out[7], out[8] = word2bytes(z);
  76. return out;
  77. end
  78. return XTEA;