Subversion Repositories pub

Compare Revisions

Ignore whitespace Rev 182 → Rev 183

/relevation/ext/cryptopy-1.2.5.patched/crypto/cipher/arc4.py
0,0 → 1,75
""" crypto.cipher.arc4
 
A Stream Cipher Encryption Algorithm 'Arcfour'
 
A few lines of code/ideas borrowed from [PING]
[PING] CipherSaber implementation by Ka-Ping Yee <ping@lfw.org>, 5 May 2000.
 
Some documentation text and test vectors taken from [IDARC4]
[IDARCH4] K.Kaukonen, R.Thayer, "A Stream Cipher Encryption Algorithm 'Arcfour'",
ftp://ietf.org/draft-kaukonen-cipher-arcfour-03.txt
Generally munged to map to crypto.cipher calling conventions
 
Copyright © (c) 2002 by Paul A. Lambert
Read LICENSE.txt for license information.
 
November 5, 2002
"""
 
class ARC4:
""" ARC4 Stream Cipher Algorithm
"""
def __init__(self,key=None):
""" key -> octet string for key """
self.name = 'ARC4'
self.strength = None # depends on keySize
self.blockSize = 1 # blockSize is in bytes
 
if key != None:
self.setKey(key)
 
def setKey(self, key):
""" Set initial state from key. Never use the same key more than once!
"""
self.keySize = len(key)
self.strength = self.keySize # this does not include subtracting IV size :-(
i, j, self.state = 0, 0, range(256)
for i in range(256):
j = (j + self.state[i] + ord(key[i % len(key)])) % 256
self.state[i], self.state[j] = self.state[j], self.state[i]
self.keyReady = 1 # Ready
 
def encrypt(self, plainText, more = None):
""" Encrypt a string and return a binary string
multiple sequential calls can be made using more =1,
this continues the encryption
New sessions of encrypt can NOT be called twice with the same key!!!!
"""
if self.keyReady != 1 : raise 'Error, ARC4 key already used once!'
if more != 1:
self.keyReady = None
cipherText = arcfourBlock(self.state, plainText)
return cipherText
 
 
def decrypt(self, cipherText, more = None):
""" Decrypt a string and return a string """
if self.keyReady != 1 :
raise 'set for decryption required'
if more != 1:
self.keyReady = None
plainText = arcfourBlock(self.state, cipherText)
return plainText
 
 
def arcfourBlock(state, input):
""" Use state to encrypt input string, returns string """
i, j, output = 0, 0, []
for byte in input:
i = (i + 1) % 256
j = (j + state[i]) % 256
state[i], state[j] = state[j], state[i]
n = (state[i] + state[j]) % 256
output.append(chr(ord(byte) ^ state[n]))
output = ''.join(output) # convert to string
return output