def verify_message(message, signature, hashfn=hashlib.sha256, recover_parameter=None): if not isinstance(message, bytes_types): message = py23_bytes(message, "utf-8") if not isinstance(signature, bytes_types): signature = py23_bytes(signature, "utf-8") if not isinstance(message, bytes_types): raise AssertionError() if not isinstance(signature, bytes_types): raise AssertionError() digest = hashfn(message).digest() sig = signature[1:] if recover_parameter is None: recover_parameter = bytearray( signature)[0] - 4 - 27 # recover parameter only if recover_parameter < 0: log.info("Could not recover parameter") return None if SECP256K1_MODULE == "secp256k1": ALL_FLAGS = secp256k1.lib.SECP256K1_CONTEXT_VERIFY | secp256k1.lib.SECP256K1_CONTEXT_SIGN # Placeholder pub = secp256k1.PublicKey(flags=ALL_FLAGS) # Recover raw signature sig = pub.ecdsa_recoverable_deserialize(sig, recover_parameter) # Recover PublicKey verifyPub = secp256k1.PublicKey(pub.ecdsa_recover(message, sig)) # Convert recoverable sig to normal sig normalSig = verifyPub.ecdsa_recoverable_convert(sig) # Verify verifyPub.ecdsa_verify(message, normalSig) phex = verifyPub.serialize(compressed=True) elif SECP256K1_MODULE == "cryptography": p = recover_public_key(digest, sig, recover_parameter, message) order = ecdsa.SECP256k1.order r, s = ecdsa.util.sigdecode_string(sig, order) sigder = encode_dss_signature(r, s) p.verify(sigder, message, ec.ECDSA(hashes.SHA256())) phex = compressedPubkey(p) else: # pragma: no branch # pragma: no cover p = recover_public_key(digest, sig, recover_parameter) # Will throw an exception of not valid p.verify_digest(sig, digest, sigdecode=ecdsa.util.sigdecode_string) phex = compressedPubkey(p) return phex
def recoverPubkeyParameter(message, digest, signature, pubkey): """ Use to derive a number that allows to easily recover the public key from the signature """ if not isinstance(message, bytes_types): message = py23_bytes(message, "utf-8") for i in range(0, 4): if SECP256K1_MODULE == "secp256k1": sig = pubkey.ecdsa_recoverable_deserialize(signature, i) p = secp256k1.PublicKey(pubkey.ecdsa_recover(message, sig)) if p.serialize() == pubkey.serialize(): return i elif SECP256K1_MODULE == "cryptography" and not isinstance( pubkey, PublicKey): p = recover_public_key(digest, signature, i, message) p_comp = hexlify(compressedPubkey(p)) pubkey_comp = hexlify(compressedPubkey(pubkey)) if (p_comp == pubkey_comp): return i else: # pragma: no cover p = recover_public_key(digest, signature, i) p_comp = hexlify(compressedPubkey(p)) p_string = hexlify(p.to_string()) if isinstance(pubkey, PublicKey): pubkey_string = py23_bytes(repr(pubkey), 'latin') else: # pragma: no cover pubkey_string = hexlify(pubkey.to_string()) if (p_string == pubkey_string or p_comp == pubkey_string): return i return None
def tweakaddPubkey(pk, digest256, SECP256K1_MODULE=SECP256K1_MODULE): if SECP256K1_MODULE == "secp256k1": tmp_key = secp256k1.PublicKey(pubkey=bytes(pk), raw=True) new_key = tmp_key.tweak_add(digest256) # <-- add raw_key = hexlify(new_key.serialize()).decode("ascii") else: raise Exception("Must have secp256k1 for `tweak_add`") # raw_key = ecmult(pk, 1, digest256, SECP256K1_MODULE) return PublicKey(raw_key, prefix=pk.prefix)