aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/ellipticcurve/math.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/ellipticcurve/math.py')
-rw-r--r--.venv/lib/python3.12/site-packages/ellipticcurve/math.py181
1 files changed, 181 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/ellipticcurve/math.py b/.venv/lib/python3.12/site-packages/ellipticcurve/math.py
new file mode 100644
index 00000000..981ab4e7
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/ellipticcurve/math.py
@@ -0,0 +1,181 @@
+from .point import Point
+
+
+class Math:
+
+ @classmethod
+ def modularSquareRoot(cls, value, prime):
+ return pow(value, (prime + 1) // 4, prime)
+
+ @classmethod
+ def multiply(cls, p, n, N, A, P):
+ """
+ Fast way to multily point and scalar in elliptic curves
+
+ :param p: First Point to mutiply
+ :param n: Scalar to mutiply
+ :param N: Order of the elliptic curve
+ :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
+ :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
+ :return: Point that represents the sum of First and Second Point
+ """
+ return cls._fromJacobian(
+ cls._jacobianMultiply(cls._toJacobian(p), n, N, A, P), P
+ )
+
+ @classmethod
+ def add(cls, p, q, A, P):
+ """
+ Fast way to add two points in elliptic curves
+
+ :param p: First Point you want to add
+ :param q: Second Point you want to add
+ :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
+ :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
+ :return: Point that represents the sum of First and Second Point
+ """
+ return cls._fromJacobian(
+ cls._jacobianAdd(cls._toJacobian(p), cls._toJacobian(q), A, P), P,
+ )
+
+ @classmethod
+ def inv(cls, x, n):
+ """
+ Extended Euclidean Algorithm. It's the 'division' in elliptic curves
+
+ :param x: Divisor
+ :param n: Mod for division
+ :return: Value representing the division
+ """
+ if x == 0:
+ return 0
+
+ lm = 1
+ hm = 0
+ low = x % n
+ high = n
+
+ while low > 1:
+ r = high // low
+ nm = hm - lm * r
+ nw = high - low * r
+ high = low
+ hm = lm
+ low = nw
+ lm = nm
+
+ return lm % n
+
+ @classmethod
+ def _toJacobian(cls, p):
+ """
+ Convert point to Jacobian coordinates
+
+ :param p: First Point you want to add
+ :return: Point in Jacobian coordinates
+ """
+ return Point(p.x, p.y, 1)
+
+ @classmethod
+ def _fromJacobian(cls, p, P):
+ """
+ Convert point back from Jacobian coordinates
+
+ :param p: First Point you want to add
+ :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
+ :return: Point in default coordinates
+ """
+ z = cls.inv(p.z, P)
+ x = (p.x * z ** 2) % P
+ y = (p.y * z ** 3) % P
+
+ return Point(x, y, 0)
+
+ @classmethod
+ def _jacobianDouble(cls, p, A, P):
+ """
+ Double a point in elliptic curves
+
+ :param p: Point you want to double
+ :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
+ :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
+ :return: Point that represents the sum of First and Second Point
+ """
+ if p.y == 0:
+ return Point(0, 0, 0)
+
+ ysq = (p.y ** 2) % P
+ S = (4 * p.x * ysq) % P
+ M = (3 * p.x ** 2 + A * p.z ** 4) % P
+ nx = (M**2 - 2 * S) % P
+ ny = (M * (S - nx) - 8 * ysq ** 2) % P
+ nz = (2 * p.y * p.z) % P
+
+ return Point(nx, ny, nz)
+
+ @classmethod
+ def _jacobianAdd(cls, p, q, A, P):
+ """
+ Add two points in elliptic curves
+
+ :param p: First Point you want to add
+ :param q: Second Point you want to add
+ :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
+ :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
+ :return: Point that represents the sum of First and Second Point
+ """
+ if p.y == 0:
+ return q
+ if q.y == 0:
+ return p
+
+ U1 = (p.x * q.z ** 2) % P
+ U2 = (q.x * p.z ** 2) % P
+ S1 = (p.y * q.z ** 3) % P
+ S2 = (q.y * p.z ** 3) % P
+
+ if U1 == U2:
+ if S1 != S2:
+ return Point(0, 0, 1)
+ return cls._jacobianDouble(p, A, P)
+
+ H = U2 - U1
+ R = S2 - S1
+ H2 = (H * H) % P
+ H3 = (H * H2) % P
+ U1H2 = (U1 * H2) % P
+ nx = (R ** 2 - H3 - 2 * U1H2) % P
+ ny = (R * (U1H2 - nx) - S1 * H3) % P
+ nz = (H * p.z * q.z) % P
+
+ return Point(nx, ny, nz)
+
+ @classmethod
+ def _jacobianMultiply(cls, p, n, N, A, P):
+ """
+ Multily point and scalar in elliptic curves
+
+ :param p: First Point to mutiply
+ :param n: Scalar to mutiply
+ :param N: Order of the elliptic curve
+ :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
+ :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
+ :return: Point that represents the sum of First and Second Point
+ """
+ if p.y == 0 or n == 0:
+ return Point(0, 0, 1)
+
+ if n == 1:
+ return p
+
+ if n < 0 or n >= N:
+ return cls._jacobianMultiply(p, n % N, N, A, P)
+
+ if (n % 2) == 0:
+ return cls._jacobianDouble(
+ cls._jacobianMultiply(p, n // 2, N, A, P), A, P
+ )
+
+ return cls._jacobianAdd(
+ cls._jacobianDouble(cls._jacobianMultiply(p, n // 2, N, A, P), A, P), p, A, P
+ )