ethereum.crypto.elliptic_curve
Elliptic Curves ^^^^^^^^^^^^^^^
SECP256K1B
14 | SECP256K1B = U256(7) |
---|
SECP256K1P
15 | SECP256K1P = U256( |
---|---|
16 | 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F |
17 | ) |
SECP256K1N
18 | SECP256K1N = U256( |
---|---|
19 | 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 |
20 | ) |
secp256k1_recover
Recovers the public key from a given signature.
Parameters
r : TODO s : TODO v : TODO msg_hash : Hash of the message being recovered.
Returns
public_key : ethereum.base_types.Bytes
Recovered public key.
def secp256k1_recover(r: U256, s: U256, v: U256, msg_hash: Hash32) -> Bytes:
24 | """ |
---|---|
25 | Recovers the public key from a given signature. |
26 |
|
27 | Parameters |
28 | ---------- |
29 | r : |
30 | TODO |
31 | s : |
32 | TODO |
33 | v : |
34 | TODO |
35 | msg_hash : |
36 | Hash of the message being recovered. |
37 |
|
38 | Returns |
39 | ------- |
40 | public_key : `ethereum.base_types.Bytes` |
41 | Recovered public key. |
42 | """ |
43 | is_square = pow( |
44 | pow(r, U256(3), SECP256K1P) + SECP256K1B, |
45 | (SECP256K1P - U256(1)) // U256(2), |
46 | SECP256K1P, |
47 | ) |
48 | |
49 | if is_square != 1: |
50 | raise InvalidSignatureError( |
51 | "r is not the x-coordinate of a point on the secp256k1 curve" |
52 | ) |
53 | |
54 | r_bytes = r.to_be_bytes32() |
55 | s_bytes = s.to_be_bytes32() |
56 | |
57 | signature = bytearray([0] * 65) |
58 | signature[32 - len(r_bytes) : 32] = r_bytes |
59 | signature[64 - len(s_bytes) : 64] = s_bytes |
60 | signature[64] = v |
61 | |
62 | # If the recovery algorithm returns the point at infinity, |
63 | # the signature is considered invalid |
64 | # the below function will raise a ValueError. |
65 | try: |
66 | public_key = coincurve.PublicKey.from_signature_and_message( |
67 | bytes(signature), msg_hash, hasher=None |
68 | ) |
69 | except ValueError as e: |
70 | raise InvalidSignatureError from e |
71 | |
72 | public_key = public_key.format(compressed=False)[1:] |
73 | return public_key |