Browse Source

Merge pull request #272 from libtom/update-demos-demo_dynamic.py

Update demos demo dynamic.py - everything is green
Larry Bugbee 8 years ago
parent
commit
725532c6b6
2 changed files with 94 additions and 378 deletions
  1. 94 66
      demos/demo_dynamic.py
  2. 0 312
      demos/demo_dynamic.py3

+ 94 - 66
demos/demo_dynamic.py

@@ -1,7 +1,7 @@
 
 
 
 
 """
 """
-    demo_dynamic.py                                     v2b
+    demo_dynamic.py                                    v2b
 
 
     This program demonstrates Python's use of the dynamic
     This program demonstrates Python's use of the dynamic
     language support additions to LTC, namely access to LTC
     language support additions to LTC, namely access to LTC
@@ -33,8 +33,31 @@
               mathlib.  For example, public key crypto requires
               mathlib.  For example, public key crypto requires
               a mathlib; hashing and symmetric encryption do not.
               a mathlib; hashing and symmetric encryption do not.
 
 
-    This code was written for Python 2.7 with the ctypes standard
-    library.
+    ------
+
+    This code was originally written for Python 2.7 with the
+    ctypes standard library.  This version is modified to run
+    under both Python 2.7 and 3.6.
+
+    Arguably the biggest change for Python3 has to do with
+    strings.  Under Python2, native strings are ASCII bytes and
+    passing them to LTC is natural and requires no conversion.
+    Under Python3 all native strings are Unicode which requires
+    they be converted to bytes before use by LTC.
+
+    Note the following for Python3.
+        - ASCII keys, IVs and other string arguments must be
+          'bytes'.  Define them with a 'b' prefix or convert
+          via the 'bytes()' function.
+        - "strings" returned from LTC are bytes and conversion
+          to Unicode might be necessary for proper printing.
+          If so, use <string>.decode('utf-8').
+        - The Python2 'print' statement becomes a function in
+          Python3 which requires parenthesis, eg. 'print()'.
+
+    NB: Unicode is achieved under Python2 by either defining
+        a Unicode string with a 'u' prefix or passing ASCII
+        strings thru the 'unicode()' function.
 
 
     Larry Bugbee
     Larry Bugbee
     March 2014      v1
     March 2014      v1
@@ -43,6 +66,7 @@
 """
 """
 
 
 
 
+import sys
 from ctypes import *
 from ctypes import *
 from ctypes.util import find_library
 from ctypes.util import find_library
 
 
@@ -55,21 +79,25 @@ SHOW_BUILD_OPTIONS_ALGS = True
 SHOW_SHA256_EXAMPLE     = True
 SHOW_SHA256_EXAMPLE     = True
 SHOW_CHACHA_EXAMPLE     = True
 SHOW_CHACHA_EXAMPLE     = True
 
 
-print
+print(' ')
 print('  demo_dynamic.py')
 print('  demo_dynamic.py')
 
 
+def inprint(s, indent=0):
+    "prints strings indented, including multline strings"
+    for line in s.split('\n'):
+        print(' '*indent + line)
 
 
 #-------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------
 # load the .dylib
 # load the .dylib
 
 
 libname = 'tomcrypt'
 libname = 'tomcrypt'
 libpath = find_library(libname)
 libpath = find_library(libname)
-print
+print(' ')
 print('  path to library %s: %s' % (libname, libpath))
 print('  path to library %s: %s' % (libname, libpath))
 
 
 LTC = cdll.LoadLibrary(libpath)
 LTC = cdll.LoadLibrary(libpath)
 print('  loaded: %s' % LTC)
 print('  loaded: %s' % LTC)
-print
+print(' ')
 
 
 
 
 #-------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------
@@ -78,79 +106,79 @@ print
 # and used as needed.
 # and used as needed.
 
 
 if SHOW_ALL_CONSTANTS:
 if SHOW_ALL_CONSTANTS:
