title: Twofish encryption in Python
body: <p>I have a test tool which uses Twofish as the encryption algorithm to encrypt data before sending it to the server. The code is written in C++ and uses Bruce Schneier's optimized C implementation (<a href="https://www.schneier.com/code/twofish-optimized-c.zip" rel="nofollow">https://www.schneier.com/code/twofish-optimized-c.zip</a>). I need to port this tool to Python and I am using twofish module (<a href="https://pypi.python.org/pypi/twofish/0.3.0" rel="nofollow">https://pypi.python.org/pypi/twofish/0.3.0</a>). I can encrypt and decrypt strings of 16 char length but for other string lengths it gives an error 'ValueError: invalid block length'.</p>
  
  <p>How can I encrypt &amp; decrypt large data using Python's Twofish module?</p>
  
  <pre><code>&gt;&gt;&gt; from twofish import Twofish
  &gt;&gt;&gt; key = binascii.unhexlify('8CACBE276491F6FF4B1EC0E9CFD52E76')
  &gt;&gt;&gt; t = Twofish(key)
  &gt;&gt;&gt; cipher_text = T.encrypt('deadbeaf12345678')
  &gt;&gt;&gt; plain_text = t.decrypt(cipher_text)
  &gt;&gt;&gt; plain_text
  'deadbeaf12345678'
  &gt;&gt;&gt; cipher_text = t.encrypt('deadbeaf12345678hello world 1234')
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
    File "/usr/local/lib/python2.7/site-packages/twofish.py", line 69, in encrypt
      raise ValueError('invalid block length')
  ValueError: invalid block length
  </code></pre>
  
  <p><strong>Update:</strong>
  I am trying out another solution for this problem.
  I have created a Windows DLL, twofish.dll from Bruce Schneier's optimized C implementation (<a href="https://www.schneier.com/code/twofish-optimized-c.zip" rel="nofollow">https://www.schneier.com/code/twofish-optimized-c.zip</a>).
  Also, I have exported wrapper functions for encode &amp; decode member functions using __declspec(dllexport).</p>
  
  <p>I am loading this DLL in Python using ctype.CDLL function.
  The prototype for encode function is:</p>
  
  <pre><code>__declspec(dllexport) int encode(unsigned char *key, unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int outbuflen, unsigned int&amp; outlen)
  </code></pre>
  
  <p>How should I define the argument types in Python script?</p>
  
  <pre><code>import ctypes
  import binascii
  import requests
  
  twofish_dll = ctypes.CDLL("twofish.dll")
  
  encode = twofish_dll.encode
  
  f = open('test.xml', 'r')
  plain_text = f.read()
  f.close()
  
  cipher_text = ctypes.create_string_buffer(8192)
  cipher_text_lenght = (ctypes.c_uint)()
  
  KCS = '8CACBE276491F6FF4B1EC0E9CFD52E76'
  key = binascii.unhexlify(KCS)
  
  encode.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint, ctypes.c_char_p, ctypes.c_uint, ctypes.POINTER(ctypes.c_uint)]
  encode(ctypes.c_char_p(key), ctypes.c_char_p(plain_text), len(plain_text), cipher_text, 8192, ctypes.byref(cipher_text_lenght))
  </code></pre>
  
  <p>When executed the above code throws below error:</p>
  
  <pre><code>Traceback (most recent call last):
    File "C:\Data\sepm_test.py", line 21, in &lt;module&gt;
      encode(ctypes.c_char_p(key), ctypes.c_char_p(plain_text), len(plain_text), cipher_text, 8192, ctypes.byref(cipher_text_lenght))
  TypeError: bytes or integer address expected instead of str instance
  </code></pre>