Skip to content

Commit

Permalink
Add 'curve' attribute to EccPoint and EccXPoint classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Legrandin committed Aug 18, 2024
1 parent 36080c9 commit 86e5a38
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 13 deletions.
2 changes: 2 additions & 0 deletions Changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Under development
* GH#814: RSA keys for PSS can be imported.
* GH#810: fixed negation of Ed25519 points
* Add support for Curve25519 / X25519
* Add attribute ``curve`` to EccPoint and EccXPoint classes,
with the canonical name of the curve.

3.20.0 (9 January 2024)
++++++++++++++++++++++++++
Expand Down
20 changes: 13 additions & 7 deletions lib/Crypto/PublicKey/_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ class EccPoint(object):
* Multiplying a point by a scalar: ``R = S*k``
* In-place multiplication by a scalar: ``T *= k``
:ivar curve: The **canonical** name of the curve as defined in the `ECC table`_.
:vartype curve: string
:ivar x: The affine X-coordinate of the ECC point
:vartype x: integer
Expand All @@ -146,7 +149,7 @@ def __init__(self, x, y, curve="p256"):
self._curve = _curves[curve]
except KeyError:
raise ValueError("Unknown curve name %s" % str(curve))
self._curve_name = curve
self.curve = self._curve.canonical

if self._curve.id == CurveID.CURVE25519:
raise ValueError("EccPoint cannot be created for Curve25519")
Expand Down Expand Up @@ -217,7 +220,7 @@ def __neg__(self):
def copy(self):
"""Return a copy of this point."""
x, y = self.xy
np = EccPoint(x, y, self._curve_name)
np = EccPoint(x, y, self.curve)
return np

def is_point_at_infinity(self):
Expand All @@ -232,9 +235,9 @@ def point_at_infinity(self):
"""Return the *point-at-infinity* for the curve."""

if self._curve.is_edwards:
return EccPoint(0, 1, self._curve_name)
return EccPoint(0, 1, self.curve)
else:
return EccPoint(0, 0, self._curve_name)
return EccPoint(0, 0, self.curve)

