1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
Description: Fix RecursionError in __pow__ on s390x
The recursive implementation of __pow__ reaches the maximum recursion depth
on s390x during pairing tests. This patch converts it to an iterative
square-and-multiply algorithm.
Author: Manuel Guerra <ar.manuelguerra@gmail.com>
Forwarded: https://github.com/ethereum/py_ecc/pull/159
Last-Update: 2026-01-07
--- a/py_ecc/fields/field_elements.py
+++ b/py_ecc/fields/field_elements.py
@@ -289,14 +289,19 @@ class FQP:
return self.__div__(other)
def __pow__(self: T_FQP, other: int) -> T_FQP:
- if other == 0:
- return type(self)([1] + [0] * (self.degree - 1))
- elif other == 1:
- return type(self)(self.coeffs)
- elif other % 2 == 0:
- return (self * self) ** (other // 2)
- else:
- return ((self * self) ** int(other // 2)) * self
+ if other < 0:
+ return self.inv() ** (-other)
+ res = type(self)([1] + [0] * (self.degree - 1))
+ base = self
+ exp = other
+
+ while exp > 0:
+ if exp % 2 == 1:
+ res = res * base
+ base = base * base
+ exp //= 2
+
+ return res
# Extended euclidean algorithm used to find the modular inverse
def inv(self: T_FQP) -> T_FQP:
|