tokencrawler/.venv/lib/python3.9/site-packages/solana/utils/ed25519_base.py
2022-03-17 22:16:30 +01:00

58 lines
1.3 KiB
Python

"""Curve25519/ed25519 helpers.
Sourced from https://github.com/warner/python-pure25519/blob/master/pure25519/basic.py
"""
# pylint: disable = invalid-name
Q = 2 ** 255 - 19
L = 2 ** 252 + 27742317777372353535851937790883648493
def _inv(x):
return pow(x, Q - 2, Q)
d = -121665 * _inv(121666)
I = pow(2, (Q - 1) // 4, Q) # noqa: E741
def _xrecover(y):
xx = (y * y - 1) * _inv(d * y * y + 1)
x = pow(xx, (Q + 3) // 8, Q)
if (x * x - xx) % Q != 0:
x = (x * I) % Q
if x % 2 != 0:
x = Q - x
return x
def _isoncurve(P):
x = P[0]
y = P[1]
return (-x * x + y * y - 1 - d * x * x * y * y) % Q == 0
class NotOnCurve(Exception):
"""Raised when point fall off the curve."""
def _decodepoint(unclamped: int):
clamp = (1 << 255) - 1
y = unclamped & clamp # clear MSB
x = _xrecover(y)
if bool(x & 1) != bool(unclamped & (1 << 255)):
x = Q - x
P = [x, y]
if not _isoncurve(P):
raise NotOnCurve("decoding point that is not on curve")
return P
def is_on_curve(s: bytes) -> bool:
"""Verify the bytes s is a valid point on curve or not."""
unclamped = int.from_bytes(s, byteorder="little")
try:
_ = _decodepoint(unclamped)
except NotOnCurve:
return False
else:
return True