Skip to content

Commit

Permalink
Merge 705276c into c3136e4
Browse files Browse the repository at this point in the history
  • Loading branch information
tomato42 committed Nov 11, 2019
2 parents c3136e4 + 705276c commit 89e30be
Show file tree
Hide file tree
Showing 6 changed files with 787 additions and 39 deletions.
5 changes: 3 additions & 2 deletions speed.py
Expand Up @@ -30,14 +30,15 @@ def do(setup_statements, statement):
S3 = "msg = six.b('msg')"
S4 = "sig = sk.sign(msg)"
S5 = "vk = sk.get_verifying_key()"
S6 = "vk.verify(sig, msg)"
S6 = "vk.precompute()"
S7 = "vk.verify(sig, msg)"
# 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
# benchmark to loop over S5 instead of S2
keygen = do([S1], S2)
sign = do([S1,S2,S3], S4)
verf = do([S1,S2,S3,S4,S5], S6)
verf = do([S1,S2,S3,S4,S5,S6], S7)
import ecdsa
c = getattr(ecdsa, curve)
sig = ecdsa.SigningKey.generate(c).sign(six.b("msg"))
Expand Down
14 changes: 8 additions & 6 deletions src/ecdsa/curves.py
Expand Up @@ -2,6 +2,7 @@

from . import der, ecdsa
from .util import orderlen
from .ellipticcurve import PointJacobi


# orderlen was defined in this module previously, so keep it in __all__,
Expand Down Expand Up @@ -36,33 +37,34 @@ def __repr__(self):

# the NIST curves
NIST192p = Curve("NIST192p", ecdsa.curve_192,
ecdsa.generator_192,
PointJacobi.from_affine(ecdsa.generator_192, True),
(1, 2, 840, 10045, 3, 1, 1), "prime192v1")


NIST224p = Curve("NIST224p", ecdsa.curve_224,
ecdsa.generator_224,
PointJacobi.from_affine(ecdsa.generator_224, True),
(1, 3, 132, 0, 33), "secp224r1")


NIST256p = Curve("NIST256p", ecdsa.curve_256,
ecdsa.generator_256,
PointJacobi.from_affine(ecdsa.generator_256, True),
(1, 2, 840, 10045, 3, 1, 7), "prime256v1")


NIST384p = Curve("NIST384p", ecdsa.curve_384,
ecdsa.generator_384,
PointJacobi.from_affine(ecdsa.generator_384, True),
(1, 3, 132, 0, 34), "secp384r1")


NIST521p = Curve("NIST521p", ecdsa.curve_521,
ecdsa.generator_521,
PointJacobi.from_affine(ecdsa.generator_521, True),
(1, 3, 132, 0, 35), "secp521r1")


SECP256k1 = Curve("SECP256k1", ecdsa.curve_secp256k1,
ecdsa.generator_secp256k1,
PointJacobi.from_affine(ecdsa.generator_secp256k1, True),
(1, 3, 132, 0, 10), "secp256k1")

BRAINPOOLP160r1 = Curve("BRAINPOOLP160r1",
ecdsa.curve_brainpoolp160r1,
ecdsa.generator_brainpoolp160r1,
Expand Down
39 changes: 28 additions & 11 deletions src/ecdsa/ecdsa.py
Expand Up @@ -63,6 +63,10 @@ class RSZeroError(RuntimeError):
pass


class InvalidPointError(RuntimeError):
pass


class Signature(object):
"""ECDSA signature.
"""
Expand All @@ -88,36 +92,46 @@ def recover_public_keys(self, hash, generator):
y = beta if beta % 2 == 0 else curve.p() - beta

# Compute the public key
R1 = ellipticcurve.Point(curve, x, y, n)
R1 = ellipticcurve.PointJacobi(curve, x, y, 1, n)
Q1 = numbertheory.inverse_mod(r, n) * (s * R1 + (-e % n) * generator)
Pk1 = Public_key(generator, Q1)

# And the second solution
R2 = ellipticcurve.Point(curve, x, -y, n)
R2 = ellipticcurve.PointJacobi(curve, x, -y, 1, n)
Q2 = numbertheory.inverse_mod(r, n) * (s * R2 + (-e % n) * generator)
Pk2 = Public_key(generator, Q2)

return [Pk1, Pk2]


class Public_key(object):
"""Public key for ECDSA.
"""

def __init__(self, generator, point):
"""generator is the Point that generates the group,
point is the Point that defines the public key.
def __init__(self, generator, point, verify=True):
"""
Low level ECDSA public key object.
:param generator: the Point that generates the group
:param point: the Point that defines the public key
:param bool verify: if True check if point is valid point on curve
:raises InvalidPointError: if the point parameters are invalid or
point does not lie on the curve
"""

self.curve = generator.curve()
self.generator = generator
self.point = point
n = generator.order()
if not n:
raise RuntimeError("Generator point must have order.")
if not n * point == ellipticcurve.INFINITY:
raise RuntimeError("Generator point order is bad.")
if point.x() < 0 or n <= point.x() or point.y() < 0 or n <= point.y():
raise RuntimeError("Generator point has x or y out of range.")
raise InvalidPointError("Generator point has x or y out of range.")
if verify and not self.curve.contains_point(point.x(), point.y()):
raise InvalidPointError("Point does not lie on the curve")
if not n:
raise InvalidPointError("Generator point must have order.")
if verify and not n * point == ellipticcurve.INFINITY:
raise InvalidPointError("Generator point order is bad.")

def verifies(self, hash, signature):
"""Verify that signature is a valid signature of hash.
Expand All @@ -137,7 +151,10 @@ def verifies(self, hash, signature):
c = numbertheory.inverse_mod(s, n)
u1 = (hash * c) % n
u2 = (r * c) % n
xy = u1 * G + u2 * self.point
if hasattr(G, "mul_add"):
xy = G.mul_add(u1, self.point, u2)
else:
xy = u1 * G + u2 * self.point
v = xy.x() % n
return v == r

Expand Down

0 comments on commit 89e30be

Please sign in to comment.