$ 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('rn', '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
I recieve this error everytime I try to install the blockstack-core. Running Ubuntu 16.04
Failed building wheel for fastecdsa
Running setup.py clean for fastecdsa
Failed to build fastecdsa
Installing collected packages: virtualchain, jsonpointer, jsonpatch, warlock, blockstack-profiles, fastecdsa, typing, urllib3, dropbox, blockstack
Found existing installation: virtualchain 0.14.0
Uninstalling virtualchain-0.14.0:
Exception:
Traceback (most recent call last):
File "/home/riley/.local/lib/python2.7/site-packages/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/home/riley/.local/lib/python2.7/site-packages/pip/commands/install.py", line 342, in run
prefix=options.prefix_path,
File "/home/riley/.local/lib/python2.7/site-packages/pip/req/req_set.py", line 778, in install
requirement.uninstall(auto_confirm=True)
File "/home/riley/.local/lib/python2.7/site-packages/pip/req/req_install.py", line 754, in uninstall
paths_to_remove.remove(auto_confirm)
File "/home/riley/.local/lib/python2.7/site-packages/pip/req/req_uninstall.py", line 115, in remove
renames(path, new_path)
File "/home/riley/.local/lib/python2.7/site-packages/pip/utils/__init__.py", line 267, in renames
shutil.move(old, new)
File "/usr/lib/python2.7/shutil.py", line 300, in move
rmtree(src)
File "/usr/lib/python2.7/shutil.py", line 252, in rmtree
onerror(os.remove, fullname, sys.exc_info())
File "/usr/lib/python2.7/shutil.py", line 250, in rmtree
os.remove(fullname)
OSError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/virtualchain-0.14.0.egg-info/not-zip-safe
I recieve this error everytime I try to install the blockstack-core. Running Ubuntu 16.04
Failed building wheel for fastecdsa
Running setup.py clean for fastecdsa
Failed to build fastecdsa
Installing collected packages: virtualchain, jsonpointer, jsonpatch, warlock, blockstack-profiles, fastecdsa, typing, urllib3, dropbox, blockstack
Found existing installation: virtualchain 0.14.0
Uninstalling virtualchain-0.14.0:
Exception:
Traceback (most recent call last):
File "/home/riley/.local/lib/python2.7/site-packages/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/home/riley/.local/lib/python2.7/site-packages/pip/commands/install.py", line 342, in run
prefix=options.prefix_path,
File "/home/riley/.local/lib/python2.7/site-packages/pip/req/req_set.py", line 778, in install
requirement.uninstall(auto_confirm=True)
File "/home/riley/.local/lib/python2.7/site-packages/pip/req/req_install.py", line 754, in uninstall
paths_to_remove.remove(auto_confirm)
File "/home/riley/.local/lib/python2.7/site-packages/pip/req/req_uninstall.py", line 115, in remove
renames(path, new_path)
File "/home/riley/.local/lib/python2.7/site-packages/pip/utils/__init__.py", line 267, in renames
shutil.move(old, new)
File "/usr/lib/python2.7/shutil.py", line 300, in move
rmtree(src)
File "/usr/lib/python2.7/shutil.py", line 252, in rmtree
onerror(os.remove, fullname, sys.exc_info())
File "/usr/lib/python2.7/shutil.py", line 250, in rmtree
os.remove(fullname)
OSError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/virtualchain-0.14.0.egg-info/not-zip-safe
Asked Oct 10 ’21 12:10
Rimann91
7 Answer:
Hey @Rimann91, thanks for reporting! Are you using sudo pip install
or just pip install
? You may need to do the former (unless you’re using a virtualenv).
1
Answered Feb 26 ’17 at 21:30
jcnelson
i am using a virtualenv and I use sudo on every install, thanks for the reply
1
Answered Feb 27 ’17 at 18:43
Rimann91
Are you able to install fastecdsa
by itself? e.g. with sudo pip install fastecdsa
. You may also need to install libgmp-dev
(with apt-get install
).
1
Answered Feb 27 ’17 at 19:13
jcnelson
Closing the issue from inactivity. If the problem persists, please re-open.
1
Answered Mar 20 ’17 at 22:50
jcnelson
This fixed the issue for me: export LDFLAGS="-L/usr/local/opt/openssl/lib -L /usr/local/opt/gmp/lib" && export CPPFLAGS="-I/usr/local/opt/openssl/include -I/usr/local/opt/gmp/include"
1
Answered May 25 ’17 at 01:01
radprax
libgmp-dev
sudo apt-get install libgmp-dev
then
pip3 install fastecdsa
1
Answered Aug 11 ’21 at 15:08
Elliot-Cokie
libgmp-dev
sudo apt-get install libgmp-dev
then
pip3 install fastecdsa
Thanks for sharing, this worked <3
1
Answered Oct 01 ’21 at 04:48
gawd-coder
About
This is a python package for doing fast elliptic curve cryptography, specifically
digital signatures.
Security
There is no nonce reuse, no branching on secret material,
and all points are validated before any operations are performed on them. Timing side challenges
are mitigated via Montgomery point multiplication. Nonces are generated per RFC6979. The default
curve used throughout the package is P256 which provides 128 bits of security. If you require a
higher level of security you can specify the curve parameter in a method to use a curve over a
bigger field e.g. P384. All that being said, crypto is tricky and I’m not beyond making mistakes.
Please use a more established and reviewed library for security critical applications. Open an
issue or email me if you see any security issue or risk with this library.
Python Versions Supported
The initial release of this package was targeted at python2.7. Earlier versions may work but have
no guarantee of correctness or stability. As of release 1.2.1+ python3 is supported as well. Due to
python2’s EOL on January 1st 2020 release 2.x of this package only supports python3.5+.
Operating Systems Supported
This package is targeted at the Linux and MacOS operating systems. Due to the the dependency on
the GMP C library building this package on Windows is difficult and no official support or
distributions are provided for Windows OSes. See issue11 for what users have done to get things
building.
Supported Primitives
Curves over Prime Fields
Name |
Class |
Proposed By |
---|---|---|
P192 / secp192r1 |
|
NIST / NSA |
P224 / secp224r1 |
|
NIST / NSA |
P256 / secp256r1 |
|
NIST / NSA |
P384 / secp384r1 |
|
NIST / NSA |
P521 / secp521r1 |
|
NIST / NSA |
secp192k1 |
|
Certicom |
secp224k1 |
|
Certicom |
secp256k1 (bitcoin curve) |
|
Certicom |
brainpoolP160r1 |
|
BSI |
brainpoolP192r1 |
|
BSI |
brainpoolP224r1 |
|
BSI |
brainpoolP256r1 |
|
BSI |
brainpoolP320r1 |
|
BSI |
brainpoolP384r1 |
|
BSI |
brainpoolP512r1 |
|
BSI |
Arbitrary Curves
As of version 1.5.1 construction of arbitrary curves in Weierstrass form
(y^2 = x^3 + ax + b (mod p)
) is supported. I advise against using custom curves for any
security critical applications. It’s up to you to make sure that the parameters you pass here are
correct, no validation of the base point is done, and in general no sanity checks are done. Use
at your own risk.
from fastecdsa.curve import Curve
curve = Curve(
name, # (str): The name of the curve
p, # (long): The value of p in the curve equation.
a, # (long): The value of a in the curve equation.
b, # (long): The value of b in the curve equation.
q, # (long): The order of the base point of the curve.
gx, # (long): The x coordinate of the base point of the curve.
gy, # (long): The y coordinate of the base point of the curve.
oid # (str): The object identifier of the curve (optional).
)
Hash Functions
Any hash function in the hashlib
module (md5, sha1, sha224, sha256, sha384, sha512
)
will work, as will any hash function that implements the same interface / core functionality as the
those in hashlib
. For instance, if you wish to use SHA3 as the hash function the
pysha3
package will work with this library as long as it is at version >=1.0b1 (as previous
versions didn’t work with the hmac
module which is used in nonce generation). Note
that sha3_224, sha3_256, sha3_384, sha3_512
are all in hashlib
as of python3.6.
Performance
Curves over Prime Fields
Currently it does elliptic curve arithmetic significantly faster than the ecdsa
package. You can see the times for 1,000 signature and verification operations over
various curves below. These were run on an early 2014 MacBook Air with a 1.4 GHz Intel
Core i5.
Curve |
|
|
Speedup |
P192 |
3.62s |
1m35.49s |
~26x |
P224 |
4.50s |
2m13.42s |
~29x |
P256 |
6.15s |
2m52.43s |
~28x |
P384 |
12.11s |
6m21.01s |
~31x |
P521 |
22.21s |
11m39.53s |
~31x |
secp256k1 |
5.92s |
2m57.19s |
~30x |
Benchmarking
If you’d like to benchmark performance on your machine you can do so using the command:
$ python setup.py benchmark
This will use the timeit
module to benchmark 1000 signature and verification operations
for each curve supported by this package. Alternatively, if you have not cloned the repo but
have installed the package via e.g. pip
you can use the following command:
$ python -m fastecdsa.benchmark
Installing
You can use pip: $ pip install fastecdsa
or clone the repo and use
$ python setup.py install
. Note that you need to have a C compiler.
You also need to have GMP on your system as the underlying
C code in this package includes the gmp.h
header (and links against gmp
via the -lgmp
flag). You can install all dependencies as follows:
apt
$ sudo apt-get install python-dev libgmp3-dev
yum
$ sudo yum install python-devel gmp-devel
Usage
Generating Keys
You can use this package to generate keys if you like. Recall that private keys on elliptic curves
are integers, and public keys are points i.e. integer pairs.
from fastecdsa import keys, curve
"""The reason there are two ways to generate a keypair is that generating the public key requires
a point multiplication, which can be expensive. That means sometimes you may want to delay
generating the public key until it is actually needed."""
# 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)
Signing and Verifying
Some basic usage is shown below:
from fastecdsa import curve, ecdsa, keys
from hashlib import sha384
m = "a message to sign via ECDSA" # some message
''' use default curve and hash function (P256 and SHA2) '''
private_key = keys.gen_private_key(curve.P256)
public_key = keys.get_public_key(private_key, curve.P256)
# standard signature, returns two integers
r, s = ecdsa.sign(m, private_key)
# should return True as the signature we just generated is valid.
valid = ecdsa.verify((r, s), m, public_key)
''' specify a different hash function to use with ECDSA '''
r, s = ecdsa.sign(m, private_key, hashfunc=sha384)
valid = ecdsa.verify((r, s), m, public_key, hashfunc=sha384)
''' specify a different curve to use with ECDSA '''
private_key = keys.gen_private_key(curve.P224)
public_key = keys.get_public_key(private_key, curve.P224)
r, s = ecdsa.sign(m, private_key, curve=curve.P224)
valid = ecdsa.verify((r, s), m, public_key, curve=curve.P224)
''' using SHA3 via pysha3>=1.0b1 package '''
import sha3 # pip install [--user] pysha3==1.0b1
from hashlib import sha3_256
private_key, public_key = keys.gen_keypair(curve.P256)
r, s = ecdsa.sign(m, private_key, hashfunc=sha3_256)
valid = ecdsa.verify((r, s), m, public_key, hashfunc=sha3_256)
Arbitrary Elliptic Curve Arithmetic
The Point
class allows arbitrary arithmetic to be performed over curves. The two main
operations are point addition and point multiplication (by a scalar) which can be done via the
standard python operators (+
and *
respectively):
# example taken from the document below (section 4.3.2):
# https://koclab.cs.ucsb.edu/teaching/cren/docs/w02/nist-routines.pdf
from fastecdsa.curve import P256
from fastecdsa.point import Point
xs = 0xde2444bebc8d36e682edd27e0f271508617519b3221a8fa0b77cab3989da97c9
ys = 0xc093ae7ff36e5380fc01a5aad1e66659702de80f53cec576b6350b243042a256
S = Point(xs, ys, curve=P256)
xt = 0x55a8b00f8da1d44e62f6b3b25316212e39540dc861c89575bb8cf92e35e0986b
yt = 0x5421c3209c2d6c704835d82ac4c3dd90f61a8a52598b9e7ab656e9d8c8b24316
T = Point(xt, yt, curve=P256)
# Point Addition
R = S + T
# Point Subtraction: (xs, ys) - (xt, yt) = (xs, ys) + (xt, -yt)
R = S - T
# Point Doubling
R = S + S # produces the same value as the operation below
R = 2 * S # S * 2 works fine too i.e. order doesn't matter
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
Importing and Exporting Keys
You can also export keys as files, ASN.1 encoded and formatted per RFC5480 and RFC5915. Both
private keys and public keys can be exported as follows:
from fastecdsa.curve import P256
from fastecdsa.keys import export_key, gen_keypair
d, Q = gen_keypair(P256)
# save the private key to disk
export_key(d, curve=P256, filepath='/path/to/exported/p256.key')
# save the public key to disk
export_key(Q, curve=P256, filepath='/path/to/exported/p256.pub')
Keys stored in this format can also be imported. The import function will figure out if the key
is a public or private key and parse it accordingly:
from fastecdsa.keys import import_key
# if the file is a private key then parsed_d is a long and parsed_Q is a Point object
# if the file is a public key then parsed_d will be None
parsed_d, parsed_Q = import_key('/path/to/file.key')
Other encoding formats can also be specified, such as SEC1 for public keys. This is done using
classes found in the fastecdsa.encoding
package, and passing them as keyword args to
the key functions:
from fastecdsa.curve import P256
from fastecdsa.encoding.sec1 import SEC1Encoder
from fastecdsa.keys import export_key, gen_keypair, import_key
_, Q = gen_keypair(P256)
export_key(Q, curve=P256, filepath='/path/to/p256.key', encoder=SEC1Encoder)
parsed_Q = import_key('/path/to/p256.key', curve=P256, public=True, decoder=SEC1Encoder)
Encoding Signatures
DER encoding of ECDSA signatures as defined in RFC2459 is also supported. The
fastecdsa.encoding.der
provides the DEREncoder
class which encodes signatures:
from fastecdsa.encoding.der import DEREncoder
r, s = 0xdeadc0de, 0xbadc0de
encoded = DEREncoder.encode_signature(r, s)
decoded_r, decoded_s = DEREncoder.decode_signature(encoded)
Acknowledgements
Thanks to those below for contributing improvements:
-
boneyard93501
-
clouds56
-
m-kus
-
sirk390
-
targon
-
NotStatilko
-
bbbrumley
-
luinxz
-
JJChiDguez
-
J08nY
-
trevor-crypto
-
sylvainpelissier
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 frommpz_get_str()
— seems to be because memory allocators in different VC runtimes are sometimes incompatible. Changing thefree
to__gmp_default_free
fixed this issue.
Yes, I suppose it’s not explicitly stated in the README (which it probably should be), but the package isn’t written with Windows in mind as one of the target OSes. This is precisely because compiling the C extensions on Windows is a major pain, the main issues which you’ve touched on already (installing GMP on Windows is a nightmare and the C compiler for Python isn’t anything to write home about either).
Does MPIR expose the same functions / interface that GMP does or did you have to rewrite all the GMP library calls to MPIR calls?
MPIR was basically a drop-in replacement — just have to rename mpir.h
to gmp.h
and mpir.lib
to gmp.lib
in when you place them in your include/lib directories.
Understood. I can try to see if I can make the configuration / setup process play nice with Windows, but I can’t promise any results. Ideally it would be nice to be able to just pip install fastecdsa
on Windows without any further hassle but that seems a bit unrealistic given my experience writing packages for Windows. I’ll keep the issue open until a satisfactory resolution is arrived at.
I try this steps:
-
Download from http://www.mpir.org/downloads.html MPIR-2.6.0.source.bz2, unpack to MPIR-2.6.0
-
Download from http://yasm.tortall.net/Download.html Win32 .exe (for general use on 32-bit Windows) (Not shure it needed)
rename it to yasm.exe and put to
C:Users%username%AppDataLocalProgramsCommonMicrosoftVisual C++ for Python9.0VCbin -
Run cmd.exe, cd to unpacked MPIR-2.6.0 dir
-
run «C:Users%username%AppDataLocalProgramsCommonMicrosoftVisual C++ for Python9.0vcvarsall.bat»
so set Visual C++ for Python9.0 compiler -
cd to unpacked MPIR-2.6.0win dir
-
edit configure.bat
addset ABI=32
set VCTARGET=x86between :exitlp
and :: ARCH is native ABI
save and run configure.bat -
run make.bat
no errors/warnings -
/optional/ run make.bat check -> OK
(make tune and make speed fails) -
run gen_mpir_h.bat
-
copy MPIR-2.6.0gmp.h to C:Users%username%AppDataLocalProgramsCommonMicrosoftVisual C++ for Python9.0VCincludegmp.h
copy(whith rename) MPIR-2.6.0winmpir.lib C:Users%username%AppDataLocalProgramsCommonMicrosoftVisual C++ for Python9.0VClibgmp.lib
Well, first part done
as ymgve say,
I had to move all variable declarations to the start of functions
after this process
python setup.py build -> builded OK, but have linker «warning LNK4098: defaultlib ‘LIBCMT’ conflicts with use of other libs; use /NODEFAULTLIB:library»
python setup.py install
check at my project. It works!
Able to build and install but something is still going wrong —
$ python setup.py build $ python setup.py install $ python setup.py test running test Traceback (most recent call last): File "C:Python27librunpy.py", line 174, in _run_module_as_main "__main__", fname, loader, pkg_name) File "C:Python27librunpy.py", line 72, in _run_code exec code in run_globals File "C:UsersADesktopfastecdsafastecdsatest.py", line 13, in <module> from .ecdsa import sign, verify File "fastecdsaecdsa.py", line 4, in <module> from fastecdsa import _ecdsa ImportError: DLL load failed: The specified module could not be found.
Continuing to investigate… (as you can probably tell I don’t do much development on the Windows platform so if I’m missing something obvious please let me know)
Probably, «setup.py install» doesn’t pack _ecdsa.pyd to egg file or egg file not yet in Libsite-packages
I will try to reproduce steps at fresh windows install to refresh my memory
I’m getting the .pyd
files in the install, and indeed ipython recognizes that e.g. curvemath
is an importable module, but when I try to import it the DLL load fails. I presume this is because it correctly sees that there is no underlying DLL for curvemath
or _ecdsa
. I have .exp
and .lib
and .obj
files but I seem to be missing the bin/
folder that would hold the DLLs.
As I checkout my working machine, _ecdsa.dll not used at all. I have this file only at build dir and after removing this folder, scripts works as usual.
If I remove ecdsa.pyd from Libsite-packagesfastecdsa-1.6.4-py2.7-win32.egg (7zip helps) scripts fails with
File «d:Python27libsite-packagespkg_resources_init.py», line 1883, in
_extract_resource
timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
KeyError: ‘fastecdsa_ecdsa.pyd’
So, it looks like .dll have to be converted to .pyd and .pyd packed to egg
I had the same error. To fix it, just put mpir.dll
from MPIR-Binary-masterdllx64Release
in to the directory of package, C:Python37Libsite-packagesfastecdsa
Here is somthing interesting — I have not directory of package, .Libsite-packagesfastecdsa just egg file in .Libsite-packages
Different python build/install systems? How to check it?
Also, no mpir.dll at my machine at all. Have mpir.lib at MPIR build dir copyed to VClibgmp.lib
Attached file is build log from scratch. But, from working machine, were exist working fastecdsa pack
build.log
Here is somthing interesting — I have not directory of package, .Libsite-packagesfastecdsa just egg file in .Libsite-packages
Different python build/install systems? How to check it?
Also, no mpir.dll at my machine at all. Have mpir.lib at MPIR build dir copyed to VClibgmp.lib
Attached file is build log from scratch. But, from working machine, were exist working fastecdsa pack
build.log
You can just copy fastecdsa
from egg directory to site-packages
. Also I dont know about python 2.7. I’ve tested on 3+ only. My steps were:
copy gmp.h
to C:Program Files (x86)Microsoft Visual Studio 14.0VCinclude
copy mpir.lib
to package directory, it could be C:Python37Libsite-packagesfastecdsa
or C:Python37Libsite-packagesfastecdsa-1.6.5-py3.7-win-amd64.eggfastecdsa
Hello, I encountered same problem, but solved.
I generate gmp.h, gmp.lib, gmp.def and gmp.dll from GMP.
I check what’s name of DLL lack by DependencyWalker.
So I copy libgmp-10.dll
from gmp.dll
.
You need to have an microsoft visual 2019 and Microsoft c++ in visual studio
to run the fastedcsa. You cannot install it without Microsoft c++. after that follow this instruction.
- Download https://github.com/ChillMagic/MPIR-Binary
- Download https://github.com/AntonKueltz/fastecdsa
- rename mpir.h to gmp.h from MPIR-Binary-masterinclude and rename mpir.lib to gmp.lib from MPIR-Binary-masterlibMDx64Release
- Copy and paste gmp.lib C:Program Files (x86)Microsoft Visual Studio2019BuildToolsVCToolsMSVC14.21.27702libx64
- Copy and paste gmp.h C:Phyton3include
- I don’t remember if I do this ( just put mpir.dll from MPIR-Binary-masterdllx64Release in to the directory of package, C:Python37Libsite-packagesfastecdsa ) Do it last if you have error. if not working try to rename it again to gmp.dll But I guess it’s not needed to install fastedcsa.
- Open CMD and cd to where you put your fastecdsa E:Downloadfastecdsa-master
- when your cmd is in the directory type: python setup.py build
- after installation type again: python setup.py install
- Good Luck treasure hunting.
Per @naphy0’s suggestion, i’ve (probably) gotten a build fully working by doing the following steps:
- Install Visual Studio 2019 buildtools, and adding the C++ suite from the main menu.
- Downloading MPIR-Library, and adding
include/**
to$pyinstall/include
, andlib/MD/win32/Release
to$pyinstall/libs
- Add
extra_link_args=["/NODEFAULTLIB:MSVCRT"]
to every extension object insetup.py
(since the linker was complaining about it) - Drink some coffee while running
python setup.py build
- Watch intensely while running
python setup.py test
And all of that resulted into a successful test.
Ran 32 tests in 9.355s
OK
I pushed a commit to my fork that has the prerequisites all ready for a windows build, the only thing that needs to be installed is buildtools from here, under «Tools for Visual Studio 2019». (plus the C++ build tools)
ShadowJonathan@041d9f4
If any contributor from here can please pull on a windows machine, build, and confirm the library works as intended, please let me know. This library is required in libp2p, and currently any windows build will fail because of a fastecdsa
win32 wheel missing from the pypi repo (see libp2p/py-libp2p#363).
Im currently on travel but will verify on my Windows VM as soon as I am able. Thanks for your work toward getting this package building on Windows!
I’ve also been poking around looking at automated wheel builds for windows in general, this setup has worked on my normal desktop computer (due to some other options not wanting to work before), so I am not 100% sure either about this configuration working all the time, nor if the produced library is stable enough for use.
Thanks for your work toward getting this package building on Windows!
No problem!
I’ve confirmed that building it like this only works with 32-bits python installs, anything 64-bit (amd64
) fails while spitting this:
...
curveMath.c
src/curveMath.c(81): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
src/curveMath.c(115): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
src/curveMath.c(116): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
...
Creating library buildtemp.win-amd64-3.8Releasesrccurvemath.cp38-win_amd64.lib and object buildtemp.win-amd64-3.8Releasesrccurvemath.cp38-win_amd64.exp
gmp.lib(mulmod_2expm1.obj) : error LNK2001: unresolved external symbol __security_check_cookie
gmp.lib(mulmid.obj) : error LNK2001: unresolved external symbol __security_check_cookie
gmp.lib(mulmid_n.obj) : error LNK2001: unresolved external symbol __security_check_cookie
gmp.lib(toom42_mulmid.obj) : error LNK2001: unresolved external symbol __security_check_cookie
gmp.lib(mulmod_2expp1.obj) : error LNK2001: unresolved external symbol __security_check_cookie
gmp.lib(inv_divappr_q_n.obj) : error LNK2001: unresolved external symbol __security_check_cookie
gmp.lib(dc_divappr_q.obj) : error LNK2001: unresolved external symbol __security_check_cookie
gmp.lib(hgcd_appr.obj) : error LNK2001: unresolved external symbol __security_check_cookie
gmp.lib(dc_bdiv_q.obj) : error LNK2001: unresolved external symbol __security_check_cookie
gmp.lib(hgcd_step.obj) : error LNK2001: unresolved external symbol __security_check_cookie
(etc.)
(this is after adding extra libraries under lib/MD/x64
and placing their folders first)