Giter VIP home page Giter VIP logo

fastecdsa's People

Contributors

akaidiot avatar antonkueltz avatar bbbrumley avatar boneyard93501 avatar botovq avatar clouds56 avatar j08ny avatar jcogs33 avatar m-kus avatar nicolapace avatar notstatilko avatar sirk390 avatar sylvainpelissier avatar trevor-crypto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fastecdsa's Issues

Bug in evaluate and/or point_is_on_curve function?

x = 14899878097
y = secp256k1.evaluate(14899878097)
Point(x, y, curve=secp256k1)

Results in:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-92-e37ebd4d2471> in <module>
      1 x = 14899878097
      2 y = secp256k1.evaluate(14899878097)
----> 3 Point(x, y, curve=secp256k1)

~/.pyenv/versions/3.7.0/envs/phemex-puzzle/lib/python3.7/site-packages/fastecdsa/point.py in __init__(self, x, y, curve)
     31         if not (x == 0 and y == 1 and curve is None) and not curve.is_point_on_curve((x, y)):
     32             raise ValueError(
---> 33                 'coordinates are not on curve <{}>\n\tx={:x}\n\ty={:x}'.format(curve.name, x, y))
     34         else:
     35             self.x = x

ValueError: coordinates are not on curve <secp256k1>
	x=3781a18d1
	y=29c04c1ef9a7fd2ea7b8569578

Installation issue

Hi,

I'm having difficulties to install it properly.
I'm using a compiled version python 3.8.1
I first tried with

pip install fastecdsa

the install went fine but i got this error

from fastecdsa.point import Point
Traceback (most recent call last):
File "", line 1, in
File "./fastecdsa-2.1.3/fastecdsa/point.py", line 1, in
from fastecdsa import curvemath
ImportError: ./fastecdsa-2.1.3/fastecdsa/curvemath.cpython-38-x86_64-linux-gnu.so: undefined symbol: mpz_clears

I also tried different versions but same issue.
I also tried with the setup.py file

everything was fine except those warnings

Search "mpz" (10 hits in 1 file)
new 6 (10 hits)
Line 54: src/curveMath.c:35: warning: implicit declaration of function ‘mpz_inits’
Line 55: src/curveMath.c:58: warning: implicit declaration of function ‘mpz_clears’
Line 58: src/curve.c:15: warning: implicit declaration of function ‘mpz_clears’
Line 61: src/point.c:13: warning: implicit declaration of function ‘mpz_clears’
Line 66: src/_ecdsa.c:25: warning: implicit declaration of function ‘mpz_inits’
Line 67: src/_ecdsa.c:32: warning: implicit declaration of function ‘mpz_clears’
Line 70: src/curveMath.c:35: warning: implicit declaration of function ‘mpz_inits’
Line 71: src/curveMath.c:58: warning: implicit declaration of function ‘mpz_clears’
Line 74: src/curve.c:15: warning: implicit declaration of function ‘mpz_clears’
Line 77: src/point.c:13: warning: implicit declaration of function ‘mpz_clears’

When I use this command

python3.8.1/Python-3.8.1/build/bin/python3 setup.py test

I'm having almost all the tests failing for the same error

undefined symbol: mpz_clears

I have python-devel and gmp-devel installed but I think it's related to how I compiled Python 3.8.1

if you have some tips it will be great.

Thanks for your support.

EDIT

I think the issue is coming from the gmp lib on rhel6

nm -D ./python3.8.1/Python-3.8.1/build/lib/python3.8/site-packages/fastecdsa-2.1.3-py3.8-linux-x86_64.egg/fastecdsa/curvemath.cpython-38-x86_64-linux-gnu.so |grep clear

             U __gmpz_clear
             U mpz_clears

ldd ./python3.8.1/Python-3.8.1/build/lib/python3.8/site-packages/fastecdsa-2.1.3-py3.8-linux-x86_64.egg/fastecdsa/curvemath.cpython-38-x86_64-linux-gnu.so

    linux-vdso.so.1 =>  
    libgmp.so.3 => /usr/lib64/libgmp.so.3
    libpthread.so.0 => /lib64/libpthread.so.0 
    libc.so.6 => /lib64/libc.so.6 
    /lib64/ld-linux-x86-64.so.2 

nm -D /usr/lib64/libgmp.so.3|grep clear

000000347100a0e0 T __gmp_randclear
000000347100ac90 T __gmp_randclear_mt
000000347100bf80 T __gmpf_clear
0000003471022a60 T __gmpq_clear
0000003471013b60 T __gmpz_clear

rpm -qa|grep gmp

gmp-4.3.1-13.el6.x86_64
gmp-devel-4.3.1-13.el6.x86_64

I don't think there is a more recent version available en rhel6...

Error on pip3 install fastecdsa missing "gmp.h"

Hello,
running the command to install fastecdsa on python3 on MAcOS 11.2.1 BigSur processor M1

i receive this error

