Skip to main content

Fast elliptic curve digital signatures

Project description

PyPI Travis CI Documentation Status

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

fastecdsa.curve.P192

NIST / NSA

P224 / secp224r1

fastecdsa.curve.P224

NIST / NSA

P256 / secp256r1

fastecdsa.curve.P256

NIST / NSA

P384 / secp384r1

fastecdsa.curve.P384

NIST / NSA

P521 / secp521r1

fastecdsa.curve.P521

NIST / NSA

secp192k1

fastecdsa.curve.secp192k1

Certicom

secp224k1

fastecdsa.curve.secp224k1

Certicom

secp256k1 (bitcoin curve)

fastecdsa.curve.secp256k1

Certicom

brainpoolP160r1

fastecdsa.curve.brainpoolP160r1

BSI

brainpoolP192r1

fastecdsa.curve.brainpoolP192r1

BSI

brainpoolP224r1

fastecdsa.curve.brainpoolP224r1

BSI

brainpoolP256r1

fastecdsa.curve.brainpoolP256r1

BSI

brainpoolP320r1

fastecdsa.curve.brainpoolP320r1

BSI

brainpoolP384r1

fastecdsa.curve.brainpoolP384r1

BSI

brainpoolP512r1

fastecdsa.curve.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

fastecdsa time

ecdsa time

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 python3-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

  • akaIDIOT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastecdsa-2.3.2.tar.gz (47.7 kB view details)

Uploaded Source

Built Distributions

fastecdsa-2.3.2-cp312-cp312-macosx_14_0_arm64.whl (58.0 kB view details)

Uploaded CPython 3.12 macOS 14.0+ ARM64

fastecdsa-2.3.2-cp311-cp311-macosx_12_0_arm64.whl (57.9 kB view details)

Uploaded CPython 3.11 macOS 12.0+ ARM64

fastecdsa-2.3.2-cp310-cp310-macosx_12_0_arm64.whl (57.9 kB view details)

Uploaded CPython 3.10 macOS 12.0+ ARM64

fastecdsa-2.3.2-cp39-cp39-macosx_12_0_arm64.whl (57.9 kB view details)

Uploaded CPython 3.9 macOS 12.0+ ARM64

fastecdsa-2.3.2-cp38-cp38-macosx_12_0_arm64.whl (57.9 kB view details)

Uploaded CPython 3.8 macOS 12.0+ ARM64

fastecdsa-2.3.2-cp37-cp37m-macosx_12_0_arm64.whl (57.9 kB view details)

Uploaded CPython 3.7m macOS 12.0+ ARM64

File details

Details for the file fastecdsa-2.3.2.tar.gz.

File metadata

  • Download URL: fastecdsa-2.3.2.tar.gz
  • Upload date:
  • Size: 47.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.7

File hashes

Hashes for fastecdsa-2.3.2.tar.gz
Algorithm Hash digest
SHA256 f35255a6d3e41109166b5d4b08866d5acbb99f2e1e64d3a7e74c774664cda842
MD5 70173954f8949c0eac7ca062111912e0
BLAKE2b-256 fc21d5585856169c595d99a596dd8000afae40053f9f5c955d8ec8fb2ec3247c

See more details on using hashes here.

File details

Details for the file fastecdsa-2.3.2-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for fastecdsa-2.3.2-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 cc7189b971bc434b4145c9e7084e4970a0817623927a647b70fb162060baaea2
MD5 b7b7966dae1358bc9afd913a168139dd
BLAKE2b-256 1c7d37bf10fdcf600f4d2d0a3522cd67e1e821cd5a515211075facbf0d93b8dd

See more details on using hashes here.

File details

Details for the file fastecdsa-2.3.2-cp311-cp311-macosx_12_0_arm64.whl.

File metadata

File hashes

Hashes for fastecdsa-2.3.2-cp311-cp311-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 5ba5eb5b33d4b861731108d0ac6e544fcdbdc1ab095a5e86e68081ba5713c958
MD5 6165fe77959855cc59ec4d4fcb9cdb24
BLAKE2b-256 f0566146872b905d8394a9c0ca7c158e99e207dd0d92dffaa5e7d61a415ddf8f

See more details on using hashes here.

File details

Details for the file fastecdsa-2.3.2-cp310-cp310-macosx_12_0_arm64.whl.

File metadata

File hashes

Hashes for fastecdsa-2.3.2-cp310-cp310-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 138278b123b6c519f24fe9043d857e2f92c421c4fe256ac80d57404a38dc1326
MD5 5011cdfddd3e50297a3f66113ad199ac
BLAKE2b-256 7c0ab0e6dfcef078c35cab431e26c6236189a499e33482937a98418777c2063d

See more details on using hashes here.

File details

Details for the file fastecdsa-2.3.2-cp39-cp39-macosx_12_0_arm64.whl.

File metadata

File hashes

Hashes for fastecdsa-2.3.2-cp39-cp39-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 368f757403f191560d6e0757b8580a58c7b0b53d4db0fa8154b398c1de9f733d
MD5 5830cb289fbeb1a9c199ae2806cc85f2
BLAKE2b-256 d5cae7c897489c0fdf3b662fd3e9768ddb7c3abad99ed11887de75f5c748ff64

See more details on using hashes here.

File details

Details for the file fastecdsa-2.3.2-cp38-cp38-macosx_12_0_arm64.whl.

File metadata

File hashes

Hashes for fastecdsa-2.3.2-cp38-cp38-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 398448290a70bede54f1a8878e797865c40f359ca5840dd12fa33cab277b3b47
MD5 d9906c110367836566246b287ec521cf
BLAKE2b-256 bdce05fe86e97c408c91ccf73b56d07f37bc32c73a527bca163e015bb9594ec2

See more details on using hashes here.

File details

Details for the file fastecdsa-2.3.2-cp37-cp37m-macosx_12_0_arm64.whl.

File metadata

File hashes

Hashes for fastecdsa-2.3.2-cp37-cp37m-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 08deada741efb94691873d50c0002b2b826bc41459f0d427fbc1a791176e7c2d
MD5 ee4c38ec8e2cb9d94e55162d68b811e4
BLAKE2b-256 c30d5ce7fd93778fbb5b6279c1435919dda93ca2d9d9eb7792e8b575abee7672

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page