diff options
author | Legrandin <gooksankoo@hoiptorrow.mailexpire.com> | 2012-06-20 23:35:07 +0200 |
---|---|---|
committer | Legrandin <gooksankoo@hoiptorrow.mailexpire.com> | 2012-06-20 23:35:07 +0200 |
commit | bf24d2907edb2e0dd2eede63b8679b8bdfdc96b7 (patch) | |
tree | d6d8b29c81d3b868bfccada1a51d8d96e9875af5 /lib | |
parent | 63a45be86bc9d9a94116f359e6bd22103009bb5b (diff) | |
download | pycrypto-bf24d2907edb2e0dd2eede63b8679b8bdfdc96b7.tar.gz |
Added ARC4-drop[n] cipher
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Crypto/Cipher/ARC4.py | 21 | ||||
-rw-r--r-- | lib/Crypto/SelfTest/Cipher/test_ARC4.py | 20 |
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__': |