-    print '-'*60
-    print '  all supported constants and their values:'
+    print('-'*60)
+    print('  all supported constants and their values:')
 
 
     # get size to allocate for constants output list
     # get size to allocate for constants output list
     str_len = c_int(0)
     str_len = c_int(0)
     ret = LTC.crypt_list_all_constants(None, byref(str_len))
     ret = LTC.crypt_list_all_constants(None, byref(str_len))
-    print '    need to allocate %d bytes to build list \n' % str_len.value
+    print('    need to allocate %d bytes to build list \n' % str_len.value)
 
 
     # allocate that size and get (name, size) pairs, each pair
     # allocate that size and get (name, size) pairs, each pair
     # separated by a newline char.
     # separated by a newline char.
     names_sizes = c_buffer(str_len.value)
     names_sizes = c_buffer(str_len.value)
     ret = LTC.crypt_list_all_constants(names_sizes, byref(str_len))
     ret = LTC.crypt_list_all_constants(names_sizes, byref(str_len))
-    print names_sizes.value
-    print
+    print(names_sizes.value.decode("utf-8"))
+    print(' ')
 
 
 
 
 if SHOW_ALL_SIZES:
 if SHOW_ALL_SIZES:
-    print '-'*60
-    print '  all supported sizes:'
+    print('-'*60)
+    print('  all supported sizes:')
 
 
     # get size to allocate for sizes output list
     # get size to allocate for sizes output list
     str_len = c_int(0)
     str_len = c_int(0)
     ret = LTC.crypt_list_all_sizes(None, byref(str_len))
     ret = LTC.crypt_list_all_sizes(None, byref(str_len))
-    print '    need to allocate %d bytes to build list \n' % str_len.value
+    print('    need to allocate %d bytes to build list \n' % str_len.value)
 
 
     # allocate that size and get (name, size) pairs, each pair
     # allocate that size and get (name, size) pairs, each pair
     # separated by a newline char.
     # separated by a newline char.
     names_sizes = c_buffer(str_len.value)
     names_sizes = c_buffer(str_len.value)
     ret = LTC.crypt_list_all_sizes(names_sizes, byref(str_len))
     ret = LTC.crypt_list_all_sizes(names_sizes, byref(str_len))
-    print names_sizes.value
-    print
+    print(names_sizes.value.decode("utf-8"))
+    print(' ')
 
 
 
 
 #-------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------
 # get individually named constants and sizes
 # get individually named constants and sizes
 
 
 if SHOW_SELECTED_CONSTANTS:
 if SHOW_SELECTED_CONSTANTS:
-    print '-'*60
-    print '\n  selected constants:'
+    print('-'*60)
+    print('\n  selected constants:')
 
 
     names = [
     names = [
-        'ENDIAN_LITTLE',
-        'ENDIAN_64BITWORD',
-        'PK_PUBLIC',
-        'MAX_RSA_SIZE',
-        'CTR_COUNTER_BIG_ENDIAN',
+        b'ENDIAN_LITTLE',
+        b'ENDIAN_64BITWORD',
+        b'PK_PUBLIC',
+        b'MAX_RSA_SIZE',
+        b'CTR_COUNTER_BIG_ENDIAN',
     ]
     ]
     for name in names:
     for name in names:
         const_value = c_int(0)
         const_value = c_int(0)
         rc = LTC.crypt_get_constant(name, byref(const_value))
         rc = LTC.crypt_get_constant(name, byref(const_value))
         value = const_value.value
         value = const_value.value
-        print '    %-25s  %d' % (name, value)
-    print
+        print('    %-25s  %d' % (name.decode("utf-8"), value))
+    print(' ')
 
 
 if SHOW_SELECTED_SIZES:
 if SHOW_SELECTED_SIZES:
