#copyright ReportLab Europe Limited. 2000-2016 #see license.txt for license details ''' Arciv Stream ciphering ''' __all__='''ArcIV encode decode'''.split() __version__="1.0" from reportlab.lib.utils import isUnicode class ArcIV: ''' performs 'ArcIV' Stream Encryption of S using key Based on what is widely thought to be RSA's ArcIV algorithm. It produces output streams that are identical. NB there is no separate decoder arciv(arciv(s,key),key) == s ''' def __init__(self,key): self._key = key self.reset() def reset(self): '''restore the cipher to it's start state''' #Initialize private key, k With the values of the key mod 256. #and sbox With numbers 0 - 255. Then compute sbox key = self._key if isUnicode(key): key = key.encode('utf8') sbox = list(range(256)) k = list(range(256)) lk = len(key) for i in sbox: k[i] = key[i % lk] % 256 #Re-order sbox using the private key, k. #Iterating each element of sbox re-calculate the counter j #Then interchange the elements sbox[a] & sbox[b] j = 0 for i in range(256): j = (j+sbox[i]+k[i]) % 256 sbox[i], sbox[j] = sbox[j], sbox[i] self._sbox, self._i, self._j = sbox, 0, 0 def _encode(self, B): ''' return the list of encoded bytes of B, B might be a string or a list of integers between 0 <= i <= 255 ''' sbox, i, j = self._sbox, self._i, self._j C = list(B.encode('utf8')) if isinstance(B,str) else (list(B) if isinstance(B,bytes) else B[:]) n = len(C) p = 0 while p