| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- local Array = require("lockbox.util.array");
- local Stream = require("lockbox.util.stream");
- local Queue = require("lockbox.util.queue");
- local CFB = {};
- CFB.Cipher = function()
- local public = {};
- local key;
- local blockCipher;
- local padding;
- local inputQueue;
- local outputQueue;
- local iv;
- public.setKey = function(keyBytes)
- key = keyBytes;
- return public;
- end
- public.setBlockCipher = function(cipher)
- blockCipher = cipher;
- return public;
- end
- public.setPadding = function(paddingMode)
- padding = paddingMode;
- return public;
- end
- public.init = function()
- inputQueue = Queue();
- outputQueue = Queue();
- iv = nil;
- return public;
- end
- public.update = function(messageStream)
- local byte = messageStream();
- while (byte ~= nil) do
- inputQueue.push(byte);
- if(inputQueue.size() >= blockCipher.blockSize) then
- local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);
- if(iv == nil) then
- iv = block;
- else
- local out = iv;
- out = blockCipher.encrypt(key, out);
- out = Array.XOR(out, block);
- Array.writeToQueue(outputQueue, out);
- iv = out;
- end
- end
- byte = messageStream();
- end
- return public;
- end
- public.finish = function()
- local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());
- public.update(paddingStream);
- return public;
- end
- public.getOutputQueue = function()
- return outputQueue;
- end
- public.asHex = function()
- return Stream.toHex(outputQueue.pop);
- end
- public.asBytes = function()
- return Stream.toArray(outputQueue.pop);
- end
- public.asString = function()
- return Stream.toString(outputQueue.pop);
- end
- return public;
- end
- CFB.Decipher = function()
- local public = {};
- local key;
- local blockCipher;
- local padding;
- local inputQueue;
- local outputQueue;
- local iv;
- public.setKey = function(keyBytes)
- key = keyBytes;
- return public;
- end
- public.setBlockCipher = function(cipher)
- blockCipher = cipher;
- return public;
- end
- public.setPadding = function(paddingMode)
- padding = paddingMode;
- return public;
- end
- public.init = function()
- inputQueue = Queue();
- outputQueue = Queue();
- iv = nil;
- return public;
- end
- public.update = function(messageStream)
- local byte = messageStream();
- while (byte ~= nil) do
- inputQueue.push(byte);
- if(inputQueue.size() >= blockCipher.blockSize) then
- local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);
- if(iv == nil) then
- iv = block;
- else
- local out = iv;
- out = blockCipher.encrypt(key, out);
- out = Array.XOR(out, block);
- Array.writeToQueue(outputQueue, out);
- iv = block;
- end
- end
- byte = messageStream();
- end
- return public;
- end
- public.finish = function()
- local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());
- public.update(paddingStream);
- return public;
- end
- public.getOutputQueue = function()
- return outputQueue;
- end
- public.asHex = function()
- return Stream.toHex(outputQueue.pop);
- end
- public.asBytes = function()
- return Stream.toArray(outputQueue.pop);
- end
- public.asString = function()
- return Stream.toString(outputQueue.pop);
- end
- return public;
- end
- return CFB;
|