-    print '-'*60
-    print '\n  selected sizes:'
+    print('-'*60)
+    print('\n  selected sizes:')
 
 
     names = [
     names = [
-        'rijndael_key',
-        'rsa_key',
-        'symmetric_CTR',
-        'twofish_key',
-        'ecc_point',
-        'gcm_state',
-        'sha512_state',
+        b'rijndael_key',
+        b'rsa_key',
+        b'symmetric_CTR',
+        b'twofish_key',
+        b'ecc_point',
+        b'gcm_state',
+        b'sha512_state',
     ]
     ]
     for name in names:
     for name in names:
         size_value = c_int(0)
         size_value = c_int(0)
         rc = LTC.crypt_get_size(name, byref(size_value))
         rc = LTC.crypt_get_size(name, byref(size_value))
         value = size_value.value
         value = size_value.value
-        print '    %-25s  %d' % (name, value)
-    print
+        print('    %-25s  %d' % (name.decode("utf-8"), value))
+    print(' ')
 
 
 
 
 #-------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------
@@ -163,13 +191,14 @@ if SHOW_SELECTED_SIZES:
 #   nm /usr/local/lib/libtomcrypt.dylib | grep " D "
 #   nm /usr/local/lib/libtomcrypt.dylib | grep " D "
 
 
 def get_named_string(lib, name):
 def get_named_string(lib, name):
-    return c_char_p.in_dll(lib, name).value
+    return c_char_p.in_dll(lib, name).value.decode("utf-8")
 
 
 if SHOW_BUILD_OPTIONS_ALGS:
 if SHOW_BUILD_OPTIONS_ALGS:
-    print '-'*60
-    print 'This is a string compiled into LTC showing compile '
-    print 'options and algorithms supported by this build \n'
-    print get_named_string(LTC, 'crypt_build_settings')
+    print('-'*60)
+    print('This is a string compiled into LTC showing compile')
+    print('options and algorithms supported by this build \n')
+#    print(get_named_string(LTC, 'crypt_build_settings'))
+    inprint(get_named_string(LTC, 'crypt_build_settings'), 4)
 
 
 
 
 #-------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------
@@ -180,32 +209,34 @@ if SHOW_BUILD_OPTIONS_ALGS:
 # - - - - - - - - - - - - -
 # - - - - - - - - - - - - -
 # definitions
 # definitions
 
 
+from binascii import hexlify, unhexlify
+
+def _err2str(err):
+    # define return type
+    errstr = LTC.error_to_string
+    errstr.restype = c_char_p
+    # get and return err string
+    return errstr(err)
+
 def _get_size(name):
 def _get_size(name):
     size = c_int(0)
     size = c_int(0)
-    rc = LTC.crypt_get_size(name, byref(size))
+    rc = LTC.crypt_get_size(bytes(name), byref(size))
     if rc != 0:
     if rc != 0:
         raise Exception('LTC.crypt_get_size(%s) rc = %d' % (name, rc))
         raise Exception('LTC.crypt_get_size(%s) rc = %d' % (name, rc))
     return size.value
     return size.value
 
 
 def _get_constant(name):
 def _get_constant(name):
     constant = c_int(0)
     constant = c_int(0)
-    rc = LTC.crypt_get_constant(name, byref(constant))
+    rc = LTC.crypt_get_constant(bytes(name), byref(constant))
     if rc != 0:
     if rc != 0:
         raise Exception('LTC.crypt_get_constant(%s) rc = %d' % (name, rc))
         raise Exception('LTC.crypt_get_constant(%s) rc = %d' % (name, rc))
     return constant.value
     return constant.value
 
 
-def _err2str(err):
-    # define return type
-    errstr = LTC.error_to_string
-    errstr.restype = c_char_p
-    # get and return err string
-    return errstr(err)
-
-CRYPT_OK = _get_constant('CRYPT_OK')
+CRYPT_OK = _get_constant(b'CRYPT_OK')
 
 
 class SHA256(object):
 class SHA256(object):
     def __init__(self):
     def __init__(self):
-        self.state = c_buffer(_get_size('sha256_state'))
+        self.state = c_buffer(_get_size(b'sha256_state'))
         LTC.sha256_init(byref(self.state))
         LTC.sha256_init(byref(self.state))
     def update(self, data):
     def update(self, data):
         LTC.sha256_process(byref(self.state), data, len(data))
         LTC.sha256_process(byref(self.state), data, len(data))
