summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Kario <hkario@redhat.com>2021-09-08 22:18:08 +0200
committerHubert Kario <hkario@redhat.com>2021-09-08 22:18:08 +0200
commit0e16ea6eacc609034a2dc3d5dfa1e53d42c41158 (patch)
tree446768e5ca7c3d46b6376acdf80416857234c211
parentc7b5e063447e5d67acc61ec35d9521fa0fce7a24 (diff)
downloadecdsa-stable-speed.tar.gz
Perform exactly the same operations for every speed.py runstable-speed
To make comparisons between different algorithms meaningful, we need to benchmark the exact same operations over and over. Use 100 deterministically random keys to even out key-to-key or sig-to-sig (for verification) differences
-rw-r--r--speed.py53
1 files changed, 39 insertions, 14 deletions
diff --git a/speed.py b/speed.py
index 7e5eb02..c44dcba 100644
--- a/speed.py
+++ b/speed.py
@@ -1,8 +1,10 @@
-import six
import timeit
from ecdsa.curves import curves
+UNIQUE_KEYS = 100
+
+
def do(setup_statements, statement):
# extracted from timeit.py
t = timeit.Timer(stmt=statement, setup="\n".join(setup_statements))
@@ -12,7 +14,7 @@ def do(setup_statements, statement):
x = t.timeit(number)
if x >= 0.2:
break
- return x / number
+ return x / number / UNIQUE_KEYS
prnt_form = (
@@ -43,13 +45,21 @@ print(
)
for curve in [i.name for i in curves]:
- S1 = "import six; from ecdsa import SigningKey, %s" % curve
- S2 = "sk = SigningKey.generate(%s)" % curve
- S3 = "msg = six.b('msg')"
- S4 = "sig = sk.sign(msg)"
- S5 = "vk = sk.get_verifying_key()"
- S6 = "vk.precompute()"
- S7 = "vk.verify(sig, msg)"
+ S1 = "from ecdsa import SigningKey, %s" % curve
+ S1 += "; from ecdsa.util import PRNG"
+ # as the code is very much data dependant, use the same 100 keys
+ # to sign the same 100 messages over and over to make the
+ # benchmarking stable
+ S2 = (
+ "sk = ["
+ "SigningKey.generate({0}, entropy=PRNG(i)) "
+ "for i in range({1})]"
+ ).format(curve, UNIQUE_KEYS)
+ S3 = "msg = b'msg'"
+ S4 = "sig = [k.sign(msg, entropy=PRNG(b'A')) for k in sk]"
+ S5 = "vk = [k.get_verifying_key() for k in sk]"
+ S6 = "[k.precompute() for k in vk]"
+ S7 = "[k.verify(s, msg) for k, s in zip(vk, sig)]"
# We happen to know that .generate() also calculates the
# verifying key, which is the time-consuming part. If the code
# were changed to lazily calculate vk, we'd need to change this
@@ -61,7 +71,7 @@ for curve in [i.name for i in curves]:
import ecdsa
c = getattr(ecdsa, curve)
- sig = ecdsa.SigningKey.generate(c).sign(six.b("msg"))
+ sig = ecdsa.SigningKey.generate(c).sign(b"msg")
print(
prnt_form.format(
name=curve,
@@ -101,10 +111,25 @@ for curve in [i.name for i in curves]:
if curve == "Ed25519" or curve == "Ed448":
continue
S1 = "from ecdsa import SigningKey, ECDH, {0}".format(curve)
- S2 = "our = SigningKey.generate({0})".format(curve)
- S3 = "remote = SigningKey.generate({0}).verifying_key".format(curve)
- S4 = "ecdh = ECDH(private_key=our, public_key=remote)"
- S5 = "ecdh.generate_sharedsecret_bytes()"
+ S1 += "; from ecdsa.util import PRNG"
+ # as with signatures, calculate shared secrets for the same
+ # set of keys over and over
+ S2 = (
+ "our = ["
+ "SigningKey.generate({0}, entropy=PRNG(i)) "
+ "for i in range({1})]"
+ ).format(curve, UNIQUE_KEYS)
+ S3 = (
+ "remote = ["
+ "SigningKey.generate({0}, entropy=PRNG(i+10)).verifying_key "
+ "for i in range({1})]"
+ ).format(curve, UNIQUE_KEYS)
+ S4 = (
+ "ecdh = ["
+ "ECDH(private_key=o, public_key=r) "
+ "for o, r in zip(our, remote)]"
+ )
+ S5 = "[e.generate_sharedsecret_bytes() for e in ecdh]"
ecdh = do([S1, S2, S3, S4], S5)
print(
ecdh_form.format(