summaryrefslogtreecommitdiff
path: root/admin/plot_verify_timing.py
blob: b34400bc5cbf693ae099b83a1040352ef5cb4174 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python3
"""
small helper script used to compare timing of verify() & dummy_verify()
"""
# core
from argparse import ArgumentParser
import sys
from timeit import default_timer as tick
# site
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
# pkg
from passlib.context import CryptContext
# local
__all__ = [
    "main"
]

def main(*args):
    #
    # parse args
    #
    parser = ArgumentParser("""plot hash timing""")
    parser.add_argument("-n", "--number", help="number of iterations",
                        type=int, default=300)
    parser.add_argument("-o", "--output", help="pdf file",
                        default="plot_hash.pdf")

    opts = parser.parse_args(args)

    #
    # init vars
    #
    ctx = CryptContext(schemes=["pbkdf2_sha256"])

    secret = "a9w3857naw958ioa"
    wrong_secret = "q0389wairuowieru"
    hash = ctx.hash(secret)
    ctx.dummy_verify()

    correct = []
    wrong = []
    missing = []

    loops = opts.number

    #
    # run timing loop
    #
    for _ in range(loops):
        # correct pwd
        start = tick()
        ctx.verify(secret, hash)
        delta = tick() - start
        correct.append(delta)

        # wrong pwd
        start = tick()
        ctx.verify(wrong_secret, hash)
        delta = tick() - start
        wrong.append(delta)

        # wrong user / dummy verify
        start = tick()
        ctx.dummy_verify()
        delta = tick() - start
        missing.append(delta)

    #
    # calc quartiles for verify() samples
    #
    samples = sorted(correct + wrong)
    count = len(samples)
    q1 = samples[count // 4]
    q3 = samples[count * 3 // 4]
    iqr = q3 - q1
    ub = q3 + 1.5 * iqr
    lb = q1 - 1.5 * iqr

    #
    # add in dummy samples, calc bounds
    #
    samples.extend(missing)
    ymin = min(min(samples), lb - 0.5 * iqr)
    ymax = max(max(samples), ub)

    #
    # generate graph
    #
    with PdfPages(opts.output) as pdf:
        plt.plot(range(loops), correct, 'go', label="verify success")
        plt.plot(range(loops), wrong, 'yo', label="verify failed")
        plt.plot(range(loops), missing, 'ro', label="dummy_verify()")

        plt.axis([0, loops, ymin, ymax])

        plt.axhline(y=q1, xmax=count, color="r")
        plt.axhline(y=q3, xmax=count, color="r")
        plt.axhline(y=lb, xmax=count, color="orange")
        plt.axhline(y=ub, xmax=count, color="orange")

        plt.ylabel('elapsed time')
        plt.xlabel('loop count')
        plt.legend(shadow=True, title="Legend", fancybox=True)

        plt.title('%s verify timing' % ctx.handler().name)
        pdf.savefig()
        plt.close()

if __name__ == "__main__":
    sys.exit(main(*sys.argv[1:]))