ethereum.crypto.elliptic_curve

Elliptic Curves ^^^^^^^^^^^^^^^

SECP256K1N

14
SECP256K1N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141

F

16
F = TypeVar("F", bound=Field)

T

17
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:
21
    """
22
    Recovers the public key from a given signature.
23
24
    Parameters
25
    ----------
26
    r :
27
        TODO
28
    s :
29
        TODO
30
    v :
31
        TODO
32
    msg_hash :
33
        Hash of the message being recovered.
34
35
    Returns
36
    -------
37
    public_key : `ethereum.base_types.Bytes`
38
        Recovered public key.
39
    """
40
    r_bytes = r.to_be_bytes32()
41
    s_bytes = s.to_be_bytes32()
42
43
    signature = bytearray([0] * 65)
44
    signature[32 - len(r_bytes) : 32] = r_bytes
45
    signature[64 - len(s_bytes) : 64] = s_bytes
46
    signature[64] = v
47
    public_key = coincurve.PublicKey.from_signature_and_message(
48
        bytes(signature), msg_hash, hasher=None
49
    )
50
    public_key = public_key.format(compressed=False)[1:]
51
    return public_key

EllipticCurve

Superclass for integers modulo a prime. Not intended to be used directly, but rather to be subclassed.

class EllipticCurve:

__slots__

60
    __slots__ = ("x", "y")

FIELD

62
    FIELD: Type[F]

A

63
    A: F

B

64
    B: F

x

66
    x: F

y

67
    y: F

__new__

Make new point on the curve. The point is not checked to see if it is on the curve.

def __new__(cls: Type[T], ​​x: F, ​​y: F) -> T:
70
        """
71
        Make new point on the curve. The point is not checked to see if it is
72
        on the curve.
73
        """
74
        res = object.__new__(cls)
75
        res.x = x
76
        res.y = y
77
        return res

__init__

Checks if the point is on the curve. To skip this check call __new__() directly.

def __init__(self, ​​x: F, ​​y: F) -> None:
80
        """
81
        Checks if the point is on the curve. To skip this check call
82
        `__new__()` directly.
83
        """
84
        if (
85
            x != self.FIELD.zero() or y != self.FIELD.zero()
86
        ) and y ** 2 - x**3 - self.A * x - self.B != self.FIELD.zero():
87
            raise ValueError("Point not on curve")

__eq__

Test two points for equality.

def __eq__(self, ​​other: object) -> bool:
90
        """
91
        Test two points for equality.
92
        """
93
        if not isinstance(other, type(self)):
94
            return False
95
        return self.x == other.x and self.y == other.y

__str__

Stringify a point as its coordinates.

def __str__(self) -> str:
98
        """
99
        Stringify a point as its coordinates.
100
        """
101
        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.

103
    @classmethod
def point_at_infinity(cls: Type[T]) -> T:
105
        """
106
        Return the point at infinity. This is the identity element of the group
107
        operation.
108
109
        The point at infinity doesn't actually have coordinates so we use
110
        `(0, 0)` (which isn't on the curve) to represent it.
111
        """
112
        return cls.__new__(cls, cls.FIELD.zero(), cls.FIELD.zero())

double

Add a point to itself.

def double(self: T) -> T:
115
        """
116
        Add a point to itself.
117
        """
118
        x, y, F = self.x, self.y, self.FIELD
119
        if x == 0 and y == 0:
120
            return self
121
        lam = (F.from_int(3) * x**2 + self.A) / (F.from_int(2) * y)
122
        new_x = lam**2 - x - x
123
        new_y = lam * (x - new_x) - y
124
        return self.__new__(type(self), new_x, new_y)

__add__

Add two points together.

def __add__(self: T, ​​other: T) -> T:
127
        """
128
        Add two points together.
129
        """
130
        ZERO = self.FIELD.zero()
131
        self_x, self_y, other_x, other_y = self.x, self.y, other.x, other.y
132
        if self_x == ZERO and self_y == ZERO:
133
            return other
134
        if other_x == ZERO and other_y == ZERO:
135
            return self
136
        if self_x == other_x:
137
            if self_y == other_y:
138
                return self.double()
139
            else:
140
                return self.point_at_infinity()
141
        lam = (other_y - self_y) / (other_x - self_x)
142
        x = lam**2 - self_x - other_x
143
        y = lam * (self_x - x) - self_y
144
        return self.__new__(type(self), x, y)

mul_by

Multiply self by n using the double and add algorithm.

def mul_by(self: T, ​​n: int) -> T:
147
        """
148
        Multiply `self` by `n` using the double and add algorithm.
149
        """
150
        res = self.__new__(type(self), self.FIELD.zero(), self.FIELD.zero())
151
        s = self
152
        while n != 0:
153
            if n % 2 == 1:
154
                res = res + s
155
            s = s + s
156
            n //= 2
157
        return res