AntonKueltz / fastecdsa

Python library for fast elliptic curve crypto
https://pypi.python.org/pypi/fastecdsa
The Unlicense
264 stars 77 forks source link

Customize curve parameters #12

Closed ctshihg closed 6 years ago

ctshihg commented 6 years ago

Hi,

I would like to add 160-bit elliptic curve parameter, therefore , I modified the curve.py by adding the following code:

P160 = Curve(
    'P160',
    1461501637330902918203684832716283019653785059327,
    -3,
    163235791306168110546604919403271579530548345413,
    1415829711185579849932474815350688732073257074689,
    425826231723888350446541592701409065913635568770,
    203520114162904107873991457957346892027982641970
)

I'm sure that I successfully modified the curve.py package, because the following code can work:

ECg = Point(curve.P160.gx,curve.P160.gy,curve=P160)
print(curve.P160.is_point_on_curve((ECg.x,ECg.y)))

However, I can not do addition or multiplication. If I try the following code, I will get the error below:

ECg*2

SystemError                               Traceback (most recent call last)
<ipython-input-72-9ed303a18d8a> in <module>()
----> 1 ECg*2

/usr/local/lib/python3.4/dist-packages/fastecdsa-1.4.3-py3.4-linux-x86_64.egg/fastecdsa/point.py in __mul__(self, scalar)
     85             raise TypeError('Curve point multiplication must be by an integer')
     86         else:
---> 87             x, y = curvemath.mul(str(self.x), str(self.y), str(d), self.curve.name)
     88             return Point(int(x), int(y), self.curve)
     89 

SystemError: error return without exception set

I have no idea about why I got this system error.

Thanks!

AntonKueltz commented 6 years ago

The reason you're getting this error is that the curve P160 and it's parameters is not defined in the C extension code. The point validation logic is all pure python, but the actual curve arithmetic gets passed off to the C extensions since it's much faster than pure python.

I could probably add some functionality to allow arbitrary curve construction as long as the curves are defined in the form of the Weierstrass equation (e.g. y^2 = x^3 + ax + b). I think the C code is written generically enough that it wouldn't take too long to implement this. Would that be something you find useful?

ctshihg commented 6 years ago

Hi AntonKueltz,

I was trying to profiling a elliptic curve based protocol with arbitrary curve and this is exactly what I needed.

Thanks!

AntonKueltz commented 6 years ago

Okay, I'll try to get those changes in within a couple days.

AntonKueltz commented 6 years ago

Version 1.5.1 should have the changes you're looking for (pip install fastecdsa==1.5.1)


In [1]: from fastecdsa.curve import Curve

In [2]: from fastecdsa.point import Point

In [3]: P160 = Curve(
   ...:     'P160',
   ...:     1461501637330902918203684832716283019653785059327,
   ...:     -3,
   ...:     163235791306168110546604919403271579530548345413,
   ...:     1415829711185579849932474815350688732073257074689,
   ...:     425826231723888350446541592701409065913635568770,
   ...:     203520114162904107873991457957346892027982641970
   ...: )

In [4]: ECg = P160.G

In [5]: print(P160.is_point_on_curve((ECg.x,ECg.y)))
True

In [6]: doubled = ECg * 2

In [7]: vars(doubled)
Out[7]:
{'curve': <fastecdsa.curve.Curve instance at 0x11151acf8>,
 'x': 16984103820118642236896513183038186009872590470L,
 'y': 1373093393927139016463695321221277758035357890939L}
AntonKueltz commented 6 years ago

Added in b84de4c.

ctshihg commented 6 years ago

I faced another problem in 1.5.1 version, Here are my testing code:

from fastecdsa.curve import Curve
from fastecdsa.point import Point
P160 = Curve(
    'P160',
   1461501637330902918203684832716283019653785059327,
   -3,
   163235791306168110546604919403271579530548345413,
   1415829711185579849932474815350688732073257074689,
   425826231723888350446541592701409065913635568770,
   203520114162904107873991457957346892027982641970
   )
ECa = -3
ECb = 163235791306168110546604919403271579530548345413
ECp = 1461501637330902918203684832716283019653785059327
ECg = P160.G
ECr = P160.p
print(P160.is_point_on_curve((ECg.x,ECg.y)))
doubled = ECg * 2
vars(doubled)

Here are the result:

True
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-c8ac0106c3b0> in <module>()
     17 ECr = P160.p
     18 print(P160.is_point_on_curve((ECg.x,ECg.y)))
---> 19 doubled = ECg * 2
     20 vars(doubled)

/usr/local/lib/python3.5/site-packages/fastecdsa/point.py in __mul__(self, scalar)
    104                 str(self.curve.q),
    105                 str(self.curve.gx),
--> 106                 str(self.curve.gy)
    107             )
    108             return Point(int(x), int(y), self.curve)

TypeError: function takes exactly 4 arguments (9 given)

Do you have any idea of it? Thanks a lot!

AntonKueltz commented 6 years ago

Do you have a version pre-1.5.1 cloned / forked your machine that you are using for dev purposes? What is happening is that the code is trying to call the old multiplication interface pre-1.5.1 which took 4 args, but it's calling it with the new interface which provides 9 args. I don't have access to your environment so it's not really possible to debug this beyond speculation.

I recommend doing a pip uninstall fastecdsa and then a pip install fastecdsa==1.5.1 (do this in any virtualenvs that use the package as well). Then take care to NOT execute your example code in any cloned or forked version of the repo that you have locally.