def recover_public_key(digest, signature, i, message=None):
<EOL>curve = ecdsa.SECP256k1.curve<EOL>G = ecdsa.SECP256k1.generator<EOL>order = ecdsa.SECP256k1.order<EOL>yp = i % <NUM_LIT:2><EOL>r, s = ecdsa.util.sigdecode_string(signature, order)<EOL>x = r + (i // <NUM_LIT:2>) * order<EOL>alpha = ((x * x * x) + (curve.a() * x) + curve.b()) % curve.p()<EOL>beta = ecdsa.numbertheory.square_root_mod_prime(alpha, curve.p())<EOL>y = beta if (beta - yp) % <NUM_LIT:2> == <NUM_LIT:0> else curve.p() - beta<EOL>R = ecdsa.ellipticcurve.Point(curve, x, y, order)<EOL>e = ecdsa.util.string_to_number(digest)<EOL>Q = ecdsa.numbertheory.inverse_mod(r, order) * (s * R + (-e % order) * G)<EOL>if SECP256K1_MODULE == "<STR_LIT>" and message is not None:<EOL><INDENT>if not isinstance(message, bytes):<EOL><INDENT>message = bytes(message, "<STR_LIT:utf-8>")  <EOL><DEDENT>sigder = encode_dss_signature(r, s)<EOL>public_key = ec.EllipticCurvePublicNumbers(<EOL>Q._Point__x, Q._Point__y, ec.SECP256K1()<EOL>).public_key(default_backend())<EOL>public_key.verify(sigder, message, ec.ECDSA(hashes.SHA256()))<EOL>return public_key<EOL><DEDENT>else:<EOL><INDENT>if not ecdsa.VerifyingKey.from_public_point(<EOL>Q, curve=ecdsa.SECP256k1<EOL>).verify_digest(<EOL>signature, digest, sigdecode=ecdsa.util.sigdecode_string<EOL>):  <EOL><INDENT>return None  <EOL><DEDENT>return ecdsa.VerifyingKey.from_public_point(<EOL>Q, curve=ecdsa.SECP256k1<EOL>)<EOL><DEDENT>
Recover the public key from the the signature