arciv.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #copyright ReportLab Europe Limited. 2000-2016
  2. #see license.txt for license details
  3. '''
  4. Arciv Stream ciphering
  5. '''
  6. __all__='''ArcIV encode decode'''.split()
  7. __version__="1.0"
  8. from reportlab.lib.utils import isUnicode
  9. class ArcIV:
  10. '''
  11. performs 'ArcIV' Stream Encryption of S using key
  12. Based on what is widely thought to be RSA's ArcIV algorithm.
  13. It produces output streams that are identical.
  14. NB there is no separate decoder arciv(arciv(s,key),key) == s
  15. '''
  16. def __init__(self,key):
  17. self._key = key
  18. self.reset()
  19. def reset(self):
  20. '''restore the cipher to it's start state'''
  21. #Initialize private key, k With the values of the key mod 256.
  22. #and sbox With numbers 0 - 255. Then compute sbox
  23. key = self._key
  24. if isUnicode(key): key = key.encode('utf8')
  25. sbox = list(range(256))
  26. k = list(range(256))
  27. lk = len(key)
  28. for i in sbox:
  29. k[i] = key[i % lk] % 256
  30. #Re-order sbox using the private key, k.
  31. #Iterating each element of sbox re-calculate the counter j
  32. #Then interchange the elements sbox[a] & sbox[b]
  33. j = 0
  34. for i in range(256):
  35. j = (j+sbox[i]+k[i]) % 256
  36. sbox[i], sbox[j] = sbox[j], sbox[i]
  37. self._sbox, self._i, self._j = sbox, 0, 0
  38. def _encode(self, B):
  39. '''
  40. return the list of encoded bytes of B, B might be a string or a
  41. list of integers between 0 <= i <= 255
  42. '''
  43. sbox, i, j = self._sbox, self._i, self._j
  44. C = list(B.encode('utf8')) if isinstance(B,str) else (list(B) if isinstance(B,bytes) else B[:])
  45. n = len(C)
  46. p = 0
  47. while p<n:
  48. #update the variables i, j.
  49. self._i = i = (i + 1) % 256
  50. self._j = j = (j + sbox[i]) % 256
  51. #swap sbox[i] and sbox[j]
  52. sbox[i], sbox[j] = sbox[j], sbox[i]
  53. #overwrite the plaintext with the ciphered byte
  54. C[p] = C[p] ^ sbox[(sbox[i] + sbox[j]) % 256]
  55. p += 1
  56. return C
  57. def encode(self,S):
  58. 'ArcIV encode string S'
  59. return bytes(self._encode(S))
  60. _TESTS=[{
  61. 'key': b"\x01\x23\x45\x67\x89\xab\xcd\xef",
  62. 'input': b"\x01\x23\x45\x67\x89\xab\xcd\xef",
  63. 'output': b"\x75\xb7\x87\x80\x99\xe0\xc5\x96",
  64. },
  65. {
  66. 'key': b"\x01\x23\x45\x67\x89\xab\xcd\xef",
  67. 'input': b"\x00\x00\x00\x00\x00\x00\x00\x00",
  68. 'output': b"\x74\x94\xc2\xe7\x10\x4b\x08\x79",
  69. },
  70. {
  71. 'key': b"\x00\x00\x00\x00\x00\x00\x00\x00",
  72. 'input': b"\x00\x00\x00\x00\x00\x00\x00\x00",
  73. 'output': b"\xde\x18\x89\x41\xa3\x37\x5d\x3a",
  74. },
  75. {
  76. 'key': b"\xef\x01\x23\x45",
  77. 'input': b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
  78. 'output': b"\xd6\xa1\x41\xa7\xec\x3c\x38\xdf\xbd\x61",
  79. },
  80. {
  81. 'key': b"\x01\x23\x45\x67\x89\xab\xcd\xef",
  82. 'input': b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  83. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  84. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  85. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  86. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  87. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  88. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  89. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  90. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  91. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  92. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  93. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  94. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  95. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  96. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  97. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  98. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  99. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  100. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  101. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  102. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  103. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  104. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  105. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  106. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  107. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  108. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  109. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  110. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  111. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  112. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  113. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  114. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  115. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  116. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  117. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  118. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  119. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  120. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  121. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  122. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  123. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  124. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  125. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  126. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  127. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  128. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  129. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  130. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  131. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  132. \x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\
  133. \x01",
  134. 'output': b"\x75\x95\xc3\xe6\x11\x4a\x09\x78\x0c\x4a\xd4\
  135. \x52\x33\x8e\x1f\xfd\x9a\x1b\xe9\x49\x8f\
  136. \x81\x3d\x76\x53\x34\x49\xb6\x77\x8d\xca\
  137. \xd8\xc7\x8a\x8d\x2b\xa9\xac\x66\x08\x5d\
  138. \x0e\x53\xd5\x9c\x26\xc2\xd1\xc4\x90\xc1\
  139. \xeb\xbe\x0c\xe6\x6d\x1b\x6b\x1b\x13\xb6\
  140. \xb9\x19\xb8\x47\xc2\x5a\x91\x44\x7a\x95\
  141. \xe7\x5e\x4e\xf1\x67\x79\xcd\xe8\xbf\x0a\
  142. \x95\x85\x0e\x32\xaf\x96\x89\x44\x4f\xd3\
  143. \x77\x10\x8f\x98\xfd\xcb\xd4\xe7\x26\x56\
  144. \x75\x00\x99\x0b\xcc\x7e\x0c\xa3\xc4\xaa\
  145. \xa3\x04\xa3\x87\xd2\x0f\x3b\x8f\xbb\xcd\
  146. \x42\xa1\xbd\x31\x1d\x7a\x43\x03\xdd\xa5\
  147. \xab\x07\x88\x96\xae\x80\xc1\x8b\x0a\xf6\
  148. \x6d\xff\x31\x96\x16\xeb\x78\x4e\x49\x5a\
  149. \xd2\xce\x90\xd7\xf7\x72\xa8\x17\x47\xb6\
  150. \x5f\x62\x09\x3b\x1e\x0d\xb9\xe5\xba\x53\
  151. \x2f\xaf\xec\x47\x50\x83\x23\xe6\x71\x32\
  152. \x7d\xf9\x44\x44\x32\xcb\x73\x67\xce\xc8\
  153. \x2f\x5d\x44\xc0\xd0\x0b\x67\xd6\x50\xa0\
  154. \x75\xcd\x4b\x70\xde\xdd\x77\xeb\x9b\x10\
  155. \x23\x1b\x6b\x5b\x74\x13\x47\x39\x6d\x62\
  156. \x89\x74\x21\xd4\x3d\xf9\xb4\x2e\x44\x6e\
  157. \x35\x8e\x9c\x11\xa9\xb2\x18\x4e\xcb\xef\
  158. \x0c\xd8\xe7\xa8\x77\xef\x96\x8f\x13\x90\
  159. \xec\x9b\x3d\x35\xa5\x58\x5c\xb0\x09\x29\
  160. \x0e\x2f\xcd\xe7\xb5\xec\x66\xd9\x08\x4b\
  161. \xe4\x40\x55\xa6\x19\xd9\xdd\x7f\xc3\x16\
  162. \x6f\x94\x87\xf7\xcb\x27\x29\x12\x42\x64\
  163. \x45\x99\x85\x14\xc1\x5d\x53\xa1\x8c\x86\
  164. \x4c\xe3\xa2\xb7\x55\x57\x93\x98\x81\x26\
  165. \x52\x0e\xac\xf2\xe3\x06\x6e\x23\x0c\x91\
  166. \xbe\xe4\xdd\x53\x04\xf5\xfd\x04\x05\xb3\
  167. \x5b\xd9\x9c\x73\x13\x5d\x3d\x9b\xc3\x35\
  168. \xee\x04\x9e\xf6\x9b\x38\x67\xbf\x2d\x7b\
  169. \xd1\xea\xa5\x95\xd8\xbf\xc0\x06\x6f\xf8\
  170. \xd3\x15\x09\xeb\x0c\x6c\xaa\x00\x6c\x80\
  171. \x7a\x62\x3e\xf8\x4c\x3d\x33\xc1\x95\xd2\
  172. \x3e\xe3\x20\xc4\x0d\xe0\x55\x81\x57\xc8\
  173. \x22\xd4\xb8\xc5\x69\xd8\x49\xae\xd5\x9d\
  174. \x4e\x0f\xd7\xf3\x79\x58\x6b\x4b\x7f\xf6\
  175. \x84\xed\x6a\x18\x9f\x74\x86\xd4\x9b\x9c\
  176. \x4b\xad\x9b\xa2\x4b\x96\xab\xf9\x24\x37\
  177. \x2c\x8a\x8f\xff\xb1\x0d\x55\x35\x49\x00\
  178. \xa7\x7a\x3d\xb5\xf2\x05\xe1\xb9\x9f\xcd\
  179. \x86\x60\x86\x3a\x15\x9a\xd4\xab\xe4\x0f\
  180. \xa4\x89\x34\x16\x3d\xdd\xe5\x42\xa6\x58\
  181. \x55\x40\xfd\x68\x3c\xbf\xd8\xc0\x0f\x12\
  182. \x12\x9a\x28\x4d\xea\xcc\x4c\xde\xfe\x58\
  183. \xbe\x71\x37\x54\x1c\x04\x71\x26\xc8\xd4\
  184. \x9e\x27\x55\xab\x18\x1a\xb7\xe9\x40\xb0\
  185. \xc0",
  186. },
  187. ]
  188. def encode(text, key):
  189. "One-line shortcut for making an encoder object"
  190. return ArcIV(key).encode(text)
  191. def decode(text, key):
  192. "One-line shortcut for decoding"
  193. # yes, encode and decode are symmetric - see docstring
  194. return ArcIV(key).encode(text)
  195. if __name__=='__main__':
  196. i = 0
  197. for t in _TESTS:
  198. o = ArcIV(t['key']).encode(t['input'])
  199. o = ArcIV(t['key']).encode(t['output'])
  200. i += 1