Created
September 11, 2022 18:50
-
-
Save sixTheDave/038463c232c5cf644860ab038a1c9fde to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from eth_account.account import to_standard_signature_bytes | |
from eth_keys import keys | |
from eth_utils import (big_endian_to_int, to_bytes) | |
from hexbytes import HexBytes | |
from eth_keys.backends.native.jacobian import (inv, fast_multiply, fast_add) | |
from eth_keys.constants import (SECPK1_G as G, SECPK1_N as N) | |
def recover_public_key(message_hash, signature): | |
message_hash_bytes = HexBytes(message_hash) | |
if len(message_hash_bytes) != 32: | |
raise ValueError("The message hash must be exactly 32-bytes") | |
signature_bytes = HexBytes(signature) | |
signature_obj = keys.Signature(signature_bytes = to_standard_signature_bytes(signature_bytes)) | |
return signature_obj.recover_public_key_from_msg_hash(message_hash_bytes) | |
def forge(public_key, a = 0, b = 1): | |
t = public_key.to_bytes() | |
Y = big_endian_to_int(t[:32]), big_endian_to_int(t[32:]) | |
r, y = fast_add(fast_multiply(G, a), fast_multiply(Y, b)) | |
s_raw = r * inv(b, N) % N | |
v_raw = (y % 2) ^ (0 if s_raw * 2 < N else 1) | |
s = s_raw if s_raw * 2 < N else N - s_raw | |
v = v_raw + 27 | |
z = a * s_raw % N | |
eth_signature_bytes = to_bytes(r).rjust(32, b'\0') + to_bytes(s).rjust(32, b'\0') + to_bytes(v) | |
return '0x' + to_bytes(z).rjust(32, b'\0').hex(), '0x' + eth_signature_bytes.hex() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment