Python实现ECDSA大整数点乘运算错误求助
修复ECDSA点乘法的大整数精度问题
我帮你定位到了两个核心问题,正是它们导致大整数坐标计算结果不符合预期:
1. math.pow 引发的精度丢失
math.pow() 是为浮点数运算设计的函数,当传入70位的超大整数时,它会将整数转换为浮点数存储——但浮点数的精度只有64位,根本无法完整保存70位整数的全部信息,这会直接导致平方计算出现误差,后续的点加法、加倍运算自然全错了。
解决方法:改用Python原生的整数幂运算符 **,它能完美处理任意大小的整数,不会丢失精度。
2. 可选优化:显式处理负数模运算
虽然Python的 % 运算符能自动处理负数,但在有限域运算中,显式将结果转为正数可以避免某些边界场景下的符号意外问题。
修复后的完整代码
修改加法与加倍函数
def addition(self, p, q): if p.is_infinite: return q elif q.is_infinite: return p else: if (q.x - p.x) == 0: point = Point.Point(0, 0) point.is_infinite = True return point # 替换math.pow为整数幂运算符 s = int(((q.y - p.y) * Utils.Utils.mode_inverse(q.x - p.x, self.prime)) % self.prime) xr = int((s**2 - p.x - q.x) % self.prime) # 显式加prime确保结果为正整数 yr = int(((s * (p.x - xr)) - p.y + self.prime) % self.prime) r = Point.Point(xr, yr) return r def double(self, p): if p.is_infinite: return p if p.y == 0: point = Point.Point(0, 0) point.is_infinite = True return point # 替换math.pow为整数幂运算符,同时将a转为模p的正数 adjusted_a = self.a % self.prime s = int((((3 * p.x**2) + adjusted_a) * Utils.Utils.mode_inverse(2 * p.y, self.prime)) % self.prime) xr = int((s**2 - 2 * p.x) % self.prime) # 显式加prime确保结果为正整数 yr = int(((s * (p.x - xr)) - p.y + self.prime) % self.prime) r = Point.Point(xr, yr) return r
点乘法函数的可读性优化
你的乘法逻辑本身是正确的,只是可以把无穷远点的初始化写得更清晰:
def multiplication(self, p, t): bin_t = bin(t)[2:] # 直接初始化无穷远点,无需复制p的坐标 Q = Point.Point(0, 0) Q.is_infinite = True for digit in bin_t: Q = self.double(Q) if digit == '1': Q = self.addition(Q, p) return Q
验证修复结果
用你提供的P-224参数计算2G,现在应该能得到和在线计算器完全一致的结果:
- Px = 11838696407187388799350957250141035264678915751356546206913969278886
- Py = 2966624012289393637077209076615926844583158638456025172915528198331
另外建议你预先把曲线参数a=-3转为模p的正数(即a = (p - 3) % p),这样可以避免负数参与运算,让代码逻辑更直观。
内容的提问来源于stack exchange,提问作者Yashar
相关产品推荐
相关产品推荐

