Check whether a public_key matches an address

The following question has been asked on Telegram:

Hello, I want to check whether a public_key that a user send is matched his/her tezos address.
Is there a way to check the match in run time?

Yes there is a way.

You can get an address from a public key hash by doing sp.to_address(sp.implicit_account(<key>)).

Here is an example:

import smartpy as sp

def main():
    class MyContract(sp.Contract):
        def check_key_address(self, key, address):
            sp.cast(key, sp.key_hash)
            sp.cast(address, sp.address)
            assert address == sp.to_address(sp.implicit_account(key)), "NotSimilar"

if "templates" not in __name__:
    def test():
        alice = sp.test_account("alice")
        bob = sp.test_account("bob")
        sc = sp.test_scenario(main)
        c1 = main.MyContract()
        sc += c1
        c1.check_key_address(key=alice.public_key_hash, address=alice.address)
        c1.check_key_address(key=alice.public_key_hash, address=bob.address).run(
            valid=False, exception="NotSimilar")
        c1.check_key_address(key=bob.public_key_hash, address=alice.address).run(
            valid=False, exception="NotSimilar")

Note that there is no way to get the public key hash from the address.