pcbc.lua 4.1 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 PCBC = {};
  5. PCBC.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 = block;
  41. out = Array.XOR(iv, out);
  42. out = blockCipher.encrypt(key, out);
  43. iv = Array.XOR(out, block);
  44. Array.writeToQueue(outputQueue, out);
  45. end
  46. end
  47. byte = messageStream();
  48. end
  49. return public;
  50. end
  51. public.finish = function()
  52. local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());
  53. public.update(paddingStream);
  54. return public;
  55. end
  56. public.getOutputQueue = function()
  57. return outputQueue;
  58. end
  59. public.asHex = function()
  60. return Stream.toHex(outputQueue.pop);
  61. end
  62. public.asBytes = function()
  63. return Stream.toArray(outputQueue.pop);
  64. end
  65. public.asString = function()
  66. return Stream.toString(outputQueue.pop);
  67. end
  68. return public;
  69. end
  70. PCBC.Decipher = function()
  71. local public = {};
  72. local key;
  73. local blockCipher;
  74. local padding;
  75. local inputQueue;
  76. local outputQueue;
  77. local iv;
  78. public.setKey = function(keyBytes)
  79. key = keyBytes;
  80. return public;
  81. end
  82. public.setBlockCipher = function(cipher)
  83. blockCipher = cipher;
  84. return public;
  85. end
  86. public.setPadding = function(paddingMode)
  87. padding = paddingMode;
  88. return public;
  89. end
  90. public.init = function()
  91. inputQueue = Queue();
  92. outputQueue = Queue();
  93. iv = nil;
  94. return public;
  95. end
  96. public.update = function(messageStream)
  97. local byte = messageStream();
  98. while (byte ~= nil) do
  99. inputQueue.push(byte);
  100. if(inputQueue.size() >= blockCipher.blockSize) then
  101. local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);
  102. if(iv == nil) then
  103. iv = block;
  104. else
  105. local out = block;
  106. out = blockCipher.decrypt(key, out);
  107. out = Array.XOR(iv, out);
  108. Array.writeToQueue(outputQueue, out);
  109. iv = Array.XOR(out, block);
  110. end
  111. end
  112. byte = messageStream();
  113. end
  114. return public;
  115. end
  116. public.finish = function()
  117. local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());
  118. public.update(paddingStream);
  119. return public;
  120. end
  121. public.getOutputQueue = function()
  122. return outputQueue;
  123. end
  124. public.asHex = function()
  125. return Stream.toHex(outputQueue.pop);
  126. end
  127. public.asBytes = function()
  128. return Stream.toArray(outputQueue.pop);
  129. end
  130. public.asString = function()
  131. return Stream.toString(outputQueue.pop);
  132. end
  133. return public;
  134. end
  135. return PCBC;