Package: fastecdsa
ContentsAboutSecurityPython Versions SupportedOperating Systems SupportedSupported PrimitivesCurves over Prime FieldsArbitrary CurvesHash FunctionsPerformanceCurves over Prime FieldsBenchmarkingInstallingaptyumUsageGenerating KeysSigning and VerifyingArbitrary Elliptic Curve ArithmeticImporting and Exporting KeysEncoding SignaturesAcknowledgementsAboutThis is a python package for doing fast elliptic curve cryptography, specifically
digital signatures.SecurityThere 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 perRFC6979. 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 SupportedThe 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 SupportedThis 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. Seeissue11for what users have done to get things
building.Supported PrimitivesCurves over Prime FieldsNameClassProposed ByP192 / secp192r1fastecdsa.curve.P192NIST / NSAP224 / secp224r1fastecdsa.curve.P224NIST / NSAP256 / secp256r1fastecdsa.curve.P256NIST / NSAP384 / secp384r1fastecdsa.curve.P384NIST / NSAP521 / secp521r1fastecdsa.curve.P521NIST / NSAsecp192k1fastecdsa.curve.secp192k1Certicomsecp224k1fastecdsa.curve.secp224k1Certicomsecp256k1 (bitcoin curve)fastecdsa.curve.secp256k1CerticombrainpoolP160r1fastecdsa.curve.brainpoolP160r1BSIbrainpoolP192r1fastecdsa.curve.brainpoolP192r1BSIbrainpoolP224r1fastecdsa.curve.brainpoolP224r1BSIbrainpoolP256r1fastecdsa.curve.brainpoolP256r1BSIbrainpoolP320r1fastecdsa.curve.brainpoolP320r1BSIbrainpoolP384r1fastecdsa.curve.brainpoolP384r1BSIbrainpoolP512r1fastecdsa.curve.brainpoolP512r1BSIArbitrary CurvesAs 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.fromfastecdsa.curveimportCurvecurve=Curve(name,# (str): The name of the curvep,# (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 FunctionsAny hash function in thehashlibmodule (md5, sha1, sha224, sha256, sha384, sha512)
will work, as will any hash function that implements the same interface / core functionality as the
those inhashlib. For instance, if you wish to use SHA3 as the hash function thepysha3package will work with this library as long as it is at version >=1.0b1 (as previous
versions didn’t work with thehmacmodule which is used in nonce generation). Note
thatsha3_224, sha3_256, sha3_384, sha3_512are all inhashlibas of python3.6.PerformanceCurves over Prime FieldsCurrently it does elliptic curve arithmetic significantly faster than theecdsapackage. 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.CurvefastecdsatimeecdsatimeSpeedupP1923.62s1m35.49s~26xP2244.50s2m13.42s~29xP2566.15s2m52.43s~28xP38412.11s6m21.01s~31xP52122.21s11m39.53s~31xsecp256k15.92s2m57.19s~30xBenchmarkingIf you’d like to benchmark performance on your machine you can do so using the command:$pythonsetup.pybenchmarkThis will use thetimeitmodule 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.pipyou can use the following command:$python-mfastecdsa.benchmarkInstallingYou can use pip:$ pip install fastecdsaor clone the repo and use$ python setup.py install. Note that you need to have a C compiler.
You  also need to haveGMPon your system as the underlying
C code in this package includes thegmp.hheader (and links against gmp
via the-lgmpflag). You can install all dependencies as follows:apt$sudoapt-getinstallpython3-devlibgmp3-devyum$sudoyuminstallpython-develgmp-develUsageGenerating KeysYou 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.fromfastecdsaimportkeys,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 P256priv_key,pub_key=keys.gen_keypair(curve.P256)# generate a private key for curve P256priv_key=keys.gen_private_key(curve.P256)# get the public key corresponding to the private key we just generatedpub_key=keys.get_public_key(priv_key,curve.P256)Signing and VerifyingSome basic usage is shown below:fromfastecdsaimportcurve,ecdsa,keysfromhashlibimportsha384m="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 integersr,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 '''importsha3# pip install [--user] pysha3==1.0b1fromhashlibimportsha3_256private_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 ArithmeticThePointclass 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.pdffromfastecdsa.curveimportP256fromfastecdsa.pointimportPointxs=0xde2444bebc8d36e682edd27e0f271508617519b3221a8fa0b77cab3989da97c9ys=0xc093ae7ff36e5380fc01a5aad1e66659702de80f53cec576b6350b243042a256S=Point(xs,ys,curve=P256)xt=0x55a8b00f8da1d44e62f6b3b25316212e39540dc861c89575bb8cf92e35e0986byt=0x5421c3209c2d6c704835d82ac4c3dd90f61a8a52598b9e7ab656e9d8c8b24316T=Point(xt,yt,curve=P256)# Point AdditionR=S+T# Point Subtraction: (xs, ys) - (xt, yt) = (xs, ys) + (xt, -yt)R=S-T# Point DoublingR=S+S# produces the same value as the operation belowR=2*S# S * 2 works fine too i.e. order doesn't matterd=0xc51e4753afdec1e6b6c6a5b992f43f8dd0c7a8933072708b6522468b2ffb06fd# Scalar MultiplicationR=d*S# S * d works fine too i.e. order doesn't mattere=0xd37f628ece72a462f0145cbefe3f0b355ee8332d37acdd83a358016aea029db7# Joint Scalar MultiplicationR=d*S+e*TImporting and Exporting KeysYou can also export keys as files, ASN.1 encoded and formatted perRFC5480andRFC5915. Both
private keys and public keys can be exported as follows:fromfastecdsa.curveimportP256fromfastecdsa.keysimportexport_key,gen_keypaird,Q=gen_keypair(P256)# save the private key to diskexport_key(d,curve=P256,filepath='/path/to/exported/p256.key')# save the public key to diskexport_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:fromfastecdsa.keysimportimport_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 Noneparsed_d,parsed_Q=import_key('/path/to/file.key')Other encoding formats can also be specified, such asSEC1for public keys. This is done using
classes found in thefastecdsa.encodingpackage, and passing them as keyword args to
the key functions:fromfastecdsa.curveimportP256fromfastecdsa.encoding.sec1importSEC1Encoderfromfastecdsa.keysimportexport_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 SignaturesDER encoding of ECDSA signatures as defined inRFC2459is also supported. Thefastecdsa.encoding.derprovides theDEREncoderclass which encodes signatures:fromfastecdsa.encoding.derimportDEREncoderr,s=0xdeadc0de,0xbadc0deencoded=DEREncoder.encode_signature(r,s)decoded_r,decoded_s=DEREncoder.decode_signature(encoded)AcknowledgementsThanks to those below for contributing improvements:boneyard93501clouds56m-kussirk390targonNotStatilkobbbrumleyluinxzJJChiDguezJ08nYtrevor-cryptosylvainpelissierakaIDIOT