Collecting fastecdsa==2.1.2
Using cached fastecdsa-2.1.2.tar.gz (45 kB)
Requirement already satisfied: Flask==1.1.2 in /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages (from -r requirements.txt (line 2)) (1.1.2)
Requirement already satisfied: Jinja2>=2.10.1 in /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages (from Flask==1.1.2->-r requirements.txt (line 2)) (2.11.3)
Requirement already satisfied: click>=5.1 in /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages (from Flask==1.1.2->-r requirements.txt (line 2)) (7.1.2)
Requirement already satisfied: Werkzeug>=0.15 in /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages (from Flask==1.1.2->-r requirements.txt (line 2)) (1.0.1)
Requirement already satisfied: itsdangerous>=0.24 in /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages (from Flask==1.1.2->-r requirements.txt (line 2)) (1.1.0)
Requirement already satisfied: MarkupSafe>=0.23 in /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages (from Jinja2>=2.10.1->Flask==1.1.2->-r requirements.txt (line 2)) (1.1.1)
Building wheels for collected packages: fastecdsa
Building wheel for fastecdsa (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: /usr/local/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/hc/95xyw1f130n9plwy22r75fx80000gn/T/pip-install-yo45ct23/fastecdsa_14e0e140f6b84d978471bc00bdf1c985/setup.py'"'"'; file='"'"'/private/var/folders/hc/95xyw1f130n9plwy22r75fx80000gn/T/pip-install-yo45ct23/fastecdsa_14e0e140f6b84d978471bc00bdf1c985/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' bdist_wheel -d /private/var/folders/hc/95xyw1f130n9plwy22r75fx80000gn/T/pip-wheel-ss14hg94
cwd: /private/var/folders/hc/95xyw1f130n9plwy22r75fx80000gn/T/pip-install-yo45ct23/fastecdsa_14e0e140f6b84d978471bc00bdf1c985/
Complete output (49 lines):
running bdist_wheel
running build
running build_py
creating build
creating build/lib.macosx-10.9-x86_64-3.9
creating build/lib.macosx-10.9-x86_64-3.9/fastecdsa
copying fastecdsa/benchmark.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa
copying fastecdsa/util.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa
copying fastecdsa/init.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa
copying fastecdsa/keys.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa
copying fastecdsa/curve.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa
copying fastecdsa/point.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa
copying fastecdsa/ecdsa.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa
creating build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_point.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_keygen.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_nonce_generation.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_key_recovery.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_whycheproof_vectors.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/init.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_brainpool_ecdh.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_rfc6979_ecdsa.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_whitespace_parsing.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_prime_field_curve_math.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
copying fastecdsa/tests/test_p256_ecdsa.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests
creating build/lib.macosx-10.9-x86_64-3.9/fastecdsa/encoding
copying fastecdsa/encoding/pem.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/encoding
copying fastecdsa/encoding/util.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/encoding
copying fastecdsa/encoding/init.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/encoding
copying fastecdsa/encoding/sec1.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/encoding
copying fastecdsa/encoding/der.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/encoding
copying fastecdsa/encoding/asn1.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/encoding
creating build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests/encoding
copying fastecdsa/tests/encoding/test_sec1.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests/encoding
copying fastecdsa/tests/encoding/init.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests/encoding
copying fastecdsa/tests/encoding/test_der.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests/encoding
copying fastecdsa/tests/encoding/test_asn1.py -> build/lib.macosx-10.9-x86_64-3.9/fastecdsa/tests/encoding
running build_ext
building 'fastecdsa.curvemath' extension
creating build/temp.macosx-10.9-x86_64-3.9
creating build/temp.macosx-10.9-x86_64-3.9/src
gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -arch x86_64 -g -I/usr/local/include -L/usr/local/lib -Isrc/ -I/Library/Frameworks/Python.framework/Versions/3.9/include/python3.9 -c src/curve.c -o build/temp.macosx-10.9-x86_64-3.9/src/curve.o -O2
clang: warning: argument unused during compilation: '-L/usr/local/lib' [-Wunused-command-line-argument]
In file included from src/curve.c:1:
src/curve.h:4:10: fatal error: 'gmp.h' file not found
#include "gmp.h"
^~~~~~~
1 error generated.
error: command '/usr/bin/gcc' failed with exit code 1

multiplication speed problem

here i love to share info

12million lines read and write takes 5 min maximum

Point Addition

R = S + T

12million lines read and write takes 5 min maximum

Point Subtraction: (xs, ys) - (xt, yt) = (xs, ys) + (xt, -yt)

R = S - T

12million lines read and write takes 5 min maximum

Point Doubling

R = S + S # produces the same value as the operation below

**12million lines read and write takes 3 hours 13 min **
R = 2 * S # S * 2 works fine too i.e. order doesn't matter

**12million lines read and write takes 3hours to 4 hours where ever i use * in calc **

d = 0xc51e4753afdec1e6b6c6a5b992f43f8dd0c7a8933072708b6522468b2ffb06fd

Scalar Multiplication

R = d * S # S * d works fine too i.e. order doesn't matter

e = 0xd37f628ece72a462f0145cbefe3f0b355ee8332d37acdd83a358016aea029db7

Joint Scalar Multiplication

R = d * S + e * T

pls correct this problem where 3 to 4 hours take for point to point (scalar) multiplication
Thankx

Key Error when decoding DER signatures on P521 curve

Hello,

There is a key error when decoding the encoded signature using the P521-curve.

'''
    Generating Keys
'''

from fastecdsa import keys, curve, ecdsa

priv_key,pub_key = keys.gen_keypair(curve.P521)

'''
    Signing and verifyng
'''
m = "Hello World"

r,s = ecdsa.sign(m,priv_key,curve=curve.P521)
valid = ecdsa.verify((r,s),m,pub_key,curve=curve.P521)

'''
    Encoding signatures
'''

from fastecdsa.encoding.der import DEREncoder

encoded = DEREncoder.encode_signature(r,s)
decoded_r, decoded_s = DEREncoder.decode_signature(encoded)

print(decoded_r)

Does fastecdsa support gpu computation?

After I read the documentation, I realized that, fastecdsa does not support gpu computation in Cuda or OpenCl, am I right?

Will you think that compute the result by running the script on GPU will be even faster than on CPU?

Can this be a feature request?

I think there is a python package called numba which allow python code to be run on gpu, but i still learning it.

Importing a public key (originally a byte array) from a ATECC508A cryptochip

This involves importing a public key from the cryptographic chip ATECC508A into the library. I found I had a public key that was generated using the p-256 according to the chip documentation, yet the fastecdsa library tells me that the point is not on the curve.

I created a gist to describe my procedure:
https://gist.github.com/bshambaugh/6f0fe5a63f96b0e0a95b404cc103e9c4

As well as my broader (newbie) exploration:
https://raptorlicious.blogspot.com/2020/07/bringing-together-last-3-cryptography.html

If this is out of scope, is there a better place for this question? Thanks for your time.

Great library — keep it up

Hi @AntonKueltz

This is not a bug report. I was wandering around GitHub looking for ECC libraries to learn it and implement by myself. Almost every lib out there is shitty for learning. They have tons of dependencies, tons of unreadable "optimized" code.

Thanks for such a great tool! fastecdsa is one of the best in this regard. Please keep it up. In particular, Python is very helpful due to built-in bigint support.

Cannot `pip install fastecdsa` on Ubuntu 16.10

$ pip install fastecdsa
Collecting fastecdsa
  Using cached fastecdsa-1.4.2.tar.gz
Building wheels for collected packages: fastecdsa
  Running setup.py bdist_wheel for fastecdsa ... error
  Complete output from command /home/exarkun/Environments/blockstack/bin/python2 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-s9DeNL/fastecdsa/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmptYsju2pip-wheel- --python-tag cp27:
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-x86_64-2.7
  creating build/lib.linux-x86_64-2.7/fastecdsa
  copying fastecdsa/__init__.py -> build/lib.linux-x86_64-2.7/fastecdsa
  copying fastecdsa/test.py -> build/lib.linux-x86_64-2.7/fastecdsa
  copying fastecdsa/keys.py -> build/lib.linux-x86_64-2.7/fastecdsa
  copying fastecdsa/curve.py -> build/lib.linux-x86_64-2.7/fastecdsa
  copying fastecdsa/ecdsa.py -> build/lib.linux-x86_64-2.7/fastecdsa
  copying fastecdsa/util.py -> build/lib.linux-x86_64-2.7/fastecdsa
  copying fastecdsa/point.py -> build/lib.linux-x86_64-2.7/fastecdsa
  warning: build_py: byte-compiling is disabled, skipping.
  
  running build_ext
  building 'fastecdsa.curvemath' extension
  creating build/temp.linux-x86_64-2.7
  creating build/temp.linux-x86_64-2.7/src
  x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-lMBuS3/python2.7-2.7.12=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Isrc/ -I/usr/include/python2.7 -c src/curveMath.c -o build/temp.linux-x86_64-2.7/src/curveMath.o -O2
  x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-lMBuS3/python2.7-2.7.12=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Isrc/ -I/usr/include/python2.7 -c src/curve.c -o build/temp.linux-x86_64-2.7/src/curve.o -O2
  x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-lMBuS3/python2.7-2.7.12=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Isrc/ -I/usr/include/python2.7 -c src/point.c -o build/temp.linux-x86_64-2.7/src/point.o -O2
  x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-lMBuS3/python2.7-2.7.12=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -Wdate
-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-lMBuS3/python2.7-2.7.12=. -fstack-protector-strong -Wformat -Werror=format-security build/temp.linux-x86_64-2.7/src/curveMath.o build/temp.linux-x86_64-2.7/src/curve.o build/temp.linux-x86_64-2.7/src/point.o -lgmp -o build/lib.linux-x86_64-2.7/fastecdsa/curvemath.so
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(lt20-get_str.o): relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(realloc.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(lt43-set_str.o): relocation R_X86_64_32 against symbol `__gmp_digit_value_tab' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(sizeinbase.o): relocation R_X86_64_32S against symbol `__gmpn_bases' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(lt88-get_str.o): relocation R_X86_64_32S against symbol `__gmpn_bases' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(lt89-set_str.o): relocation R_X86_64_32S against symbol `__gmpn_bases' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(lt99-tdiv_qr.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(mu_div_qr.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(assert.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(memory.o): relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(mul_fft.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(lt98-gcdext.o): relocation R_X86_64_32 against symbol `__gmpn_gcdext_hook' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(gcd_subdiv_step.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(gcdext_lehmer.o): relocation R_X86_64_32 against symbol `__gmpn_gcdext_hook' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(sbpi1_divappr_q.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(hgcd_step.o): relocation R_X86_64_32 against `.text' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(bdiv_q.o): relocation R_X86_64_32S against symbol `__gmp_binvert_limb_table' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(binvert.o): relocation R_X86_64_32S against symbol `__gmp_binvert_limb_table' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libgmp.a(lt5-clears.o): relocation R_X86_64_PC32 against symbol `__gmp_free_func' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: final link failed: Bad value
  collect2: error: ld returned 1 exit status
  error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
  
  ----------------------------------------
  Failed building wheel for fastecdsa

How to replicate signatures from other implementations / verify correctness?

I'm looking for a Python library for ECDSA. I need to match the output of projects in other languages using different libraries for ECDSA. I took some known (key, message, signature) "test vectors" from this ECDSA library in Go and was able to replicate them (or at least the first and fourth) with elliptic in JavaScript, to verify that they work the same. However, I can't seem to do the same with fastecdsa.

How would you write a function that, given two 32-byte bytes values for both the key and the message digest, returns a DER-encoded bytes signature? I tried this (paraphrased):

from fastecdsa import curve, ecdsa

def sign(private_key_bytes: bytes, message_digest_bytes: bytes) -> bytes:
    private_key = int.from_bytes(private_key_bytes, byteorder='big')
    r, s = ecdsa.sign(
        message_digest_bytes.hex(), private_key, curve=curve.secp256k1, prehashed=True
    )
    r_bytes = r.to_bytes(32, byteorder='big')
    s_bytes = s.to_bytes(32, byteorder='big')
    # Hacky hard-coded DER encoding that works for the two cases I'm testing.
    return b'\x30\x44' + b'\x02\x20' + r_bytes + b'\x02\x20' + s_bytes

You can see it failing on the two test vectors I copied from the Go project.

About message

How can I manual insert my hashed message and check signature?

Cannot `pip install fastecdsa` on Windows 10

C:\Program Files (x86)\Python37-32\Scripts>pip install fastecdsa
Collecting fastecdsa
  Using cached https://files.pythonhosted.org/packages/41/b7/292c58a399df59a0c9f52878b73ca51b292d3b963f500f7c85414759b4f2/fastecdsa-1.7.4.tar.gz
Requirement already satisfied: six in c:\program files (x86)\python37-32\lib\site-packages (from fastecdsa) (1.12.0)
Building wheels for collected packages: fastecdsa
  Building wheel for fastecdsa (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: 'c:\program files (x86)\python37-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\malik\\AppData\\Local\\Temp\\pip-install-0s2cfv5w\\fastecdsa\\setup.py'"'"'; __file__='"'"'C:\\Users\\malik\\AppData\\Local\\Temp\\pip-install-0s2cfv5w\\fastecdsa\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\malik\AppData\Local\Temp\pip-wheel-mpgsiicz' --python-tag cp37
       cwd: C:\Users\malik\AppData\Local\Temp\pip-install-0s2cfv5w\fastecdsa\
  Complete output (42 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build\lib.win32-3.7
  creating build\lib.win32-3.7\fastecdsa
  copying fastecdsa\benchmark.py -> build\lib.win32-3.7\fastecdsa
  copying fastecdsa\curve.py -> build\lib.win32-3.7\fastecdsa
  copying fastecdsa\ecdsa.py -> build\lib.win32-3.7\fastecdsa
  copying fastecdsa\keys.py -> build\lib.win32-3.7\fastecdsa
  copying fastecdsa\point.py -> build\lib.win32-3.7\fastecdsa
  copying fastecdsa\util.py -> build\lib.win32-3.7\fastecdsa
  copying fastecdsa\__init__.py -> build\lib.win32-3.7\fastecdsa
  creating build\lib.win32-3.7\fastecdsa\encoding
  copying fastecdsa\encoding\asn1.py -> build\lib.win32-3.7\fastecdsa\encoding
  copying fastecdsa\encoding\der.py -> build\lib.win32-3.7\fastecdsa\encoding
  copying fastecdsa\encoding\pem.py -> build\lib.win32-3.7\fastecdsa\encoding
  copying fastecdsa\encoding\sec1.py -> build\lib.win32-3.7\fastecdsa\encoding
  copying fastecdsa\encoding\util.py -> build\lib.win32-3.7\fastecdsa\encoding
  copying fastecdsa\encoding\__init__.py -> build\lib.win32-3.7\fastecdsa\encoding
  creating build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_asn1.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_brainpool_ecdh.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_keygen.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_key_encoding.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_key_recovery.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_nonce_generation.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_p256_ecdsa.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_prime_field_curve_math.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_rfc6979_ecdsa.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_signature_encoding.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\test_whitespace_parsing.py -> build\lib.win32-3.7\fastecdsa\tests
  copying fastecdsa\tests\__init__.py -> build\lib.win32-3.7\fastecdsa\tests
  running build_ext
  building 'fastecdsa.curvemath' extension
  creating build\temp.win32-3.7
  creating build\temp.win32-3.7\Release
  creating build\temp.win32-3.7\Release\src
  C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.23.28105\bin\HostX86\x86\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MT -Isrc/ "-Ic:\program files (x86)\python37-32\include" "-Ic:\program files (x86)\python37-32\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.23.28105\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt" /Tcsrc/curveMath.c /Fobuild\temp.win32-3.7\Release\src/curveMath.obj -O2
  curveMath.c
  C:\Users\malik\AppData\Local\Temp\pip-install-0s2cfv5w\fastecdsa\src\curveMath.h(6): fatal error C1083: Cannot open include file: 'gmp.h': No such file or directory
  error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.23.28105\\bin\\HostX86\\x86\\cl.exe' failed with exit status 2

Point at infinity not emplemented

Operands with resulting point at infinity fails to
ValueError: (x, y) coordinates are not on curve <test_curve> or simply does wrong (0G or NG )

print ("G =  %s" % (G))
print ("0*G = %s" % (0*G))
print ("G - G = %s" % (G - G))
G =  X: 0x500
Y: 0x823
(On curve <test_curve>)
0*G = X: 0x500
Y: 0x823
(On curve <test_curve>)
    print ("G - G = %s" % (G - G))
  File "build\bdist.win32\egg\fastecdsa\point.py", line 99, in __sub__
  File "build\bdist.win32\egg\fastecdsa\point.py", line 74, in __add__
  File "build\bdist.win32\egg\fastecdsa\point.py", line 31, in __init__
ValueError: (x, y) coordinates are not on curve <test_curve>

May be need to define Infinity point and add check for this to "is_point_on_curve"

Issues Installing Ubuntu 18

I have Ubuntu 18 .1. I installed python 3.7.2. I have tried to install fastecdsa1.6.5 but I get this error.

building 'fastecdsa.curvemath' extension creating build/temp.linux-x86_64-3.7 creating build/temp.linux-x86_64-3.7/src gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -Isrc/ -I/usr/local/include/python3.7m -c src/curveMath.c -o build/temp.linux-x86_64-3.7/src/curveMath.o -O2 In file included from src/curveMath.c:1:0: src/curveMath.h:6:10: fatal error: gmp.h: No such file or directory #include <gmp.h> ^~~~~~~ compilation terminated. error: command 'gcc' failed with exit status 1

Point to non-point equality

Checking equality of a curve point with something which is not a curve point raises a type error. Instead, I think it should return False which is, at least in my experience, the standard convention. (e.g. 5 == "5", None == object(), {} == []).

Using curve P192 gives error when doing ecdsa verify

Hello,

I am just getting to grips with fastecdsa but when I change the curve to use P192 and run through your simple example code I get the following:

Traceback (most recent call last):
File "", line 1, in
File "build/bdist.linux-x86_64/egg/fastecdsa/ecdsa.py", line 72, in verify
raise EcdsaError('Invalid public key, point is not on curve {}'.format(curve.name))
fastecdsa.ecdsa.EcdsaError

Am I missing something in setup or am I doing something very stupid.

Thanks,

Gajinder Panesar

Installation Problems

would you like me to help you track down the problems with your package setup?

root@ubuntu:~/opencl/fastecdsa/fastecdsa# python setup.py test
running test
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
"main", fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/home/marchon/opencl/fastecdsa/fastecdsa/fastecdsa/test.py", line 5, in
from .curve import P192, P224, P256, P384, P521, secp256k1
File "fastecdsa/curve.py", line 1, in
from fastecdsa import curvemath
ImportError: cannot import name curvemath

Having difficulty on Python 3.5.2, macOS Sierra.

Howdy!

I'm having some trouble installing fastecdsa on Python 3.5.2, installed via the official packages, with homebrew-supplied libgmp.

In a fresh virtual environment, pip install fastecdsa explodes gloriously:

Collecting fastecdsa
  Using cached fastecdsa-1.1.3.tar.gz
Installing collected packages: fastecdsa
  Running setup.py install for fastecdsa ... error
    Complete output from command /Users/amcgregor/Projects/test/.venv/bin/python3 -u -c "import setuptools, tokenize;__file__='/private/var/folders/xp/zg8pvtm16tl_tx4fp4sthm7c0000gn/T/pip-build-1nokhsj2/fastecdsa/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /var/folders/xp/zg8pvtm16tl_tx4fp4sthm7c0000gn/T/pip-ahgmwxsn-record/install-record.txt --single-version-externally-managed --compile --install-headers /Users/amcgregor/Projects/test/.venv/include/site/python3.5/fastecdsa:
    running install
    running build
    running build_py
    creating build
    creating build/lib.macosx-10.6-intel-3.5
    creating build/lib.macosx-10.6-intel-3.5/fastecdsa
    copying fastecdsa/__init__.py -> build/lib.macosx-10.6-intel-3.5/fastecdsa
    copying fastecdsa/curve.py -> build/lib.macosx-10.6-intel-3.5/fastecdsa
    copying fastecdsa/ecdsa.py -> build/lib.macosx-10.6-intel-3.5/fastecdsa
    copying fastecdsa/keys.py -> build/lib.macosx-10.6-intel-3.5/fastecdsa
    copying fastecdsa/test.py -> build/lib.macosx-10.6-intel-3.5/fastecdsa
    copying fastecdsa/util.py -> build/lib.macosx-10.6-intel-3.5/fastecdsa
    running build_ext
    building 'fastecdsa.curvemath' extension
    creating build/temp.macosx-10.6-intel-3.5
    creating build/temp.macosx-10.6-intel-3.5/src
    /usr/bin/clang -fno-strict-aliasing -Wsign-compare -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -arch i386 -arch x86_64 -g -Isrc/ -I/Users/amcgregor/Projects/test/.venv/include -I/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m -c src/curveMath.c -o build/temp.macosx-10.6-intel-3.5/src/curveMath.o -O2
    In file included from src/curveMath.c:1:
    src/curveMath.h:10:10: fatal error: 'gmp.h' file not found
    #include <gmp.h>
             ^
    1 error generated.
    error: command '/usr/bin/clang' failed with exit status 1

    ----------------------------------------
Command "/Users/amcgregor/Projects/test/.venv/bin/python3 -u -c "import setuptools, tokenize;__file__='/private/var/folders/xp/zg8pvtm16tl_tx4fp4sthm7c0000gn/T/pip-build-1nokhsj2/fastecdsa/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /var/folders/xp/zg8pvtm16tl_tx4fp4sthm7c0000gn/T/pip-ahgmwxsn-record/install-record.txt --single-version-externally-managed --compile --install-headers /Users/amcgregor/Projects/test/.venv/include/site/python3.5/fastecdsa" failed with error code 1 in /private/var/folders/xp/zg8pvtm16tl_tx4fp4sthm7c0000gn/T/pip-build-1nokhsj2/fastecdsa/

With --global-option=build_ext --global-option="-I/usr/local/include" --global-option="-L/usr/local/lib" in there, we get further:

/Users/amcgregor/Projects/test/.venv/lib/python3.5/site-packages/pip/commands/install.py:180: UserWarning: Disabling all use of wheels due to the use of --build-options / --global-options / --install-options.
  cmdoptions.check_install_build_global(options)
Collecting fastecdsa
  Using cached fastecdsa-1.1.3.tar.gz
Installing collected packages: fastecdsa
  Running setup.py install for fastecdsa ... done
Successfully installed fastecdsa-1.1.3
pip install --global-option=build_ext --global-option="-I/usr/local/include"   1.60s user 0.67s system 91% cpu 2.480 total

However, when running python -c "from fastecdsa import curve, ecdsa, keys":

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/amcgregor/Projects/test/.venv/lib/python3.5/site-packages/fastecdsa/curve.py", line 1, in <module>
    from fastecdsa import curvemath
ImportError: dlopen(/Users/amcgregor/Projects/test/.venv/lib/python3.5/site-packages/fastecdsa/curvemath.cpython-35m-darwin.so, 2): Symbol not found: _Py_InitModule4_64
  Referenced from: /Users/amcgregor/Projects/test/.venv/lib/python3.5/site-packages/fastecdsa/curvemath.cpython-35m-darwin.so
  Expected in: flat namespace
 in /Users/amcgregor/Projects/test/.venv/lib/python3.5/site-packages/fastecdsa/curvemath.cpython-35m-darwin.so

What might be going on here?

fastecdsa for c

Dear dev
if you have fastecdsa for c implmentation, it would be great, or reffer link simlar ecdsa in c
bc python fastecdsa slow in multiple works, or you can update it by applying python gmpy2 for fast processing
waiting your updates and refrences
regards

Type checks when calculating with point at infinity

At the moment, there are cases in which calculating with the point at infinity gives unexpected results and others in which an AttributeError is raised:

  • Point.IDENTITY_ELEMENT + 2 gives 2
  • Point.IDENTITY_ELEMENT - 2 raises an AttributeError
  • Point.IDENTITY_ELEMENT * 1.5 raises an AttributeError

In all of these cases I would expect an TypeError.

elliptic curve public key recovery feature

Thanks to the popularity of Ethereum, most of the libraries working around Ethereum no longer provide public keys, but only the last 20 bit of the hash of the public key. In fact, some libraries (geth-android for example) made it difficult to get public key as it is treated as a secret, making it difficult to use fastecdsa with those. I need to mention that treating public key as a secret is not a secret - it started in Bitcoin though, 9 years ago.

Traditionally, the public key is used to re-generate r, which is checked against signature (r,s). Now a public key is recovered from the message hash and signature (r, s) (plus a sign bit), then hashed, and compared against a known public hash. This allowed a form of "public key" called "address" that is both smaller and more secretive. This way, before the owner signs anything, no one can deduce the public key and leverage any security breaches that depends on the knowledge of the public key; after the owner signs anything, the money is moved and protected by a different set of keys, reducing attack surface by far.

It would be great to see the support of recover() function in order for fastecdsa to be usable in cryptocurrencies. The method is mentioned here: https://crypto.stackexchange.com/questions/18105/how-does-recovering-the-public-key-from-an-ecdsa-signature-work

Customize curve parameters

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!

Cutomize curve without p value

Hi!

I saw a similar question was asked, but I'm trying to generate a custom Curve() with my own parameters and I can't find how to exclude p value since I'm using y^2 = x^3 + 7 (NIST256P) and I don't need the modulus. I looked through the official documentation but didn't see anything that answered this question. My only thought was to make p a huge value, but I'm sure there's a better way.

ValueError when multiplying the generator with the order of the curve

Multiplying the generator with the order of the curve gives a ValueError:

$ python -c 'from fastecdsa.curve import secp256k1; secp256k1.q * secp256k1.G'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/bbralf/brainbot-com/venv/lib64/python3.8/site-packages/fastecdsa/point.py", line 163, in __rmul__
    return self.__mul__(scalar)
  File "/home/bbralf/brainbot-com/venv/lib64/python3.8/site-packages/fastecdsa/point.py", line 150, in __mul__
    return Point(int(x), int(y), self.curve)
  File "/home/bbralf/brainbot-com/venv/lib64/python3.8/site-packages/fastecdsa/point.py", line 33, in __init__
    raise ValueError(
ValueError: coordinates are not on curve <secp256k1>
        x=0
        y=0

Issue with running it on python 2

The function bytes_to_int at https://github.com/AntonKueltz/fastecdsa/blob/master/fastecdsa/encoding/util.py uses a function indexbytes from the library called six. It looks like this function call is not compatible with python version 2.

six.py

def indexbytes(buf, i):
        return ord(buf[i])

fastecdsa/encoding/util.py

def bytes_to_int(bytestr):
    """Make an integer from a big endian bytestring."""
    value = 0
    for i in range(len(bytestr)):
        value = value * 256 + indexbytes(bytestr, i)
    return value

This is causing some runtime errors. I had to manually update the util.py method to the following:

def bytes_to_int(bytestr):
    """Make an integer from a big endian bytestring."""
    value = 0
    for i in range(len(bytestr)):
        value = value * 256 + bytestr[i]
    return value

And everything started working again. Is it possible to make a change to this so those of us using python 2 don't run into this issue?

benchmark command doesn't work

I cannot run the benchmark command on Python 3.8:

tomato@bursa22(pts/19)$ virtualenv3 -p `which python3` venv-py3
Running virtualenv with interpreter /bin/python3
Using base prefix '/usr'
New python executable in /home/tomato/workspace/fastecdsa/venv-py3/bin/python3
Also creating executable in /home/tomato/workspace/fastecdsa/venv-py3/bin/python
Installing setuptools, pip, wheel...
done.
$ :) [22:18:09] ~/workspace/fastecdsa 
tomato@bursa22(pts/19)$ ls
docs  fastecdsa  LICENSE  MANIFEST.in  README.rst  setup.py  src  venv-py3
$ :) [22:18:15] ~/workspace/fastecdsa 
tomato@bursa22(pts/19)$ ./venv-py3/bin/python setup.py install
running install
running bdist_egg
running egg_info
creating fastecdsa.egg-info
writing fastecdsa.egg-info/PKG-INFO
writing dependency_links to fastecdsa.egg-info/dependency_links.txt
writing requirements to fastecdsa.egg-info/requires.txt
writing top-level names to fastecdsa.egg-info/top_level.txt
writing manifest file 'fastecdsa.egg-info/SOURCES.txt'
reading manifest file 'fastecdsa.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'fastecdsa.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib.linux-x86_64-3.8
creating build/lib.linux-x86_64-3.8/fastecdsa
copying fastecdsa/curve.py -> build/lib.linux-x86_64-3.8/fastecdsa
copying fastecdsa/__init__.py -> build/lib.linux-x86_64-3.8/fastecdsa
copying fastecdsa/ecdsa.py -> build/lib.linux-x86_64-3.8/fastecdsa
copying fastecdsa/benchmark.py -> build/lib.linux-x86_64-3.8/fastecdsa
copying fastecdsa/keys.py -> build/lib.linux-x86_64-3.8/fastecdsa
copying fastecdsa/util.py -> build/lib.linux-x86_64-3.8/fastecdsa
copying fastecdsa/point.py -> build/lib.linux-x86_64-3.8/fastecdsa
creating build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_prime_field_curve_math.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/__init__.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_signature_encoding.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_nonce_generation.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_brainpool_ecdh.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_asn1.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_key_encoding.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_p256_ecdsa.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_rfc6979_ecdsa.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_key_recovery.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_keygen.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
copying fastecdsa/tests/test_whitespace_parsing.py -> build/lib.linux-x86_64-3.8/fastecdsa/tests
creating build/lib.linux-x86_64-3.8/fastecdsa/encoding
copying fastecdsa/encoding/der.py -> build/lib.linux-x86_64-3.8/fastecdsa/encoding
copying fastecdsa/encoding/__init__.py -> build/lib.linux-x86_64-3.8/fastecdsa/encoding
copying fastecdsa/encoding/sec1.py -> build/lib.linux-x86_64-3.8/fastecdsa/encoding
copying fastecdsa/encoding/asn1.py -> build/lib.linux-x86_64-3.8/fastecdsa/encoding
copying fastecdsa/encoding/util.py -> build/lib.linux-x86_64-3.8/fastecdsa/encoding
copying fastecdsa/encoding/pem.py -> build/lib.linux-x86_64-3.8/fastecdsa/encoding
running build_ext
building 'fastecdsa.curvemath' extension
creating build/temp.linux-x86_64-3.8
creating build/temp.linux-x86_64-3.8/src
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Isrc/ -I/usr/include/python3.8 -c src/curveMath.c -o build/temp.linux-x86_64-3.8/src/curveMath.o -O2
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Isrc/ -I/usr/include/python3.8 -c src/curve.c -o build/temp.linux-x86_64-3.8/src/curve.o -O2
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Isrc/ -I/usr/include/python3.8 -c src/point.c -o build/temp.linux-x86_64-3.8/src/point.o -O2
gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now build/temp.linux-x86_64-3.8/src/curveMath.o build/temp.linux-x86_64-3.8/src/curve.o build/temp.linux-x86_64-3.8/src/point.o -L/usr/lib -lgmp -o build/lib.linux-x86_64-3.8/fastecdsa/curvemath.cpython-38-x86_64-linux-gnu.so
building 'fastecdsa._ecdsa' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Isrc/ -I/usr/include/python3.8 -c src/_ecdsa.c -o build/temp.linux-x86_64-3.8/src/_ecdsa.o -O2
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Isrc/ -I/usr/include/python3.8 -c src/curveMath.c -o build/temp.linux-x86_64-3.8/src/curveMath.o -O2
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Isrc/ -I/usr/include/python3.8 -c src/curve.c -o build/temp.linux-x86_64-3.8/src/curve.o -O2
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -Isrc/ -I/usr/include/python3.8 -c src/point.c -o build/temp.linux-x86_64-3.8/src/point.o -O2
gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now build/temp.linux-x86_64-3.8/src/_ecdsa.o build/temp.linux-x86_64-3.8/src/curveMath.o build/temp.linux-x86_64-3.8/src/curve.o build/temp.linux-x86_64-3.8/src/point.o -L/usr/lib -lgmp -o build/lib.linux-x86_64-3.8/fastecdsa/_ecdsa.cpython-38-x86_64-linux-gnu.so
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
creating build/bdist.linux-x86_64/egg/fastecdsa
copying build/lib.linux-x86_64-3.8/fastecdsa/curve.py -> build/bdist.linux-x86_64/egg/fastecdsa
copying build/lib.linux-x86_64-3.8/fastecdsa/curvemath.cpython-38-x86_64-linux-gnu.so -> build/bdist.linux-x86_64/egg/fastecdsa
copying build/lib.linux-x86_64-3.8/fastecdsa/__init__.py -> build/bdist.linux-x86_64/egg/fastecdsa
creating build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_prime_field_curve_math.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/__init__.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_signature_encoding.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_nonce_generation.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_brainpool_ecdh.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_asn1.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_key_encoding.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_p256_ecdsa.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_rfc6979_ecdsa.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_key_recovery.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_keygen.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/tests/test_whitespace_parsing.py -> build/bdist.linux-x86_64/egg/fastecdsa/tests
copying build/lib.linux-x86_64-3.8/fastecdsa/_ecdsa.cpython-38-x86_64-linux-gnu.so -> build/bdist.linux-x86_64/egg/fastecdsa
copying build/lib.linux-x86_64-3.8/fastecdsa/ecdsa.py -> build/bdist.linux-x86_64/egg/fastecdsa
copying build/lib.linux-x86_64-3.8/fastecdsa/benchmark.py -> build/bdist.linux-x86_64/egg/fastecdsa
copying build/lib.linux-x86_64-3.8/fastecdsa/keys.py -> build/bdist.linux-x86_64/egg/fastecdsa
copying build/lib.linux-x86_64-3.8/fastecdsa/util.py -> build/bdist.linux-x86_64/egg/fastecdsa
copying build/lib.linux-x86_64-3.8/fastecdsa/point.py -> build/bdist.linux-x86_64/egg/fastecdsa
creating build/bdist.linux-x86_64/egg/fastecdsa/encoding
copying build/lib.linux-x86_64-3.8/fastecdsa/encoding/der.py -> build/bdist.linux-x86_64/egg/fastecdsa/encoding
copying build/lib.linux-x86_64-3.8/fastecdsa/encoding/__init__.py -> build/bdist.linux-x86_64/egg/fastecdsa/encoding
copying build/lib.linux-x86_64-3.8/fastecdsa/encoding/sec1.py -> build/bdist.linux-x86_64/egg/fastecdsa/encoding
copying build/lib.linux-x86_64-3.8/fastecdsa/encoding/asn1.py -> build/bdist.linux-x86_64/egg/fastecdsa/encoding
copying build/lib.linux-x86_64-3.8/fastecdsa/encoding/util.py -> build/bdist.linux-x86_64/egg/fastecdsa/encoding
copying build/lib.linux-x86_64-3.8/fastecdsa/encoding/pem.py -> build/bdist.linux-x86_64/egg/fastecdsa/encoding
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/curve.py to curve.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/__init__.py to __init__.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_prime_field_curve_math.py to test_prime_field_curve_math.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/__init__.py to __init__.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_signature_encoding.py to test_signature_encoding.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_nonce_generation.py to test_nonce_generation.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_brainpool_ecdh.py to test_brainpool_ecdh.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_asn1.py to test_asn1.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_key_encoding.py to test_key_encoding.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_p256_ecdsa.py to test_p256_ecdsa.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_rfc6979_ecdsa.py to test_rfc6979_ecdsa.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_key_recovery.py to test_key_recovery.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_keygen.py to test_keygen.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/tests/test_whitespace_parsing.py to test_whitespace_parsing.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/ecdsa.py to ecdsa.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/benchmark.py to benchmark.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/keys.py to keys.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/util.py to util.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/point.py to point.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/encoding/der.py to der.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/encoding/__init__.py to __init__.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/encoding/sec1.py to sec1.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/encoding/asn1.py to asn1.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/encoding/util.py to util.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/encoding/pem.py to pem.cpython-38.pyc
creating stub loader for fastecdsa/curvemath.cpython-38-x86_64-linux-gnu.so
creating stub loader for fastecdsa/_ecdsa.cpython-38-x86_64-linux-gnu.so
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/curvemath.py to curvemath.cpython-38.pyc
byte-compiling build/bdist.linux-x86_64/egg/fastecdsa/_ecdsa.py to _ecdsa.cpython-38.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying fastecdsa.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying fastecdsa.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying fastecdsa.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying fastecdsa.egg-info/requires.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying fastecdsa.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
writing build/bdist.linux-x86_64/egg/EGG-INFO/native_libs.txt
zip_safe flag not set; analyzing archive contents...
fastecdsa.__pycache__._ecdsa.cpython-38: module references __file__
fastecdsa.__pycache__.curvemath.cpython-38: module references __file__
creating dist
creating 'dist/fastecdsa-1.7.5-py3.8-linux-x86_64.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing fastecdsa-1.7.5-py3.8-linux-x86_64.egg
creating /home/tomato/workspace/fastecdsa/venv-py3/lib/python3.8/site-packages/fastecdsa-1.7.5-py3.8-linux-x86_64.egg
Extracting fastecdsa-1.7.5-py3.8-linux-x86_64.egg to /home/tomato/workspace/fastecdsa/venv-py3/lib/python3.8/site-packages
Adding fastecdsa 1.7.5 to easy-install.pth file

Installed /home/tomato/workspace/fastecdsa/venv-py3/lib/python3.8/site-packages/fastecdsa-1.7.5-py3.8-linux-x86_64.egg
Processing dependencies for fastecdsa==1.7.5
Searching for six
Reading https://pypi.org/simple/six/
Downloading https://files.pythonhosted.org/packages/65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl#sha256=1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd
Best match: six 1.13.0
Processing six-1.13.0-py2.py3-none-any.whl
Installing six-1.13.0-py2.py3-none-any.whl to /home/tomato/workspace/fastecdsa/venv-py3/lib/python3.8/site-packages
Adding six 1.13.0 to easy-install.pth file

Installed /home/tomato/workspace/fastecdsa/venv-py3/lib/python3.8/site-packages/six-1.13.0-py3.8.egg
Finished processing dependencies for fastecdsa==1.7.5
$ :) [22:18:28] ~/workspace/fastecdsa 
tomato@bursa22(pts/19)$ ./venv-py3/bin/python setup.py benchmark
running benchmark
Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 192, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/tomato/workspace/fastecdsa/fastecdsa/benchmark.py", line 10, in <module>
    from .ecdsa import sign, verify
  File "/home/tomato/workspace/fastecdsa/fastecdsa/ecdsa.py", line 4, in <module>
    from fastecdsa import _ecdsa
ImportError: cannot import name '_ecdsa' from 'fastecdsa' (/home/tomato/workspace/fastecdsa/fastecdsa/__init__.py)

ecdsa.verify with secp256k1 returns False

Hello! I recently installed your library via pip and tried to sign and verify message with secp256k1. As a result i have False, although to me the code seems correct. Can you help me with this?

from fastecdsa import keys, curve as curve_, ecdsa
from hashlib import sha3_256

curve = curve_.secp256k1

message = b'Hello, World!'
privkey, pubkey = keys.gen_keypair(curve=curve)
sign = ecdsa.sign(message, privkey, hashfunc=sha3_256)

print(ecdsa.verify(sign, message, pubkey, 
    hashfunc=sha3_256, curve=curve)
)

Also, when i replace curve with curve_.P256 i get True. Is it a bug?

Certificate parsing might be broken?

Hello,

thanks for the library -- it is very helpful. Having said this -- I am trying to reconcile it against OpenSSL and I am finding this hard.

One issue seems to be that the PEM import is broken. See the Azure Notebook here
https://ecdsa-skloesch.notebooks.azure.com/j/notebooks/FastECDSA.ipynb

In brief, the issue is the following:

This code works

keypem = """-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDAH346L7Ww1kqEPnQSVFz3Oy8maQOjIi0fX1ZD4tgjdoAcGBSuBBAAK
oUQDQgAELAcTVHlPOP9Dnv9S+LR1sN7zSiEKo7iKY/KnKV019B+w811PRdlWV/o3
1qVDG+lEGpVjj8cQiE9D//eThCgFbg==
-----END EC PRIVATE KEY-----"""
key, pubkey = fe_pem.PEMEncoder.decode_private_key(keypem)
print(keypem)
print(fe_keys.export_key(key, curve=CURVE))

This code works but gives a different result (only difference: newlines in the certificate file)

keypem = """
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDAH346L7Ww1kqEPnQSVFz3Oy8maQOjIi0fX1ZD4tgjdoAcGBSuBBAAK
oUQDQgAELAcTVHlPOP9Dnv9S+LR1sN7zSiEKo7iKY/KnKV019B+w811PRdlWV/o3
1qVDG+lEGpVjj8cQiE9D//eThCgFbg==
-----END EC PRIVATE KEY-----
"""
key, pubkey = fe_pem.PEMEncoder.decode_private_key(keypem)
print(keypem)
print(fe_keys.export_key(key, curve=CURVE))

And finally, this code breaks (multiple new lines)

keypem = """


-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDAH346L7Ww1kqEPnQSVFz3Oy8maQOjIi0fX1ZD4tgjdoAcGBSuBBAAK
oUQDQgAELAcTVHlPOP9Dnv9S+LR1sN7zSiEKo7iKY/KnKV019B+w811PRdlWV/o3
1qVDG+lEGpVjj8cQiE9D//eThCgFbg==
-----END EC PRIVATE KEY-----


"""
key, pubkey = fe_pem.PEMEncoder.decode_private_key(keypem)
print(keypem)
print(fe_keys.export_key(key, curve=CURVE))

How is the performance boost achieved?

Would be great to include how did you achieve the performance boost in the README, especially if the performance boost comes at the cost of something else - otherwise I wonder why python-ecdsa couldn't do the same thing if it's better in every way (perhaps just because it's less maintained?), if it's too good to be true...

Of course if the perf boost comes at no cost, would help to state that explicitly as well so it's clear.

Thanks!

Speed compare with python-ecdsa?

I've recently merged a faster implementation of elliptic curve arithmetic to python-ecdsa (tlsfuzzer/python-ecdsa#127) and was trying to compare performance with this library, but I'm getting some silly numbers.

(after running pip install -e . I got the benchmark running, see #44 though)

with fastecdsa 50a3cdf I'm getting

1000 signatures and verifications with curve P192 took 1.47 seconds
1000 signatures and verifications with curve P224 took 1.89 seconds
1000 signatures and verifications with curve P256 took 2.42 seconds
1000 signatures and verifications with curve P384 took 5.15 seconds
1000 signatures and verifications with curve P521 took 9.48 seconds
1000 signatures and verifications with curve secp192k1 took 1.47 seconds
1000 signatures and verifications with curve secp224k1 took 1.89 seconds
1000 signatures and verifications with curve secp256k1 took 2.43 seconds
1000 signatures and verifications with curve brainpoolP160r1 took 1.05 seconds
1000 signatures and verifications with curve brainpoolP192r1 took 1.46 seconds
1000 signatures and verifications with curve brainpoolP224r1 took 1.88 seconds
1000 signatures and verifications with curve brainpoolP256r1 took 2.41 seconds
1000 signatures and verifications with curve brainpoolP320r1 took 3.66 seconds
1000 signatures and verifications with curve brainpoolP384r1 took 5.12 seconds
1000 signatures and verifications with curve brainpoolP512r1 took 8.96 seconds

while with current master of python-ecdsa (8deb089e7d5), with gmpy2 installed, I'm getting:

                  siglen    keygen   keygen/s      sign     sign/s    verify   verify/s
        NIST192p:     48   0.00016s   6138.39   0.00017s   5781.36   0.00033s   2996.27
        NIST224p:     56   0.00020s   4882.81   0.00022s   4625.53   0.00042s   2391.89
        NIST256p:     64   0.00023s   4332.80   0.00024s   4130.10   0.00048s   2092.61
        NIST384p:     96   0.00040s   2503.29   0.00041s   2420.89   0.00080s   1247.25
        NIST521p:    132   0.00071s   1417.89   0.00072s   1388.78   0.00139s    721.06
       SECP256k1:     64   0.00023s   4276.34   0.00024s   4149.60   0.00046s   2187.62
 BRAINPOOLP160r1:     40   0.00014s   7198.78   0.00015s   6814.04   0.00029s   3495.85
 BRAINPOOLP192r1:     48   0.00016s   6143.59   0.00017s   5831.40   0.00032s   3121.77
 BRAINPOOLP224r1:     56   0.00020s   4892.69   0.00022s   4578.01   0.00041s   2458.99
 BRAINPOOLP256r1:     64   0.00023s   4321.77   0.00024s   4156.66   0.00051s   1972.34
 BRAINPOOLP320r1:     80   0.00031s   3218.62   0.00032s   3100.46   0.00060s   1660.37
 BRAINPOOLP384r1:     96   0.00041s   2465.49   0.00042s   2401.97   0.00080s   1248.43
 BRAINPOOLP512r1:    128   0.00062s   1609.65   0.00063s   1576.10   0.00127s    789.65

so for NIST192p, the combined sign and verify looks to be almost 3 times faster than fastecdsa, which doesn't make sense for the non-native code in python-ecdsa... Are the benchmark commands doing different things?

Memory leak

Some of the functions seem to leak memory. The test program below will continuously eat up more and more memory.

I suspect the issue is in your use of Py_BuildValue without freeing the char* afterwards. For example, in curvemath_mul, resultX and resultY are allocated but never freed.

#!/usr/bin/env python

import fastecdsa.curvemath, fastecdsa.curve, gc

sx = str(fastecdsa.curve.secp256k1.G[0])
sy = str(fastecdsa.curve.secp256k1.G[1])
sz = str(2**255-1)

while True:
    fastecdsa.curvemath.mul(sx, sy, sz, 'secp256k1')
    gc.collect()

Issues Installing in anaconda virtual environment

I followed the instruction in 'installing' section.
I'm using now anaconda and working in virtual environment

first, I type followings

$ sudo apt-get install python-dev libgmp3-dev

and this is successful works and follow type that

$ pip install fastecdsa

then I get error

ERROR: Command errored out with exit status 1:
   command: /home/kimjungmin/anaconda3/envs/sage/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-niky0gtn/fastecdsa/setup.py'"'"'; __file__='"'"'/tmp/pip-install-niky0gtn/fastecdsa/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-kmu6bhwv --python-tag cp36
       cwd: /tmp/pip-install-niky0gtn/fastecdsa/
  Complete output (44 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-x86_64-3.6
  creating build/lib.linux-x86_64-3.6/fastecdsa
  copying fastecdsa/ecdsa.py -> build/lib.linux-x86_64-3.6/fastecdsa
  copying fastecdsa/keys.py -> build/lib.linux-x86_64-3.6/fastecdsa
  copying fastecdsa/__init__.py -> build/lib.linux-x86_64-3.6/fastecdsa
  copying fastecdsa/benchmark.py -> build/lib.linux-x86_64-3.6/fastecdsa
  copying fastecdsa/util.py -> build/lib.linux-x86_64-3.6/fastecdsa
  copying fastecdsa/point.py -> build/lib.linux-x86_64-3.6/fastecdsa
  copying fastecdsa/curve.py -> build/lib.linux-x86_64-3.6/fastecdsa
  creating build/lib.linux-x86_64-3.6/fastecdsa/encoding
  copying fastecdsa/encoding/sec1.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
  copying fastecdsa/encoding/asn1.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
  copying fastecdsa/encoding/pem.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
  copying fastecdsa/encoding/__init__.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
  copying fastecdsa/encoding/util.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
  copying fastecdsa/encoding/der.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
  creating build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_p256_ecdsa.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_signature_encoding.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_key_recovery.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_rfc6979_ecdsa.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_brainpool_ecdh.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/__init__.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_whitespace_parsing.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_prime_field_curve_math.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_key_encoding.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_asn1.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_nonce_generation.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  copying fastecdsa/tests/test_keygen.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
  running build_ext
  building 'fastecdsa.curvemath' extension
  creating build/temp.linux-x86_64-3.6
  creating build/temp.linux-x86_64-3.6/src
  /home/kimjungmin/anaconda3/envs/sage/bin/x86_64-conda_cos6-linux-gnu-cc -DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -fPIC -Isrc/ -I/home/kimjungmin/anaconda3/envs/sage/include/python3.6m -c src/curveMath.c -o build/temp.linux-x86_64-3.6/src/curveMath.o -O2
  In file included from src/curveMath.c:1:0:
  src/curveMath.h:6:10: fatal error: gmp.h: No such file or directory
   #include <gmp.h>
            ^~~~~~~
  compilation terminated.
  error: command '/home/kimjungmin/anaconda3/envs/sage/bin/x86_64-conda_cos6-linux-gnu-cc' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for fastecdsa
  Running setup.py clean for fastecdsa
Failed to build fastecdsa
Installing collected packages: fastecdsa
  Running setup.py install for fastecdsa ... error
    ERROR: Command errored out with exit status 1:
     command: /home/kimjungmin/anaconda3/envs/sage/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-niky0gtn/fastecdsa/setup.py'"'"'; __file__='"'"'/tmp/pip-install-niky0gtn/fastecdsa/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-r_9fcsat/install-record.txt --single-version-externally-managed --compile
         cwd: /tmp/pip-install-niky0gtn/fastecdsa/
    Complete output (44 lines):
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.6
    creating build/lib.linux-x86_64-3.6/fastecdsa
    copying fastecdsa/ecdsa.py -> build/lib.linux-x86_64-3.6/fastecdsa
    copying fastecdsa/keys.py -> build/lib.linux-x86_64-3.6/fastecdsa
    copying fastecdsa/__init__.py -> build/lib.linux-x86_64-3.6/fastecdsa
    copying fastecdsa/benchmark.py -> build/lib.linux-x86_64-3.6/fastecdsa
    copying fastecdsa/util.py -> build/lib.linux-x86_64-3.6/fastecdsa
    copying fastecdsa/point.py -> build/lib.linux-x86_64-3.6/fastecdsa
    copying fastecdsa/curve.py -> build/lib.linux-x86_64-3.6/fastecdsa
    creating build/lib.linux-x86_64-3.6/fastecdsa/encoding
    copying fastecdsa/encoding/sec1.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
    copying fastecdsa/encoding/asn1.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
    copying fastecdsa/encoding/pem.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
    copying fastecdsa/encoding/__init__.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
    copying fastecdsa/encoding/util.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
    copying fastecdsa/encoding/der.py -> build/lib.linux-x86_64-3.6/fastecdsa/encoding
    creating build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_p256_ecdsa.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_signature_encoding.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_key_recovery.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_rfc6979_ecdsa.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_brainpool_ecdh.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/__init__.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_whitespace_parsing.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_prime_field_curve_math.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_key_encoding.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_asn1.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_nonce_generation.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    copying fastecdsa/tests/test_keygen.py -> build/lib.linux-x86_64-3.6/fastecdsa/tests
    running build_ext
    building 'fastecdsa.curvemath' extension
    creating build/temp.linux-x86_64-3.6
    creating build/temp.linux-x86_64-3.6/src
    /home/kimjungmin/anaconda3/envs/sage/bin/x86_64-conda_cos6-linux-gnu-cc -DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -fPIC -Isrc/ -I/home/kimjungmin/anaconda3/envs/sage/include/python3.6m -c src/curveMath.c -o build/temp.linux-x86_64-3.6/src/curveMath.o -O2
    In file included from src/curveMath.c:1:0:
    src/curveMath.h:6:10: fatal error: gmp.h: No such file or directory
     #include <gmp.h>
              ^~~~~~~
    compilation terminated.
    error: command '/home/kimjungmin/anaconda3/envs/sage/bin/x86_64-conda_cos6-linux-gnu-cc' failed with exit status 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /home/kimjungmin/anaconda3/envs/sage/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-niky0gtn/fastecdsa/setup.py'"'"'; __file__='"'"'/tmp/pip-install-niky0gtn/fastecdsa/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-r_9fcsat/install-record.txt --single-version-externally-managed --compile Check the logs for full command output.

But I have gmp.h header in /home/kimjungmin/anaconda3/envs/sage/include

ironically, In base env, that command

$ pip install fastecdsa

is good works.

I don't know how I can found solution. please help.

Issues with getting fastecdsa working in Windows

There are some issues getting the module working in Windows - I found fixes, but they aren't very elegant:

  • The Microsoft Visual C++ Compiler for Python 2.7 package doesn't seem to support C99 style variables, so I had to move all variable declarations to the start of functions.
  • Don't bother trying to get GMP working on Windows, just use MPIR instead.
  • If the MPIR library is compiled against a different runtime than fastecdsa (I used VS2015 for compiling MPIR and the previously mentioned VCC for Python 2.7 on fastecdsa), it will mysteriously crash after free()ing the buffer returned from mpz_get_str() - seems to be because memory allocators in different VC runtimes are sometimes incompatible. Changing the free to __gmp_default_free fixed this issue.

Could not import "keys"

Hello,

Just git clone the project, and no error while install it under Python3 but I can't run the first example, because of an import problem:

$ python3 fastecdsa.py
Traceback (most recent call last):
File "fastecdsa.py", line 1, in
from fastecdsa import keys, curve
File "/mnt/hgfs/Kali/Inso2019/fastecdsa.py", line 1, in
from fastecdsa import keys, curve
ImportError: cannot import name 'keys' from 'fastecdsa' (/mnt/hgfs/Kali/Inso2019/fastecdsa.py)

$ cat fastecdsa.py
from fastecdsa import keys, curve

generate a keypair (i.e. both keys) for curve P256

priv_key, pub_key = keys.gen_keypair(curve.P256)

generate a private key for curve P256

priv_key = keys.gen_private_key(curve.P256)

get the public key corresponding to the private key we just generated

pub_key = keys.get_public_key(priv_key, curve.P256)

From the past equivalent problem the advice was to move to more recent version than 1.1.2 I have clone the 1.7.1. Seems the issue doesn't gone.

What log or else would help you to understand what happened on my machine? (A up-to-date Linux Kali, Linux distribution derived from Debian)

Regards,

Phil

Point multiplication by negative factor is not correct

Simple verification with negative factor fails like shown:

#!/usr/bin/env python

from fastecdsa.curve import P256
from fastecdsa.point import Point

a = -1 * P256.G
b = (-1 % P256.q) * P256.G

assert(a == b)

As stated in StackExchange, the identity xP = (x+q)P should hold even for negative values.

I think that if all multiplications should be done modulus curve's q (but I don't know much about EC, so the fix could be broader).

sign_digest() and verify_digest()

I'm migrating from python-ecdsa to fastecdsa and missed those functions. They are used on a few occasions:

  1. When the message itself is shorter than the integer order 𝑛.
  2. When benchmarking the signing (but not hashing).
  3. When the hash function was done elsewhere. (e.g. When the message was in a Merkle tree format and the Merkle tree class returns a digest directly, not giving the tree itself for resource consideration since the tree is a GB in size).

:)

Implement point counting for curves

Implement point counting for arbitrary elliptic curves. Validate by computing and comparing to the published values for standardized curves. Start with Schoof C implementation, and if too slow move to SEA. Sub-tasks -

  • Implement computation of Frobenius trace mod small primes in GMP C
  • Implement CRT using GMP C (or investigate if iterative is better as we compute Frobenius trace mod small primes)
  • Consolidate into algorithm and expose to python via C extension

Computational Complexity

Hey, rather than an issue with your code I had a question. You note that you're using Montgomery reduction to achieve a better performance. However, I can't seem to find what exact form of it you are using. Could you comment on this, in terms of multiplication, what is the computational complexity. Thus how many multiplications still take place?

Next, it seems that the signing procedure is a bit slower than verification for secp256k1. Based on how ecdsa works, one would expect that it would be the other way around. Could you comment on how this is achieved?

Thanks in advance!

ECDSA verification fails for extreme value in k and s^-1 (P-256, SHA-256)

Hello,

When verifying a ECDSA signature (P-256, SHA-256) with a extreme value in k and s^-1, the verification fails even if the signature is correct. It is possible to check this using the Google Wycheproof test 345 (https://github.com/google/wycheproof/blob/master/testvectors/ecdsa_secp256r1_sha256_test.json):

{
      "key" : {
        "curve" : "secp256r1",
        "keySize" : 256,
        "type" : "EcPublicKey",
        "uncompressed" : "04c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e",
        "wx" : "00c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107",
        "wy" : "00bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e"
      },
      "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e",
      "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExqdxUnAkIneSFwpvju5zW/Mrf5iv\nZp6tKZgC4y18MQe8O0teZauIe700NXKz5WGSYf46Bz4v/XhBL3JoZ9tYng==\n-----END PUBLIC KEY-----",
      "sha" : "SHA-256",
      "type" : "EcdsaVerify",
      "tests" : [
        {
          "tcId" : 345,
          "comment" : "extreme value for k and s^-1",
          "msg" : "313233343030",
          "sig" : "304502207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978022100b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc",
          "result" : "valid",
          "flags" : []
        }
      ]
    },

I've added a PoC using fast-ecdsa and python-cryptography (below).

#!/usr/bin/env python3

"""
$ python3 -m pip freeze | grep -i fastecdsa
fastecdsa==2.1.1
$ python3
Python 3.7.3 (default, Oct  7 2019, 12:56:13) 
[GCC 8.3.0] on linux
"""

from fastecdsa import keys, curve, ecdsa
from fastecdsa.curve import P256
from fastecdsa.encoding.sec1 import SEC1Encoder
from fastecdsa.encoding.der import DEREncoder

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric import utils

from hashlib import sha256

import json
import sys
import binascii

def import_key_string(key_str: str, curve= P256, public: bool = False, decoder=SEC1Encoder):
    data = bytearray.fromhex(key_str)

    if public:
        return decoder.decode_public_key(data, curve)
    else:
        return decoder.decode_private_key(data)

"""
{
      "key" : {
        "curve" : "secp256r1",
        "keySize" : 256,
        "type" : "EcPublicKey",
        "uncompressed" : "04c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e",
        "wx" : "00c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107",
        "wy" : "00bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e"
      },
      "keyDer" : "3059301306072a8648ce3d020106082a8648ce3d03010703420004c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e",
      "keyPem" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExqdxUnAkIneSFwpvju5zW/Mrf5iv\nZp6tKZgC4y18MQe8O0teZauIe700NXKz5WGSYf46Bz4v/XhBL3JoZ9tYng==\n-----END PUBLIC KEY-----",
      "sha" : "SHA-256",
      "type" : "EcdsaVerify",
      "tests" : [
        {
          "tcId" : 345,
          "comment" : "extreme value for k and s^-1",
          "msg" : "313233343030",
          "sig" : "304502207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978022100b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc",
          "result" : "valid",
          "flags" : []
        }
      ]
    },

"""

### using fast-ecdsa

public_key = import_key_string("04c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e", curve=P256, public=True, decoder=SEC1Encoder)
decoded_r, decoded_s = DEREncoder.decode_signature(bytearray.fromhex("304502207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978022100b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc"))
msg = bytearray.fromhex("313233343030")

valid = ecdsa.verify((decoded_r, decoded_s), msg, public_key)

print("Result fast-ecdsa:", valid)

### using python cryptography 

curve = ec.SECP256R1()
algo = ec.ECDSA(hashes.SHA256())

pubnum = ec.EllipticCurvePublicNumbers(
    int("00c6a771527024227792170a6f8eee735bf32b7f98af669ead299802e32d7c3107", 16), int("00bc3b4b5e65ab887bbd343572b3e5619261fe3a073e2ffd78412f726867db589e", 16), curve)

data = bytes(bytearray.fromhex("313233343030"))

public_key = pubnum.public_key(default_backend())
signature = bytes(bytearray.fromhex("304502207cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978022100b6db6db6249249254924924924924924625bd7a09bec4ca81bcdd9f8fd6b63cc"))
 
try:
  public_key.verify(signature, data, ec.ECDSA(hashes.SHA256()))

except cryptography.exceptions.InvalidSignature:
  print("Result fast-ecdsa:", "False")
else:
  print("Result cryptography.io:", "True")

Best regards,
Antonio

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.