| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- local Bit = require("lockbox.util.bit");
- local Array = require("lockbox.util.array");
- local Stream = require("lockbox.util.stream");
- local Math = require("math");
- local AND = Bit.band;
- local RSHIFT = Bit.rshift;
- 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 PBKDF2 = function()
- local public = {};
- local blockLen = 16;
- local dKeyLen = 256;
- local iterations = 4096;
- local salt;
- local password;
- local PRF;
- local dKey;
- public.setBlockLen = function(len)
- blockLen = len;
- return public;
- end
- public.setDKeyLen = function(len)
- dKeyLen = len
- return public;
- end
- public.setIterations = function(iter)
- iterations = iter;
- return public;
- end
- public.setSalt = function(saltBytes)
- salt = saltBytes;
- return public;
- end
- public.setPassword = function(passwordBytes)
- password = passwordBytes;
- return public;
- end
- public.setPRF = function(prf)
- PRF = prf;
- return public;
- end
- local buildBlock = function(i)
- local b0, b1, b2, b3 = word2bytes(i);
- local ii = {b0, b1, b2, b3};
- local s = Array.concat(salt, ii);
- local out = {};
- PRF.setKey(password);
- for c = 1, iterations do
- PRF.init()
- .update(Stream.fromArray(s));
- s = PRF.finish().asBytes();
- if(c > 1) then
- out = Array.XOR(out, s);
- else
- out = s;
- end
- end
- return out;
- end
- public.finish = function()
- local blocks = Math.ceil(dKeyLen / blockLen);
- dKey = {};
- for b = 1, blocks do
- local block = buildBlock(b);
- dKey = Array.concat(dKey, block);
- end
- if(Array.size(dKey) > dKeyLen) then dKey = Array.truncate(dKey, dKeyLen); end
- return public;
- end
- public.asBytes = function()
- return dKey;
- end
- public.asHex = function()
- return Array.toHex(dKey);
- end
- public.asString = function()
- return Array.toString(dKey);
- end
- return public;
- end
- return PBKDF2;
|