@property
def x(self):
Expand Down Expand Up @@ -333,6 +336,9 @@ class EccXPoint(object):
* Multiplying a point by a scalar: ``R = S*k``
* In-place multiplication by a scalar: ``T *= k``
:ivar curve: The **canonical** name of the curve as defined in the `ECC table`_.
:vartype curve: string
:ivar x: The affine X-coordinate of the ECC point
:vartype x: integer
"""
Expand All @@ -346,7 +352,7 @@ def __init__(self, x, curve):
self._curve = _curves[curve]
except KeyError:
raise ValueError("Unknown curve name %s" % str(curve))
self._curve_name = curve
self.curve = self._curve.canonical

if self._curve.id != CurveID.CURVE25519:
raise ValueError("EccXPoint can only be created for Curve25519")
Expand Down Expand Up @@ -404,7 +410,7 @@ def copy(self):
x = self.x
except ValueError:
return self.point_at_infinity()
return EccXPoint(x, self._curve_name)
return EccXPoint(x, self.curve)

def is_point_at_infinity(self):
"""``True`` if this is the *point-at-infinity*."""
Expand All @@ -418,7 +424,7 @@ def is_point_at_infinity(self):
def point_at_infinity(self):
"""Return the *point-at-infinity* for the curve."""

return EccXPoint(self._curve.Gx, self._curve_name) * 0
return EccXPoint(self._curve.Gx, self.curve) * 0

@property
def x(self):
Expand Down
2 changes: 2 additions & 0 deletions lib/Crypto/PublicKey/_point.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ from typing import Union, Optional, Tuple
from Crypto.Math.Numbers import Integer

class EccPoint(object):
curve: str
def __init__(self,
x: Union[int, Integer],
y: Union[int, Integer],
Expand Down Expand Up @@ -30,6 +31,7 @@ class EccPoint(object):


class EccXPoint(object):
curve: str
def __init__(self,
x: Union[int, Integer],
curve: Optional[str] = ...) -> None: ...
Expand Down
4 changes: 4 additions & 0 deletions lib/Crypto/SelfTest/PublicKey/test_ECC_Curve25519.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ def test_init(self):
EccXPoint(9, "curve25519")
EccXPoint(2**255 - 19 + 5, "curve25519")

def test_curve_attribute(self):
point = EccXPoint(9, "curve25519")
self.assertEqual(point.curve, "Curve25519")

def test_init_fail(self):
self.assertRaises(ValueError, EccXPoint, 3*(2**255 - 19), "curve25519")
self.assertRaises(ValueError, EccXPoint, 9, "curve25518")
Expand Down
9 changes: 6 additions & 3 deletions lib/Crypto/SelfTest/PublicKey/test_ECC_Ed25519.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ class TestEccPoint_Ed25519(unittest.TestCase):
G3xy = {"x": 46896733464454938657123544595386787789046198280132665686241321779790909858396,
"y": 8324843778533443976490377120369201138301417226297555316741202210403726505172}

pointG = EccPoint(Gxy['x'], Gxy['y'], curve="Ed25519")
pointG2 = EccPoint(G2xy['x'], G2xy['y'], curve="Ed25519")
pointG3 = EccPoint(G3xy['x'], G3xy['y'], curve="Ed25519")
pointG = EccPoint(Gxy['x'], Gxy['y'], curve="ed25519")
pointG2 = EccPoint(G2xy['x'], G2xy['y'], curve="ed25519")
pointG3 = EccPoint(G3xy['x'], G3xy['y'], curve="ed25519")

def test_curve_attribute(self):
self.assertEqual(self.pointG.curve, "Ed25519")

def test_init_xy(self):
EccPoint(self.Gxy['x'], self.Gxy['y'], curve="Ed25519")
Expand Down
9 changes: 6 additions & 3 deletions lib/Crypto/SelfTest/PublicKey/test_ECC_Ed448.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ class TestEccPoint_Ed448(unittest.TestCase):
G3xy = {"x": 0x865886b9108af6455bd64316cb6943332241b8b8cda82c7e2ba077a4a3fcfe8daa9cbf7f6271fd6e862b769465da8575728173286ff2f8f,
"y": 0xe005a8dbd5125cf706cbda7ad43aa6449a4a8d952356c3b9fce43c82ec4e1d58bb3a331bdb6767f0bffa9a68fed02dafb822ac13588ed6fc}

pointG = EccPoint(Gxy['x'], Gxy['y'], curve="Ed448")
pointG2 = EccPoint(G2xy['x'], G2xy['y'], curve="Ed448")
pointG3 = EccPoint(G3xy['x'], G3xy['y'], curve="Ed448")
pointG = EccPoint(Gxy['x'], Gxy['y'], curve="ed448")
pointG2 = EccPoint(G2xy['x'], G2xy['y'], curve="ed448")
pointG3 = EccPoint(G3xy['x'], G3xy['y'], curve="ed448")

def test_curve_attribute(self):
self.assertEqual(self.pointG.curve, "Ed448")

def test_init_xy(self):
EccPoint(self.Gxy['x'], self.Gxy['y'], curve="Ed448")
Expand Down
15 changes: 15 additions & 0 deletions lib/Crypto/SelfTest/PublicKey/test_ECC_NIST.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class TestEccPoint_NIST_P192(unittest.TestCase):
0x264424096af2b3597796db48f8dfb41fa9cecc97691a9c79,
curve='p192')

def test_curve_attribute(self):
self.assertEqual(self.pointS.curve, "NIST P-192")

def test_set(self):
pointW = EccPoint(0, 0)
pointW.set(self.pointS)
Expand Down Expand Up @@ -226,6 +229,9 @@ class TestEccPoint_NIST_P224(unittest.TestCase):
0xc42a8a4d34984f0b71b5b4091af7dceb33ea729c1a2dc8b434f10c34,
curve='p224')

def test_curve_attribute(self):
self.assertEqual(self.pointS.curve, "NIST P-224")

def test_set(self):
pointW = EccPoint(0, 0)
pointW.set(self.pointS)
Expand Down Expand Up @@ -364,6 +370,9 @@ class TestEccPoint_NIST_P256(unittest.TestCase):
0x55a8b00f8da1d44e62f6b3b25316212e39540dc861c89575bb8cf92e35e0986b,
0x5421c3209c2d6c704835d82ac4c3dd90f61a8a52598b9e7ab656e9d8c8b24316)

def test_curve_attribute(self):
self.assertEqual(self.pointS.curve, "NIST P-256")

def test_set(self):
pointW = EccPoint(0, 0)
pointW.set(self.pointS)
Expand Down Expand Up @@ -504,6 +513,9 @@ class TestEccPoint_NIST_P384(unittest.TestCase):
0x84009a263fefba7c2c57cffa5db3634d286131afc0fca8d25afa22a7b5dce0d9470da89233cee178592f49b6fecb5092,
"p384")

def test_curve_attribute(self):
self.assertEqual(self.pointS.curve, "NIST P-384")

def test_set(self):
pointW = EccPoint(0, 0, "p384")
pointW.set(self.pointS)
Expand Down Expand Up @@ -635,6 +647,9 @@ class TestEccPoint_NIST_P521(unittest.TestCase):
0x000001fdf842769c707c93c630df6d02eff399a06f1b36fb9684f0b373ed064889629abb92b1ae328fdb45534268384943f0e9222afe03259b32274d35d1b9584c65e305,
"p521")

def test_curve_attribute(self):
self.assertEqual(self.pointS.curve, "NIST P-521")

def test_set(self):
pointW = EccPoint(0, 0)
pointW.set(self.pointS)
Expand Down

0 comments on commit 86e5a38

Please sign in to comment.