Skip to content

Commit

Permalink
Merge c7157cc into 5a6fc04
Browse files Browse the repository at this point in the history
  • Loading branch information
samrushing committed Mar 26, 2015
2 parents 5a6fc04 + c7157cc commit f134f10
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
39 changes: 39 additions & 0 deletions ecdsa/keys.py
Expand Up @@ -7,6 +7,7 @@
from .util import string_to_number, number_to_string, randrange
from .util import sigencode_string, sigdecode_string
from .util import oid_ecPublicKey, encoded_oid_ecPublicKey
from .numbertheory import square_root_mod_prime
from .six import PY3, b
from hashlib import sha1

Expand Down Expand Up @@ -47,6 +48,30 @@ def from_string(klass, string, curve=NIST192p, hashfunc=sha1,
point = ellipticcurve.Point(curve.curve, x, y, order)
return klass.from_public_point(point, curve, hashfunc)

# based on code from https://github.com/richardkiss/pycoin
@classmethod
def from_sec (klass, string, curve=NIST192p, hashfunc=sha1, validate_point=True):
if string.startswith (b'\x04'):
# uncompressed
return klass.from_string (string[1:], curve, hashfunc, validate_point)
elif string.startswith (b('\x02')) or string.startswith (b'\x03'):
# compressed
is_even = string.startswith (b'\x02')
x = string_to_number (string[1:])
order = curve.order
p = curve.curve.p()
alpha = (pow(x, 3, p) + curve.curve.a() * x + curve.curve.b()) % p
beta = square_root_mod_prime (alpha, p)
if is_even == bool(beta & 1):
y = p - beta
else:
y = beta
if validate_point:
assert ecdsa.point_is_valid(curve.generator, x, y)
from . import ellipticcurve
point = ellipticcurve.Point (curve.curve, x, y, order)
return klass.from_public_point (point, curve, hashfunc)

@classmethod
def from_pem(klass, string):
return klass.from_der(der.unpem(string))
Expand Down Expand Up @@ -83,6 +108,20 @@ def to_string(self):
y_str = number_to_string(self.pubkey.point.y(), order)
return x_str + y_str

def to_sec(self, compressed=True):
order = self.pubkey.order
x = self.pubkey.point.x()
y = self.pubkey.point.y()
x_str = number_to_string(x, order)
if compressed:
if y & 1:
return b('\x03') + x_str
else:
return b('\x02') + x_str
else:
y_str = number_to_string(y, order)
return b('\x04') + x_str + y_str

def to_pem(self):
return der.topem(self.to_der(), "PUBLIC KEY")

Expand Down
17 changes: 17 additions & 0 deletions ecdsa/test_pyecdsa.py
Expand Up @@ -50,6 +50,23 @@ def test_basic(self):
pub2 = VerifyingKey.from_string(pub.to_string())
self.assertTrue(pub2.verify(sig, data))

def test_sec(self):
for i in range (20):
skey = SigningKey.generate()
pkey0 = skey.get_verifying_key()
sec0 = pkey0.to_sec()
pkey1 = VerifyingKey.from_sec (sec0)
self.assertEqual (pkey0.to_string(), pkey1.to_string())
pkey2 = VerifyingKey.from_sec (unhexlify (b (
'045b9dfc2af65bd5fb0bd01103ab21e9cfeb1eeafa10795d6801b14e09beadd7f8'
'55981f2803fc3c07edfc2435fbf2326d65d3f237f0bcc2399514255b8d4285c5')),
curve=SECP256k1
)
self.assertEqual (
pkey2.to_sec (compressed=True),
unhexlify (b('035b9dfc2af65bd5fb0bd01103ab21e9cfeb1eeafa10795d6801b14e09beadd7f8'))
)

def test_deterministic(self):
data = b("blahblah")
secexp = int("9d0219792467d7d37b4d43298a7d0c05", 16)
Expand Down

0 comments on commit f134f10

Please sign in to comment.