From d3644aa3547f2a02cbd1aa8f951b77bdff0bc8bc Mon Sep 17 00:00:00 2001 From: Lee Miller Date: Sun, 7 Jan 2024 03:20:51 +0200 Subject: [PATCH 1/4] Add a test for short pubkey coordinates --- src/pyelliptic/tests/test_ecc.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/pyelliptic/tests/test_ecc.py b/src/pyelliptic/tests/test_ecc.py index 6327d333..e6c20923 100644 --- a/src/pyelliptic/tests/test_ecc.py +++ b/src/pyelliptic/tests/test_ecc.py @@ -1,5 +1,6 @@ """Tests for ECC object""" +import os import unittest from hashlib import sha512 @@ -30,6 +31,22 @@ class TestECC(unittest.TestCase): pubkey = eccobj.get_pubkey() self.assertEqual(pubkey[:4], b'\x02\xca\x00\x20') + def test_short_keys(self): + """Check formatting of the keys with leading zeroes""" + def sample_key(_): + return os.urandom(32), os.urandom(31), os.urandom(30) + + try: + gen_orig = pyelliptic.ECC._generate + pyelliptic.ECC._generate = sample_key + eccobj = pyelliptic.ECC(curve='secp256k1') + pubkey = eccobj.get_pubkey() + self.assertEqual(pubkey[:4], b'\x02\xca\x00\x20') + self.assertEqual(pubkey[36:38], b'\x00\x20') + self.assertEqual(len(pubkey[38:]), 32) + finally: + pyelliptic.ECC._generate = gen_orig + def test_decode_keys(self): """Check keys decoding""" # pylint: disable=protected-access -- 2.45.1 From 688094371e2e9c26481858507002a8dc303fee5f Mon Sep 17 00:00:00 2001 From: Lee Miller Date: Sun, 7 Jan 2024 03:31:05 +0200 Subject: [PATCH 2/4] Relax the assertion about privkey length --- src/pyelliptic/tests/test_ecc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyelliptic/tests/test_ecc.py b/src/pyelliptic/tests/test_ecc.py index e6c20923..43c01542 100644 --- a/src/pyelliptic/tests/test_ecc.py +++ b/src/pyelliptic/tests/test_ecc.py @@ -27,7 +27,7 @@ class TestECC(unittest.TestCase): def test_random_keys(self): """A dummy test for random keys in ECC object""" eccobj = pyelliptic.ECC(curve='secp256k1') - self.assertEqual(len(eccobj.privkey), 32) + self.assertTrue(len(eccobj.privkey) <= 32) pubkey = eccobj.get_pubkey() self.assertEqual(pubkey[:4], b'\x02\xca\x00\x20') -- 2.45.1 From 8e952799062f2a6dc171ae7310c4b652f0b8a67a Mon Sep 17 00:00:00 2001 From: Lee Miller Date: Sun, 7 Jan 2024 03:32:10 +0200 Subject: [PATCH 3/4] Pad pubkey coordinates in pyelliptic.ECC.get_pubkey() --- src/pyelliptic/ecc.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/pyelliptic/ecc.py b/src/pyelliptic/ecc.py index d25b0129..c670d023 100644 --- a/src/pyelliptic/ecc.py +++ b/src/pyelliptic/ecc.py @@ -107,12 +107,19 @@ class ECC(object): High level function which returns : curve(2) + len_of_pubkeyX(2) + pubkeyX + len_of_pubkeyY + pubkeyY """ + ctx = OpenSSL.BN_CTX_new() + n = OpenSSL.BN_new() + group = OpenSSL.EC_GROUP_new_by_curve_name(self.curve) + OpenSSL.EC_GROUP_get_order(group, n, ctx) + key_len = OpenSSL.BN_num_bytes(n) + pubkey_x = self.pubkey_x.rjust(key_len, b'\x00') + pubkey_y = self.pubkey_y.rjust(key_len, b'\x00') return b''.join(( pack('!H', self.curve), - pack('!H', len(self.pubkey_x)), - self.pubkey_x, - pack('!H', len(self.pubkey_y)), - self.pubkey_y, + pack('!H', len(pubkey_x)), + pubkey_x, + pack('!H', len(pubkey_y)), + pubkey_y, )) def get_privkey(self): -- 2.45.1 From b3c5900eb3b69c30a961c9060a8f049c0aec373a Mon Sep 17 00:00:00 2001 From: Peter Surda Date: Tue, 20 Feb 2024 08:47:07 +0800 Subject: [PATCH 4/4] Code quality fixes --- src/pyelliptic/tests/test_ecc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pyelliptic/tests/test_ecc.py b/src/pyelliptic/tests/test_ecc.py index 43c01542..e87d1c21 100644 --- a/src/pyelliptic/tests/test_ecc.py +++ b/src/pyelliptic/tests/test_ecc.py @@ -33,7 +33,9 @@ class TestECC(unittest.TestCase): def test_short_keys(self): """Check formatting of the keys with leading zeroes""" + # pylint: disable=protected-access def sample_key(_): + """Fake ECC keypair""" return os.urandom(32), os.urandom(31), os.urandom(30) try: -- 2.45.1