ethereum.crypto.elliptic_curve
Elliptic Curves ^^^^^^^^^^^^^^^
SECP256K1N
15 | SECP256K1N = U256( |
---|---|
16 | 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 |
17 | ) |
F
19 | F = TypeVar("F", bound=Field) |
---|
T
20 | T = TypeVar("T", bound="EllipticCurve") |
---|
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 | r_bytes = r.to_be_bytes32() |
44 | s_bytes = s.to_be_bytes32() |
45 | |
46 | signature = bytearray([0] * 65) |
47 | signature[32 - len(r_bytes) : 32] = r_bytes |
48 | signature[64 - len(s_bytes) : 64] = s_bytes |
49 | signature[64] = v |
50 | public_key = coincurve.PublicKey.from_signature_and_message( |
51 | bytes(signature), msg_hash, hasher=None |
52 | ) |
53 | public_key = public_key.format(compressed=False)[1:] |
54 | return public_key |
EllipticCurve
Superclass for integers modulo a prime. Not intended to be used directly, but rather to be subclassed.
class EllipticCurve:
__slots__
63 | __slots__ = ("x", "y") |
---|
FIELD
65 | FIELD: Type[F] |
---|
A
66 | A: F |
---|
B
67 | B: F |
---|
x
69 | x: F |
---|
y
70 | y: F |
---|
__new__
Make new point on the curve. The point is not checked to see if it is on the curve.
__init__
Checks if the point is on the curve. To skip this check call
__new__()
directly.
def __init__(self, x: F, y: F) -> None:
83 | """ |
---|---|
84 | Checks if the point is on the curve. To skip this check call |
85 | `__new__()` directly. |
86 | """ |
87 | if ( |
88 | x != self.FIELD.zero() or y != self.FIELD.zero() |
89 | ) and y ** 2 - x**3 - self.A * x - self.B != self.FIELD.zero(): |
90 | raise ValueError("Point not on curve") |
__eq__
Test two points for equality.
def __eq__(self, other: object) -> bool:
93 | """ |
---|---|
94 | Test two points for equality. |
95 | """ |
96 | if not isinstance(other, type(self)): |
97 | return False |
98 | return self.x == other.x and self.y == other.y |
__str__
Stringify a point as its coordinates.
def __str__(self) -> str:
101 | """ |
---|---|
102 | Stringify a point as its coordinates. |
103 | """ |
104 | return str((self.x, self.y)) |
point_at_infinity
Return the point at infinity. This is the identity element of the group operation.
The point at infinity doesn't actually have coordinates so we use
(0, 0)
(which isn't on the curve) to represent it.
106 | @classmethod |
---|
def point_at_infinity(cls: Type[T]) -> T:
108 | """ |
---|---|
109 | Return the point at infinity. This is the identity element of the group |
110 | operation. |
111 |
|
112 | The point at infinity doesn't actually have coordinates so we use |
113 | `(0, 0)` (which isn't on the curve) to represent it. |
114 | """ |
115 | return cls.__new__(cls, cls.FIELD.zero(), cls.FIELD.zero()) |
double
Add a point to itself.
def double(self: T) -> T:
118 | """ |
---|---|
119 | Add a point to itself. |
120 | """ |
121 | x, y, F = self.x, self.y, self.FIELD |
122 | if x == 0 and y == 0: |
123 | return self |
124 | lam = (F.from_int(3) * x**2 + self.A) / (F.from_int(2) * y) |
125 | new_x = lam**2 - x - x |
126 | new_y = lam * (x - new_x) - y |
127 | return self.__new__(type(self), new_x, new_y) |
__add__
Add two points together.
def __add__(self: T, other: T) -> T:
130 | """ |
---|---|
131 | Add two points together. |
132 | """ |
133 | ZERO = self.FIELD.zero() |
134 | self_x, self_y, other_x, other_y = self.x, self.y, other.x, other.y |
135 | if self_x == ZERO and self_y == ZERO: |
136 | return other |
137 | if other_x == ZERO and other_y == ZERO: |
138 | return self |
139 | if self_x == other_x: |
140 | if self_y == other_y: |
141 | return self.double() |
142 | else: |
143 | return self.point_at_infinity() |
144 | lam = (other_y - self_y) / (other_x - self_x) |
145 | x = lam**2 - self_x - other_x |
146 | y = lam * (self_x - x) - self_y |
147 | return self.__new__(type(self), x, y) |
mul_by
Multiply self
by n
using the double and add algorithm.