基于Python与SymPy实现椭圆曲线:EllipticCurve类代码完善问询
Hey there! Let's work through finishing your elliptic curve implementation with Python and SymPy, fixing existing issues and adding core functionality to ensure correctness.
First, Fix the Discriminant Calculation
Your current discriminant property has a bug: it references a and b directly instead of the instance attributes self.a and self.b. Plus, we should add a check in __init__ to ensure the curve is non-singular (discriminant ≠ 0), which is a requirement for valid elliptic curves.
Here's the corrected code snippet for the EllipticCurve class:
class EllipticCurve: def __init__(self, a, b): self.a = a self.b = b # Validate non-singular curve if self.discriminant == 0: raise ValueError("Singular elliptic curve not allowed; discriminant must be non-zero") def __eq__(self, other): if isinstance(other, EllipticCurve): return self.a == other.a and self.b == other.b return NotImplemented def __ne__(self, other): result = self.__eq__(other) return not result if result is not NotImplemented else result @property def discriminant(self): # Corrected to use instance attributes return 4 * self.a**3 + 27 * self.b**2
Add a Point Class for Curve Points
Elliptic curve operations revolve around points on the curve (including the point at infinity, O). A dedicated Point class will make managing these points and their operations clean.
Add this top-level Point class:
class Point: def __init__(self, curve, x, y): self.curve = curve self.x = x self.y = y # Verify the point lies on the curve (skip for the point at infinity) if self != curve.O: assert self.y**2 == self.x**3 + curve.a * self.x + curve.b, \ f"Point ({x}, {y}) is not on the given elliptic curve" def __eq__(self, other): if isinstance(other, Point): return self.curve == other.curve and self.x == other.x and self.y == other.y # Handle comparison with the infinity point marker return False def __repr__(self): if self == self.curve.O: return "O" return f"Point({self.x}, {self.y})"
Then update the EllipticCurve class to define O as a special Point instance:
class EllipticCurve: def __init__(self, a, b): self.a = a self.b = b if self.discriminant == 0: raise ValueError("Singular elliptic curve not allowed; discriminant must be non-zero") # Define the point at infinity (special case Point) self.O = Point(self, None, None) # ... keep existing __eq__, __ne__, discriminant methods ...
Implement Core Elliptic Curve Operations
The most critical operations are point addition and scalar multiplication. Let's add these to the Point class using SymPy's symbolic arithmetic capabilities.
Point Addition (__add__)
This handles three key cases:
- Adding the infinity point
Oto any point returns the original point - Adding a point to its inverse (same x-coordinate, opposite y-coordinate) returns
O - Adding two distinct points, or doubling a point (adding a point to itself)
Add this method to the Point class:
def __add__(self, other): # Case 1: Add with infinity point if self == self.curve.O: return other if other == self.curve.O: return self # Case 2: Add point to its inverse (result is infinity) if self.x == other.x and self.y != other.y: return self.curve.O # Calculate slope (m) if self != other: # Slope between two distinct points m = (other.y - self.y) / (other.x - self.x) else: # Slope for point doubling m = (3 * self.x**2 + self.curve.a) / (2 * self.y) # Compute new point coordinates x3 = m**2 - self.x - other.x y3 = m * (self.x - x3) - self.y return Point(self.curve, x3, y3)
Scalar Multiplication (__mul__)
Use the double-and-add algorithm for efficient scalar multiplication (a foundational operation for elliptic curve cryptography):
def __mul__(self, scalar): result = self.curve.O current = self remaining = scalar while remaining > 0: if remaining % 2 == 1: result = result + current current = current + current remaining = remaining // 2 return result # Allow scalar * point (e.g., 3 * P instead of P * 3) __rmul__ = __mul__
Test with SymPy
To verify correctness, use SymPy's symbolic variables to test the operations:
from sympy import symbols # Define symbolic variables a, b, x1, y1, x2, y2 = symbols('a b x1 y1 x2 y2') # Create a symbolic elliptic curve curve = EllipticCurve(a, b) # Create two symbolic points on the curve P = Point(curve, x1, y1) Q = Point(curve, x2, y2) # Test point addition print("P + Q =", P + Q) # Test point doubling print("2P =", 2 * P) # Test scalar multiplication print("3P =", 3 * P)
Key Notes for Correctness
- SymPy Compatibility: All operations use SymPy's symbolic arithmetic, so you can work with both numerical values and symbolic variables seamlessly.
- Boundary Cases: The implementation handles the infinity point and inverse points correctly, which are easy to overlook.
- Validation: The
Pointconstructor ensures all points (exceptO) lie on the curve, preventing invalid operations.
内容的提问来源于stack exchange,提问作者popololvic

