diff options
author | Camil Staps | 2015-04-29 16:09:07 +0200 |
---|---|---|
committer | Camil Staps | 2015-04-29 16:09:07 +0200 |
commit | 5b49333e6b2415deb65dfef3b2153183ad3bd483 (patch) | |
tree | f7e7f5837cc8833d7143d5597213f996468ccd8f | |
parent | Changelog (diff) |
python3 works as well now
-rw-r--r-- | pypride.py | 42 | ||||
-rwxr-xr-x | test-vectors.py | 37 |
2 files changed, 39 insertions, 40 deletions
@@ -56,6 +56,8 @@ This implementation is fully based on the report PRIDE was presented in (https:/ Test vectors can be found in test-vectors.py and were taken from appendix J of that paper. """ +import binascii, sys + class Pride: def __init__(self,key): @@ -64,9 +66,9 @@ class Pride: Input: the key as a 128-bit raw string""" if len(key) != 16: - raise ValueError, "Key must be a 128-bit raw string" + raise ValueError("Key must be a 128-bit raw string") self.whitening_key = string2number(key[:8]) - self.roundkeys = [roundKey(key[8:], i) for i in xrange(0,21)] + self.roundkeys = [roundKey(key[8:], i) for i in range(0,21)] def encrypt(self,block): """Encrypt 1 block (8 bytes) @@ -80,7 +82,7 @@ class Pride: state = pLayer_dec(state) state = addRoundKey(state, self.whitening_key) # 19 rounds R - for i in xrange (1,20): + for i in range (1,20): state = addRoundKey(state, self.roundkeys[i]) state = sBoxLayer(state) state = lLayer(state) @@ -108,7 +110,7 @@ class Pride: state = sBoxLayer_dec(state) state = addRoundKey(state, self.roundkeys[20]) # 19 rounds R - for i in xrange(19,0,-1): + for i in range(19,0,-1): state = lLayer_dec(state) state = sBoxLayer_dec(state) state = addRoundKey(state, self.roundkeys[i]) @@ -120,11 +122,11 @@ class Pride: # 4 to 4-bit S-Box and its inverse Sbox= [0x0,0x4,0x8,0xf,0x1,0x5,0xe,0x9,0x2,0x7,0xa,0xc,0xb,0xd,0x6,0x3] -Sbox_inv = [Sbox.index(x) for x in xrange(16)] +Sbox_inv = [Sbox.index(x) for x in range(16)] # 64-bit permutation P and its inverse PBox = [0, 16, 32, 48, 1, 17, 33, 49, 2, 18, 34, 50, 3, 19, 35, 51, 4, 20, 36, 52, 5, 21, 37, 53, 6, 22, 38, 54, 7, 23, 39, 55, 8, 24, 40, 56, 9, 25, 41, 57, 10, 26, 42, 58, 11, 27, 43, 59, 12, 28, 44, 60, 13, 29, 45, 61, 14, 30, 46, 62, 15, 31, 47, 63] -PBox_inv = [PBox.index(x) for x in xrange(64)] +PBox_inv = [PBox.index(x) for x in range(64)] def swap(byte): """Swap byte nibbles""" @@ -187,16 +189,9 @@ def roundKey(key, i): the round number Output: the round key as raw string""" - return pLayer_dec(string2number( - key[0] - + chr((ord(key[1]) + 193 * i) % 256) - + key[2] - + chr((ord(key[3]) + 165 * i) % 256) - + key[4] - + chr((ord(key[5]) + 81 * i) % 256) - + key[6] - + chr((ord(key[7]) + 197 * i) % 256) - )) + key = string_bytes(key) + key_parts = [key[0], (key[1] + 193 * i) % 256, key[2], (key[3] + 165 * i) % 256, key[4], (key[5] + 81 * i) % 256, key[6], (key[7] + 197 * i) % 256] + return pLayer_dec(sum([(1 << (8 * (7-i))) * k for i, k in enumerate(key_parts)])) def addRoundKey(state,roundkey): return state ^ roundkey @@ -207,7 +202,7 @@ def sBoxLayer(state): Input: 64-bit integer Output: 64-bit integer""" - return sum([Sbox[( state >> (i * 4)) & 0xf] << (i * 4) for i in xrange(16)]) + return sum([Sbox[( state >> (i * 4)) & 0xf] << (i * 4) for i in range(16)]) def sBoxLayer_dec(state): """Inverse SBox function for decryption @@ -215,7 +210,7 @@ def sBoxLayer_dec(state): Input: 64-bit integer Output: 64-bit integer""" - return sum([Sbox_inv[( state >> (i * 4)) & 0xf] << (i * 4) for i in xrange(16)]) + return sum([Sbox_inv[( state >> (i * 4)) & 0xf] << (i * 4) for i in range(16)]) def pLayer(state): """Permutation layer for encryption @@ -223,7 +218,7 @@ def pLayer(state): Input: 64-bit integer Output: 64-bit integer""" - return sum ([((state >> i) & 1) << PBox[i] for i in xrange(64)]) + return sum ([((state >> i) & 1) << PBox[i] for i in range(64)]) def pLayer_dec(state): """Permutation layer for decryption @@ -231,7 +226,7 @@ def pLayer_dec(state): Input: 64-bit integer Output: 64-bit integer""" - return sum ([((state >> i) & 1) << PBox_inv[i] for i in xrange(64)]) + return sum ([((state >> i) & 1) << PBox_inv[i] for i in range(64)]) def lLayer(state): """Perform the L layer: @@ -271,7 +266,7 @@ def string2number(i): Input: string (big-endian) Output: long or integer """ - return int(i.encode('hex'), 16) + return int(binascii.hexlify(i), 16) def number2string_N(i, N): """Convert a number to a string of fixed size @@ -281,4 +276,7 @@ def number2string_N(i, N): Output: string (big-endian) """ s = '%0*x' % (N*2, i) - return s.decode('hex') + return binascii.unhexlify(s) + +def string_bytes(s): + return [ord(c) for c in s] if sys.version_info.major == 2 else s
\ No newline at end of file diff --git a/test-vectors.py b/test-vectors.py index 55e6a26..a6bcae8 100755 --- a/test-vectors.py +++ b/test-vectors.py @@ -22,14 +22,15 @@ from pypride import Pride import time +import binascii def test(): test_vectors = [ - {'key': "00000000000000000000000000000000", 'plaintext': "0000000000000000", 'ciphertext': "82b4109fcc70bd1f"}, - {'key': "00000000000000000000000000000000", 'plaintext': "ffffffffffffffff", 'ciphertext': "d70e60680a17b956"}, - {'key': "ffffffffffffffff0000000000000000", 'plaintext': "0000000000000000", 'ciphertext': "28f19f97f5e846a9"}, - {'key': "0000000000000000ffffffffffffffff", 'plaintext': "0000000000000000", 'ciphertext': "d123ebaf368fce62"}, - {'key': "0000000000000000fedcba9876543210", 'plaintext': "0123456789abcdef", 'ciphertext': "d1372929712d336e"} + {'key': '00000000000000000000000000000000', 'plaintext': '0000000000000000', 'ciphertext': '82b4109fcc70bd1f'}, + {'key': '00000000000000000000000000000000', 'plaintext': 'ffffffffffffffff', 'ciphertext': 'd70e60680a17b956'}, + {'key': 'ffffffffffffffff0000000000000000', 'plaintext': '0000000000000000', 'ciphertext': '28f19f97f5e846a9'}, + {'key': '0000000000000000ffffffffffffffff', 'plaintext': '0000000000000000', 'ciphertext': 'd123ebaf368fce62'}, + {'key': '0000000000000000fedcba9876543210', 'plaintext': '0123456789abcdef', 'ciphertext': 'd1372929712d336e'} ] time_cipher = 0 @@ -38,37 +39,37 @@ def test(): all_passed = True - for _ in xrange(100): + for _ in range(100): for v_i, vector in enumerate(test_vectors): - key = vector['key'].decode('hex') + key = binascii.unhexlify(vector['key']) start = time.time() cipher = Pride(key) time_cipher += time.time() - start - plaintext = vector['plaintext'].decode('hex') + plaintext = binascii.unhexlify(vector['plaintext']) start = time.time() encryption = cipher.encrypt(plaintext) time_encrypt += time.time() - start - ciphertext = vector['ciphertext'].decode('hex') + ciphertext = binascii.unhexlify(vector['ciphertext']) start = time.time() decryption = cipher.decrypt(ciphertext) time_decrypt += time.time() - start - if encryption != vector['ciphertext'].decode('hex'): - print "Encryption for vector", v_i, "failed: was", encryption.encode('hex'), "; should have been", vector['ciphertext'] + if encryption != binascii.unhexlify(vector['ciphertext']): + print('Encryption for vector ' + str(v_i) + ' failed: was ' + str(binascii.hexlify(encryption)) + '; should have been ' + vector['ciphertext']) all_passed = False - if decryption != vector['plaintext'].decode('hex'): - print "Decryption for vector", v_i, "failed: was", decryption.encode('hex'), "; should have been", vector['plaintext'] + if decryption != binascii.unhexlify(vector['plaintext']): + print('Decryption for vector ' + str(v_i) + ' failed: was ' + str(binascii.hexlify(decryption)) + '; should have been ' + vector['plaintext']) all_passed = False if all_passed: - print "All tests passed." + print('All tests passed.') - print "Generating round keys:", str(time_cipher) + "s" - print "Encryption: ", str(time_encrypt) + "s" - print "Decryption: ", str(time_decrypt) + "s" + print('Generating round keys: ' + str(time_cipher) + 's') + print('Encryption: ' + str(time_encrypt) + 's') + print('Decryption: ' + str(time_decrypt) + 's') import profile -profile.run('test()')
\ No newline at end of file +profile.run('test()') |