@@ -216,7 +247,7 @@ class SHA256(object):
 
 
 class ChaCha(object):
 class ChaCha(object):
     def __init__(self, key, rounds):
     def __init__(self, key, rounds):
-        self.state   = c_buffer(_get_size('chacha_state'))
+        self.state   = c_buffer(_get_size(b'chacha_state'))
         self.counter = c_int(1)
         self.counter = c_int(1)
         err = LTC.chacha_setup(byref(self.state), key, len(key), rounds)
         err = LTC.chacha_setup(byref(self.state), key, len(key), rounds)
         if err != CRYPT_OK:
         if err != CRYPT_OK:
@@ -235,42 +266,39 @@ class ChaCha(object):
 # - - - - - - - - - - - - -
 # - - - - - - - - - - - - -
 # a SHA256 app fragment
 # a SHA256 app fragment
 
 
-# from wrapper import *         # uncomment in real life
-
 if SHOW_SHA256_EXAMPLE:
 if SHOW_SHA256_EXAMPLE:
-    print '-'*60
-    data = 'hello world'
+    print('-'*60)
+    data = b'hello world'               # we want bytes, not Unicode
 
 
     sha256 = SHA256()
     sha256 = SHA256()
     sha256.update(data)
     sha256.update(data)
     md = sha256.digest()
     md = sha256.digest()
 
 
     template = '\n  the SHA256 digest for "%s" is %s \n'
     template = '\n  the SHA256 digest for "%s" is %s \n'
-    print template % (data, md.encode('hex'))
+    print(template % (data, hexlify(md)))
 
 
 # - - - - - - - - - - - - -
 # - - - - - - - - - - - - -
 # a ChaCha app fragment
 # a ChaCha app fragment
 
 
 if SHOW_CHACHA_EXAMPLE:
 if SHOW_CHACHA_EXAMPLE:
-    print '-'*60
-    key     = 'hownowbrowncow\x00\x00'  # exactly 16 or 32 bytes
+    print('-'*60)
+    key     = b'hownowbrowncow\x00\x00' # exactly 16 or 32 bytes
     rounds  = 12                        # common values: 8, 12, 20
     rounds  = 12                        # common values: 8, 12, 20
-    iv      = '123456789012'            # exactly 12 bytes
-    plain   = 'Kilroy was here, there, and everywhere!'
+    iv      = b'123456789012'           # exactly 12 bytes
+    plain   = b'Kilroy was here, there, and everywhere!'
 
 
     cha = ChaCha(key, rounds)
     cha = ChaCha(key, rounds)
     cha.set_iv32(iv)
     cha.set_iv32(iv)
     cipher = cha.crypt(plain)
     cipher = cha.crypt(plain)
 
 
     template = '\n  ChaCha%d ciphertext   for "%s" is "%s"'
     template = '\n  ChaCha%d ciphertext   for "%s" is "%s"'
-    print template % (rounds, plain, cipher.encode('hex'))
+    print(template % (rounds, plain, hexlify(cipher)))
 
 
-    # reset to decrypt
-    cha.set_iv32(iv)
+    cha.set_iv32(iv)                    # reset to decrypt
     decrypted = cha.crypt(cipher)
     decrypted = cha.crypt(cipher)
 
 
     template = '  ChaCha%d decoded text for "%s" is "%s" \n'
     template = '  ChaCha%d decoded text for "%s" is "%s" \n'
-    print template % (rounds, plain, decrypted)
+    print(template % (rounds, plain, decrypted.decode("utf-8")))
 
 
 # Footnote: Keys should be erased fm memory as soon as possible after use,
 # Footnote: Keys should be erased fm memory as soon as possible after use,
 # and that includes Python.  For a tip on how to do that in Python, see
 # and that includes Python.  For a tip on how to do that in Python, see

