diff options
author | Brian Warner <warner@lothar.com> | 2013-10-01 16:13:26 -0700 |
---|---|---|
committer | Brian Warner <warner@lothar.com> | 2013-10-01 16:13:26 -0700 |
commit | 12f68c43669d7efb73717846ba0fe4cbb439563e (patch) | |
tree | 5962289afbb5f3b8e227b57fb492709a45888f52 | |
parent | c50d4892ac022aefb271f7464027c81c8710bf43 (diff) | |
parent | 13d645ddabe57b53dc62272ee4cb9ad14493a7f6 (diff) | |
download | ecdsa-12f68c43669d7efb73717846ba0fe4cbb439563e.tar.gz |
Merge branch 'py3'
-rw-r--r-- | .gitignore | 56 | ||||
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | ecdsa/__init__.py | 7 | ||||
-rw-r--r-- | ecdsa/curves.py | 4 | ||||
-rw-r--r-- | ecdsa/der.py | 101 | ||||
-rw-r--r-- | ecdsa/ecdsa.py | 363 | ||||
-rw-r--r-- | ecdsa/ellipticcurve.py | 73 | ||||
-rw-r--r-- | ecdsa/keys.py | 39 | ||||
-rw-r--r-- | ecdsa/numbertheory.py | 47 | ||||
-rw-r--r-- | ecdsa/rfc6979.py | 17 | ||||
-rw-r--r-- | ecdsa/six.py | 394 | ||||
-rw-r--r-- | ecdsa/test_pyecdsa.py | 403 | ||||
-rw-r--r-- | ecdsa/util.py | 28 | ||||
-rwxr-xr-x | setup.py | 12 |
14 files changed, 1011 insertions, 535 deletions
@@ -1,8 +1,48 @@ -/.coverage -/coverage-html/ -/t/ -/build/ -/ecdsa/_version.py -/MANIFEST -/dist/ -*.pyc +*.py[cod] +ecdsa/_version.py +MANIFEST + +# C extensions +*.so +*.dylib + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 +__pycache__ + +# Installer logs +pip-log.txt + +# Other logs +*.log + +# Unit test / coverage reports +.coverage +coverage-html +.tox +nosetests.xml +t/ + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# Backup files +*.swp +*~ diff --git a/.travis.yml b/.travis.yml index e452544..bb87cb5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,8 @@ python: - "2.5" - "2.6" - "2.7" + - "3.2" + - "3.3" install: true script: - python setup.py test diff --git a/ecdsa/__init__.py b/ecdsa/__init__.py index 0ba98be..77fec2d 100644 --- a/ecdsa/__init__.py +++ b/ecdsa/__init__.py @@ -1,6 +1,7 @@ - -from keys import SigningKey, VerifyingKey, BadSignatureError, BadDigestError -from curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p +__all__ = ["curves", "der", "ecdsa", "ellipticcurve", "keys", "numbertheory", + "test_pyecdsa", "util", "six"] +from .keys import SigningKey, VerifyingKey, BadSignatureError, BadDigestError +from .curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p _hush_pyflakes = [SigningKey, VerifyingKey, BadSignatureError, BadDigestError, NIST192p, NIST224p, NIST256p, NIST384p, NIST521p] diff --git a/ecdsa/curves.py b/ecdsa/curves.py index e254ebb..b8772a2 100644 --- a/ecdsa/curves.py +++ b/ecdsa/curves.py @@ -1,4 +1,6 @@ -import der, ecdsa +from __future__ import division + +from . import der, ecdsa class UnknownCurveError(Exception): pass diff --git a/ecdsa/der.py b/ecdsa/der.py index e03ad9c..e7b6068 100644 --- a/ecdsa/der.py +++ b/ecdsa/der.py @@ -1,39 +1,43 @@ +from __future__ import division + import binascii import base64 +from .six import int2byte, b, PY3, integer_types, text_type class UnexpectedDER(Exception): pass def encode_constructed(tag, value): - return chr(0xa0+tag) + encode_length(len(value)) + value + return int2byte(0xa0+tag) + encode_length(len(value)) + value def encode_integer(r): assert r >= 0 # can't support negative numbers yet - h = "%x" % r - if len(h)%2: - h = "0" + h + h = ("%x" % r).encode() + if len(h) % 2: + h = b("0") + h s = binascii.unhexlify(h) - if ord(s[0]) <= 0x7f: - return "\x02" + chr(len(s)) + s + num = s[0] if isinstance(s[0], integer_types) else ord(s[0]) + if num <= 0x7f: + return b("\x02") + int2byte(len(s)) + s else: # DER integers are two's complement, so if the first byte is # 0x80-0xff then we need an extra 0x00 byte to prevent it from # looking negative. - return "\x02" + chr(len(s)+1) + "\x00" + s + return b("\x02") + int2byte(len(s)+1) + b("\x00") + s def encode_bitstring(s): - return "\x03" + encode_length(len(s)) + s + return b("\x03") + encode_length(len(s)) + s def encode_octet_string(s): - return "\x04" + encode_length(len(s)) + s + return b("\x04") + encode_length(len(s)) + s def encode_oid(first, second, *pieces): assert first <= 2 assert second <= 39 - encoded_pieces = [chr(40*first+second)] + [encode_number(p) - for p in pieces] - body = "".join(encoded_pieces) - return "\x06" + encode_length(len(body)) + body + encoded_pieces = [int2byte(40*first+second)] + [encode_number(p) + for p in pieces] + body = b('').join(encoded_pieces) + return b('\x06') + encode_length(len(body)) + body def encode_sequence(*encoded_pieces): total_len = sum([len(p) for p in encoded_pieces]) - return "\x30" + encode_length(total_len) + "".join(encoded_pieces) + return b('\x30') + encode_length(total_len) + b('').join(encoded_pieces) def encode_number(n): b128_digits = [] while n: @@ -42,10 +46,10 @@ def encode_number(n): if not b128_digits: b128_digits.append(0) b128_digits[-1] &= 0x7f - return "".join([chr(d) for d in b128_digits]) + return b('').join([int2byte(d) for d in b128_digits]) def remove_constructed(string): - s0 = ord(string[0]) + s0 = string[0] if isinstance(string[0], integer_types) else ord(string[0]) if (s0 & 0xe0) != 0xa0: raise UnexpectedDER("wanted constructed tag (0xa0-0xbf), got 0x%02x" % s0) @@ -56,26 +60,26 @@ def remove_constructed(string): return tag, body, rest def remove_sequence(string): - if not string.startswith("\x30"): - raise UnexpectedDER("wanted sequence (0x30), got 0x%02x" % - ord(string[0])) + if not string.startswith(b("\x30")): + n = string[0] if isinstance(string[0], integer_types) else ord(string[0]) + raise UnexpectedDER("wanted sequence (0x30), got 0x%02x" % n) length, lengthlength = read_length(string[1:]) endseq = 1+lengthlength+length return string[1+lengthlength:endseq], string[endseq:] def remove_octet_string(string): - if not string.startswith("\x04"): - raise UnexpectedDER("wanted octetstring (0x04), got 0x%02x" % - ord(string[0])) + if not string.startswith(b("\x04")): + n = string[0] if isinstance(string[0], integer_types) else ord(string[0]) + raise UnexpectedDER("wanted octetstring (0x04), got 0x%02x" % n) length, llen = read_length(string[1:]) body = string[1+llen:1+llen+length] rest = string[1+llen+length:] return body, rest def remove_object(string): - if not string.startswith("\x06"): - raise UnexpectedDER("wanted object (0x06), got 0x%02x" % - ord(string[0])) + if not string.startswith(b("\x06")): + n = string[0] if isinstance(string[0], integer_types) else ord(string[0]) + raise UnexpectedDER("wanted object (0x06), got 0x%02x" % n) length, lengthlength = read_length(string[1:]) body = string[1+lengthlength:1+lengthlength+length] rest = string[1+lengthlength+length:] @@ -92,13 +96,14 @@ def remove_object(string): return tuple(numbers), rest def remove_integer(string): - if not string.startswith("\x02"): - raise UnexpectedDER("wanted integer (0x02), got 0x%02x" % - ord(string[0])) + if not string.startswith(b("\x02")): + n = string[0] if isinstance(string[0], integer_types) else ord(string[0]) + raise UnexpectedDER("wanted integer (0x02), got 0x%02x" % n) length, llen = read_length(string[1:]) numberbytes = string[1+llen:1+llen+length] rest = string[1+llen+length:] - assert ord(numberbytes[0]) < 0x80 # can't support negative numbers yet + nbytes = numberbytes[0] if isinstance(numberbytes[0], integer_types) else ord(numberbytes[0]) + assert nbytes < 0x80 # can't support negative numbers yet return int(binascii.hexlify(numberbytes), 16), rest def read_number(string): @@ -109,7 +114,7 @@ def read_number(string): if llen > len(string): raise UnexpectedDER("ran out of length bytes") number = number << 7 - d = ord(string[llen]) + d = string[llen] if isinstance(string[llen], integer_types) else ord(string[llen]) number += (d & 0x7f) llen += 1 if not d & 0x80: @@ -119,29 +124,30 @@ def read_number(string): def encode_length(l): assert l >= 0 if l < 0x80: - return chr(l) - s = "%x" % l + return int2byte(l) + s = ("%x" % l).encode() if len(s)%2: - s = "0"+s + s = b("0")+s s = binascii.unhexlify(s) llen = len(s) - return chr(0x80|llen) + s + return int2byte(0x80|llen) + s def read_length(string): - if not (ord(string[0]) & 0x80): + num = string[0] if isinstance(string[0], integer_types) else ord(string[0]) + if not (num & 0x80): # short form - return (ord(string[0]) & 0x7f), 1 + return (num & 0x7f), 1 # else long-form: b0&0x7f is number of additional base256 length bytes, # big-endian - llen = ord(string[0]) & 0x7f + llen = num & 0x7f if llen > len(string)-1: raise UnexpectedDER("ran out of length bytes") return int(binascii.hexlify(string[1:1+llen]), 16), 1+llen def remove_bitstring(string): - if not string.startswith("\x03"): - raise UnexpectedDER("wanted bitstring (0x03), got 0x%02x" % - ord(string[0])) + num = string[0] if isinstance(string[0], integer_types) else ord(string[0]) + if not string.startswith(b("\x03")): + raise UnexpectedDER("wanted bitstring (0x03), got 0x%02x" % num) length, llen = read_length(string[1:]) body = string[1+llen:1+llen+length] rest = string[1+llen+length:] @@ -177,14 +183,17 @@ def remove_bitstring(string): # iso(1) identified-organization(3) certicom(132) curve(0) 34 } def unpem(pem): - d = "".join([l.strip() for l in pem.split("\n") - if l and not l.startswith("-----")]) + if isinstance(pem, text_type): + pem = pem.encode() + + d = b("").join([l.strip() for l in pem.split(b("\n")) + if l and not l.startswith(b("-----"))]) return base64.b64decode(d) def topem(der, name): b64 = base64.b64encode(der) - lines = ["-----BEGIN %s-----\n" % name] - lines.extend([b64[start:start+64]+"\n" + lines = [("-----BEGIN %s-----\n" % name).encode()] + lines.extend([b64[start:start+64]+b("\n") for start in range(0, len(b64), 64)]) - lines.append("-----END %s-----\n" % name) - return "".join(lines) + lines.append(("-----END %s-----\n" % name).encode()) + return b("").join(lines) diff --git a/ecdsa/ecdsa.py b/ecdsa/ecdsa.py index 3b2fd5f..7538399 100644 --- a/ecdsa/ecdsa.py +++ b/ecdsa/ecdsa.py @@ -1,4 +1,5 @@ #! /usr/bin/env python + """ Implementation of Elliptic-Curve Digital Signatures. @@ -30,16 +31,16 @@ Example: # Verifying a signature for a hash value: if pubkey.verifies( hash, signature ): - print "Demo verification succeeded." + print_("Demo verification succeeded.") else: - print "*** Demo verification failed." + print_("*** Demo verification failed.") # Verification fails if the hash value is modified: if pubkey.verifies( hash-1, signature ): - print "**** Demo verification failed to reject tampered hash." + print_("**** Demo verification failed to reject tampered hash.") else: - print "Demo verification correctly rejected tampered hash." + print_("Demo verification correctly rejected tampered hash.") Version of 2009.05.16. @@ -52,9 +53,9 @@ Revision history: Written in 2005 by Peter Pearson and placed in the public domain. """ - -import ellipticcurve -import numbertheory +from .six import int2byte, b, print_ +from . import ellipticcurve +from . import numbertheory import random @@ -82,11 +83,11 @@ class Public_key( object ): self.point = point n = generator.order() if not n: - raise RuntimeError, "Generator point must have order." + raise RuntimeError("Generator point must have order.") if not n * point == ellipticcurve.INFINITY: - raise RuntimeError, "Generator point order is bad." + 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 RuntimeError("Generator point has x or y out of range.") def verifies( self, hash, signature ): @@ -143,10 +144,10 @@ class Private_key( object ): k = random_k % n p1 = k * G r = p1.x() - if r == 0: raise RuntimeError, "amazingly unlucky random number r" + if r == 0: raise RuntimeError("amazingly unlucky random number r") s = ( numbertheory.inverse_mod( k, n ) * \ ( hash + ( self.secret_multiplier * r ) % n ) ) % n - if s == 0: raise RuntimeError, "amazingly unlucky random number s" + if s == 0: raise RuntimeError("amazingly unlucky random number s") return Signature( r, s ) @@ -154,19 +155,23 @@ class Private_key( object ): def int_to_string( x ): """Convert integer x into a string of bytes, as per X9.62.""" assert x >= 0 - if x == 0: return chr(0) - result = "" - while x > 0: - q, r = divmod( x, 256 ) - result = chr( r ) + result - x = q - return result + if x == 0: return b('\0') + result = [] + while x: + ordinal = x & 0xFF + result.append(int2byte(ordinal)) + x >>= 8 + + result.reverse() + return b('').join(result) def string_to_int( s ): """Convert a string of bytes into an integer, as per X9.62.""" - result = 0L - for c in s: result = 256 * result + ord( c ) + result = 0 + for c in s: + if not isinstance(c, int): c = ord( c ) + result = 256 * result + c return result @@ -201,73 +206,73 @@ def point_is_valid( generator, x, y ): # NIST Curve P-192: -_p = 6277101735386680763835789423207666416083908700390324961279L -_r = 6277101735386680763835789423176059013767194773182842284081L +_p = 6277101735386680763835789423207666416083908700390324961279 +_r = 6277101735386680763835789423176059013767194773182842284081 # s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L # c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65L -_b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1L -_Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012L -_Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811L +_b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1 +_Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012 +_Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811 curve_192 = ellipticcurve.CurveFp( _p, -3, _b ) generator_192 = ellipticcurve.Point( curve_192, _Gx, _Gy, _r ) # NIST Curve P-224: -_p = 26959946667150639794667015087019630673557916260026308143510066298881L -_r = 26959946667150639794667015087019625940457807714424391721682722368061L +_p = 26959946667150639794667015087019630673557916260026308143510066298881 +_r = 26959946667150639794667015087019625940457807714424391721682722368061 # s = 0xbd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5L # c = 0x5b056c7e11dd68f40469ee7f3c7a7d74f7d121116506d031218291fbL -_b = 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4L -_Gx =0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21L -_Gy = 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34L +_b = 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 +_Gx =0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21 +_Gy = 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34 curve_224 = ellipticcurve.CurveFp( _p, -3, _b ) generator_224 = ellipticcurve.Point( curve_224, _Gx, _Gy, _r ) # NIST Curve P-256: -_p = 115792089210356248762697446949407573530086143415290314195533631308867097853951L -_r = 115792089210356248762697446949407573529996955224135760342422259061068512044369L +_p = 115792089210356248762697446949407573530086143415290314195533631308867097853951 +_r = 115792089210356248762697446949407573529996955224135760342422259061068512044369 # s = 0xc49d360886e704936a6678e1139d26b7819f7e90L # c = 0x7efba1662985be9403cb055c75d4f7e0ce8d84a9c5114abcaf3177680104fa0dL -_b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bL -_Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296L -_Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5L +_b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b +_Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 +_Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 curve_256 = ellipticcurve.CurveFp( _p, -3, _b ) generator_256 = ellipticcurve.Point( curve_256, _Gx, _Gy, _r ) # NIST Curve P-384: -_p = 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319L -_r = 39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643L +_p = 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319 +_r = 39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643 # s = 0xa335926aa319a27a1d00896a6773a4827acdac73L # c = 0x79d1e655f868f02fff48dcdee14151ddb80643c1406d0ca10dfe6fc52009540a495e8042ea5f744f6e184667cc722483L -_b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aefL -_Gx = 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7L -_Gy = 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5fL +_b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef +_Gx = 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7 +_Gy = 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f curve_384 = ellipticcurve.CurveFp( _p, -3, _b ) generator_384 = ellipticcurve.Point( curve_384, _Gx, _Gy, _r ) # NIST Curve P-521: -_p = 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151L -_r = 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449L +_p = 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151 +_r = 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449 # s = 0xd09e8800291cb85396cc6717393284aaa0da64baL # c = 0x0b48bfa5f420a34949539d2bdfc264eeeeb077688e44fbf0ad8f6d0edb37bd6b533281000518e19f1b9ffbe0fe9ed8a3c2200b8f875e523868c70c1e5bf55bad637L -_b = 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00L -_Gx = 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66L -_Gy = 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650L +_b = 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 +_Gx = 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66 +_Gy = 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650 curve_521 = ellipticcurve.CurveFp( _p, -3, _b ) generator_521 = ellipticcurve.Point( curve_521, _Gx, _Gy, _r ) # Certicom secp256-k1 -_a = 0x0000000000000000000000000000000000000000000000000000000000000000L -_b = 0x0000000000000000000000000000000000000000000000000000000000000007L -_p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fL -_Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798L -_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L -_r = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141L +_a = 0x0000000000000000000000000000000000000000000000000000000000000000 +_b = 0x0000000000000000000000000000000000000000000000000000000000000007 +_p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f +_Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 +_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 +_r = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 curve_secp256k1 = ellipticcurve.CurveFp( _p, _a, _b) generator_secp256k1 = ellipticcurve.Point( curve_secp256k1, _Gx, _Gy, _r) @@ -281,7 +286,7 @@ def __main__(): """generator defines the curve; is (x,y) a point on this curve? "expected" is True if the right answer is Yes.""" if point_is_valid( generator, x, y ) == expected: - print "Point validity tested as expected." + print_("Point validity tested as expected.") else: raise TestFailure("*** Point validity test gave wrong result.") @@ -293,245 +298,245 @@ def __main__(): ellipticcurve.Point( curve_192, Qx, Qy ) ) got = pubk.verifies( digest_integer( Msg ), Signature( R, S ) ) if got == expected: - print "Signature tested as expected: got %s, expected %s." % \ - ( got, expected ) + print_("Signature tested as expected: got %s, expected %s." % \ + ( got, expected )) else: raise TestFailure("*** Signature test failed: got %s, expected %s." % \ ( got, expected )) - print "NIST Curve P-192:" + print_("NIST Curve P-192:") p192 = generator_192 # From X9.62: - d = 651056770906015076056810763456358567190100156695615665659L + d = 651056770906015076056810763456358567190100156695615665659 Q = d * p192 - if Q.x() != 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5L: + if Q.x() != 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5: raise TestFailure("*** p192 * d came out wrong.") else: - print "p192 * d came out right." + print_("p192 * d came out right.") - k = 6140507067065001063065065565667405560006161556565665656654L + k = 6140507067065001063065065565667405560006161556565665656654 R = k * p192 - if R.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEADL \ - or R.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835L: + if R.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \ + or R.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835: raise TestFailure("*** k * p192 came out wrong.") else: - print "k * p192 came out right." + print_("k * p192 came out right.") - u1 = 2563697409189434185194736134579731015366492496392189760599L - u2 = 6266643813348617967186477710235785849136406323338782220568L + u1 = 2563697409189434185194736134579731015366492496392189760599 + u2 = 6266643813348617967186477710235785849136406323338782220568 temp = u1 * p192 + u2 * Q - if temp.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEADL \ - or temp.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835L: + if temp.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \ + or temp.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835: raise TestFailure("*** u1 * p192 + u2 * Q came out wrong.") else: - print "u1 * p192 + u2 * Q came out right." + print_("u1 * p192 + u2 * Q came out right.") - e = 968236873715988614170569073515315707566766479517L + e = 968236873715988614170569073515315707566766479517 pubk = Public_key( generator_192, generator_192 * d ) privk = Private_key( pubk, d ) sig = privk.sign( e, k ) r, s = sig.r, sig.s - if r != 3342403536405981729393488334694600415596881826869351677613L \ - or s != 5735822328888155254683894997897571951568553642892029982342L: + if r != 3342403536405981729393488334694600415596881826869351677613 \ + or s != 5735822328888155254683894997897571951568553642892029982342: raise TestFailure("*** r or s came out wrong.") else: - print "r and s came out right." + print_("r and s came out right.") valid = pubk.verifies( e, sig ) - if valid: print "Signature verified OK." + if valid: print_("Signature verified OK.") else: raise TestFailure("*** Signature failed verification.") valid = pubk.verifies( e-1, sig ) - if not valid: print "Forgery was correctly rejected." + if not valid: print_("Forgery was correctly rejected.") else: raise TestFailure("*** Forgery was erroneously accepted.") - print "Testing point validity, as per ECDSAVS.pdf B.2.2:" + print_("Testing point validity, as per ECDSAVS.pdf B.2.2:") test_point_validity( \ p192, \ - 0xcd6d0f029a023e9aaca429615b8f577abee685d8257cc83aL, \ - 0x00019c410987680e9fb6c0b6ecc01d9a2647c8bae27721bacdfcL, \ + 0xcd6d0f029a023e9aaca429615b8f577abee685d8257cc83a, \ + 0x00019c410987680e9fb6c0b6ecc01d9a2647c8bae27721bacdfc, \ False ) test_point_validity( p192, \ - 0x00017f2fce203639e9eaf9fb50b81fc32776b30e3b02af16c73bL, \ - 0x95da95c5e72dd48e229d4748d4eee658a9a54111b23b2adbL, \ + 0x00017f2fce203639e9eaf9fb50b81fc32776b30e3b02af16c73b, \ + 0x95da95c5e72dd48e229d4748d4eee658a9a54111b23b2adb, \ False ) test_point_validity( p192, \ - 0x4f77f8bc7fccbadd5760f4938746d5f253ee2168c1cf2792L, \ - 0x000147156ff824d131629739817edb197717c41aab5c2a70f0f6L, \ + 0x4f77f8bc7fccbadd5760f4938746d5f253ee2168c1cf2792, \ + 0x000147156ff824d131629739817edb197717c41aab5c2a70f0f6, \ False ) test_point_validity( p192, \ - 0xc58d61f88d905293bcd4cd0080bcb1b7f811f2ffa41979f6L, \ - 0x8804dc7a7c4c7f8b5d437f5156f3312ca7d6de8a0e11867fL, \ + 0xc58d61f88d905293bcd4cd0080bcb1b7f811f2ffa41979f6, \ + 0x8804dc7a7c4c7f8b5d437f5156f3312ca7d6de8a0e11867f, \ True ) test_point_validity( p192, \ - 0xcdf56c1aa3d8afc53c521adf3ffb96734a6a630a4a5b5a70L, \ - 0x97c1c44a5fb229007b5ec5d25f7413d170068ffd023caa4eL, \ + 0xcdf56c1aa3d8afc53c521adf3ffb96734a6a630a4a5b5a70, \ + 0x97c1c44a5fb229007b5ec5d25f7413d170068ffd023caa4e, \ True ) test_point_validity( p192, \ - 0x89009c0dc361c81e99280c8e91df578df88cdf4b0cdedcedL, \ - 0x27be44a529b7513e727251f128b34262a0fd4d8ec82377b9L, \ + 0x89009c0dc361c81e99280c8e91df578df88cdf4b0cdedced, \ + 0x27be44a529b7513e727251f128b34262a0fd4d8ec82377b9, \ True ) test_point_validity( p192, \ - 0x6a223d00bd22c52833409a163e057e5b5da1def2a197dd15L, \ - 0x7b482604199367f1f303f9ef627f922f97023e90eae08abfL, \ + 0x6a223d00bd22c52833409a163e057e5b5da1def2a197dd15, \ + 0x7b482604199367f1f303f9ef627f922f97023e90eae08abf, \ True ) test_point_validity( p192, \ - 0x6dccbde75c0948c98dab32ea0bc59fe125cf0fb1a3798edaL, \ - 0x0001171a3e0fa60cf3096f4e116b556198de430e1fbd330c8835L, \ + 0x6dccbde75c0948c98dab32ea0bc59fe125cf0fb1a3798eda, \ + 0x0001171a3e0fa60cf3096f4e116b556198de430e1fbd330c8835, \ False ) test_point_validity( p192, \ - 0xd266b39e1f491fc4acbbbc7d098430931cfa66d55015af12L, \ - 0x193782eb909e391a3148b7764e6b234aa94e48d30a16dbb2L, \ + 0xd266b39e1f491fc4acbbbc7d098430931cfa66d55015af12, \ + 0x193782eb909e391a3148b7764e6b234aa94e48d30a16dbb2, \ False ) test_point_validity( p192, \ - 0x9d6ddbcd439baa0c6b80a654091680e462a7d1d3f1ffeb43L, \ - 0x6ad8efc4d133ccf167c44eb4691c80abffb9f82b932b8caaL, \ + 0x9d6ddbcd439baa0c6b80a654091680e462a7d1d3f1ffeb43, \ + 0x6ad8efc4d133ccf167c44eb4691c80abffb9f82b932b8caa, \ False ) test_point_validity( p192, \ - 0x146479d944e6bda87e5b35818aa666a4c998a71f4e95edbcL, \ - 0xa86d6fe62bc8fbd88139693f842635f687f132255858e7f6L, \ + 0x146479d944e6bda87e5b35818aa666a4c998a71f4e95edbc, \ + 0xa86d6fe62bc8fbd88139693f842635f687f132255858e7f6, \ False ) test_point_validity( p192, \ - 0xe594d4a598046f3598243f50fd2c7bd7d380edb055802253L, \ - 0x509014c0c4d6b536e3ca750ec09066af39b4c8616a53a923L, \ + 0xe594d4a598046f3598243f50fd2c7bd7d380edb055802253, \ + 0x509014c0c4d6b536e3ca750ec09066af39b4c8616a53a923, \ False ) - print "Trying signature-verification tests from ECDSAVS.pdf B.2.4:" - print "P-192:" - Msg = 0x84ce72aa8699df436059f052ac51b6398d2511e49631bcb7e71f89c499b9ee425dfbc13a5f6d408471b054f2655617cbbaf7937b7c80cd8865cf02c8487d30d2b0fbd8b2c4e102e16d828374bbc47b93852f212d5043c3ea720f086178ff798cc4f63f787b9c2e419efa033e7644ea7936f54462dc21a6c4580725f7f0e7d158L - Qx = 0xd9dbfb332aa8e5ff091e8ce535857c37c73f6250ffb2e7acL - Qy = 0x282102e364feded3ad15ddf968f88d8321aa268dd483ebc4L - R = 0x64dca58a20787c488d11d6dd96313f1b766f2d8efe122916L - S = 0x1ecba28141e84ab4ecad92f56720e2cc83eb3d22dec72479L + print_("Trying signature-verification tests from ECDSAVS.pdf B.2.4:") + print_("P-192:") + Msg = 0x84ce72aa8699df436059f052ac51b6398d2511e49631bcb7e71f89c499b9ee425dfbc13a5f6d408471b054f2655617cbbaf7937b7c80cd8865cf02c8487d30d2b0fbd8b2c4e102e16d828374bbc47b93852f212d5043c3ea720f086178ff798cc4f63f787b9c2e419efa033e7644ea7936f54462dc21a6c4580725f7f0e7d158 + Qx = 0xd9dbfb332aa8e5ff091e8ce535857c37c73f6250ffb2e7ac + Qy = 0x282102e364feded3ad15ddf968f88d8321aa268dd483ebc4 + R = 0x64dca58a20787c488d11d6dd96313f1b766f2d8efe122916 + S = 0x1ecba28141e84ab4ecad92f56720e2cc83eb3d22dec72479 test_signature_validity( Msg, Qx, Qy, R, S, True ) - Msg = 0x94bb5bacd5f8ea765810024db87f4224ad71362a3c28284b2b9f39fab86db12e8beb94aae899768229be8fdb6c4f12f28912bb604703a79ccff769c1607f5a91450f30ba0460d359d9126cbd6296be6d9c4bb96c0ee74cbb44197c207f6db326ab6f5a659113a9034e54be7b041ced9dcf6458d7fb9cbfb2744d999f7dfd63f4L - Qx = 0x3e53ef8d3112af3285c0e74842090712cd324832d4277ae7L - Qy = 0xcc75f8952d30aec2cbb719fc6aa9934590b5d0ff5a83adb7L - R = 0x8285261607283ba18f335026130bab31840dcfd9c3e555afL - S = 0x356d89e1b04541afc9704a45e9c535ce4a50929e33d7e06cL + Msg = 0x94bb5bacd5f8ea765810024db87f4224ad71362a3c28284b2b9f39fab86db12e8beb94aae899768229be8fdb6c4f12f28912bb604703a79ccff769c1607f5a91450f30ba0460d359d9126cbd6296be6d9c4bb96c0ee74cbb44197c207f6db326ab6f5a659113a9034e54be7b041ced9dcf6458d7fb9cbfb2744d999f7dfd63f4 + Qx = 0x3e53ef8d3112af3285c0e74842090712cd324832d4277ae7 + Qy = 0xcc75f8952d30aec2cbb719fc6aa9934590b5d0ff5a83adb7 + R = 0x8285261607283ba18f335026130bab31840dcfd9c3e555af + S = 0x356d89e1b04541afc9704a45e9c535ce4a50929e33d7e06c test_signature_validity( Msg, Qx, Qy, R, S, True ) - Msg = 0xf6227a8eeb34afed1621dcc89a91d72ea212cb2f476839d9b4243c66877911b37b4ad6f4448792a7bbba76c63bdd63414b6facab7dc71c3396a73bd7ee14cdd41a659c61c99b779cecf07bc51ab391aa3252386242b9853ea7da67fd768d303f1b9b513d401565b6f1eb722dfdb96b519fe4f9bd5de67ae131e64b40e78c42ddL - Qx = 0x16335dbe95f8e8254a4e04575d736befb258b8657f773cb7L - Qy = 0x421b13379c59bc9dce38a1099ca79bbd06d647c7f6242336L - R = 0x4141bd5d64ea36c5b0bd21ef28c02da216ed9d04522b1e91L - S = 0x159a6aa852bcc579e821b7bb0994c0861fb08280c38daa09L + Msg = 0xf6227a8eeb34afed1621dcc89a91d72ea212cb2f476839d9b4243c66877911b37b4ad6f4448792a7bbba76c63bdd63414b6facab7dc71c3396a73bd7ee14cdd41a659c61c99b779cecf07bc51ab391aa3252386242b9853ea7da67fd768d303f1b9b513d401565b6f1eb722dfdb96b519fe4f9bd5de67ae131e64b40e78c42dd + Qx = 0x16335dbe95f8e8254a4e04575d736befb258b8657f773cb7 + Qy = 0x421b13379c59bc9dce38a1099ca79bbd06d647c7f6242336 + R = 0x4141bd5d64ea36c5b0bd21ef28c02da216ed9d04522b1e91 + S = 0x159a6aa852bcc579e821b7bb0994c0861fb08280c38daa09 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0x16b5f93afd0d02246f662761ed8e0dd9504681ed02a253006eb36736b563097ba39f81c8e1bce7a16c1339e345efabbc6baa3efb0612948ae51103382a8ee8bc448e3ef71e9f6f7a9676694831d7f5dd0db5446f179bcb737d4a526367a447bfe2c857521c7f40b6d7d7e01a180d92431fb0bbd29c04a0c420a57b3ed26ccd8aL - Qx = 0xfd14cdf1607f5efb7b1793037b15bdf4baa6f7c16341ab0bL - Qy = 0x83fa0795cc6c4795b9016dac928fd6bac32f3229a96312c4L - R = 0x8dfdb832951e0167c5d762a473c0416c5c15bc1195667dc1L - S = 0x1720288a2dc13fa1ec78f763f8fe2ff7354a7e6fdde44520L + Msg = 0x16b5f93afd0d02246f662761ed8e0dd9504681ed02a253006eb36736b563097ba39f81c8e1bce7a16c1339e345efabbc6baa3efb0612948ae51103382a8ee8bc448e3ef71e9f6f7a9676694831d7f5dd0db5446f179bcb737d4a526367a447bfe2c857521c7f40b6d7d7e01a180d92431fb0bbd29c04a0c420a57b3ed26ccd8a + Qx = 0xfd14cdf1607f5efb7b1793037b15bdf4baa6f7c16341ab0b + Qy = 0x83fa0795cc6c4795b9016dac928fd6bac32f3229a96312c4 + R = 0x8dfdb832951e0167c5d762a473c0416c5c15bc1195667dc1 + S = 0x1720288a2dc13fa1ec78f763f8fe2ff7354a7e6fdde44520 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0x08a2024b61b79d260e3bb43ef15659aec89e5b560199bc82cf7c65c77d39192e03b9a895d766655105edd9188242b91fbde4167f7862d4ddd61e5d4ab55196683d4f13ceb90d87aea6e07eb50a874e33086c4a7cb0273a8e1c4408f4b846bceae1ebaac1b2b2ea851a9b09de322efe34cebe601653efd6ddc876ce8c2f2072fbL - Qx = 0x674f941dc1a1f8b763c9334d726172d527b90ca324db8828L - Qy = 0x65adfa32e8b236cb33a3e84cf59bfb9417ae7e8ede57a7ffL - R = 0x9508b9fdd7daf0d8126f9e2bc5a35e4c6d800b5b804d7796L - S = 0x36f2bf6b21b987c77b53bb801b3435a577e3d493744bfab0L + Msg = 0x08a2024b61b79d260e3bb43ef15659aec89e5b560199bc82cf7c65c77d39192e03b9a895d766655105edd9188242b91fbde4167f7862d4ddd61e5d4ab55196683d4f13ceb90d87aea6e07eb50a874e33086c4a7cb0273a8e1c4408f4b846bceae1ebaac1b2b2ea851a9b09de322efe34cebe601653efd6ddc876ce8c2f2072fb + Qx = 0x674f941dc1a1f8b763c9334d726172d527b90ca324db8828 + Qy = 0x65adfa32e8b236cb33a3e84cf59bfb9417ae7e8ede57a7ff + R = 0x9508b9fdd7daf0d8126f9e2bc5a35e4c6d800b5b804d7796 + S = 0x36f2bf6b21b987c77b53bb801b3435a577e3d493744bfab0 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0x1843aba74b0789d4ac6b0b8923848023a644a7b70afa23b1191829bbe4397ce15b629bf21a8838298653ed0c19222b95fa4f7390d1b4c844d96e645537e0aae98afb5c0ac3bd0e4c37f8daaff25556c64e98c319c52687c904c4de7240a1cc55cd9756b7edaef184e6e23b385726e9ffcba8001b8f574987c1a3fedaaa83ca6dL - Qx = 0x10ecca1aad7220b56a62008b35170bfd5e35885c4014a19fL - Qy = 0x04eb61984c6c12ade3bc47f3c629ece7aa0a033b9948d686L - R = 0x82bfa4e82c0dfe9274169b86694e76ce993fd83b5c60f325L - S = 0xa97685676c59a65dbde002fe9d613431fb183e8006d05633L + Msg = 0x1843aba74b0789d4ac6b0b8923848023a644a7b70afa23b1191829bbe4397ce15b629bf21a8838298653ed0c19222b95fa4f7390d1b4c844d96e645537e0aae98afb5c0ac3bd0e4c37f8daaff25556c64e98c319c52687c904c4de7240a1cc55cd9756b7edaef184e6e23b385726e9ffcba8001b8f574987c1a3fedaaa83ca6d + Qx = 0x10ecca1aad7220b56a62008b35170bfd5e35885c4014a19f + Qy = 0x04eb61984c6c12ade3bc47f3c629ece7aa0a033b9948d686 + R = 0x82bfa4e82c0dfe9274169b86694e76ce993fd83b5c60f325 + S = 0xa97685676c59a65dbde002fe9d613431fb183e8006d05633 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0x5a478f4084ddd1a7fea038aa9732a822106385797d02311aeef4d0264f824f698df7a48cfb6b578cf3da416bc0799425bb491be5b5ecc37995b85b03420a98f2c4dc5c31a69a379e9e322fbe706bbcaf0f77175e05cbb4fa162e0da82010a278461e3e974d137bc746d1880d6eb02aa95216014b37480d84b87f717bb13f76e1L - Qx = 0x6636653cb5b894ca65c448277b29da3ad101c4c2300f7c04L - Qy = 0xfdf1cbb3fc3fd6a4f890b59e554544175fa77dbdbeb656c1L - R = 0xeac2ddecddfb79931a9c3d49c08de0645c783a24cb365e1cL - S = 0x3549fee3cfa7e5f93bc47d92d8ba100e881a2a93c22f8d50L + Msg = 0x5a478f4084ddd1a7fea038aa9732a822106385797d02311aeef4d0264f824f698df7a48cfb6b578cf3da416bc0799425bb491be5b5ecc37995b85b03420a98f2c4dc5c31a69a379e9e322fbe706bbcaf0f77175e05cbb4fa162e0da82010a278461e3e974d137bc746d1880d6eb02aa95216014b37480d84b87f717bb13f76e1 + Qx = 0x6636653cb5b894ca65c448277b29da3ad101c4c2300f7c04 + Qy = 0xfdf1cbb3fc3fd6a4f890b59e554544175fa77dbdbeb656c1 + R = 0xeac2ddecddfb79931a9c3d49c08de0645c783a24cb365e1c + S = 0x3549fee3cfa7e5f93bc47d92d8ba100e881a2a93c22f8d50 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0xc598774259a058fa65212ac57eaa4f52240e629ef4c310722088292d1d4af6c39b49ce06ba77e4247b20637174d0bd67c9723feb57b5ead232b47ea452d5d7a089f17c00b8b6767e434a5e16c231ba0efa718a340bf41d67ea2d295812ff1b9277daacb8bc27b50ea5e6443bcf95ef4e9f5468fe78485236313d53d1c68f6ba2L - Qx = 0xa82bd718d01d354001148cd5f69b9ebf38ff6f21898f8aaaL - Qy = 0xe67ceede07fc2ebfafd62462a51e4b6c6b3d5b537b7caf3eL - R = 0x4d292486c620c3de20856e57d3bb72fcde4a73ad26376955L - S = 0xa85289591a6081d5728825520e62ff1c64f94235c04c7f95L + Msg = 0xc598774259a058fa65212ac57eaa4f52240e629ef4c310722088292d1d4af6c39b49ce06ba77e4247b20637174d0bd67c9723feb57b5ead232b47ea452d5d7a089f17c00b8b6767e434a5e16c231ba0efa718a340bf41d67ea2d295812ff1b9277daacb8bc27b50ea5e6443bcf95ef4e9f5468fe78485236313d53d1c68f6ba2 + Qx = 0xa82bd718d01d354001148cd5f69b9ebf38ff6f21898f8aaa + Qy = 0xe67ceede07fc2ebfafd62462a51e4b6c6b3d5b537b7caf3e + R = 0x4d292486c620c3de20856e57d3bb72fcde4a73ad26376955 + S = 0xa85289591a6081d5728825520e62ff1c64f94235c04c7f95 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0xca98ed9db081a07b7557f24ced6c7b9891269a95d2026747add9e9eb80638a961cf9c71a1b9f2c29744180bd4c3d3db60f2243c5c0b7cc8a8d40a3f9a7fc910250f2187136ee6413ffc67f1a25e1c4c204fa9635312252ac0e0481d89b6d53808f0c496ba87631803f6c572c1f61fa049737fdacce4adff757afed4f05beb658L - Qx = 0x7d3b016b57758b160c4fca73d48df07ae3b6b30225126c2fL - Qy = 0x4af3790d9775742bde46f8da876711be1b65244b2b39e7ecL - R = 0x95f778f5f656511a5ab49a5d69ddd0929563c29cbc3a9e62L - S = 0x75c87fc358c251b4c83d2dd979faad496b539f9f2ee7a289L + Msg = 0xca98ed9db081a07b7557f24ced6c7b9891269a95d2026747add9e9eb80638a961cf9c71a1b9f2c29744180bd4c3d3db60f2243c5c0b7cc8a8d40a3f9a7fc910250f2187136ee6413ffc67f1a25e1c4c204fa9635312252ac0e0481d89b6d53808f0c496ba87631803f6c572c1f61fa049737fdacce4adff757afed4f05beb658 + Qx = 0x7d3b016b57758b160c4fca73d48df07ae3b6b30225126c2f + Qy = 0x4af3790d9775742bde46f8da876711be1b65244b2b39e7ec + R = 0x95f778f5f656511a5ab49a5d69ddd0929563c29cbc3a9e62 + S = 0x75c87fc358c251b4c83d2dd979faad496b539f9f2ee7a289 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0x31dd9a54c8338bea06b87eca813d555ad1850fac9742ef0bbe40dad400e10288acc9c11ea7dac79eb16378ebea9490e09536099f1b993e2653cd50240014c90a9c987f64545abc6a536b9bd2435eb5e911fdfde2f13be96ea36ad38df4ae9ea387b29cced599af777338af2794820c9cce43b51d2112380a35802ab7e396c97aL - Qx = 0x9362f28c4ef96453d8a2f849f21e881cd7566887da8beb4aL - Qy = 0xe64d26d8d74c48a024ae85d982ee74cd16046f4ee5333905L - R = 0xf3923476a296c88287e8de914b0b324ad5a963319a4fe73bL - S = 0xf0baeed7624ed00d15244d8ba2aede085517dbdec8ac65f5L + Msg = 0x31dd9a54c8338bea06b87eca813d555ad1850fac9742ef0bbe40dad400e10288acc9c11ea7dac79eb16378ebea9490e09536099f1b993e2653cd50240014c90a9c987f64545abc6a536b9bd2435eb5e911fdfde2f13be96ea36ad38df4ae9ea387b29cced599af777338af2794820c9cce43b51d2112380a35802ab7e396c97a + Qx = 0x9362f28c4ef96453d8a2f849f21e881cd7566887da8beb4a + Qy = 0xe64d26d8d74c48a024ae85d982ee74cd16046f4ee5333905 + R = 0xf3923476a296c88287e8de914b0b324ad5a963319a4fe73b + S = 0xf0baeed7624ed00d15244d8ba2aede085517dbdec8ac65f5 test_signature_validity( Msg, Qx, Qy, R, S, True ) - Msg = 0xb2b94e4432267c92f9fdb9dc6040c95ffa477652761290d3c7de312283f6450d89cc4aabe748554dfb6056b2d8e99c7aeaad9cdddebdee9dbc099839562d9064e68e7bb5f3a6bba0749ca9a538181fc785553a4000785d73cc207922f63e8ce1112768cb1de7b673aed83a1e4a74592f1268d8e2a4e9e63d414b5d442bd0456dL - Qx = 0xcc6fc032a846aaac25533eb033522824f94e670fa997ecefL - Qy = 0xe25463ef77a029eccda8b294fd63dd694e38d223d30862f1L - R = 0x066b1d07f3a40e679b620eda7f550842a35c18b80c5ebe06L - S = 0xa0b0fb201e8f2df65e2c4508ef303bdc90d934016f16b2dcL + Msg = 0xb2b94e4432267c92f9fdb9dc6040c95ffa477652761290d3c7de312283f6450d89cc4aabe748554dfb6056b2d8e99c7aeaad9cdddebdee9dbc099839562d9064e68e7bb5f3a6bba0749ca9a538181fc785553a4000785d73cc207922f63e8ce1112768cb1de7b673aed83a1e4a74592f1268d8e2a4e9e63d414b5d442bd0456d + Qx = 0xcc6fc032a846aaac25533eb033522824f94e670fa997ecef + Qy = 0xe25463ef77a029eccda8b294fd63dd694e38d223d30862f1 + R = 0x066b1d07f3a40e679b620eda7f550842a35c18b80c5ebe06 + S = 0xa0b0fb201e8f2df65e2c4508ef303bdc90d934016f16b2dc test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0x4366fcadf10d30d086911de30143da6f579527036937007b337f7282460eae5678b15cccda853193ea5fc4bc0a6b9d7a31128f27e1214988592827520b214eed5052f7775b750b0c6b15f145453ba3fee24a085d65287e10509eb5d5f602c440341376b95c24e5c4727d4b859bfe1483d20538acdd92c7997fa9c614f0f839d7L - Qx = 0x955c908fe900a996f7e2089bee2f6376830f76a19135e753L - Qy = 0xba0c42a91d3847de4a592a46dc3fdaf45a7cc709b90de520L - R = 0x1f58ad77fc04c782815a1405b0925e72095d906cbf52a668L - S = 0xf2e93758b3af75edf784f05a6761c9b9a6043c66b845b599L + Msg = 0x4366fcadf10d30d086911de30143da6f579527036937007b337f7282460eae5678b15cccda853193ea5fc4bc0a6b9d7a31128f27e1214988592827520b214eed5052f7775b750b0c6b15f145453ba3fee24a085d65287e10509eb5d5f602c440341376b95c24e5c4727d4b859bfe1483d20538acdd92c7997fa9c614f0f839d7 + Qx = 0x955c908fe900a996f7e2089bee2f6376830f76a19135e753 + Qy = 0xba0c42a91d3847de4a592a46dc3fdaf45a7cc709b90de520 + R = 0x1f58ad77fc04c782815a1405b0925e72095d906cbf52a668 + S = 0xf2e93758b3af75edf784f05a6761c9b9a6043c66b845b599 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0x543f8af57d750e33aa8565e0cae92bfa7a1ff78833093421c2942cadf9986670a5ff3244c02a8225e790fbf30ea84c74720abf99cfd10d02d34377c3d3b41269bea763384f372bb786b5846f58932defa68023136cd571863b304886e95e52e7877f445b9364b3f06f3c28da12707673fecb4b8071de06b6e0a3c87da160cef3L - Qx = 0x31f7fa05576d78a949b24812d4383107a9a45bb5fccdd835L - Qy = 0x8dc0eb65994a90f02b5e19bd18b32d61150746c09107e76bL - R = 0xbe26d59e4e883dde7c286614a767b31e49ad88789d3a78ffL - S = 0x8762ca831c1ce42df77893c9b03119428e7a9b819b619068L + Msg = 0x543f8af57d750e33aa8565e0cae92bfa7a1ff78833093421c2942cadf9986670a5ff3244c02a8225e790fbf30ea84c74720abf99cfd10d02d34377c3d3b41269bea763384f372bb786b5846f58932defa68023136cd571863b304886e95e52e7877f445b9364b3f06f3c28da12707673fecb4b8071de06b6e0a3c87da160cef3 + Qx = 0x31f7fa05576d78a949b24812d4383107a9a45bb5fccdd835 + Qy = 0x8dc0eb65994a90f02b5e19bd18b32d61150746c09107e76b + R = 0xbe26d59e4e883dde7c286614a767b31e49ad88789d3a78ff + S = 0x8762ca831c1ce42df77893c9b03119428e7a9b819b619068 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0xd2e8454143ce281e609a9d748014dcebb9d0bc53adb02443a6aac2ffe6cb009f387c346ecb051791404f79e902ee333ad65e5c8cb38dc0d1d39a8dc90add5023572720e5b94b190d43dd0d7873397504c0c7aef2727e628eb6a74411f2e400c65670716cb4a815dc91cbbfeb7cfe8c929e93184c938af2c078584da045e8f8d1L - Qx = 0x66aa8edbbdb5cf8e28ceb51b5bda891cae2df84819fe25c0L - Qy = 0x0c6bc2f69030a7ce58d4a00e3b3349844784a13b8936f8daL - R = 0xa4661e69b1734f4a71b788410a464b71e7ffe42334484f23L - S = 0x738421cf5e049159d69c57a915143e226cac8355e149afe9L + Msg = 0xd2e8454143ce281e609a9d748014dcebb9d0bc53adb02443a6aac2ffe6cb009f387c346ecb051791404f79e902ee333ad65e5c8cb38dc0d1d39a8dc90add5023572720e5b94b190d43dd0d7873397504c0c7aef2727e628eb6a74411f2e400c65670716cb4a815dc91cbbfeb7cfe8c929e93184c938af2c078584da045e8f8d1 + Qx = 0x66aa8edbbdb5cf8e28ceb51b5bda891cae2df84819fe25c0 + Qy = 0x0c6bc2f69030a7ce58d4a00e3b3349844784a13b8936f8da + R = 0xa4661e69b1734f4a71b788410a464b71e7ffe42334484f23 + S = 0x738421cf5e049159d69c57a915143e226cac8355e149afe9 test_signature_validity( Msg, Qx, Qy, R, S, False ) - Msg = 0x6660717144040f3e2f95a4e25b08a7079c702a8b29babad5a19a87654bc5c5afa261512a11b998a4fb36b5d8fe8bd942792ff0324b108120de86d63f65855e5461184fc96a0a8ffd2ce6d5dfb0230cbbdd98f8543e361b3205f5da3d500fdc8bac6db377d75ebef3cb8f4d1ff738071ad0938917889250b41dd1d98896ca06fbL - Qx = 0xbcfacf45139b6f5f690a4c35a5fffa498794136a2353fc77L - Qy = 0x6f4a6c906316a6afc6d98fe1f0399d056f128fe0270b0f22L - R = 0x9db679a3dafe48f7ccad122933acfe9da0970b71c94c21c1L - S = 0x984c2db99827576c0a41a5da41e07d8cc768bc82f18c9da9L + Msg = 0x6660717144040f3e2f95a4e25b08a7079c702a8b29babad5a19a87654bc5c5afa261512a11b998a4fb36b5d8fe8bd942792ff0324b108120de86d63f65855e5461184fc96a0a8ffd2ce6d5dfb0230cbbdd98f8543e361b3205f5da3d500fdc8bac6db377d75ebef3cb8f4d1ff738071ad0938917889250b41dd1d98896ca06fb + Qx = 0xbcfacf45139b6f5f690a4c35a5fffa498794136a2353fc77 + Qy = 0x6f4a6c906316a6afc6d98fe1f0399d056f128fe0270b0f22 + R = 0x9db679a3dafe48f7ccad122933acfe9da0970b71c94c21c1 + S = 0x984c2db99827576c0a41a5da41e07d8cc768bc82f18c9da9 test_signature_validity( Msg, Qx, Qy, R, S, False ) - print "Testing the example code:" + print_("Testing the example code:") # Building a public/private key pair from the NIST Curve P-192: @@ -558,14 +563,14 @@ def __main__(): # Verifying a signature for a hash value: if pubkey.verifies( hash, signature ): - print "Demo verification succeeded." + print_("Demo verification succeeded.") else: raise TestFailure("*** Demo verification failed.") if pubkey.verifies( hash-1, signature ): raise TestFailure( "**** Demo verification failed to reject tampered hash.") else: - print "Demo verification correctly rejected tampered hash." + print_("Demo verification correctly rejected tampered hash.") if __name__ == "__main__": __main__() diff --git a/ecdsa/ellipticcurve.py b/ecdsa/ellipticcurve.py index c1eb361..4a25112 100644 --- a/ecdsa/ellipticcurve.py +++ b/ecdsa/ellipticcurve.py @@ -32,7 +32,10 @@ # # Written in 2005 by Peter Pearson and placed in the public domain. -import numbertheory +from __future__ import division + +from .six import print_ +from . import numbertheory class CurveFp( object ): """Elliptic Curve over the field of integers modulo a prime.""" @@ -70,14 +73,14 @@ class Point( object ): if self.__curve: assert self.__curve.contains_point( x, y ) if order: assert self * order == INFINITY - def __cmp__( self, other ): + def __eq__( self, other ): """Return 0 if the points are identical, 1 otherwise.""" if self.__curve == other.__curve \ and self.__x == other.__x \ and self.__y == other.__y: - return 0 + return 1 else: - return 1 + return 0 def __add__( self, other ): """Add one point to another point.""" @@ -108,7 +111,7 @@ class Point( object ): def leftmost_bit( x ): assert x > 0 - result = 1L + result = 1 while result <= x: result = 2 * result return result // 2 @@ -124,12 +127,12 @@ class Point( object ): negative_self = Point( self.__curve, self.__x, -self.__y, self.__order ) i = leftmost_bit( e3 ) // 2 result = self - # print "Multiplying %s by %d (e3 = %d):" % ( self, other, e3 ) + # print_("Multiplying %s by %d (e3 = %d):" % ( self, other, e3 )) while i > 1: result = result.double() if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self - # print ". . . i = %d, result = %s" % ( i, result ) + # print_(". . . i = %d, result = %s" % ( i, result )) i = i // 2 return result @@ -186,41 +189,41 @@ def __main__(): p1 = Point( c, x1, y1 ) p2 = Point( c, x2, y2 ) p3 = p1 + p2 - print "%s + %s = %s" % ( p1, p2, p3 ), + print_("%s + %s = %s" % ( p1, p2, p3 ), end=' ') if p3.x() != x3 or p3.y() != y3: raise FailedTest("Failure: should give (%d,%d)." % ( x3, y3 )) else: - print " Good." + print_(" Good.") def test_double( c, x1, y1, x3, y3 ): """We expect that on curve c, 2*(x1,y1) = (x3, y3).""" p1 = Point( c, x1, y1 ) p3 = p1.double() - print "%s doubled = %s" % ( p1, p3 ), + print_("%s doubled = %s" % ( p1, p3 ), end=' ') if p3.x() != x3 or p3.y() != y3: raise FailedTest("Failure: should give (%d,%d)." % ( x3, y3 )) else: - print " Good." + print_(" Good.") def test_double_infinity( c ): """We expect that on curve c, 2*INFINITY = INFINITY.""" p1 = INFINITY p3 = p1.double() - print "%s doubled = %s" % ( p1, p3 ), + print_("%s doubled = %s" % ( p1, p3 ), end=' ') if p3.x() != INFINITY.x() or p3.y() != INFINITY.y(): raise FailedTest("Failure: should give (%d,%d)." % ( INFINITY.x(), INFINITY.y() )) else: - print " Good." + print_(" Good.") def test_multiply( c, x1, y1, m, x3, y3 ): """We expect that on curve c, m*(x1,y1) = (x3,y3).""" p1 = Point( c, x1, y1 ) p3 = p1 * m - print "%s * %d = %s" % ( p1, m, p3 ), + print_("%s * %d = %s" % ( p1, m, p3 ), end=' ') if p3.x() != x3 or p3.y() != y3: raise FailedTest("Failure: should give (%d,%d)." % ( x3, y3 )) else: - print " Good." + print_(" Good.") # A few tests from X9.62 B.3: @@ -240,21 +243,21 @@ def __main__(): check = INFINITY for i in range( 7 + 1 ): p = ( i % 7 ) * g - print "%s * %d = %s, expected %s . . ." % ( g, i, p, check ), + print_("%s * %d = %s, expected %s . . ." % ( g, i, p, check ), end=' ') if p == check: - print " Good." + print_(" Good.") else: raise FailedTest("Bad.") check = check + g # NIST Curve P-192: - p = 6277101735386680763835789423207666416083908700390324961279L - r = 6277101735386680763835789423176059013767194773182842284081L + p = 6277101735386680763835789423207666416083908700390324961279 + r = 6277101735386680763835789423176059013767194773182842284081 #s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L - c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65L - b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1L - Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012L - Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811L + c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65 + b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1 + Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012 + Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811 c192 = CurveFp( p, -3, b ) p192 = Point( c192, Gx, Gy, r ) @@ -262,29 +265,29 @@ def __main__(): # Checking against some sample computations presented # in X9.62: - d = 651056770906015076056810763456358567190100156695615665659L + d = 651056770906015076056810763456358567190100156695615665659 Q = d * p192 - if Q.x() != 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5L: + if Q.x() != 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5: raise FailedTest("p192 * d came out wrong.") else: - print "p192 * d came out right." + print_("p192 * d came out right.") - k = 6140507067065001063065065565667405560006161556565665656654L + k = 6140507067065001063065065565667405560006161556565665656654 R = k * p192 - if R.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEADL \ - or R.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835L: + if R.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \ + or R.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835: raise FailedTest("k * p192 came out wrong.") else: - print "k * p192 came out right." + print_("k * p192 came out right.") - u1 = 2563697409189434185194736134579731015366492496392189760599L - u2 = 6266643813348617967186477710235785849136406323338782220568L + u1 = 2563697409189434185194736134579731015366492496392189760599 + u2 = 6266643813348617967186477710235785849136406323338782220568 temp = u1 * p192 + u2 * Q - if temp.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEADL \ - or temp.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835L: + if temp.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \ + or temp.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835: raise FailedTest("u1 * p192 + u2 * Q came out wrong.") else: - print "u1 * p192 + u2 * Q came out right." + print_("u1 * p192 + u2 * Q came out right.") if __name__ == "__main__": __main__() diff --git a/ecdsa/keys.py b/ecdsa/keys.py index 3ea97c1..6e80dcb 100644 --- a/ecdsa/keys.py +++ b/ecdsa/keys.py @@ -1,12 +1,13 @@ import binascii -import ecdsa -import der -import rfc6979 -from curves import NIST192p, find_curve -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 . import ecdsa +from . import der +from . import rfc6979 +from .curves import NIST192p, find_curve +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 .six import PY3, b from hashlib import sha1 class BadSignatureError(Exception): @@ -40,7 +41,7 @@ class VerifyingKey: x = string_to_number(xs) y = string_to_number(ys) assert ecdsa.point_is_valid(curve.generator, x, y) - import ellipticcurve + from . import ellipticcurve point = ellipticcurve.Point(curve.curve, x, y, order) return klass.from_public_point(point, curve, hashfunc) @@ -52,23 +53,23 @@ class VerifyingKey: def from_der(klass, string): # [[oid_ecPublicKey,oid_curve], point_str_bitstring] s1,empty = der.remove_sequence(string) - if empty != "": + if empty != b(""): raise der.UnexpectedDER("trailing junk after DER pubkey: %s" % binascii.hexlify(empty)) s2,point_str_bitstring = der.remove_sequence(s1) # s2 = oid_ecPublicKey,oid_curve oid_pk, rest = der.remove_object(s2) oid_curve, empty = der.remove_object(rest) - if empty != "": + if empty != b(""): raise der.UnexpectedDER("trailing junk after DER pubkey objects: %s" % binascii.hexlify(empty)) assert oid_pk == oid_ecPublicKey, (oid_pk, oid_ecPublicKey) curve = find_curve(oid_curve) point_str, empty = der.remove_bitstring(point_str_bitstring) - if empty != "": + if empty != b(""): raise der.UnexpectedDER("trailing junk after pubkey pointstring: %s" % binascii.hexlify(empty)) - assert point_str.startswith("\x00\x04") + assert point_str.startswith(b("\x00\x04")) return klass.from_string(point_str[2:], curve) def to_string(self): @@ -87,7 +88,7 @@ class VerifyingKey: order = self.pubkey.order x_str = number_to_string(self.pubkey.point.x(), order) y_str = number_to_string(self.pubkey.point.y(), order) - point_str = "\x00\x04" + x_str + y_str + point_str = b("\x00\x04") + x_str + y_str return der.encode_sequence(der.encode_sequence(encoded_oid_ecPublicKey, self.curve.encoded_oid), der.encode_bitstring(point_str)) @@ -151,14 +152,16 @@ class SigningKey: def from_pem(klass, string, hashfunc=sha1): # the privkey pem file has two sections: "EC PARAMETERS" and "EC # PRIVATE KEY". The first is redundant. - privkey_pem = string[string.index("-----BEGIN EC PRIVATE KEY-----"):] + if PY3 and isinstance(string, str): + string = string.encode() + privkey_pem = string[string.index(b("-----BEGIN EC PRIVATE KEY-----")):] return klass.from_der(der.unpem(privkey_pem), hashfunc) @classmethod def from_der(klass, string, hashfunc=sha1): # SEQ([int(1), octetstring(privkey),cont[0], oid(secp224r1), # cont[1],bitstring]) s, empty = der.remove_sequence(string) - if empty != "": + if empty != b(""): raise der.UnexpectedDER("trailing junk after DER privkey: %s" % binascii.hexlify(empty)) one, s = der.remove_integer(s) @@ -171,7 +174,7 @@ class SigningKey: raise der.UnexpectedDER("expected tag 0 in DER privkey," " got %d" % tag) curve_oid, empty = der.remove_object(curve_oid_str) - if empty != "": + if empty != b(""): raise der.UnexpectedDER("trailing junk after DER privkey " "curve_oid: %s" % binascii.hexlify(empty)) curve = find_curve(curve_oid) @@ -189,7 +192,7 @@ class SigningKey: # our from_string method likes fixed-length privkey strings if len(privkey_str) < curve.baselen: - privkey_str = "\x00"*(curve.baselen-len(privkey_str)) + privkey_str + privkey_str = b("\x00")*(curve.baselen-len(privkey_str)) + privkey_str return klass.from_string(privkey_str, curve, hashfunc) def to_string(self): @@ -204,7 +207,7 @@ class SigningKey: def to_der(self): # SEQ([int(1), octetstring(privkey),cont[0], oid(secp224r1), # cont[1],bitstring]) - encoded_vk = "\x00\x04" + self.get_verifying_key().to_string() + encoded_vk = b("\x00\x04") + self.get_verifying_key().to_string() return der.encode_sequence(der.encode_integer(1), der.encode_octet_string(self.to_string()), der.encode_constructed(0, self.curve.encoded_oid), diff --git a/ecdsa/numbertheory.py b/ecdsa/numbertheory.py index a07fb57..3a74bd9 100644 --- a/ecdsa/numbertheory.py +++ b/ecdsa/numbertheory.py @@ -9,7 +9,10 @@ # 2008.11.14: Use pow( base, exponent, modulus ) for modular_exp. # Make gcd and lcm accept arbitrarly many arguments. +from __future__ import division +from .six import print_, integer_types +from .six.moves import reduce import math import types @@ -171,7 +174,7 @@ def square_root_mod_prime( a, p ): d = modular_exp( a, (p-1)//4, p ) if d == 1: return modular_exp( a, (p+3)//8, p ) if d == p-1: return ( 2 * a * modular_exp( 4*a, (p-5)//8, p ) ) % p - raise RuntimeError, "Shouldn't get here." + raise RuntimeError("Shouldn't get here.") for b in range( 2, p ): if jacobi( b*b-4*a, p ) == -1: @@ -179,7 +182,7 @@ def square_root_mod_prime( a, p ): ff = polynomial_exp_mod( ( 0, 1 ), (p+1)//2, f, p ) assert ff[1] == 0 return ff[0] - raise RuntimeError, "No b found." + raise RuntimeError("No b found.") @@ -245,7 +248,7 @@ def lcm( *a ): def factorization( n ): """Decompose n into a list of (prime,exponent) pairs.""" - assert isinstance( n, types.IntType ) or isinstance( n, types.LongType ) + assert isinstance( n, integer_types ) if n < 2: return [] @@ -296,7 +299,7 @@ def factorization( n ): def phi( n ): """Return the Euler totient function of n.""" - assert isinstance( n, types.IntType ) or isinstance( n, types.LongType ) + assert isinstance( n, integer_types ) if n < 3: return 1 @@ -443,7 +446,7 @@ def is_prime( n ): while ( r % 2 ) == 0: s = s + 1 r = r // 2 - for i in xrange( t ): + for i in range( t ): a = smallprimes[ i ] y = modular_exp( a, r, n ) if y != 1 and y != n-1: @@ -499,17 +502,17 @@ def __main__(): # p = square_root_mod_prime( 2, 3 ) - print "Testing gcd..." + print_("Testing gcd...") assert gcd( 3*5*7, 3*5*11, 3*5*13 ) == 3*5 assert gcd( [ 3*5*7, 3*5*11, 3*5*13 ] ) == 3*5 assert gcd( 3 ) == 3 - print "Testing lcm..." + print_("Testing lcm...") assert lcm( 3, 5*3, 7*3 ) == 3*5*7 assert lcm( [ 3, 5*3, 7*3 ] ) == 3*5*7 assert lcm( 3 ) == 3 - print "Testing next_prime..." + print_("Testing next_prime...") bigprimes = ( 999671, 999683, 999721, @@ -531,7 +534,7 @@ def __main__(): 999979, 999983 ) - for i in xrange( len( bigprimes ) - 1 ): + for i in range( len( bigprimes ) - 1 ): assert next_prime( bigprimes[i] ) == bigprimes[ i+1 ] error_tally = 0 @@ -539,7 +542,7 @@ def __main__(): # Test the square_root_mod_prime function: for p in smallprimes: - print "Testing square_root_mod_prime for modulus p = %d." % p + print_("Testing square_root_mod_prime for modulus p = %d." % p) squares = [] for root in range( 0, 1+p//2 ): @@ -548,8 +551,8 @@ def __main__(): calculated = square_root_mod_prime( sq, p ) if ( calculated * calculated ) % p != sq: error_tally = error_tally + 1 - print "Failed to find %d as sqrt( %d ) mod %d. Said %d." % \ - ( root, sq, p, calculated ) + print_("Failed to find %d as sqrt( %d ) mod %d. Said %d." % \ + ( root, sq, p, calculated )) for nonsquare in range( 0, p ): if nonsquare not in squares: @@ -559,24 +562,24 @@ def __main__(): pass else: error_tally = error_tally + 1 - print "Failed to report no root for sqrt( %d ) mod %d." % \ - ( nonsquare, p ) + print_("Failed to report no root for sqrt( %d ) mod %d." % \ + ( nonsquare, p )) # Test the jacobi function: for m in range( 3, 400, 2 ): - print "Testing jacobi for modulus m = %d." % m + print_("Testing jacobi for modulus m = %d." % m) if is_prime( m ): squares = [] for root in range( 1, m ): if jacobi( root * root, m ) != 1: error_tally = error_tally + 1 - print "jacobi( %d * %d, %d ) != 1" % ( root, root, m ) + print_("jacobi( %d * %d, %d ) != 1" % ( root, root, m )) squares.append( root * root % m ) for i in range( 1, m ): if not i in squares: if jacobi( i, m ) != -1: error_tally = error_tally + 1 - print "jacobi( %d, %d ) != -1" % ( i, m ) + print_("jacobi( %d, %d ) != -1" % ( i, m )) else: # m is not prime. f = factorization( m ) for a in range( 1, m ): @@ -585,11 +588,11 @@ def __main__(): c = c * jacobi( a, i[0] ) ** i[1] if c != jacobi( a, m ): error_tally = error_tally + 1 - print "%d != jacobi( %d, %d )" % ( c, a, m ) + print_("%d != jacobi( %d, %d )" % ( c, a, m )) # Test the inverse_mod function: - print "Testing inverse_mod . . ." + print_("Testing inverse_mod . . .") import random n_tests = 0 for i in range( 100 ): @@ -601,12 +604,12 @@ def __main__(): inv = inverse_mod( a, m ) if inv <= 0 or inv >= m or ( a * inv ) % m != 1: error_tally = error_tally + 1 - print "%d = inverse_mod( %d, %d ) is wrong." % ( inv, a, m ) + print_("%d = inverse_mod( %d, %d ) is wrong." % ( inv, a, m )) assert n_tests > 1000 - print n_tests, " tests of inverse_mod completed." + print_(n_tests, " tests of inverse_mod completed.") class FailedTest(Exception): pass - print error_tally, "errors detected." + print_(error_tally, "errors detected.") if error_tally != 0: raise FailedTest("%d errors detected" % error_tally) diff --git a/ecdsa/rfc6979.py b/ecdsa/rfc6979.py index b36c20a..d1a0a8e 100644 --- a/ecdsa/rfc6979.py +++ b/ecdsa/rfc6979.py @@ -13,7 +13,8 @@ Many thanks to Coda Hale for his implementation in Go language: import hmac from binascii import hexlify -from util import number_to_string, number_to_string_crop +from .util import number_to_string, number_to_string_crop +from .six import b try: bin(0) @@ -61,25 +62,25 @@ def generate_k(generator, secexp, hash_func, data): ''' qlen = bit_length(generator.order()) - holen = hash_func().digestsize + holen = hash_func().digest_size rolen = (qlen + 7) / 8 bx = number_to_string(secexp, generator.order()) + bits2octets(data, generator.order()) # Step B - v = '\x01' * holen + v = b('\x01') * holen # Step C - k = '\x00' * holen + k = b('\x00') * holen # Step D - k = hmac.new(k, v+'\x00'+bx, hash_func).digest() + k = hmac.new(k, v+b('\x00')+bx, hash_func).digest() # Step E v = hmac.new(k, v, hash_func).digest() # Step F - k = hmac.new(k, v+'\x01'+bx, hash_func).digest() + k = hmac.new(k, v+b('\x01')+bx, hash_func).digest() # Step G v = hmac.new(k, v, hash_func).digest() @@ -87,7 +88,7 @@ def generate_k(generator, secexp, hash_func, data): # Step H while True: # Step H1 - t = '' + t = b('') # Step H2 while len(t) < rolen: @@ -100,5 +101,5 @@ def generate_k(generator, secexp, hash_func, data): if secret >= 1 and secret < generator.order(): return secret - k = hmac.new(k, v+'\x00', hash_func).digest() + k = hmac.new(k, v+b('\x00'), hash_func).digest() v = hmac.new(k, v, hash_func).digest() diff --git a/ecdsa/six.py b/ecdsa/six.py new file mode 100644 index 0000000..3003f8f --- /dev/null +++ b/ecdsa/six.py @@ -0,0 +1,394 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2012 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.2.0" + + +# True if we are running on Python 3. +PY3 = sys.version_info[0] == 3 + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) + # This is a bit ugly, but it avoids running this again. + delattr(tp, self.name) + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + + +class _MovedItems(types.ModuleType): + """Lazy loading of moved objects""" + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("reload_module", "__builtin__", "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("winreg", "_winreg"), +] +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) +del attr + +moves = sys.modules[__name__ + ".moves"] = _MovedItems("moves") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_code = "__code__" + _func_defaults = "__defaults__" + + _iterkeys = "keys" + _itervalues = "values" + _iteritems = "items" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_code = "func_code" + _func_defaults = "func_defaults" + + _iterkeys = "iterkeys" + _itervalues = "itervalues" + _iteritems = "iteritems" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) + + +def iterkeys(d): + """Return an iterator over the keys of a dictionary.""" + return iter(getattr(d, _iterkeys)()) + +def itervalues(d): + """Return an iterator over the values of a dictionary.""" + return iter(getattr(d, _itervalues)()) + +def iteritems(d): + """Return an iterator over the (key, value) pairs of a dictionary.""" + return iter(getattr(d, _iteritems)()) + + +if PY3: + def b(s): + return s.encode("latin-1") + def u(s): + return s + if sys.version_info[1] <= 1: + def int2byte(i): + return bytes((i,)) + else: + # This is about 2x faster than the implementation above on 3.2+ + int2byte = operator.methodcaller("to_bytes", 1, "big") + import io + StringIO = io.StringIO + BytesIO = io.BytesIO +else: + def b(s): + return s + def u(s): + if isinstance(s, unicode): + return s + return unicode(s, "unicode_escape") + int2byte = chr + import StringIO + StringIO = BytesIO = StringIO.StringIO +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +if PY3: + import builtins + exec_ = getattr(builtins, "exec") + + + def reraise(tp, value, tb=None): + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + + + print_ = getattr(builtins, "print") + del builtins + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + + def print_(*args, **kwargs): + """The new-style print function.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + def write(data): + if not isinstance(data, basestring): + data = str(data) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) + +_add_doc(reraise, """Reraise an exception.""") + + +def with_metaclass(meta, base=object): + """Create a base class with a metaclass.""" + return meta("NewBase", (base,), {}) diff --git a/ecdsa/test_pyecdsa.py b/ecdsa/test_pyecdsa.py index af27871..2c851b5 100644 --- a/ecdsa/test_pyecdsa.py +++ b/ecdsa/test_pyecdsa.py @@ -1,3 +1,5 @@ +from __future__ import with_statement, division + import unittest import os import time @@ -6,16 +8,17 @@ import subprocess from binascii import hexlify, unhexlify from hashlib import sha1, sha256, sha512 -from keys import SigningKey, VerifyingKey -from keys import BadSignatureError -import util -from util import sigencode_der, sigencode_strings -from util import sigdecode_der, sigdecode_strings -from curves import Curve, UnknownCurveError -from curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, SECP256k1 -from ellipticcurve import Point -import der -import rfc6979 +from .six import b, print_, binary_type +from .keys import SigningKey, VerifyingKey +from .keys import BadSignatureError +from . import util +from .util import sigencode_der, sigencode_strings +from .util import sigdecode_der, sigdecode_strings +from .curves import Curve, UnknownCurveError +from .curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, SECP256k1 +from .ellipticcurve import Point +from . import der +from . import rfc6979 class SubprocessError(Exception): pass @@ -29,7 +32,7 @@ def run_openssl(cmd): if p.returncode != 0: raise SubprocessError("cmd '%s %s' failed: rc=%s, stdout/err was %s" % (OPENSSL, cmd, p.returncode, stdout)) - return stdout + return stdout.decode() BENCH = False @@ -38,17 +41,17 @@ class ECDSA(unittest.TestCase): priv = SigningKey.generate() pub = priv.get_verifying_key() - data = "blahblah" + data = b("blahblah") sig = priv.sign(data) - self.failUnless(pub.verify(sig, data)) - self.failUnlessRaises(BadSignatureError, pub.verify, sig, data+"bad") + self.assertTrue(pub.verify(sig, data)) + self.assertRaises(BadSignatureError, pub.verify, sig, data+b("bad")) pub2 = VerifyingKey.from_string(pub.to_string()) - self.failUnless(pub2.verify(sig, data)) + self.assertTrue(pub2.verify(sig, data)) def test_deterministic(self): - data = "blahblah" + data = b("blahblah") secexp = int("9d0219792467d7d37b4d43298a7d0c05", 16) priv = SigningKey.from_secret_exponent(secexp, SECP256k1, sha256) @@ -57,96 +60,96 @@ class ECDSA(unittest.TestCase): k = rfc6979.generate_k(SECP256k1.generator, secexp, sha256, sha256(data).digest()) sig1 = priv.sign(data, k=k) - self.failUnless(pub.verify(sig1, data)) + self.assertTrue(pub.verify(sig1, data)) sig2 = priv.sign(data, k=k) - self.failUnless(pub.verify(sig2, data)) + self.assertTrue(pub.verify(sig2, data)) sig3 = priv.sign_deterministic(data, sha256) - self.failUnless(pub.verify(sig3, data)) + self.assertTrue(pub.verify(sig3, data)) - self.failUnlessEqual(sig1, sig2) - self.failUnlessEqual(sig1, sig3) + self.assertEqual(sig1, sig2) + self.assertEqual(sig1, sig3) def test_bad_usage(self): # sk=SigningKey() is wrong - self.failUnlessRaises(TypeError, SigningKey) - self.failUnlessRaises(TypeError, VerifyingKey) + self.assertRaises(TypeError, SigningKey) + self.assertRaises(TypeError, VerifyingKey) def test_lengths(self): default = NIST192p priv = SigningKey.generate() pub = priv.get_verifying_key() - self.failUnlessEqual(len(pub.to_string()), default.verifying_key_length) - sig = priv.sign("data") - self.failUnlessEqual(len(sig), default.signature_length) + self.assertEqual(len(pub.to_string()), default.verifying_key_length) + sig = priv.sign(b("data")) + self.assertEqual(len(sig), default.signature_length) if BENCH: - print + print_() for curve in (NIST192p, NIST224p, NIST256p, NIST384p, NIST521p): start = time.time() priv = SigningKey.generate(curve=curve) pub1 = priv.get_verifying_key() keygen_time = time.time() - start pub2 = VerifyingKey.from_string(pub1.to_string(), curve) - self.failUnlessEqual(pub1.to_string(), pub2.to_string()) - self.failUnlessEqual(len(pub1.to_string()), + self.assertEqual(pub1.to_string(), pub2.to_string()) + self.assertEqual(len(pub1.to_string()), curve.verifying_key_length) start = time.time() - sig = priv.sign("data") + sig = priv.sign(b("data")) sign_time = time.time() - start - self.failUnlessEqual(len(sig), curve.signature_length) + self.assertEqual(len(sig), curve.signature_length) if BENCH: start = time.time() - pub1.verify(sig, "data") + pub1.verify(sig, b("data")) verify_time = time.time() - start - print "%s: siglen=%d, keygen=%0.3fs, sign=%0.3f, verify=%0.3f" \ + print_("%s: siglen=%d, keygen=%0.3fs, sign=%0.3f, verify=%0.3f" \ % (curve.name, curve.signature_length, - keygen_time, sign_time, verify_time) + keygen_time, sign_time, verify_time)) def test_serialize(self): - seed = "secret" + seed = b("secret") curve = NIST192p secexp1 = util.randrange_from_seed__trytryagain(seed, curve.order) secexp2 = util.randrange_from_seed__trytryagain(seed, curve.order) - self.failUnlessEqual(secexp1, secexp2) + self.assertEqual(secexp1, secexp2) priv1 = SigningKey.from_secret_exponent(secexp1, curve) priv2 = SigningKey.from_secret_exponent(secexp2, curve) - self.failUnlessEqual(hexlify(priv1.to_string()), + self.assertEqual(hexlify(priv1.to_string()), hexlify(priv2.to_string())) - self.failUnlessEqual(priv1.to_pem(), priv2.to_pem()) + self.assertEqual(priv1.to_pem(), priv2.to_pem()) pub1 = priv1.get_verifying_key() pub2 = priv2.get_verifying_key() - data = "data" + data = b("data") sig1 = priv1.sign(data) sig2 = priv2.sign(data) - self.failUnless(pub1.verify(sig1, data)) - self.failUnless(pub2.verify(sig1, data)) - self.failUnless(pub1.verify(sig2, data)) - self.failUnless(pub2.verify(sig2, data)) - self.failUnlessEqual(hexlify(pub1.to_string()), + self.assertTrue(pub1.verify(sig1, data)) + self.assertTrue(pub2.verify(sig1, data)) + self.assertTrue(pub1.verify(sig2, data)) + self.assertTrue(pub2.verify(sig2, data)) + self.assertEqual(hexlify(pub1.to_string()), hexlify(pub2.to_string())) def test_nonrandom(self): - s = "all the entropy in the entire world, compressed into one line" + s = b("all the entropy in the entire world, compressed into one line") def not_much_entropy(numbytes): return s[:numbytes] # we control the entropy source, these two keys should be identical: priv1 = SigningKey.generate(entropy=not_much_entropy) priv2 = SigningKey.generate(entropy=not_much_entropy) - self.failUnlessEqual(hexlify(priv1.get_verifying_key().to_string()), + self.assertEqual(hexlify(priv1.get_verifying_key().to_string()), hexlify(priv2.get_verifying_key().to_string())) # likewise, signatures should be identical. Obviously you'd never # want to do this with keys you care about, because the secrecy of # the private key depends upon using different random numbers for # each signature - sig1 = priv1.sign("data", entropy=not_much_entropy) - sig2 = priv2.sign("data", entropy=not_much_entropy) - self.failUnlessEqual(hexlify(sig1), hexlify(sig2)) + sig1 = priv1.sign(b("data"), entropy=not_much_entropy) + sig2 = priv2.sign(b("data"), entropy=not_much_entropy) + self.assertEqual(hexlify(sig1), hexlify(sig2)) - def failUnlessPrivkeysEqual(self, priv1, priv2): - self.failUnlessEqual(priv1.privkey.secret_multiplier, + def assertTruePrivkeysEqual(self, priv1, priv2): + self.assertEqual(priv1.privkey.secret_multiplier, priv2.privkey.secret_multiplier) - self.failUnlessEqual(priv1.privkey.public_key.generator, + self.assertEqual(priv1.privkey.public_key.generator, priv2.privkey.public_key.generator) def failIfPrivkeysEqual(self, priv1, priv2): @@ -154,146 +157,146 @@ class ECDSA(unittest.TestCase): priv2.privkey.secret_multiplier) def test_privkey_creation(self): - s = "all the entropy in the entire world, compressed into one line" + s = b("all the entropy in the entire world, compressed into one line") def not_much_entropy(numbytes): return s[:numbytes] priv1 = SigningKey.generate() - self.failUnlessEqual(priv1.baselen, NIST192p.baselen) + self.assertEqual(priv1.baselen, NIST192p.baselen) priv1 = SigningKey.generate(curve=NIST224p) - self.failUnlessEqual(priv1.baselen, NIST224p.baselen) + self.assertEqual(priv1.baselen, NIST224p.baselen) priv1 = SigningKey.generate(entropy=not_much_entropy) - self.failUnlessEqual(priv1.baselen, NIST192p.baselen) + self.assertEqual(priv1.baselen, NIST192p.baselen) priv2 = SigningKey.generate(entropy=not_much_entropy) - self.failUnlessEqual(priv2.baselen, NIST192p.baselen) - self.failUnlessPrivkeysEqual(priv1, priv2) + self.assertEqual(priv2.baselen, NIST192p.baselen) + self.assertTruePrivkeysEqual(priv1, priv2) priv1 = SigningKey.from_secret_exponent(secexp=3) - self.failUnlessEqual(priv1.baselen, NIST192p.baselen) + self.assertEqual(priv1.baselen, NIST192p.baselen) priv2 = SigningKey.from_secret_exponent(secexp=3) - self.failUnlessPrivkeysEqual(priv1, priv2) + self.assertTruePrivkeysEqual(priv1, priv2) priv1 = SigningKey.from_secret_exponent(secexp=4, curve=NIST224p) - self.failUnlessEqual(priv1.baselen, NIST224p.baselen) + self.assertEqual(priv1.baselen, NIST224p.baselen) def test_privkey_strings(self): priv1 = SigningKey.generate() s1 = priv1.to_string() - self.failUnlessEqual(type(s1), str) - self.failUnlessEqual(len(s1), NIST192p.baselen) + self.assertEqual(type(s1), binary_type) + self.assertEqual(len(s1), NIST192p.baselen) priv2 = SigningKey.from_string(s1) - self.failUnlessPrivkeysEqual(priv1, priv2) + self.assertTruePrivkeysEqual(priv1, priv2) s1 = priv1.to_pem() - self.failUnlessEqual(type(s1), str) - self.failUnless(s1.startswith("-----BEGIN EC PRIVATE KEY-----")) - self.failUnless(s1.strip().endswith("-----END EC PRIVATE KEY-----")) + self.assertEqual(type(s1), binary_type) + self.assertTrue(s1.startswith(b("-----BEGIN EC PRIVATE KEY-----"))) + self.assertTrue(s1.strip().endswith(b("-----END EC PRIVATE KEY-----"))) priv2 = SigningKey.from_pem(s1) - self.failUnlessPrivkeysEqual(priv1, priv2) + self.assertTruePrivkeysEqual(priv1, priv2) s1 = priv1.to_der() - self.failUnlessEqual(type(s1), str) + self.assertEqual(type(s1), binary_type) priv2 = SigningKey.from_der(s1) - self.failUnlessPrivkeysEqual(priv1, priv2) + self.assertTruePrivkeysEqual(priv1, priv2) priv1 = SigningKey.generate(curve=NIST256p) s1 = priv1.to_pem() - self.failUnlessEqual(type(s1), str) - self.failUnless(s1.startswith("-----BEGIN EC PRIVATE KEY-----")) - self.failUnless(s1.strip().endswith("-----END EC PRIVATE KEY-----")) + self.assertEqual(type(s1), binary_type) + self.assertTrue(s1.startswith(b("-----BEGIN EC PRIVATE KEY-----"))) + self.assertTrue(s1.strip().endswith(b("-----END EC PRIVATE KEY-----"))) priv2 = SigningKey.from_pem(s1) - self.failUnlessPrivkeysEqual(priv1, priv2) + self.assertTruePrivkeysEqual(priv1, priv2) s1 = priv1.to_der() - self.failUnlessEqual(type(s1), str) + self.assertEqual(type(s1), binary_type) priv2 = SigningKey.from_der(s1) - self.failUnlessPrivkeysEqual(priv1, priv2) + self.assertTruePrivkeysEqual(priv1, priv2) - def failUnlessPubkeysEqual(self, pub1, pub2): - self.failUnlessEqual(pub1.pubkey.point, pub2.pubkey.point) - self.failUnlessEqual(pub1.pubkey.generator, pub2.pubkey.generator) - self.failUnlessEqual(pub1.curve, pub2.curve) + def assertTruePubkeysEqual(self, pub1, pub2): + self.assertEqual(pub1.pubkey.point, pub2.pubkey.point) + self.assertEqual(pub1.pubkey.generator, pub2.pubkey.generator) + self.assertEqual(pub1.curve, pub2.curve) def test_pubkey_strings(self): priv1 = SigningKey.generate() pub1 = priv1.get_verifying_key() s1 = pub1.to_string() - self.failUnlessEqual(type(s1), str) - self.failUnlessEqual(len(s1), NIST192p.verifying_key_length) + self.assertEqual(type(s1), binary_type) + self.assertEqual(len(s1), NIST192p.verifying_key_length) pub2 = VerifyingKey.from_string(s1) - self.failUnlessPubkeysEqual(pub1, pub2) + self.assertTruePubkeysEqual(pub1, pub2) priv1 = SigningKey.generate(curve=NIST256p) pub1 = priv1.get_verifying_key() s1 = pub1.to_string() - self.failUnlessEqual(type(s1), str) - self.failUnlessEqual(len(s1), NIST256p.verifying_key_length) + self.assertEqual(type(s1), binary_type) + self.assertEqual(len(s1), NIST256p.verifying_key_length) pub2 = VerifyingKey.from_string(s1, curve=NIST256p) - self.failUnlessPubkeysEqual(pub1, pub2) + self.assertTruePubkeysEqual(pub1, pub2) pub1_der = pub1.to_der() - self.failUnlessEqual(type(pub1_der), str) + self.assertEqual(type(pub1_der), binary_type) pub2 = VerifyingKey.from_der(pub1_der) - self.failUnlessPubkeysEqual(pub1, pub2) + self.assertTruePubkeysEqual(pub1, pub2) - self.failUnlessRaises(der.UnexpectedDER, - VerifyingKey.from_der, pub1_der+"junk") + self.assertRaises(der.UnexpectedDER, + VerifyingKey.from_der, pub1_der+b("junk")) badpub = VerifyingKey.from_der(pub1_der) class FakeGenerator: def order(self): return 123456789 badcurve = Curve("unknown", None, FakeGenerator(), (1,2,3,4,5,6)) badpub.curve = badcurve badder = badpub.to_der() - self.failUnlessRaises(UnknownCurveError, VerifyingKey.from_der, badder) + self.assertRaises(UnknownCurveError, VerifyingKey.from_der, badder) pem = pub1.to_pem() - self.failUnlessEqual(type(pem), str) - self.failUnless(pem.startswith("-----BEGIN PUBLIC KEY-----"), pem) - self.failUnless(pem.strip().endswith("-----END PUBLIC KEY-----"), pem) + self.assertEqual(type(pem), binary_type) + self.assertTrue(pem.startswith(b("-----BEGIN PUBLIC KEY-----")), pem) + self.assertTrue(pem.strip().endswith(b("-----END PUBLIC KEY-----")), pem) pub2 = VerifyingKey.from_pem(pem) - self.failUnlessPubkeysEqual(pub1, pub2) + self.assertTruePubkeysEqual(pub1, pub2) def test_signature_strings(self): priv1 = SigningKey.generate() pub1 = priv1.get_verifying_key() - data = "data" + data = b("data") sig = priv1.sign(data) - self.failUnlessEqual(type(sig), str) - self.failUnlessEqual(len(sig), NIST192p.signature_length) - self.failUnless(pub1.verify(sig, data)) + self.assertEqual(type(sig), binary_type) + self.assertEqual(len(sig), NIST192p.signature_length) + self.assertTrue(pub1.verify(sig, data)) sig = priv1.sign(data, sigencode=sigencode_strings) - self.failUnlessEqual(type(sig), tuple) - self.failUnlessEqual(len(sig), 2) - self.failUnlessEqual(type(sig[0]), str) - self.failUnlessEqual(type(sig[1]), str) - self.failUnlessEqual(len(sig[0]), NIST192p.baselen) - self.failUnlessEqual(len(sig[1]), NIST192p.baselen) - self.failUnless(pub1.verify(sig, data, sigdecode=sigdecode_strings)) + self.assertEqual(type(sig), tuple) + self.assertEqual(len(sig), 2) + self.assertEqual(type(sig[0]), binary_type) + self.assertEqual(type(sig[1]), binary_type) + self.assertEqual(len(sig[0]), NIST192p.baselen) + self.assertEqual(len(sig[1]), NIST192p.baselen) + self.assertTrue(pub1.verify(sig, data, sigdecode=sigdecode_strings)) sig_der = priv1.sign(data, sigencode=sigencode_der) - self.failUnlessEqual(type(sig_der), str) - self.failUnless(pub1.verify(sig_der, data, sigdecode=sigdecode_der)) + self.assertEqual(type(sig_der), binary_type) + self.assertTrue(pub1.verify(sig_der, data, sigdecode=sigdecode_der)) def test_hashfunc(self): sk = SigningKey.generate(curve=NIST256p, hashfunc=sha256) - data = "security level is 128 bits" + data = b("security level is 128 bits") sig = sk.sign(data) vk = VerifyingKey.from_string(sk.get_verifying_key().to_string(), curve=NIST256p, hashfunc=sha256) - self.failUnless(vk.verify(sig, data)) + self.assertTrue(vk.verify(sig, data)) sk2 = SigningKey.generate(curve=NIST256p) sig2 = sk2.sign(data, hashfunc=sha256) vk2 = VerifyingKey.from_string(sk2.get_verifying_key().to_string(), curve=NIST256p, hashfunc=sha256) - self.failUnless(vk2.verify(sig2, data)) + self.assertTrue(vk2.verify(sig2, data)) vk3 = VerifyingKey.from_string(sk.get_verifying_key().to_string(), curve=NIST256p) - self.failUnless(vk3.verify(sig, data, hashfunc=sha256)) + self.assertTrue(vk3.verify(sig, data, hashfunc=sha256)) class OpenSSL(unittest.TestCase): @@ -318,7 +321,7 @@ class OpenSSL(unittest.TestCase): # e.g. "OpenSSL 1.0.0 29 Mar 2010", or "OpenSSL 1.0.0a 1 Jun 2010", # or "OpenSSL 0.9.8o 01 Jun 2010" vs = v.split()[1].split(".") - if vs >= ["1","0","0"]: + if vs >= ["1","0","0"]: return "-SHA1" else: return "-ecdsa-with-SHA1" @@ -345,19 +348,20 @@ class OpenSSL(unittest.TestCase): os.mkdir("t") run_openssl("ecparam -name %s -genkey -out t/privkey.pem" % curvename) run_openssl("ec -in t/privkey.pem -pubout -out t/pubkey.pem") - data = "data" - open("t/data.txt","wb").write(data) + data = b("data") + with open("t/data.txt","wb") as e: e.write(data) run_openssl("dgst %s -sign t/privkey.pem -out t/data.sig t/data.txt" % mdarg) run_openssl("dgst %s -verify t/pubkey.pem -signature t/data.sig t/data.txt" % mdarg) - pubkey_pem = open("t/pubkey.pem").read() + with open("t/pubkey.pem","rb") as e: pubkey_pem = e.read() vk = VerifyingKey.from_pem(pubkey_pem) # 3 - sig_der = open("t/data.sig","rb").read() - self.failUnless(vk.verify(sig_der, data, # 5 + with open("t/data.sig","rb") as e: sig_der = e.read() + self.assertTrue(vk.verify(sig_der, data, # 5 hashfunc=sha1, sigdecode=sigdecode_der)) - sk = SigningKey.from_pem(open("t/privkey.pem").read()) # 1 + with open("t/privkey.pem") as e: fp = e.read() + sk = SigningKey.from_pem(fp) # 1 sig = sk.sign(data) - self.failUnless(vk.verify(sig, data)) + self.assertTrue(vk.verify(sig, data)) def test_to_openssl_nist192p(self): self.do_test_to_openssl(NIST192p, "prime192v1") @@ -377,91 +381,92 @@ class OpenSSL(unittest.TestCase): os.mkdir("t") sk = SigningKey.generate(curve=curve) vk = sk.get_verifying_key() - data = "data" - open("t/pubkey.der","wb").write(vk.to_der()) # 4 - open("t/pubkey.pem","wb").write(vk.to_pem()) # 4 + data = b("data") + with open("t/pubkey.der","wb") as e: e.write(vk.to_der()) # 4 + with open("t/pubkey.pem","wb") as e: e.write(vk.to_pem()) # 4 sig_der = sk.sign(data, hashfunc=sha1, sigencode=sigencode_der) - open("t/data.sig","wb").write(sig_der) # 6 - open("t/data.txt","wb").write(data) - open("t/baddata.txt","wb").write(data+"corrupt") - self.failUnlessRaises(SubprocessError, run_openssl, + with open("t/data.sig","wb") as e: e.write(sig_der) # 6 + with open("t/data.txt","wb") as e: e.write(data) + with open("t/baddata.txt","wb") as e: e.write(data+b("corrupt")) + + self.assertRaises(SubprocessError, run_openssl, "dgst %s -verify t/pubkey.der -keyform DER -signature t/data.sig t/baddata.txt" % mdarg) run_openssl("dgst %s -verify t/pubkey.der -keyform DER -signature t/data.sig t/data.txt" % mdarg) - open("t/privkey.pem","wb").write(sk.to_pem()) # 2 + with open("t/privkey.pem","wb") as e: e.write(sk.to_pem()) # 2 run_openssl("dgst %s -sign t/privkey.pem -out t/data.sig2 t/data.txt" % mdarg) run_openssl("dgst %s -verify t/pubkey.pem -signature t/data.sig2 t/data.txt" % mdarg) class DER(unittest.TestCase): def test_oids(self): oid_ecPublicKey = der.encode_oid(1, 2, 840, 10045, 2, 1) - self.failUnlessEqual(hexlify(oid_ecPublicKey), "06072a8648ce3d0201") - self.failUnlessEqual(hexlify(NIST224p.encoded_oid), "06052b81040021") - self.failUnlessEqual(hexlify(NIST256p.encoded_oid), - "06082a8648ce3d030107") - x = oid_ecPublicKey + "more" + self.assertEqual(hexlify(oid_ecPublicKey), b("06072a8648ce3d0201")) + self.assertEqual(hexlify(NIST224p.encoded_oid), b("06052b81040021")) + self.assertEqual(hexlify(NIST256p.encoded_oid), + b("06082a8648ce3d030107")) + x = oid_ecPublicKey + b("more") x1, rest = der.remove_object(x) - self.failUnlessEqual(x1, (1, 2, 840, 10045, 2, 1)) - self.failUnlessEqual(rest, "more") + self.assertEqual(x1, (1, 2, 840, 10045, 2, 1)) + self.assertEqual(rest, b("more")) def test_integer(self): - self.failUnlessEqual(der.encode_integer(0), "\x02\x01\x00") - self.failUnlessEqual(der.encode_integer(1), "\x02\x01\x01") - self.failUnlessEqual(der.encode_integer(127), "\x02\x01\x7f") - self.failUnlessEqual(der.encode_integer(128), "\x02\x02\x00\x80") - self.failUnlessEqual(der.encode_integer(256), "\x02\x02\x01\x00") - #self.failUnlessEqual(der.encode_integer(-1), "\x02\x01\xff") - - def s(n): return der.remove_integer(der.encode_integer(n) + "junk") - self.failUnlessEqual(s(0), (0, "junk")) - self.failUnlessEqual(s(1), (1, "junk")) - self.failUnlessEqual(s(127), (127, "junk")) - self.failUnlessEqual(s(128), (128, "junk")) - self.failUnlessEqual(s(256), (256, "junk")) - self.failUnlessEqual(s(1234567890123456789012345678901234567890), - ( 1234567890123456789012345678901234567890,"junk")) + self.assertEqual(der.encode_integer(0), b("\x02\x01\x00")) + self.assertEqual(der.encode_integer(1), b("\x02\x01\x01")) + self.assertEqual(der.encode_integer(127), b("\x02\x01\x7f")) + self.assertEqual(der.encode_integer(128), b("\x02\x02\x00\x80")) + self.assertEqual(der.encode_integer(256), b("\x02\x02\x01\x00")) + #self.assertEqual(der.encode_integer(-1), b("\x02\x01\xff")) + + def s(n): return der.remove_integer(der.encode_integer(n) + b("junk")) + self.assertEqual(s(0), (0, b("junk"))) + self.assertEqual(s(1), (1, b("junk"))) + self.assertEqual(s(127), (127, b("junk"))) + self.assertEqual(s(128), (128, b("junk"))) + self.assertEqual(s(256), (256, b("junk"))) + self.assertEqual(s(1234567890123456789012345678901234567890), + (1234567890123456789012345678901234567890,b("junk"))) def test_number(self): - self.failUnlessEqual(der.encode_number(0), "\x00") - self.failUnlessEqual(der.encode_number(127), "\x7f") - self.failUnlessEqual(der.encode_number(128), "\x81\x00") - self.failUnlessEqual(der.encode_number(3*128+7), "\x83\x07") - #self.failUnlessEqual(der.read_number("\x81\x9b"+"more"), (155, 2)) - #self.failUnlessEqual(der.encode_number(155), "\x81\x9b") + self.assertEqual(der.encode_number(0), b("\x00")) + self.assertEqual(der.encode_number(127), b("\x7f")) + self.assertEqual(der.encode_number(128), b("\x81\x00")) + self.assertEqual(der.encode_number(3*128+7), b("\x83\x07")) + #self.assertEqual(der.read_number("\x81\x9b"+"more"), (155, 2)) + #self.assertEqual(der.encode_number(155), b("\x81\x9b")) for n in (0, 1, 2, 127, 128, 3*128+7, 840, 10045): #, 155): - x = der.encode_number(n) + "more" + x = der.encode_number(n) + b("more") n1, llen = der.read_number(x) - self.failUnlessEqual(n1, n) - self.failUnlessEqual(x[llen:], "more") + self.assertEqual(n1, n) + self.assertEqual(x[llen:], b("more")) def test_length(self): - self.failUnlessEqual(der.encode_length(0), "\x00") - self.failUnlessEqual(der.encode_length(127), "\x7f") - self.failUnlessEqual(der.encode_length(128), "\x81\x80") - self.failUnlessEqual(der.encode_length(255), "\x81\xff") - self.failUnlessEqual(der.encode_length(256), "\x82\x01\x00") - self.failUnlessEqual(der.encode_length(3*256+7), "\x82\x03\x07") - self.failUnlessEqual(der.read_length("\x81\x9b"+"more"), (155, 2)) - self.failUnlessEqual(der.encode_length(155), "\x81\x9b") + self.assertEqual(der.encode_length(0), b("\x00")) + self.assertEqual(der.encode_length(127), b("\x7f")) + self.assertEqual(der.encode_length(128), b("\x81\x80")) + self.assertEqual(der.encode_length(255), b("\x81\xff")) + self.assertEqual(der.encode_length(256), b("\x82\x01\x00")) + self.assertEqual(der.encode_length(3*256+7), b("\x82\x03\x07")) + self.assertEqual(der.read_length(b("\x81\x9b")+b("more")), (155, 2)) + self.assertEqual(der.encode_length(155), b("\x81\x9b")) for n in (0, 1, 2, 127, 128, 255, 256, 3*256+7, 155): - x = der.encode_length(n) + "more" + x = der.encode_length(n) + b("more") n1, llen = der.read_length(x) - self.failUnlessEqual(n1, n) - self.failUnlessEqual(x[llen:], "more") + self.assertEqual(n1, n) + self.assertEqual(x[llen:], b("more")) def test_sequence(self): - x = der.encode_sequence("ABC", "DEF") + "GHI" - self.failUnlessEqual(x, "\x30\x06ABCDEFGHI") + x = der.encode_sequence(b("ABC"), b("DEF")) + b("GHI") + self.assertEqual(x, b("\x30\x06ABCDEFGHI")) x1, rest = der.remove_sequence(x) - self.failUnlessEqual(x1, "ABCDEF") - self.failUnlessEqual(rest, "GHI") + self.assertEqual(x1, b("ABCDEF")) + self.assertEqual(rest, b("GHI")) def test_constructed(self): x = der.encode_constructed(0, NIST224p.encoded_oid) - self.failUnlessEqual(hexlify(x), "a007" + "06052b81040021") - x = der.encode_constructed(1, unhexlify("0102030a0b0c")) - self.failUnlessEqual(hexlify(x), "a106" + "0102030a0b0c") + self.assertEqual(hexlify(x), b("a007") + b("06052b81040021")) + x = der.encode_constructed(1, unhexlify(b("0102030a0b0c"))) + self.assertEqual(hexlify(x), b("a106") + b("0102030a0b0c")) class Util(unittest.TestCase): def test_trytryagain(self): @@ -471,10 +476,10 @@ class Util(unittest.TestCase): for order in (2**8-2, 2**8-1, 2**8, 2**8+1, 2**8+2, 2**16-1, 2**16+1): n = tta(seed, order) - self.failUnless(1 <= n < order, (1, n, order)) + self.assertTrue(1 <= n < order, (1, n, order)) # this trytryagain *does* provide long-term stability - self.failUnlessEqual("%x"%(tta("seed", NIST224p.order)), - "6fa59d73bf0446ae8743cf748fc5ac11d5585a90356417e97155c3bc") + self.assertEqual(("%x"%(tta("seed", NIST224p.order))).encode(), + b("6fa59d73bf0446ae8743cf748fc5ac11d5585a90356417e97155c3bc")) def test_randrange(self): # util.randrange does not provide long-term stability: we might @@ -486,7 +491,7 @@ class Util(unittest.TestCase): ): # that oddball 2**16+1 takes half our runtime n = util.randrange(order, entropy=entropy) - self.failUnless(1 <= n < order, (1, n, order)) + self.assertTrue(1 <= n < order, (1, n, order)) def OFF_test_prove_uniformity(self): order = 2**8-2 @@ -498,15 +503,15 @@ class Util(unittest.TestCase): n = util.randrange_from_seed__trytryagain(seed, order) counts[n] += 1 # this technique should use the full range - self.failUnless(counts[order-1]) + self.assertTrue(counts[order-1]) for i in range(1, order): - print "%3d: %s" % (i, "*"*(counts[i]//100)) + print_("%3d: %s" % (i, "*"*(counts[i]//100))) class RFC6979(unittest.TestCase): # https://tools.ietf.org/html/rfc6979#appendix-A.1 def _do(self, generator, secexp, hsh, hash_func, expected): actual = rfc6979.generate_k(generator, secexp, hash_func, hsh) - self.failUnlessEqual(expected, actual) + self.assertEqual(expected, actual) def test_SECP256k1(self): '''RFC doesn't contain test vectors for SECP256k1 used in bitcoin. @@ -514,7 +519,7 @@ class RFC6979(unittest.TestCase): self._do( generator = SECP256k1.generator, secexp = int("9d0219792467d7d37b4d43298a7d0c05", 16), - hsh = sha256("sample").digest(), + hsh = sha256(b("sample")).digest(), hash_func = sha256, expected = int("8fa1f95d514760e498f28957b824ee6ec39ed64826ff4fecc2b5739ec45b91cd", 16)) @@ -522,7 +527,7 @@ class RFC6979(unittest.TestCase): self._do( generator=SECP256k1.generator, secexp=int("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50", 16), - hsh=sha256("sample").digest(), + hsh=sha256(b("sample")).digest(), hash_func=sha256, expected=int("2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3", 16)) @@ -530,7 +535,7 @@ class RFC6979(unittest.TestCase): self._do( generator=SECP256k1.generator, secexp=0x1, - hsh=sha256("Satoshi Nakamoto").digest(), + hsh=sha256(b("Satoshi Nakamoto")).digest(), hash_func=sha256, expected=0x8F8A276C19F4149656B280621E358CCE24F5F52542772691EE69063B74F15D15) @@ -538,7 +543,7 @@ class RFC6979(unittest.TestCase): self._do( generator=SECP256k1.generator, secexp=0x1, - hsh=sha256("All those moments will be lost in time, like tears in rain. Time to die...").digest(), + hsh=sha256(b("All those moments will be lost in time, like tears in rain. Time to die...")).digest(), hash_func=sha256, expected=0x38AA22D72376B4DBC472E06C3BA403EE0A394DA63FC58D88686C611ABA98D6B3) @@ -546,7 +551,7 @@ class RFC6979(unittest.TestCase): self._do( generator=SECP256k1.generator, secexp=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140, - hsh=sha256("Satoshi Nakamoto").digest(), + hsh=sha256(b("Satoshi Nakamoto")).digest(), hash_func=sha256, expected=0x33A19B60E25FB6F4435AF53A3D42D493644827367E6453928554F43E49AA6F90) @@ -554,7 +559,7 @@ class RFC6979(unittest.TestCase): self._do( generator=SECP256k1.generator, secexp=0xf8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181, - hsh=sha256("Alan Turing").digest(), + hsh=sha256(b("Alan Turing")).digest(), hash_func=sha256, expected=0x525A82B70E67874398067543FD84C83D30C175FDC45FDEEE082FE13B1D7CFDF1) @@ -571,7 +576,7 @@ class RFC6979(unittest.TestCase): self._do( generator=NIST192p.generator, secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16), - hsh = sha1("sample").digest(), + hsh = sha1(b("sample")).digest(), hash_func = sha1, expected = int("37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", 16)) @@ -579,7 +584,7 @@ class RFC6979(unittest.TestCase): self._do( generator=NIST192p.generator, secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16), - hsh = sha256("sample").digest(), + hsh = sha256(b("sample")).digest(), hash_func = sha256, expected = int("32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", 16)) @@ -587,7 +592,7 @@ class RFC6979(unittest.TestCase): self._do( generator=NIST192p.generator, secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16), - hsh = sha512("sample").digest(), + hsh = sha512(b("sample")).digest(), hash_func = sha512, expected = int("A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", 16)) @@ -595,7 +600,7 @@ class RFC6979(unittest.TestCase): self._do( generator=NIST192p.generator, secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16), - hsh = sha1("test").digest(), + hsh = sha1(b("test")).digest(), hash_func = sha1, expected = int("D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", 16)) @@ -603,7 +608,7 @@ class RFC6979(unittest.TestCase): self._do( generator=NIST192p.generator, secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16), - hsh = sha256("test").digest(), + hsh = sha256(b("test")).digest(), hash_func = sha256, expected = int("5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", 16)) @@ -611,7 +616,7 @@ class RFC6979(unittest.TestCase): self._do( generator=NIST192p.generator, secexp = int("6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4", 16), - hsh = sha512("test").digest(), + hsh = sha512(b("test")).digest(), hash_func = sha512, expected = int("0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", 16)) @@ -619,7 +624,7 @@ class RFC6979(unittest.TestCase): self._do( generator=NIST521p.generator, secexp = int("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538", 16), - hsh = sha1("sample").digest(), + hsh = sha1(b("sample")).digest(), hash_func = sha1, expected = int("089C071B419E1C2820962321787258469511958E80582E95D8378E0C2CCDB3CB42BEDE42F50E3FA3C71F5A76724281D31D9C89F0F91FC1BE4918DB1C03A5838D0F9", 16)) @@ -627,7 +632,7 @@ class RFC6979(unittest.TestCase): self._do( generator=NIST521p.generator, secexp = int("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538", 16), - hsh = sha256("sample").digest(), + hsh = sha256(b("sample")).digest(), hash_func = sha256, expected = int("0EDF38AFCAAECAB4383358B34D67C9F2216C8382AAEA44A3DAD5FDC9C32575761793FEF24EB0FC276DFC4F6E3EC476752F043CF01415387470BCBD8678ED2C7E1A0", 16)) @@ -635,7 +640,7 @@ class RFC6979(unittest.TestCase): self._do( generator=NIST521p.generator, secexp = int("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538", 16), - hsh = sha512("test").digest(), + hsh = sha512(b("test")).digest(), hash_func = sha512, expected = int("16200813020EC986863BEDFC1B121F605C1215645018AEA1A7B215A564DE9EB1B38A67AA1128B80CE391C4FB71187654AAA3431027BFC7F395766CA988C964DC56D", 16)) diff --git a/ecdsa/util.py b/ecdsa/util.py index 9531a3a..2b6d379 100644 --- a/ecdsa/util.py +++ b/ecdsa/util.py @@ -1,10 +1,12 @@ +from __future__ import division import os import math import binascii from hashlib import sha256 -import der -from curves import orderlen +from . import der +from .curves import orderlen +from .six import PY3, int2byte, b, next # RFC5480: # The "unrestricted" algorithm identifier is: @@ -64,12 +66,18 @@ class PRNG: self.generator = self.block_generator(seed) def __call__(self, numbytes): - return "".join([self.generator.next() for i in range(numbytes)]) + a = [next(self.generator) for i in range(numbytes)] + + if PY3: + return bytes(a) + else: + return "".join(a) + def block_generator(self, seed): counter = 0 while True: - for byte in sha256("prng-%d-%s" % (counter, seed)).digest(): + for byte in sha256(("prng-%d-%s" % (counter, seed)).encode()).digest(): yield byte counter += 1 @@ -126,7 +134,7 @@ def randrange_from_seed__truncate_bits(seed, order, hashmod=sha256): base = "\x00"*(maxbytes-len(base)) + base topbits = 8*maxbytes - bits if topbits: - base = chr(ord(base[0]) & lsb_of_ones(topbits)) + base[1:] + base = int2byte(ord(base[0]) & lsb_of_ones(topbits)) + base[1:] number = 1+int(binascii.hexlify(base), 16) assert 1 <= number < order return number @@ -142,9 +150,9 @@ def randrange_from_seed__trytryagain(seed, order): bits, bytes, extrabits = bits_and_bytes(order) generate = PRNG(seed) while True: - extrabyte = "" + extrabyte = b("") if extrabits: - extrabyte = chr(ord(generate(1)) & lsb_of_ones(extrabits)) + extrabyte = int2byte(ord(generate(1)) & lsb_of_ones(extrabits)) guess = string_to_number(extrabyte + generate(bytes)) + 1 if 1 <= guess < order: return guess @@ -153,7 +161,7 @@ def randrange_from_seed__trytryagain(seed, order): def number_to_string(num, order): l = orderlen(order) fmt_str = "%0" + str(2*l) + "x" - string = binascii.unhexlify(fmt_str % num) + string = binascii.unhexlify((fmt_str % num).encode()) assert len(string) == l, (len(string), l) return string @@ -209,12 +217,12 @@ def sigdecode_strings(rs_strings, order): def sigdecode_der(sig_der, order): #return der.encode_sequence(der.encode_integer(r), der.encode_integer(s)) rs_strings, empty = der.remove_sequence(sig_der) - if empty != "": + if empty != b(""): raise der.UnexpectedDER("trailing junk after DER sig: %s" % binascii.hexlify(empty)) r, rest = der.remove_integer(rs_strings) s, empty = der.remove_integer(rest) - if empty != "": + if empty != b(""): raise der.UnexpectedDER("trailing junk after DER numbers: %s" % binascii.hexlify(empty)) return r, s @@ -1,8 +1,8 @@ #!/usr/bin/env python - import os, subprocess, re from distutils.core import setup, Command from distutils.command.sdist import sdist as _sdist +from ecdsa.six import print_ class Test(Command): description = "run unit tests" @@ -32,18 +32,18 @@ __version__ = '%s' def update_version_py(): if not os.path.isdir(".git"): - print "This does not appear to be a Git repository." + print_("This does not appear to be a Git repository.") return try: p = subprocess.Popen(["git", "describe", "--tags", "--dirty", "--always"], stdout=subprocess.PIPE) except EnvironmentError: - print "unable to run git, leaving ecdsa/_version.py alone" + print_("unable to run git, leaving ecdsa/_version.py alone") return stdout = p.communicate()[0] if p.returncode != 0: - print "unable to run git, leaving ecdsa/_version.py alone" + print_("unable to run git, leaving ecdsa/_version.py alone") return # we use tags like "python-ecdsa-0.5", so strip the prefix assert stdout.startswith("python-ecdsa-") @@ -51,7 +51,7 @@ def update_version_py(): f = open("ecdsa/_version.py", "w") f.write(VERSION_PY % ver) f.close() - print "set ecdsa/_version.py to '%s'" % ver + print_("set ecdsa/_version.py to '%s'" % ver) def get_version(): try: @@ -75,7 +75,7 @@ class Version(Command): pass def run(self): update_version_py() - print "Version is now", get_version() + print_("Version is now", get_version()) class sdist(_sdist): def run(self): |