Skip to content

Commit 9f548c9

Browse files
buggywhipsjaeckel
authored andcommitted
update demo_dynamic.py
1 parent 91e5e83 commit 9f548c9

1 file changed

Lines changed: 93 additions & 39 deletions

File tree

demos/demo_dynamic.py

100755100644
Lines changed: 93 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22

33
"""
4-
demo_dynamic.py v1
4+
demo_dynamic.py v2
55
66
This program demonstrates Python's use of the dynamic
77
language support additions to LTC, namely access to LTC
@@ -19,42 +19,45 @@
1919
load multiple .dylibs, but it does not support this level
2020
of tight coupling between otherwise independent libraries.)
2121
22-
My .dylib was created on OSX with the following steps:
23-
24-
1- compile LTC to a .a static lib:
25-
CFLAGS="-DLTM_DESC -DUSE_LTM" make
26-
27-
2- link LTC and LTM into a single .dylib:
28-
ar2dylib_with tomcrypt tommath
29-
where ar2dylib_with is a shell script that combines
30-
the LTC .a with the LTM .dylib
22+
My .dylib was created on OSX/macOS with the following:
23+
sudo make -j5 -f makefile.shared \
24+
CFLAGS="-DUSE_TFM -DTFM_DESC -I/usr/local/include" \
25+
EXTRALIBS=/usr/local/lib/libtfm.a install
3126
3227
Reminder: you don't need to bind in a math library unless
33-
you are going to use LTC functions that depend
34-
on a mathlib. For example, public key crypto
35-
needs a mathlib; hashing and symmetric encryption
36-
do not.
28+
you are going to use LTC functions that need a
29+
mathlib. For example, public key crypto requires
30+
a mathlib; hashing and symmetric encryption do not.
3731
3832
This code was written for Python 2.7.
3933
4034
Larry Bugbee
41-
March 2014
35+
March 2014 v1
36+
August 2017 v2
4237
4338
"""
4439

4540

4641
from ctypes import *
4742
from ctypes.util import find_library
4843

44+
# switches to enable/disable selected output
45+
SHOW_ALL_CONSTANTS = True
46+
SHOW_ALL_SIZES = True
47+
SHOW_SELECTED_CONSTANTS = True
48+
SHOW_SELECTED_SIZES = True
49+
SHOW_BUILD_OPTIONS_ALGS = True
50+
SHOW_SHA256_EXAMPLE = True
51+
SHOW_CHACHA_EXAMPLE = True
52+
53+
print
54+
print(' demo_dynamic.py')
4955

5056
#---------------------------------------------------------------
5157
# load the .dylib
5258

5359
libname = 'tomcrypt'
5460
libpath = find_library(libname)
55-
56-
print
57-
print(' demo_dynamic.py')
5861
print
5962
print(' path to library %s: %s' % (libname, libpath))
6063

@@ -69,7 +72,8 @@
6972
# supported sizes. One alternative: these lists may be parsed
7073
# and used as needed.
7174

72-
if 1:
75+
if SHOW_ALL_CONSTANTS:
76+
print '-'*60
7377
print ' all supported constants and their values:'
7478

7579
# get size to allocate for constants output list
@@ -85,7 +89,8 @@
8589
print
8690

8791

88-
if 1:
92+
if SHOW_ALL_SIZES:
93+
print '-'*60
8994
print ' all supported sizes:'
9095

9196
# get size to allocate for sizes output list
@@ -105,7 +110,8 @@
105110
# get individually named constants and sizes
106111

107112
# print selected constants
108-
if 1:
113+
if SHOW_SELECTED_CONSTANTS:
114+
print '-'*60
109115
print '\n selected constants:'
110116

