From ca15a6b6d8a1b10d03511d26e6e5217ea8d933e4 Mon Sep 17 00:00:00 2001 From: bliepp <12013202+bliepp@users.noreply.github.com> Date: Sun, 9 Jan 2022 20:54:56 +0100 Subject: [PATCH] Generate PublicKey from PrivateKey --- doc/usage.rst | 13 +++++++++++++ rsa/key.py | 12 ++++++++++++ tests/test_key.py | 6 ++++++ 3 files changed, 31 insertions(+) diff --git a/doc/usage.rst b/doc/usage.rst index a55a2bc..a00b7d2 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -40,6 +40,19 @@ Alternatively you can use :py:meth:`rsa.PrivateKey.load_pkcs1` and ... keydata = privatefile.read() >>> privkey = rsa.PrivateKey.load_pkcs1(keydata) +As public keys can be derived from private keys it is sufficient to +have only the private one. The :py:class:`rsa.PrivateKey` class +has the dedicated method :py:meth:`rsa.PrivateKey.public_key` to +retrieve the corresponding :py:class:`rsa.PublicKey` from it: + + >>> import rsa + >>> with open('private.pem', mode='rb') as privatefile: + ... keydata = privatefile.read() + >>> privkey = rsa.PrivateKey.load_pkcs1(keydata) + >>> pubkey = privkey.public_key() + + + Time to generate a key ++++++++++++++++++++++ diff --git a/rsa/key.py b/rsa/key.py index 1284ffc..42ee2bd 100644 --- a/rsa/key.py +++ b/rsa/key.py @@ -499,6 +499,18 @@ def blinded_encrypt(self, message: int) -> int: encrypted = rsa.core.encrypt_int(blinded, self.d, self.n) return self.unblind(encrypted, blindfac_inverse) + def public_key(self) -> PublicKey: + """Generates the corresponding PublicKey from the PrivateKey. + + Equivalent to + >>> pubkey = PublicKey(privkey.n, privkey.e) + + :returns: the public key that belongs to the private key + :rtype: PublicKey + """ + + return PublicKey(self.n, self.e) + @classmethod def _load_pkcs1_der(cls, keyfile: bytes) -> "PrivateKey": """Loads a key in PKCS#1 DER format. diff --git a/tests/test_key.py b/tests/test_key.py index 75e6e12..cda6084 100644 --- a/tests/test_key.py +++ b/tests/test_key.py @@ -74,6 +74,12 @@ def getprime(_): ) self.assertEqual(39317, p) self.assertEqual(33107, q) + + def test_generate_public_from_private(self): + pub, priv = rsa.key.newkeys(16) + pub_generated = priv.public_key() + + self.assertEqual(pub, pub_generated) class HashTest(unittest.TestCase):