ige.lua 4.4 KB

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