+ 0 - 312
demos/demo_dynamic.py3

@@ -1,312 +0,0 @@
-
-
-"""
-    demo_dynamic.py3                                    v2b
-
-    This program demonstrates Python's use of the dynamic
-    language support additions to LTC, namely access to LTC
-    constants, struct and union sizes, and the binding of a
-    math package to LTC.  Also provided are simple code
-    fragments to illustrate how one might write a Python
-    wrapper for LTC and how an app might call the wrapper.
-    This or a similar model should work for Ruby and other
-    dynamic languages.
-
-    This instance uses Python's ctypes and requires a single
-    .dylib linking together LTC and a math library.  Building
-    a single .dylib is needed because LTC wants a fairly tight
-    relationship between itself and the mathlib.  (ctypes can
-    load multiple .dylibs, but it does not support this level
-    of tight coupling between otherwise independent libraries.)
-
-    My .dylib was created on OSX/macOS with the following:
-        sudo make -j5 -f makefile.shared                        \
-            CFLAGS="-DUSE_TFM -DTFM_DESC -I/usr/local/include"  \
-            EXTRALIBS=/usr/local/lib/libtfm.a  install
-
-    For python 2.7.12 on Ubuntu Xenial the following worked for
-    me (without MPI support):
-        sudo make -f makefile.shared install PREFIX="/usr"
-
-    Reminder: you don't need to bind in a math library unless
-              you are going to use LTC functions that need a
-              mathlib.  For example, public key crypto requires
-              a mathlib; hashing and symmetric encryption do not.
-
-    ------
-    
-    This code was originally written for Python 2.7 with the
-    ctypes standard library.  This version was modified so that
-    it would run under both Python 2.7 and 3.6.  You might want
-    to run a diff on the .py and .py3 files to see the differences
-    between the two languages.    
-    
-    Arguably the biggest change for Python3 has to do with
-    strings.  Under Python2, native strings are ASCII bytes and
-    passing them to LTC is natural and requires no conversion.
-    Under Python3 all native strings are Unicode which requires 
-    they be converted to bytes before use by LTC.
-
-    Note the following for Python3.
-        - ASCII keys, IVs and other string arguments must be
-          'bytes'.  Define them with a 'b' prefix or convert
-          via the 'bytes()' function.
-        - "strings" returned from LTC are bytes and conversion
-          to Unicode might be necessary for proper printing.
-          If so, use <string>.decode('utf-8').
-        - The Python2 'print' statement becomes a function in
-          Python3 which requires parenthesis, eg. 'print()'.
-        
-    NB: Unicode is achieved under Python2 by either defining
-        a Unicode string with a 'u' prefix or passing ASCII
-        strings thru the 'unicode()' function.
-    
-
-    Larry Bugbee
-    March 2014      v1
-    August 2017     v2b
-
-"""
-
-
-import sys
-from ctypes import *
-from ctypes.util import find_library
-
-# switches to enable/disable selected output
-SHOW_ALL_CONSTANTS      = True
-SHOW_ALL_SIZES          = True
-SHOW_SELECTED_CONSTANTS = True
-SHOW_SELECTED_SIZES     = True
-SHOW_BUILD_OPTIONS_ALGS = True
-SHOW_SHA256_EXAMPLE     = True
-SHOW_CHACHA_EXAMPLE     = True
-
-print(' ')
-print('  demo_dynamic.py')
-
-def inprint(s, indent=0):
-    "prints strings indented, including multline strings"
-    for line in s.split('\n'):
-        print(' '*indent + line)
-
-#-------------------------------------------------------------------------------
-# load the .dylib
-
-libname = 'tomcrypt'
-libpath = find_library(libname)
-print(' ')
-print('  path to library %s: %s' % (libname, libpath))
-
-LTC = cdll.LoadLibrary(libpath)
-print('  loaded: %s' % LTC)
-print(' ')
-
-
-#-------------------------------------------------------------------------------
-# get list of all supported constants followed by a list of all
-# supported sizes.  One alternative: these lists may be parsed
-# and used as needed.
-
-if SHOW_ALL_CONSTANTS:
-    print('-'*60)
-    print('  all supported constants and their values:')
-
-    # get size to allocate for constants output list
-    str_len = c_int(0)
-    ret = LTC.crypt_list_all_constants(None, byref(str_len))
-    print('    need to allocate %d bytes to build list \n' % str_len.value)
-
-    # allocate that size and get (name, size) pairs, each pair
-    # separated by a newline char.
-    names_sizes = c_buffer(str_len.value)
-    ret = LTC.crypt_list_all_constants(names_sizes, byref(str_len))
-    print(names_sizes.value.decode("utf-8"))
-    print(' ')
-
-
-if SHOW_ALL_SIZES:
-    print('-'*60)
-    print('  all supported sizes:')
-
-    # get size to allocate for sizes output list
-    str_len = c_int(0)
-    ret = LTC.crypt_list_all_sizes(None, byref(str_len))
-    print('    need to allocate %d bytes to build list \n' % str_len.value)
-
-    # allocate that size and get (name, size) pairs, each pair
-    # separated by a newline char.
-    names_sizes = c_buffer(str_len.value)
-    ret = LTC.crypt_list_all_sizes(names_sizes, byref(str_len))
-    print(names_sizes.value.decode("utf-8"))
-    print(' ')
-
-
-#-------------------------------------------------------------------------------
-# get individually named constants and sizes
-
-if SHOW_SELECTED_CONSTANTS:
-    print('-'*60)
-    print('\n  selected constants:')
-
-    names = [
-        b'ENDIAN_LITTLE',
-        b'ENDIAN_64BITWORD',
-        b'PK_PUBLIC',
-        b'MAX_RSA_SIZE',
-        b'CTR_COUNTER_BIG_ENDIAN',
-    ]
-    for name in names:
-        const_value = c_int(0)
-        rc = LTC.crypt_get_constant(name, byref(const_value))
-        value = const_value.value
-        print('    %-25s  %d' % (name.decode("utf-8"), value))
-    print(' ')
-
-if SHOW_SELECTED_SIZES:
-    print('-'*60)
-    print('\n  selected sizes:')
-
-    names = [
-        b'rijndael_key',
-        b'rsa_key',
-        b'symmetric_CTR',
-        b'twofish_key',
-        b'ecc_point',
-        b'gcm_state',
-        b'sha512_state',
-    ]
-    for name in names:
-        size_value = c_int(0)
-        rc = LTC.crypt_get_size(name, byref(size_value))
-        value = size_value.value
-        print('    %-25s  %d' % (name.decode("utf-8"), value))
-    print(' ')
-
-
-#-------------------------------------------------------------------------------
-#-------------------------------------------------------------------------------
-# LibTomCrypt exposes one interesting string that can be accessed
-# via Python's ctypes module, "crypt_build_settings", which
-# provides a list of this build's compiler switches and supported
-# algorithms.  If someday LTC exposes other interesting strings,
-# they can be found with:
-#   nm /usr/local/lib/libtomcrypt.dylib | grep " D "
-
-def get_named_string(lib, name):
-    return c_char_p.in_dll(lib, name).value.decode("utf-8")
-
-if SHOW_BUILD_OPTIONS_ALGS:
-    print('-'*60)
-    print('This is a string compiled into LTC showing compile')
-    print('options and algorithms supported by this build \n')
-#    print(get_named_string(LTC, 'crypt_build_settings'))
-    inprint(get_named_string(LTC, 'crypt_build_settings'), 4)
-
-
-#-------------------------------------------------------------------------------
-#-------------------------------------------------------------------------------
-# here is an example of how Python code can be written to access
-# LTC's implementation of SHA256 and ChaCha,
-
-# - - - - - - - - - - - - -
-# definitions
-
-from binascii import hexlify, unhexlify
-
-def _err2str(err):
-    # define return type
-    errstr = LTC.error_to_string
-    errstr.restype = c_char_p
-    # get and return err string
-    return errstr(err)
-
-def _get_size(name):
-    size = c_int(0)
-    rc = LTC.crypt_get_size(bytes(name), byref(size))
-    if rc != 0:
-        raise Exception('LTC.crypt_get_size(%s) rc = %d' % (name, rc))
-    return size.value
-
-def _get_constant(name):
-    constant = c_int(0)
-    rc = LTC.crypt_get_constant(bytes(name), byref(constant))
-    if rc != 0:
-        raise Exception('LTC.crypt_get_constant(%s) rc = %d' % (name, rc))
-    return constant.value
-
-CRYPT_OK = _get_constant(b'CRYPT_OK')
-
-class SHA256(object):
-    def __init__(self):
-        self.state = c_buffer(_get_size(b'sha256_state'))
-        LTC.sha256_init(byref(self.state))
-    def update(self, data):
-        LTC.sha256_process(byref(self.state), data, len(data))
-    def digest(self):
-        md = c_buffer(32)
-        LTC.sha256_done(byref(self.state), byref(md))
-        return md.raw
-
-class ChaCha(object):
-    def __init__(self, key, rounds):
-        self.state   = c_buffer(_get_size(b'chacha_state'))
-        self.counter = c_int(1)
-        err = LTC.chacha_setup(byref(self.state), key, len(key), rounds)
-        if err != CRYPT_OK:
-            raise Exception('LTC.chacha_setup(), err = %d, "%s"' % (err, _err2str(err)))
-    def set_iv32(self, iv):
-        err = LTC.chacha_ivctr32(byref(self.state), iv, len(iv), byref(self.counter))
-        if err != CRYPT_OK:
-            raise Exception('LTC.chacha_ivctr32(), err = %d, "%s"' % (err, _err2str(err)))
-    def crypt(self, datain):
-        dataout = c_buffer(len(datain))
-        err = LTC.chacha_crypt(byref(self.state), datain, len(datain), byref(dataout))
-        if err != CRYPT_OK:
-            raise Exception('LTC.chacha_crypt(), err = %d, "%s"' % (err, _err2str(err)))
-        return dataout.raw
-
-# - - - - - - - - - - - - -
-# a SHA256 app fragment
-
-if SHOW_SHA256_EXAMPLE:
-    print('-'*60)
-    data = b'hello world'               # we want bytes, not Unicode
-
-    sha256 = SHA256()
-    sha256.update(data)
-    md = sha256.digest()
-
-    template = '\n  the SHA256 digest for "%s" is %s \n'
-    print(template % (data, hexlify(md)))
-
-# - - - - - - - - - - - - -
-# a ChaCha app fragment
-
-if SHOW_CHACHA_EXAMPLE:
-    print('-'*60)
-    key     = b'hownowbrowncow\x00\x00' # exactly 16 or 32 bytes
-    rounds  = 12                        # common values: 8, 12, 20
-    iv      = b'123456789012'           # exactly 12 bytes
-    plain   = b'Kilroy was here, there, and everywhere!'
-
-    cha = ChaCha(key, rounds)
-    cha.set_iv32(iv)
-    cipher = cha.crypt(plain)
-
-    template = '\n  ChaCha%d ciphertext   for "%s" is "%s"'
-    print(template % (rounds, plain, hexlify(cipher)))
-
-    cha.set_iv32(iv)                    # reset to decrypt
-    decrypted = cha.crypt(cipher)
-
-    template = '  ChaCha%d decoded text for "%s" is "%s" \n'
-    print(template % (rounds, plain, decrypted.decode("utf-8")))
-
-# Footnote: Keys should be erased fm memory as soon as possible after use,
-# and that includes Python.  For a tip on how to do that in Python, see
-# http://buggywhip.blogspot.com/2010/12/erase-keys-and-credit-card-numbers-in.html
-
-#-------------------------------------------------------------------------------
-#-------------------------------------------------------------------------------
-#-------------------------------------------------------------------------------