111117
names = [
@@ -122,7 +128,8 @@
122128
print ' %-25s %d' % (name, value)
123129

124130
# print selected sizes
125-
if 1:
131+
if SHOW_SELECTED_SIZES:
132+
print '-'*60
126133
print '\n selected sizes:'
127134

128135
names = [
@@ -143,14 +150,18 @@
143150

144151
#---------------------------------------------------------------
145152
#---------------------------------------------------------------
146-
# ctypes getting a list of this build's supported algorithms
147-
# and compiler switches
153+
# LibTomCrypt exposes one interesting string that can be accessed
154+
# via Python's ctypes module, "crypt_build_settings", which
155+
# provides a list of this build's compiler switches and supported
156+
# algorithms. If someday LTC exposes other interesting strings,
157+
# they can be found with:
158+
# nm /usr/local/lib/libtomcrypt.dylib | grep " D "
148159

149160
def get_named_string(lib, name):
150161
return c_char_p.in_dll(lib, name).value
151162

152-
if 0:
153-
print '\n%s' % ('-'*60)
163+
if SHOW_BUILD_OPTIONS_ALGS:
164+
print '-'*60
154165
print 'This is a string compiled into LTC showing compile '
155166
print 'options and algorithms supported by this build \n'
156167
print get_named_string(LTC, 'crypt_build_settings')
@@ -160,23 +171,31 @@ def get_named_string(lib, name):
160171

161172
#---------------------------------------------------------------
162173
#---------------------------------------------------------------
163-
# here is an example of how a wrapper can make Python access
164-
# more Pythonic
174+
# here is an example of how Python code can be written to access
175+
# LTC's implementation of SHA256 and ChaCha,
165176

166177
# - - - - - - - - - - - - -
167-
# a wrapper fragment...
178+
# definitions
168179

169180
def _get_size(name):
170181
size = c_int(0)
171182
rc = LTC.crypt_get_size(name, byref(size))
183+
if rc != 0:
184+
raise Exception('LTC.crypt_get_size(%s) rc = %d' % (name, rc))
172185
return size.value
173186

174-
sha256_state_struct_size = _get_size('sha256_state')
175-
sha512_state_struct_size = _get_size('sha512_state')
187+
def _get_constant(name):
188+
constant = c_int(0)
189+
rc = LTC.crypt_get_constant(name, byref(constant))
190+
if rc != 0:
191+
raise Exception('LTC.crypt_get_constant(%s) rc = %d' % (name, rc))
192+
return constant.value
193+
194+
CRYPT_OK = _get_constant('CRYPT_OK')
176195

177196
class SHA256(object):
178197
def __init__(self):
179-
self.state = c_buffer(sha256_state_struct_size)
198+
self.state = c_buffer(_get_size('sha256_state'))
180199
LTC.sha256_init(byref(self.state))
181200
def update(self, data):
182201
LTC.sha256_process(byref(self.state), data, len(data))
@@ -185,19 +204,54 @@ def digest(self):
185204
LTC.sha256_done(byref(self.state), byref(md))
186205
return md.raw
187206

207+
class ChaCha(object):
208+
def __init__(self, key, rounds):
209+
self.state = c_buffer(_get_size('chacha_state'))
210+
self.counter = c_int(1)
211+
err = LTC.chacha_setup(byref(self.state), key, len(key), rounds)
212+
def set_iv32(self, iv):
213+
err = LTC.chacha_ivctr32(byref(self.state), iv, len(iv), byref(self.counter))
214+
if err != CRYPT_OK:
215+
raise Exception('LTC.chacha_ivctr32() err = %d' % err)
216+
def crypt(self, datain):
217+
dataout = c_buffer(len(datain))
218+
err = LTC.chacha_crypt(byref(self.state), datain, len(datain), byref(dataout))
219+
if err != CRYPT_OK:
220+
raise Exception('LTC.chacha_crypt() err = %d' % err)
221+
return dataout.raw
222+
188223
# - - - - - - - - - - - - -
189-
# an app fragment...
224+
# a SHA256 app fragment...
190225

191226
# from wrapper import * # uncomment in real life
192227

193-
data = 'hello world'
228+
if SHOW_SHA256_EXAMPLE:
229+
print '-'*60
230+
data = 'hello world'
231+
232+
sha256 = SHA256()
233+
sha256.update(data)
234+
md = sha256.digest()
235+
236+
template = '\n the SHA256 digest for "%s" is %s \n'
237+
print template % (data, md.encode('hex'))
238+
239+
# - - - - - - - - - - - - -
240+
# a ChaCha app fragment...
241+
242+
if SHOW_CHACHA_EXAMPLE:
243+
print '-'*60
244+
key = 'hownowbrowncow\x00\x00' # exactly 16 or 32 bytes
245+
rounds = 12 # common values: 8, 12, 20
246+
iv = '123456789012' # exactly 12 bytes
247+
plain = 'Kilroy was here, there, and everywhere!'
194248

195-
sha256 = SHA256()
196-
sha256.update(data)
197-
md = sha256.digest()
249+
cha = ChaCha(key, rounds)
250+
cha.set_iv32(iv)
251+
cipher = cha.crypt(plain)
198252

199-
template = '\n\n the SHA256 digest for "%s" is %s \n'
200-
print template % (data, md.encode('hex'))
253+
template = '\n ChaCha%d ciphertext for "%s" is "%s" \n'
254+
print template % (rounds, plain, cipher.encode('hex'))
201255

202256

203257

0 commit comments

Comments
 (0)