summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLegrandin <gooksankoo@hoiptorrow.mailexpire.com>2012-06-20 23:35:07 +0200
committerLegrandin <gooksankoo@hoiptorrow.mailexpire.com>2012-06-20 23:35:07 +0200
commitbf24d2907edb2e0dd2eede63b8679b8bdfdc96b7 (patch)
treed6d8b29c81d3b868bfccada1a51d8d96e9875af5 /lib
parent63a45be86bc9d9a94116f359e6bd22103009bb5b (diff)
downloadpycrypto-bf24d2907edb2e0dd2eede63b8679b8bdfdc96b7.tar.gz
Added ARC4-drop[n] cipher
Diffstat (limited to 'lib')
-rw-r--r--lib/Crypto/Cipher/ARC4.py21
-rw-r--r--lib/Crypto/SelfTest/Cipher/test_ARC4.py20
2 files changed, 41 insertions, 0 deletions
diff --git a/lib/Crypto/Cipher/ARC4.py b/lib/Crypto/Cipher/ARC4.py
index b745e7c..48d39f1 100644
--- a/lib/Crypto/Cipher/ARC4.py
+++ b/lib/Crypto/Cipher/ARC4.py
@@ -63,6 +63,7 @@ As an example, encryption can be done as follows:
__revision__ = "$Id$"
+from Crypto.Util.py3compat import *
from Crypto.Cipher import _ARC4
class ARC4Cipher:
@@ -74,7 +75,18 @@ class ARC4Cipher:
See also `new()` at the module level."""
+ if len(args)>0:
+ ndrop = args[0]
+ args = args[1:]
+ else:
+ ndrop = kwargs.get('drop', 0)
+ if ndrop: del kwargs['drop']
self._cipher = _ARC4.new(key, *args, **kwargs)
+ if ndrop:
+ # This is OK even if the cipher is used for decryption, since encrypt
+ # and decrypt are actually the same thing with ARC4.
+ self._cipher.encrypt(b('\x00')*ndrop)
+
self.block_size = self._cipher.block_size
self.key_size = self._cipher.key_size
@@ -108,8 +120,17 @@ def new(key, *args, **kwargs):
The secret key to use in the symmetric cipher.
It can have any length, with a minimum of 40 bytes.
Its cryptograpic strength is always capped to 2048 bits (256 bytes).
+ :Keywords:
+ drop : integer
+ The amount of bytes to discard from the initial part of the keystream.
+ In fact, such part has been found to be distinguishable from random
+ data (while it shouldn't) and also correlated to key.
+
+ The recommended value is 3072_ bytes. The default value is 0.
:Return: an `ARC4Cipher` object
+
+ .. _3072: http://eprint.iacr.org/2002/067.pdf
"""
return ARC4Cipher(key, *args, **kwargs)
diff --git a/lib/Crypto/SelfTest/Cipher/test_ARC4.py b/lib/Crypto/SelfTest/Cipher/test_ARC4.py
index 1c5ed90..801d2cb 100644
--- a/lib/Crypto/SelfTest/Cipher/test_ARC4.py
+++ b/lib/Crypto/SelfTest/Cipher/test_ARC4.py
@@ -423,10 +423,30 @@ class RFC6229_Tests(unittest.TestCase):
count += 1
self.assertEqual(count, len(tv[1]))
+class Drop_Tests(unittest.TestCase):
+ key = b('\xAA')*16
+ data = b('\x00')*5000
+
+ def setUp(self):
+ self.cipher = ARC4.new(self.key)
+
+ def test_drop256_encrypt(self):
+ cipher_drop = ARC4.new(self.key, 256)
+ ct_drop = cipher_drop.encrypt(self.data[:16])
+ ct = self.cipher.encrypt(self.data)[256:256+16]
+ self.assertEquals(ct_drop, ct)
+
+ def test_drop256_decrypt(self):
+ cipher_drop = ARC4.new(self.key, 256)
+ pt_drop = cipher_drop.decrypt(self.data[:16])
+ pt = self.cipher.decrypt(self.data)[256:256+16]
+ self.assertEquals(pt_drop, pt)
+
def get_tests(config={}):
from common import make_stream_tests
tests = make_stream_tests(ARC4, "ARC4", test_data)
tests += list_test_cases(RFC6229_Tests)
+ tests += list_test_cases(Drop_Tests)
return tests
if __name__ == '__main__':