1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch# Author: Trevor Perrin
2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch# See the LICENSE file for legal information regarding use of this file.
3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Pure-Python RC4 implementation."""
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfrom .rc4 import RC4
7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfrom .cryptomath import *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def new(key):
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Python_RC4(key)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Python_RC4(RC4):
13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    def __init__(self, keyBytes):
14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        RC4.__init__(self, keyBytes, "python")
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        S = [i for i in range(256)]
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        j = 0
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for i in range(256):
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            j = (j + S[i] + keyBytes[i % len(keyBytes)]) % 256
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            S[i], S[j] = S[j], S[i]
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.S = S
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.i = 0
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.j = 0
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    def encrypt(self, plaintextBytes):
26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        ciphertextBytes = plaintextBytes[:]
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        S = self.S
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        i = self.i
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        j = self.j
30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        for x in range(len(ciphertextBytes)):
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            i = (i + 1) % 256
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            j = (j + S[i]) % 256
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            S[i], S[j] = S[j], S[i]
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            t = (S[i] + S[j]) % 256
35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            ciphertextBytes[x] ^= S[t]
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.i = i
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.j = j
38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        return ciphertextBytes
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def decrypt(self, ciphertext):
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return self.encrypt(ciphertext)
42