├── .gitignore ├── README.md ├── clean.sh ├── compare.sh ├── cython └── Makefile ├── dockit.sh ├── experiments ├── cython-boto │ ├── build.sh │ ├── preamble.py │ ├── setup.py │ ├── test.py │ └── tmp.sh ├── cython │ ├── cy_harmonic.pyx │ ├── harmonic.py │ └── run.py ├── numba │ ├── harmonic.py │ └── test.py ├── py23 │ ├── Makefile │ ├── example_python2.py │ └── setup.py └── pycc │ ├── Makefile │ └── test.py ├── nuitka └── Makefile ├── output ├── Dockerfile └── compare.sh ├── requirements.txt ├── scripts ├── cascade.py ├── cascade2.py ├── cascade3.py ├── cascade_init.pyx ├── harmonic_sum.py ├── hello.py ├── needs_bottle.py ├── needs_crypto.py ├── needs_flask.py └── needs_m2crypto.py ├── timer.py └── trace.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.c 2 | *.exe 3 | *.o 4 | *.pyc 5 | *.so 6 | cache/Nuitka-0.5.1.1.tar.gz 7 | cache/Nuitka-0.5.1.1/ 8 | cython/cascade 9 | cython/hello 10 | cython/harmonic_sum 11 | cython/needs_* 12 | experiments/cython-boto/boto* 13 | nuitka/*.build 14 | nuitka/*.dist 15 | output/cython/ 16 | output/nuitka/ 17 | pyinstaller/ 18 | trace.out 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | exe-from-python 2 | =============== 3 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname "${BASH_SOURCE[0]}") 4 | rm -f cython/*.c cython/*.o nuitka/*.exe 5 | rm -rf nuitka/*.build nuitka/*.dist 6 | -------------------------------------------------------------------------------- /compare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname "${BASH_SOURCE[0]}") && exec ./output/compare.sh 4 | -------------------------------------------------------------------------------- /cython/Makefile: -------------------------------------------------------------------------------- 1 | # Based on the Makefile at: 2 | # https://github.com/cython/cython/blob/master/Demos/embed/Makefile 3 | 4 | # You can override the TARGET on the command line with: make TARGET=... 5 | TARGET := hello 6 | 7 | PYTHON := python 8 | PYVERSION := $(shell $(PYTHON) -c "import sys; print(sys.version[:3])") 9 | 10 | INCDIR := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_python_inc())") 11 | PLATINCDIR := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_python_inc(plat_specific=True))") 12 | LIBDIR1 := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBDIR'))") 13 | LIBDIR2 := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBPL'))") 14 | PYLIB := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBRARY')[3:-2])") 15 | 16 | CC := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('CC'))") 17 | LINKCC := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LINKCC'))") 18 | LINKFORSHARED := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LINKFORSHARED'))") 19 | LIBS := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LIBS'))") 20 | SYSLIBS := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('SYSLIBS'))") 21 | 22 | ifeq "$(TARGET)" "cascade" 23 | MAIN := cascade_init 24 | SCRIPT := cascade_init.pyx 25 | EXTRAS := cascade cascade2 cascade3 26 | else 27 | MAIN := $(TARGET) 28 | SCRIPT := $(TARGET).py 29 | EXTRAS := 30 | endif 31 | 32 | OBJECTS := $(addsuffix .o, $(MAIN) $(EXTRAS)) 33 | 34 | all: $(TARGET) 35 | 36 | $(TARGET): $(OBJECTS) 37 | $(LINKCC) -o $@ $(OBJECTS) -L$(LIBDIR1) -L$(LIBDIR2) -l$(PYLIB) \ 38 | $(LIBS) $(SYSLIBS) $(LINKFORSHARED) 39 | 40 | $(OBJECTS): %.o: %.c 41 | $(CC) -c $< -I$(INCDIR) -I$(PLATINCDIR) 42 | 43 | $(MAIN).c: ../scripts/$(SCRIPT) 44 | cython -o $@ --embed $< 45 | 46 | $(addsuffix .c, $(EXTRAS)): %.c: ../scripts/%.py 47 | cython -o $@ $< 48 | 49 | clean: 50 | rm -f *.c *.o 51 | -------------------------------------------------------------------------------- /dockit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | cd $(dirname "${BASH_SOURCE[0]}") 5 | cd output 6 | docker build -t exe/test . 7 | exec docker run exe/test ./compare.sh 8 | -------------------------------------------------------------------------------- /experiments/cython-boto/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | cd $(dirname "${BASH_SOURCE[0]}") 5 | 6 | V2=~/.v/exe-from-python 7 | V3=~/.v/exe-from-python-experiments-py23 8 | 9 | if [ ! -f boto-2.27.0.tar.gz ] 10 | then 11 | wget https://pypi.python.org/packages/source/b/boto/boto-2.27.0.tar.gz 12 | fi 13 | 14 | rm -rf boto-2.27.0/ boto/ build/ 15 | tar xfz boto-2.27.0.tar.gz boto-2.27.0/boto 16 | cp -r boto-2.27.0/boto/ . 17 | 18 | sed -i 's/sys.stdout/None/' boto/requestlog.py 19 | 20 | #python2.7 setup.py build_ext --inplace 21 | #python3.4 setup.py build_ext --inplace 22 | 23 | for source in \ 24 | boto/[a-z]*.py \ 25 | boto/gs/[a-z]*.py \ 26 | boto/pyami/[a-z]*.py \ 27 | boto/s3/[a-z]*.py 28 | do 29 | base=${source%.py} 30 | $V2/bin/cython --lenient $base.py 31 | gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing \ 32 | -I$V3/include/python3.4m -o $base.so $base.c 33 | #exit 34 | done 35 | 36 | mv boto/__init__.py . 37 | cat preamble.py __init__.py > boto/__init__.py 38 | rm __init__.py 39 | 40 | find boto -name '[a-z]*.py' | xargs rm 41 | -------------------------------------------------------------------------------- /experiments/cython-boto/preamble.py: -------------------------------------------------------------------------------- 1 | import sys 2 | def fix(): 3 | import io 4 | sys.modules['StringIO'] = io 5 | real_StringIO = io.StringIO 6 | 7 | class StringIO(real_StringIO): 8 | def __init__(self, content): 9 | if isinstance(content, bytes): 10 | content = content.decode('ascii') 11 | return real_StringIO.__init__(self, content) 12 | 13 | io.StringIO = StringIO 14 | 15 | import configparser 16 | sys.modules['ConfigParser'] = configparser 17 | __builtins__['StandardError'] = Exception 18 | import urllib.parse 19 | sys.modules['urlparse'] = urllib.parse 20 | def cmp(a, b): 21 | if a < b: 22 | return -1 23 | elif a > b: 24 | return 1 25 | else: 26 | return 0 27 | __builtins__['cmp'] = cmp 28 | import urllib.request 29 | sys.modules['urllib2'] = urllib.request 30 | import http.client 31 | sys.modules['httplib'] = http.client 32 | import queue 33 | sys.modules['Queue'] = queue 34 | import email.message 35 | sys.modules['rfc822'] = email.message 36 | import hmac 37 | real_HMAC = hmac.HMAC 38 | 39 | class HMAC(real_HMAC): 40 | def __init__(self, key, msg = None, digestmod = None): 41 | key = key.encode('ascii') 42 | return real_HMAC.__init__(self, key, msg, digestmod) 43 | def update(self, msg): 44 | if isinstance(msg, str): 45 | msg = msg.encode('ascii') 46 | return real_HMAC.update(self, msg) 47 | 48 | hmac.HMAC = HMAC 49 | 50 | import urllib.parse 51 | real_quote = urllib.parse.quote 52 | def quote(value): # fix bucket.py:386 53 | if isinstance(value, str) and value.startswith("b'"): 54 | value = eval(value).decode('ascii') 55 | result = real_quote(value) 56 | return result 57 | urllib.quote = quote 58 | 59 | import base64 60 | real_encodestring = base64.encodestring 61 | def encodestring(s): 62 | result = real_encodestring(s) 63 | return result.decode('ascii') 64 | base64.encodestring = encodestring 65 | 66 | fix() 67 | del fix 68 | 69 | #import logging 70 | #logging.basicConfig(filename="boto.log", level=logging.DEBUG) 71 | 72 | -------------------------------------------------------------------------------- /experiments/cython-boto/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from Cython.Build import cythonize 3 | 4 | setup( 5 | name="Boto", 6 | ext_modules=( 7 | cythonize('boto/[a-z]*.py', error_on_unknown_names=False) + 8 | cythonize('boto/gs/[a-z]*.py', error_on_unknown_names=False) + 9 | cythonize('boto/pyami/[a-z]*.py', error_on_unknown_names=False) + 10 | cythonize('boto/s3/[a-z]*.py', error_on_unknown_names=False) + 11 | cythonize('boto/utils/[a-z]*.py', error_on_unknown_names=False) + 12 | [] 13 | ), 14 | ) 15 | -------------------------------------------------------------------------------- /experiments/cython-boto/test.py: -------------------------------------------------------------------------------- 1 | # Needs environment variables: 2 | # AWS_ACCESS_KEY_ID 3 | # AWS_SECRET_ACCESS_KEY 4 | 5 | import boto 6 | 7 | def main(): 8 | conn = boto.connect_s3() 9 | bucket = conn.create_bucket('jplephem') 10 | for item in bucket.list(): 11 | print(item.name) 12 | 13 | if __name__ == '__main__': 14 | main() 15 | -------------------------------------------------------------------------------- /experiments/cython-boto/tmp.sh: -------------------------------------------------------------------------------- 1 | 2 | set -e 3 | set -v 4 | 5 | V3=~/.v/exe-from-python-experiments-py23 6 | 7 | echo $V3/include/python3.4 8 | 9 | gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing \ 10 | -I$V3/include/python3.4m -o boto/auth.so boto/auth.c 11 | -------------------------------------------------------------------------------- /experiments/cython/cy_harmonic.pyx: -------------------------------------------------------------------------------- 1 | import numba 2 | import timeit 3 | 4 | def h(start, terms): 5 | n = start 6 | for i in xrange(1, terms): 7 | n += 1.0 / i 8 | return n 9 | 10 | def call_h(): 11 | return h(0.0, 10000000) 12 | 13 | def h2(start, terms): 14 | cdef double n = start 15 | cdef int i 16 | for i in xrange(1, terms): 17 | n += 1.0 / i 18 | return n 19 | 20 | def call_h2(): 21 | return h2(0.0, 10000000) 22 | 23 | def main(): 24 | print call_h() 25 | print call_h2() 26 | print min(timeit.repeat(call_h, number=1)) 27 | print min(timeit.repeat(call_h2, number=1)) 28 | 29 | if __name__ == '__main__': 30 | main() 31 | -------------------------------------------------------------------------------- /experiments/cython/harmonic.py: -------------------------------------------------------------------------------- 1 | import timeit 2 | 3 | def h(start, terms): 4 | n = start 5 | for i in xrange(1, terms): 6 | n += 1.0 / i 7 | return n 8 | 9 | def call_h(): 10 | return h(0.0, 10000000) 11 | 12 | if __name__ == '__main__': 13 | print call_h() 14 | print min(timeit.repeat(call_h, number=1)) 15 | -------------------------------------------------------------------------------- /experiments/cython/run.py: -------------------------------------------------------------------------------- 1 | import pyximport 2 | pyximport.install() 3 | import cy_harmonic 4 | cy_harmonic.main() 5 | -------------------------------------------------------------------------------- /experiments/numba/harmonic.py: -------------------------------------------------------------------------------- 1 | import numba 2 | import timeit 3 | 4 | def h(start, terms): 5 | n = start 6 | for i in xrange(1, terms): 7 | n += 1.0 / i 8 | return n 9 | 10 | def call_h(): 11 | h(0.0, 10000000) 12 | 13 | h2 = numba.jit(h) 14 | 15 | def call_h2(): 16 | h2(0.0, 10000000) 17 | 18 | h3 = numba.jit('f8,int64')(h) 19 | 20 | def call_h3(): 21 | h3(0.0, 10000000) 22 | 23 | if __name__ == '__main__': 24 | #print harmonic_sum() 25 | #print timeit(harmonic_sum, number=1) 26 | print min(timeit.repeat(call_h2, number=1)) 27 | print min(timeit.repeat(call_h3, number=1)) 28 | -------------------------------------------------------------------------------- /experiments/numba/test.py: -------------------------------------------------------------------------------- 1 | import numba 2 | 3 | #@numba.autojit 4 | @numba.jit('f8,f8') 5 | def f(x, y): 6 | return x * x + y * y 7 | 8 | if __name__ == '__main__': 9 | print numba.__version__ 10 | f.inspect_types() # nothing prints 11 | print f(3, 4) # prints "25" 12 | f.inspect_types() 13 | print f(3.1, 4.1) # prints "25" (!) 14 | f.inspect_types() 15 | -------------------------------------------------------------------------------- /experiments/py23/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing \ 3 | # -I/usr/include/python2.5 -o yourmod.so yourmod.c 4 | 5 | something: example_python2.py 6 | python3.4 setup.py build_ext --inplace 7 | 8 | #example_python2.c: example_python2.py 9 | # cython $< 10 | 11 | run: 12 | python3.4 -c 'import example_python2; example_python2.two()' 13 | 14 | clean: 15 | rm -f *.c *.so 16 | -------------------------------------------------------------------------------- /experiments/py23/example_python2.py: -------------------------------------------------------------------------------- 1 | 2 | def two(): 3 | try: 4 | print 'Plain old Python 2' 5 | except Exception, e: 6 | print e 7 | 8 | if __name__ == '__main__': 9 | two() 10 | -------------------------------------------------------------------------------- /experiments/py23/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from Cython.Build import cythonize 3 | 4 | setup( 5 | ext_modules = cythonize('example_python2.py') 6 | ) 7 | -------------------------------------------------------------------------------- /experiments/pycc/Makefile: -------------------------------------------------------------------------------- 1 | test.so: test.py 2 | pycc test.py 3 | -------------------------------------------------------------------------------- /experiments/pycc/test.py: -------------------------------------------------------------------------------- 1 | from numba import export 2 | 3 | def mult(a, b): 4 | return a * b 5 | 6 | export('mult f8(f8, f8)')(mult) 7 | -------------------------------------------------------------------------------- /nuitka/Makefile: -------------------------------------------------------------------------------- 1 | # You can override the TARGET on the command line with: make TARGET=... 2 | TARGET := hello 3 | 4 | # We download and run Nuitka directly out of its .tar.gz archive, since 5 | # installing it in a virtual environment will cause it to use the 6 | # environment's site.py in every standalone executable. Which makes 7 | # every standalone executable give IOError for "orig-prefix.txt". 8 | 9 | VERSION := 0.5.1.1 10 | NUITKA := ../cache/Nuitka-$(VERSION)/bin/nuitka 11 | URL := https://pypi.python.org/packages/source/N/Nuitka/Nuitka-$(VERSION).tar.gz#md5=f99f120a0f6f4c814095054bff53a497 12 | 13 | # We run Nuitka with the system Python, but add the virtual 14 | # environment's site-packages directory manually to PYTHONPATH so that 15 | # Nuitka can find our dependencies. 16 | 17 | SITE_PACKAGES := $(shell python -c 'import sys; print [p for p in sys.path if "site-packages" in p][0]') 18 | PYTHON := PYTHONPATH=$(SITE_PACKAGES) /usr/bin/python2.7 19 | 20 | all: $(TARGET).exe $(TARGET).dist/$(TARGET).exe 21 | 22 | $(TARGET).exe: $(NUITKA) 23 | $(PYTHON) $(NUITKA) ../scripts/$(TARGET).py 24 | 25 | $(TARGET).dist/$(TARGET).exe: $(NUITKA) 26 | $(PYTHON) $(NUITKA) --standalone ../scripts/$(TARGET).py 27 | 28 | $(NUITKA): ../cache/Nuitka-$(VERSION).tar.gz 29 | cd ../cache && tar xvfz Nuitka-$(VERSION).tar.gz && touch $(NUITKA) 30 | 31 | ../cache/Nuitka-$(VERSION).tar.gz: 32 | mkdir -p ../cache && cd ../cache && wget $(URL) 33 | -------------------------------------------------------------------------------- /output/Dockerfile: -------------------------------------------------------------------------------- 1 | # DOCKER-VERSION 0.9.1 2 | 3 | FROM ubuntu:13.10 4 | RUN apt-get -y install libpython2.7 5 | ADD cython cython 6 | ADD nuitka nuitka 7 | ADD compare.sh compare.sh 8 | -------------------------------------------------------------------------------- /output/compare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname "${BASH_SOURCE[0]}") 4 | 5 | for script in $(ls cython) 6 | do 7 | echo "======================================== Cython: $script" 8 | ./cython/$script 9 | echo "======================================== Nuitka: $script" 10 | ./nuitka/$script.dist/$script.exe 11 | echo 12 | done 13 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Under 64-bit Ubuntu, SWIG will need some help: 2 | # SWIG_FEATURES=-I/usr/include/x86_64-linux-gnu pip install -r requirements.txt 3 | 4 | cython==0.20.1 5 | nuitka==0.5.1.1 6 | PyInstaller==2.1 7 | 8 | M2Crypto==0.22.3 9 | pycrypto==2.6.1 10 | # llvmpy 11 | -------------------------------------------------------------------------------- /scripts/cascade.py: -------------------------------------------------------------------------------- 1 | from cascade2 import square 2 | print(square(9)) 3 | def main(): 4 | print(square(11)) 5 | if __name__ == '__main__': 6 | main() 7 | -------------------------------------------------------------------------------- /scripts/cascade2.py: -------------------------------------------------------------------------------- 1 | from cascade3 import square 2 | -------------------------------------------------------------------------------- /scripts/cascade3.py: -------------------------------------------------------------------------------- 1 | def square(x): 2 | return x * x 3 | -------------------------------------------------------------------------------- /scripts/cascade_init.pyx: -------------------------------------------------------------------------------- 1 | 2 | cdef extern: 3 | void initcascade() 4 | void initcascade3() 5 | void initcascade2() 6 | 7 | initcascade3() 8 | initcascade2() 9 | initcascade() 10 | 11 | import cascade 12 | cascade.main() 13 | -------------------------------------------------------------------------------- /scripts/harmonic_sum.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from time import time 3 | 4 | ten_million = 10000000 5 | xrange = range if sys.version_info >= (3, 0) else xrange 6 | 7 | def compute_harmonic_sum(terms=ten_million): 8 | t0 = time() 9 | n = 0.0 10 | for i in xrange(1, terms + 1): 11 | n += 1.0 / i 12 | t1 = time() 13 | print('Sum {}'.format(n)) 14 | print('Milliseconds {}'.format((t1 - t0) * 1000.0)) 15 | 16 | def compute_harmonic_sum_with_numpy(terms=ten_million): 17 | import numpy as np 18 | t0 = time() 19 | v = np.arange(1.0, terms + 1.0, 1.0) 20 | n = (1.0 / v).sum() 21 | t1 = time() 22 | print('Sum {}'.format(n)) 23 | print('Milliseconds {}'.format((t1 - t0) * 1000.0)) 24 | 25 | if __name__ == '__main__': 26 | if len(sys.argv) > 1: 27 | compute_harmonic_sum_with_numpy(terms=ten_million) 28 | else: 29 | compute_harmonic_sum() 30 | -------------------------------------------------------------------------------- /scripts/hello.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | print("Hello, world.") 3 | 4 | if __name__ == '__main__': 5 | main() 6 | -------------------------------------------------------------------------------- /scripts/needs_bottle.py: -------------------------------------------------------------------------------- 1 | from bottle import route, run, template 2 | 3 | @route('/hello/') 4 | def index(name): 5 | return template('Hello {{name}}!', name=name) 6 | 7 | run(host='localhost', port=8080) 8 | -------------------------------------------------------------------------------- /scripts/needs_crypto.py: -------------------------------------------------------------------------------- 1 | 2 | from Crypto.Cipher import AES 3 | 4 | def main(): 5 | obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456') 6 | message = "The answer is no" 7 | ciphertext = obj.encrypt(message) 8 | assert ciphertext == b'\xd6\x83\x8dd!VT\x92\xaa`A\x05\xe0\x9b\x8b\xf1' 9 | print(repr(ciphertext)) 10 | 11 | if __name__ == '__main__': 12 | main() 13 | -------------------------------------------------------------------------------- /scripts/needs_flask.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route("/") 5 | def hello(): 6 | return "Hello World!" 7 | 8 | if __name__ == "__main__": 9 | app.run() 10 | -------------------------------------------------------------------------------- /scripts/needs_m2crypto.py: -------------------------------------------------------------------------------- 1 | import cStringIO 2 | from binascii import hexlify, unhexlify 3 | from M2Crypto import EVP 4 | 5 | def main(): 6 | # From test_AES of: 7 | # http://svn.osafoundation.org/m2crypto/trunk/tests/test_evp.py 8 | 9 | enc = 1 10 | dec = 0 11 | test = { 12 | 'KEY': '06a9214036b8a15b512e03d534120006', 13 | 'IV': '3dafba429d9eb430b422da802c9fac41', 14 | 'PT': 'Single block msg', 15 | 'CT': 'e353779c1079aeb82708942dbe77181a', 16 | } 17 | 18 | k=EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']), iv=unhexlify(test['IV']), op=enc) 19 | pbuf=cStringIO.StringIO(test['PT']) 20 | cbuf=cStringIO.StringIO() 21 | ciphertext = hexlify(cipher_filter(k, pbuf, cbuf)) 22 | cipherpadding = ciphertext[len(test['PT']) * 2:] 23 | ciphertext = ciphertext[:len(test['PT']) * 2] # Remove the padding from the end 24 | pbuf.close() 25 | cbuf.close() 26 | assert ciphertext == test['CT'] 27 | 28 | # decrypt 29 | j=EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']), iv=unhexlify(test['IV']), op=dec) 30 | pbuf=cStringIO.StringIO() 31 | cbuf=cStringIO.StringIO(unhexlify(test['CT'] + cipherpadding)) 32 | plaintext=cipher_filter(j, cbuf, pbuf) 33 | pbuf.close() 34 | cbuf.close() 35 | assert plaintext == test['PT'] 36 | 37 | # encrypt 38 | k=EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']), iv=unhexlify(test['IV']), op=enc, padding=False) 39 | pbuf=cStringIO.StringIO(test['PT']) 40 | cbuf=cStringIO.StringIO() 41 | ciphertext = hexlify(cipher_filter(k, pbuf, cbuf)) 42 | pbuf.close() 43 | cbuf.close() 44 | assert ciphertext == test['CT'] 45 | print(repr(ciphertext)) 46 | 47 | # decrypt 48 | j=EVP.Cipher(alg='aes_128_cbc', key=unhexlify(test['KEY']), iv=unhexlify(test['IV']), op=dec, padding=False) 49 | pbuf=cStringIO.StringIO() 50 | cbuf=cStringIO.StringIO(unhexlify(test['CT'])) 51 | plaintext=cipher_filter(j, cbuf, pbuf) 52 | pbuf.close() 53 | cbuf.close() 54 | assert plaintext == test['PT'] 55 | 56 | def cipher_filter(cipher, inf, outf): 57 | while 1: 58 | buf=inf.read() 59 | if not buf: 60 | break 61 | outf.write(cipher.update(buf)) 62 | outf.write(cipher.final()) 63 | return outf.getvalue() 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /timer.py: -------------------------------------------------------------------------------- 1 | import time, argparse, subprocess 2 | 3 | # Set up the parser to take in the command/options 4 | parser = argparse.ArgumentParser(description='Process some integers.') 5 | parser.add_argument('file_name', metavar='', 6 | help='The file to output the result to') 7 | parser.add_argument('cmd', metavar='', 8 | help='The command to run (and time)') 9 | parser.add_argument('-args', dest='dash_args', nargs='*', 10 | help='Extra args to add to the command') 11 | args = parser.parse_args() 12 | 13 | # Run the process and calculate how long it takes 14 | start_time = time.clock() 15 | if args.dash_args: 16 | subprocess.call([args.cmd] + ['-{0}'.format(option) for option in args.dash_args]) 17 | else: 18 | subprocess.call(args.cmd) 19 | end_time = time.clock() 20 | deltaT = end_time - start_time 21 | 22 | # Write to file 23 | f = open(args.file_name, 'w') 24 | f.write("{0}".format(deltaT)) 25 | f.close() 26 | -------------------------------------------------------------------------------- /trace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | strace -o trace.out "$@" 4 | echo 'open() -' $(grep -cP '^open' trace.out) 5 | echo ' failure -' $(grep -cP '^open.* = -' trace.out) 6 | echo ' success -' $(grep -cP '^open.* = \d' trace.out) 7 | --------------------------------------------------------------------------------