1#!/usr/bin/env python
2
3from __future__ import print_function
4import timeit
5from setuptools import setup, Command
6import versioneer
7
8cmdclass = {}
9cmdclass.update(versioneer.get_cmdclass())
10
11class Speed(Command):
12    description = "run speed benchmarks"
13    user_options = []
14    boolean_options = []
15    def initialize_options(self):
16        pass
17    def finalize_options(self):
18        pass
19    def run(self):
20        def do(setup_statements, statement):
21            # extracted from timeit.py
22            t = timeit.Timer(stmt=statement,
23                             setup="\n".join(setup_statements))
24            # determine number so that 0.2 <= total time < 2.0
25            for i in range(1, 10):
26                number = 10**i
27                x = t.timeit(number)
28                if x >= 0.2:
29                    break
30            return x / number
31
32        def abbrev(t):
33            if t > 1.0:
34                return "%.3fs" % t
35            if t > 1e-3:
36                return "%.1fms" % (t*1e3)
37            return "%.1fus" % (t*1e6)
38
39        for params in ["ParamsEd25519",
40                       "Params1024", "Params2048", "Params3072"]:
41            S1 = "from spake2 import SPAKE2_A, SPAKE2_B; from spake2.parameters.all import %s" % params
42            S2 = "sB = SPAKE2_B(b'password', params=%s)" % params
43            S3 = "mB = sB.start()"
44            S4 = "sA = SPAKE2_A(b'password', params=%s)" % params
45            S5 = "mA = sA.start()"
46            S8 = "key = sA.finish(mB)"
47
48            full = do([S1, S2, S3], ";".join([S4, S5, S8]))
49            start = do([S1], ";".join([S4, S5]))
50            # how large is the generated message?
51            from spake2.parameters import all as all_params
52            from spake2 import SPAKE2_A
53            p = getattr(all_params, params)
54            s = SPAKE2_A(b"pw", params=p)
55            msglen = len(s.start())
56            statelen = len(s.serialize())
57            print("%-13s: msglen=%3d, statelen=%3d, full=%6s, start=%6s"
58                  % (params, msglen, statelen, abbrev(full), abbrev(start)))
59cmdclass["speed"] = Speed
60
61setup(name="spake2",
62      version=versioneer.get_version(),
63      description="SPAKE2 password-authenticated key exchange (pure python)",
64      author="Brian Warner",
65      author_email="warner-pyspake2@lothar.com",
66      url="https://github.com/warner/python-spake2",
67      package_dir={"": "src"},
68      packages=["spake2", "spake2.parameters", "spake2.test"],
69      license="MIT",
70      cmdclass=cmdclass,
71      classifiers=[
72          "Intended Audience :: Developers",
73          "License :: OSI Approved :: MIT License",
74          "Programming Language :: Python",
75          "Programming Language :: Python :: 2.7",
76          "Programming Language :: Python :: 3.3",
77          "Programming Language :: Python :: 3.4",
78          "Programming Language :: Python :: 3.5",
79          "Programming Language :: Python :: 3.6",
80          "Topic :: Security :: Cryptography",
81          ],
82      install_requires=["hkdf"],
83      )
84