Advertisement
Guest User

Untitled

a guest
Nov 30th, 2019
656
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.79 KB | None | 0 0
  1. #! /usr/bin/python
  2. # Needs Python 2.4, 2.5, 2.6 or 2.7. Doesn't work with Python 3.x.
  3.  
  4. import struct
  5.  
  6. # --- IDEA block cipher.
  7.  
  8.  
  9. def _idea_mul(a, b):
  10.   if a:
  11.     if b:
  12.       p = a * b
  13.       b, a = p & 0xffff, p >> 16
  14.       return (b - a + (b < a)) & 0xffff
  15.     else:
  16.       return (1 - a) & 0xffff
  17.   else:
  18.     return (1 - b) & 0xffff
  19.  
  20.  
  21. def _idea_inv(x):
  22.   if x <= 1:
  23.     return x
  24.   t1, y = divmod(0x10001, x)
  25.   t0 = 1
  26.   while y != 1:  # Eucledian GCD.
  27.     q, x = divmod(x, y)
  28.     t0 += q * t1
  29.     if x == 1:
  30.       return t0
  31.     q, y = divmod(y, x)
  32.     t1 += q * t0
  33.   return (1 - t1) & 0xffff
  34.  
  35.  
  36. def _idea_crypt(ckey, block, _mul=_idea_mul, _pack=struct.pack, _unpack=struct.unpack):
  37.   if len(block) != 8:
  38.     raise ValueError('IDEA block size must be 8, got: %d' % len(block))
  39.   a, b, c, d = _unpack('>4H', block)
  40.   for j in xrange(0, 48, 6):
  41.     a, b, c, d = _mul(a, ckey[j]), (b + ckey[j + 1]) & 0xffff, (c + ckey[j + 2]) & 0xffff, _mul(d, ckey[j + 3])
  42.     t, u = c, b
  43.     c = _mul(a ^ c, ckey[j + 4])
  44.     b = _mul(((b ^ d) + c) & 0xffff, ckey[j + 5])
  45.     c = (c + b) & 0xffff
  46.     a ^= b
  47.     d ^= c
  48.     b ^= t
  49.     c ^= u
  50.   return _pack('>4H', _mul(a, ckey[48]), (c + ckey[49]) & 0xffff, (b + ckey[50]) & 0xffff, _mul(d, ckey[51]))
  51.  
  52.  
  53. class IDEA(object):
  54.   """IDEA block cipher."""
  55.  
  56.   key_size = 16
  57.   block_size = 8
  58.  
  59.   __slots__ = ('_ckey', '_dkey')
  60.  
  61.   def __init__(self, key, _inv=_idea_inv):
  62.     if len(key) != 16:
  63.       raise ValueError('IDEA key size must be 16, got: %d' % len(key))
  64.     ckey = [0] * 52
  65.     ckey[:8] = struct.unpack('>8H', key)
  66.     for i in xrange(0, 44):
  67.       ckey[i + 8] = (ckey[(i & ~7) + ((i + 1) & 7)] << 9 | ckey[(i & ~7) + ((i + 2) & 7)] >> 7) & 0xffff
  68.     self._ckey = tuple(ckey)
  69.     dkey = [0] * 52
  70.     dkey[48], dkey[49], dkey[50], dkey[51] = _inv(ckey[0]), 0xffff & -ckey[1], 0xffff & -ckey[2], _inv(ckey[3])
  71.     for i in xrange(42, -6, -6):
  72.       dkey[i + 4], dkey[i + 5], dkey[i], dkey[i + 3] = ckey[46 - i], ckey[47 - i], _inv(ckey[48 - i]), _inv(ckey[51 - i])
  73.       dkey[i + 1 + (i > 0)], dkey[i + 2 - (i > 0)] = 0xffff & -ckey[49 - i], 0xffff & -ckey[50 - i]
  74.     self._dkey = tuple(dkey)
  75.  
  76.   def encrypt(self, block, _idea_crypt=_idea_crypt):
  77.     return _idea_crypt(self._ckey, block)
  78.  
  79.   def decrypt(self, block, _idea_crypt=_idea_crypt):
  80.     return _idea_crypt(self._dkey, block)
  81.  
  82.  
  83. del _idea_mul, _idea_inv, _idea_crypt
  84.  
  85.  
  86. if __name__ == '__main__':
  87.   # Test vectors from: https://www.cosic.esat.kuleuven.be/nessie/testvectors/
  88.   cb = IDEA('2bd6459f82c5b300952c49104881ff48'.decode('hex'))
  89.   plaintext, ciphertext = 'f129a6601ef62a47'.decode('hex'), 'ea024714ad5c4d84'.decode('hex')
  90.   assert cb.encrypt(plaintext) == ciphertext
  91.   assert cb.decrypt(ciphertext) == plaintext
  92.   import sys
  93.   print >>sys.stderr, __file__ + ' OK.'
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement