cbc.lua 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. local Array = require("lockbox.util.array");
  2. local Stream = require("lockbox.util.stream");
  3. local Queue = require("lockbox.util.queue");
  4. local CBC = {};
  5. CBC.Cipher = function()
  6. local public = {};
  7. local key;
  8. local blockCipher;
  9. local padding;
  10. local inputQueue;
  11. local outputQueue;
  12. local iv;
  13. public.setKey = function(keyBytes)
  14. key = keyBytes;
  15. return public;
  16. end
  17. public.setBlockCipher = function(cipher)
  18. blockCipher = cipher;
  19. return public;
  20. end
  21. public.setPadding = function(paddingMode)
  22. padding = paddingMode;
  23. return public;
  24. end
  25. public.init = function()
  26. inputQueue = Queue();
  27. outputQueue = Queue();
  28. iv = nil;
  29. return public;
  30. end
  31. public.update = function(messageStream)
  32. local byte = messageStream();
  33. while (byte ~= nil) do
  34. inputQueue.push(byte);
  35. if(inputQueue.size() >= blockCipher.blockSize) then
  36. local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);
  37. if(iv == nil) then
  38. iv = block;
  39. else
  40. local out = Array.XOR(iv, block);
  41. out = blockCipher.encrypt(key, out);
  42. Array.writeToQueue(outputQueue, out);
  43. iv = out;
  44. end
  45. end
  46. byte = messageStream();
  47. end
  48. return public;
  49. end
  50. public.finish = function()
  51. local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());
  52. public.update(paddingStream);
  53. return public;
  54. end
  55. public.getOutputQueue = function()
  56. return outputQueue;
  57. end
  58. public.asHex = function()
  59. return Stream.toHex(outputQueue.pop);
  60. end
  61. public.asBytes = function()
  62. return Stream.toArray(outputQueue.pop);
  63. end
  64. public.asString = function()
  65. return Stream.toString(outputQueue.pop);
  66. end
  67. return public;
  68. end
  69. CBC.Decipher = function()
  70. local public = {};
  71. local key;
  72. local blockCipher;
  73. local padding;
  74. local inputQueue;
  75. local outputQueue;
  76. local iv;
  77. public.setKey = function(keyBytes)
  78. key = keyBytes;
  79. return public;
  80. end
  81. public.setBlockCipher = function(cipher)
  82. blockCipher = cipher;
  83. return public;
  84. end
  85. public.setPadding = function(paddingMode)
  86. padding = paddingMode;
  87. return public;
  88. end
  89. public.init = function()
  90. inputQueue = Queue();
  91. outputQueue = Queue();
  92. iv = nil;
  93. return public;
  94. end
  95. public.update = function(messageStream)
  96. local byte = messageStream();
  97. while (byte ~= nil) do
  98. inputQueue.push(byte);
  99. if(inputQueue.size() >= blockCipher.blockSize) then
  100. local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);
  101. if(iv == nil) then
  102. iv = block;
  103. else
  104. local out = block;
  105. out = blockCipher.decrypt(key, out);
  106. out = Array.XOR(iv, out);
  107. Array.writeToQueue(outputQueue, out);
  108. iv = block;
  109. end
  110. end
  111. byte = messageStream();
  112. end
  113. return public;
  114. end
  115. public.finish = function()
  116. local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());
  117. public.update(paddingStream);
  118. return public;
  119. end
  120. public.getOutputQueue = function()
  121. return outputQueue;
  122. end
  123. public.asHex = function()
  124. return Stream.toHex(outputQueue.pop);
  125. end
  126. public.asBytes = function()
  127. return Stream.toArray(outputQueue.pop);
  128. end
  129. public.asString = function()
  130. return Stream.toString(outputQueue.pop);
  131. end
  132. return public;
  133. end
  134. return CBC;