pbkdf2.lua 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. local Bit = require("lockbox.util.bit");
  2. local Array = require("lockbox.util.array");
  3. local Stream = require("lockbox.util.stream");
  4. local Math = require("math");
  5. local AND = Bit.band;
  6. local RSHIFT = Bit.rshift;
  7. local word2bytes = function(word)
  8. local b0, b1, b2, b3;
  9. b3 = AND(word, 0xFF); word = RSHIFT(word, 8);
  10. b2 = AND(word, 0xFF); word = RSHIFT(word, 8);
  11. b1 = AND(word, 0xFF); word = RSHIFT(word, 8);
  12. b0 = AND(word, 0xFF);
  13. return b0, b1, b2, b3;
  14. end
  15. local PBKDF2 = function()
  16. local public = {};
  17. local blockLen = 16;
  18. local dKeyLen = 256;
  19. local iterations = 4096;
  20. local salt;
  21. local password;
  22. local PRF;
  23. local dKey;
  24. public.setBlockLen = function(len)
  25. blockLen = len;
  26. return public;
  27. end
  28. public.setDKeyLen = function(len)
  29. dKeyLen = len
  30. return public;
  31. end
  32. public.setIterations = function(iter)
  33. iterations = iter;
  34. return public;
  35. end
  36. public.setSalt = function(saltBytes)
  37. salt = saltBytes;
  38. return public;
  39. end
  40. public.setPassword = function(passwordBytes)
  41. password = passwordBytes;
  42. return public;
  43. end
  44. public.setPRF = function(prf)
  45. PRF = prf;
  46. return public;
  47. end
  48. local buildBlock = function(i)
  49. local b0, b1, b2, b3 = word2bytes(i);
  50. local ii = {b0, b1, b2, b3};
  51. local s = Array.concat(salt, ii);
  52. local out = {};
  53. PRF.setKey(password);
  54. for c = 1, iterations do
  55. PRF.init()
  56. .update(Stream.fromArray(s));
  57. s = PRF.finish().asBytes();
  58. if(c > 1) then
  59. out = Array.XOR(out, s);
  60. else
  61. out = s;
  62. end
  63. end
  64. return out;
  65. end
  66. public.finish = function()
  67. local blocks = Math.ceil(dKeyLen / blockLen);
  68. dKey = {};
  69. for b = 1, blocks do
  70. local block = buildBlock(b);
  71. dKey = Array.concat(dKey, block);
  72. end
  73. if(Array.size(dKey) > dKeyLen) then dKey = Array.truncate(dKey, dKeyLen); end
  74. return public;
  75. end
  76. public.asBytes = function()
  77. return dKey;
  78. end
  79. public.asHex = function()
  80. return Array.toHex(dKey);
  81. end
  82. public.asString = function()
  83. return Array.toString(dKey);
  84. end
  85. return public;
  86. end
  87. return PBKDF2;