fastecdsa

fastecdsa.curve

class fastecdsa.curve.Curve(name: str, p: int, a: int, b: int, q: int, gx: int, gy: int, oid: bytes | None = None)

Bases: object

Representation of an elliptic curve.

Defines a group with the arithmetic operations of point addition and scalar multiplication. Currently only curves defined via the equation \(y^2 \equiv x^3 + ax + b \pmod{p}\) are supported.

Attributes:
name (str): The name of the curve
p (int): The value of \(p\) in the curve equation.
a (int): The value of \(a\) in the curve equation.
b (int): The value of \(b\) in the curve equation.
q (int): The order of the base point of the curve.
oid (bytes): The object identifier of the curve.
property G: Point

The base point of the curve.

For the purposes of ECDSA this point is multiplied by a private key to obtain the corresponding public key. Make a property to avoid cyclic dependency of Point on Curve (a point lies on a curve) and Curve on Point (curves have a base point).

__init__(name: str, p: int, a: int, b: int, q: int, gx: int, gy: int, oid: bytes | None = None) None

Initialize the parameters of an elliptic curve.

WARNING: Do not generate your own parameters unless you know what you are doing or you could generate a curve severely less secure than you think. Even then, consider using a standardized curve for the sake of interoperability.

Currently only curves defined via the equation \(y^2 \equiv x^3 + ax + b \pmod{p}\) are supported.

Args:
name (string): The name of the curve
p (int): The value of \(p\) in the curve equation.
a (int): The value of \(a\) in the curve equation.
b (int): The value of \(b\) in the curve equation.
q (int): The order of the base point of the curve.
gx (int): The x coordinate of the base point of the curve.
gy (int): The y coordinate of the base point of the curve.
oid (bytes): The object identifier of the curve.
__repr__() str

Return repr(self).

__str__() str

Return str(self).

__weakref__

list of weak references to the object

evaluate(x: int) int

Evaluate the elliptic curve polynomial at ‘x’

Args:

x (int): The position to evaluate the polynomial at

Returns:

int: the value of \((x^3 + ax + b) \bmod{p}\)

classmethod get_curve_by_oid(oid: bytes) Curve | None

Get a curve via its object identifier.

Args:

oid (bytes): The object identifier for the curve.

Returns:

Curve | None: The curve corresponding to the object identifier. If the identifier does not correspond to a supported curve None is returned.

is_point_on_curve(point: Tuple[int, int]) bool

Check if a point lies on this curve.

The check is done by evaluating the curve equation \(y^2 \equiv x^3 + ax + b \pmod{p}\) at the given point \((x,y)\) with this curve’s domain parameters \((a, b, p)\). If the congruence holds, then the point lies on this curve.

Args:

point (int, int): A tuple representing the point \(P\) as an \((x, y)\) coordinate pair.

Returns:

bool: True if the point lies on this curve, otherwise False.

fastecdsa.ecdsa

exception fastecdsa.ecdsa.EcdsaError(msg: str)

Bases: Exception

fastecdsa.ecdsa.sign(msg: str | bytes | bytearray, d: int, curve: ~fastecdsa.curve.Curve = P256, hashfunc: ~typing.Callable[[~typing.Any], ~typing.Any] = <built-in function openssl_sha256>, prehashed: bool = False) Tuple[int, int]

Sign a message using the elliptic curve digital signature algorithm.

The elliptic curve signature algorithm is described in full in FIPS 186-4 Section 6. Please refer to http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf for more information.

Args:
msg (str|bytes|bytearray): A message to be signed.
d (int): The ECDSA private key of the signer.
curve (fastecdsa.curve.Curve): The curve to be used to sign the message.
hashfunc (Callable): The hash function used to compress the message.
prehashed (bool): The message being passed has already been hashed by hashfunc.
Returns:

(int, int): The signature (r, s) as a tuple.

fastecdsa.ecdsa.verify(sig: ~typing.Tuple[int, int], msg: str | bytes | bytearray, Q: ~fastecdsa.point.Point, curve: ~fastecdsa.curve.Curve = P256, hashfunc: ~typing.Callable[[~typing.Any], ~typing.Any] = <built-in function openssl_sha256>, prehashed: bool = False) bool

Verify a message signature using the elliptic curve digital signature algorithm.

The elliptic curve signature algorithm is described in full in FIPS 186-4 Section 6. Please refer to http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf for more information.

Args:
sig (int, int): The signature for the message.
msg (str|bytes|bytearray): A message to be signed.
Q (fastecdsa.point.Point): The ECDSA public key of the signer.
curve (fastecdsa.curve.Curve): The curve to be used to sign the message.
hashfunc (_hashlib.HASH): The hash function used to compress the message.
prehashed (bool): The message being passed has already been hashed by hashfunc.
Returns:

bool: True if the signature is valid, False otherwise.

Raises:
fastecdsa.ecdsa.EcdsaError: If the signature or public key are invalid. Invalid signature

in this case means that it has values less than 1 or greater than the curve order.

fastecdsa.encoding

class fastecdsa.encoding.KeyEncoder

Bases: ABC

Base class that any encoding class for EC keys should derive from.

class fastecdsa.encoding.SigEncoder

Bases: ABC

Base class that any encoding class for EC signatures should derive from.

All overriding methods should be static.

fastecdsa.encoding.der

class fastecdsa.encoding.der.DEREncoder

Bases: SigEncoder

static decode_signature(binary_data: bytes) Tuple[int, int]

Decode an EC signature from serialized DER format as described in https://tools.ietf.org/html/rfc2459 (section 7.2.2) and as detailed by bip-0066

Args:

binary_data (bytes): A sequence of bytes respresenting an ECDSA signature.

Returns (r,s)

static encode_signature(r: int, s: int) bytes
Encode an EC signature in serialized DER format as described in

https://tools.ietf.org/html/rfc2459 (section 7.2.2) and as detailed by bip-0066

Args:

r, s

Returns:

bytes: The DER encoded signature

exception fastecdsa.encoding.der.InvalidDerSignature

Bases: Exception

fastecdsa.encoding.pem

class fastecdsa.encoding.pem.PEMEncoder

Bases: KeyEncoder

decode_private_key(key: bytes) int

Decode a PEM encoded EC private key as described in RFC 5915.

Args:

key (bytes): A sequence of bytes representing an encoded EC key.

Returns:

int: The private key.

decode_public_key(key: bytes, curve: Curve) Point

Decode a PEM encoded public key as described in RFC 5480.

Args:

key (bytes): A sequence of bytes representing an encoded EC key.

Returns:

(long, fastecdsa.point.Point): A private key, public key tuple. If the encoded key was a public key the first entry in the tuple is None.

encode_private_key(d: int, curve: Curve) bytes

Encode a private EC key as described in RFC 5915.

Args:
d (int): An ECDSA private key.
curve (fastecdsa.curve.Curve): The curve that the private key is for.
Returns:

bytes: The ASCII armored encoded EC key.

encode_public_key(Q: Point) bytes

Encode an EC public key as described in RFC 5480.

Args:
Q (fastecdsa.point.Point): An ECDSA public key.
Returns:

bytes: The ASCII armored encoded EC public key.

exception fastecdsa.encoding.pem.PEMEncoderError(msg: str)

Bases: Exception

fastecdsa.encoding.sec1

exception fastecdsa.encoding.sec1.InvalidSEC1PublicKey

Bases: Exception

class fastecdsa.encoding.sec1.SEC1Encoder

Bases: KeyEncoder

decode_public_key(key: bytes, curve: Curve) Point
Decode a public key as described in http://www.secg.org/SEC1-Ver-1.0.pdf

in sections 2.3.3/2.3.4

uncompressed: 04 + x_bytes + y_bytes compressed: 02 or 03 + x_bytes

Args:

key (bytes): public key encoded using the SEC1 format curve (fastecdsa.curve.Curve): Curve to use when decoding the public key

Returns:

Point: The decoded public key

Raises:

InvalidSEC1PublicKey

encode_public_key(Q: Point, compressed: bool = True) bytes
Encode a public key as described in http://www.secg.org/SEC1-Ver-1.0.pdf
in sections 2.3.3/2.3.4

uncompressed: 04 + x_bytes + y_bytes compressed: 02 or 03 + x_bytes

Args:

Q (fastecdsa.point.Point): Public key to encode compressed (bool): Set to False if you want an uncompressed format

Returns:

bytes: The SEC1 encoded public key

fastecdsa.keys

fastecdsa.keys.export_private_key(key: int, curve: Curve, encoder: KeyEncoder, filepath: str | None = None) bytes | None

Export a private EC key using the given encoder.

Args:
key (int): A private EC key.
curve (fastecdsa.curve.Curve): The curve corresponding to the key.
encoder (fastecdsa.encoding.KeyEncoder): An instance of an encoder that can encode a private key.
filepath (str): Where to save the exported key. If None the key is simply printed.
Returns:

bytes | None: If no filepath is provided the bytes of the encoded key are returned.

fastecdsa.keys.export_public_key(key: Point, encoder: KeyEncoder, filepath: str | None = None) bytes | None

Export a private EC key using the given encoder.

Args:
key (fastecdsa.point.Point): A public EC key.
encoder (fastecdsa.encoding.KeyEncoder): An instance of an encoder that can encode a private key.
filepath (str): Where to save the exported key. If None the key is simply printed.
Returns:

bytes | None: If no filepath is provided the bytes of the encoded key are returned.

fastecdsa.keys.gen_keypair(curve: Curve) Tuple[int, Point]

Generate a keypair that consists of a private key and a public key.

The private key \(d\) is an integer generated via a cryptographically secure random number generator that lies in the range \([1,n)\), where \(n\) is the curve order. The public key \(Q\) is a point on the curve calculated as \(Q = dG\), where \(G\) is the curve’s base point.

Args:

curve (fastecdsa.curve.Curve): The curve over which the keypair will be calculated.

Returns:

(int, fastecdsa.point.Point): Returns a tuple with the private key first and public key second.

fastecdsa.keys.gen_private_key(curve: ~fastecdsa.curve.Curve, randfunc: ~typing.Callable[[~typing.Any], bytes] = <built-in function urandom>) int

Generate a private key to sign data with.

The private key \(d\) is an integer generated via a cryptographically secure random number generator that lies in the range \([1,n)\), where \(n\) is the curve order. The default random number generator used is /dev/urandom.

Args:
curve (fastecdsa.curve.Curve): The curve over which the key will be calculated.
randfunc (function): A function taking one argument ‘n’ and returning a bytestring of n random bytes suitable for cryptographic use. The default is “os.urandom”
Returns:

int: Returns a positive integer smaller than the curve order.

fastecdsa.keys.get_public_key(d: int, curve: Curve) Point

Generate a public key from a private key.

The public key \(Q\) is a point on the curve calculated as \(Q = dG\), where \(d\) is the private key and \(G\) is the curve’s base point.

Args:
d (long): An integer representing the private key.
curve (fastecdsa.curve.Curve): The curve over which the key will be calculated.
Returns:

fastecdsa.point.Point: The public key, a point on the given curve.

fastecdsa.keys.get_public_keys_from_sig(sig: Tuple[int, int], msg: str | bytes | bytearray, curve: Curve, hashfunc: Callable) Tuple[Point, Point]

Recover the public keys that can verify a signature / message pair.

Args:
sig (int, int): A ECDSA signature.
msg (str|bytes|bytearray): The message corresponding to the signature.
curve (fastecdsa.curve.Curve): The curve used to sign the message.
hashfunc (_hashlib.HASH): The hash function used to compress the message.
Returns:
(fastecdsa.point.Point, fastecdsa.point.Point): The public keys that can verify the

signature for the message.

fastecdsa.keys.import_private_key(filepath: str, decoder: KeyEncoder) int

Import a private EC key.

Args:
filepath (str): The location of the key file.
decoder (fastecdsa.encoding.KeyEncoder): The decoder used to parse the key.
Returns:

(int): A decoded private key.

fastecdsa.keys.import_public_key(filepath: str, curve: Curve, decoder: KeyEncoder) Point

Import a public EC key.

Args:
filepath (str): The location of the key file.
decoder (fastecdsa.encoding.KeyEncoder): The decoder used to parse the key.
Returns:

(fastecdsa.point.Point): A decoded public key.

fastecdsa.point

exception fastecdsa.point.CurveMismatchError(curve1: Curve, curve2: Curve)

Bases: Exception

__init__(curve1: Curve, curve2: Curve) None
__weakref__

list of weak references to the object

class fastecdsa.point.Point(x: int, y: int, curve: Curve)

Bases: object

Representation of a point on an elliptic curve.

Attributes:
x (int): The x coordinate of the point.
y (int): The y coordinate of the point.
curve (Curve): The curve that the point lies on.
__add__(other: Point) Point

Add two points on the same elliptic curve.

Args:
self (Point): a point \(P\) on the curve
other (Point): a point \(Q\) on the curve
Returns:

Point: A point \(R\) such that \(R = P + Q\)

__eq__(other: object) bool

Return self==value.

__hash__ = None
__init__(x: int, y: int, curve: Curve) None

Initialize a point on an elliptic curve.

The x and y parameters must satisfy the equation \(y^2 \equiv x^3 + ax + b \pmod{p}\), where a, b, and p are attributes of the curve parameter.

Args:
x (int): The x coordinate of the point.
y (int): The y coordinate of the point.
curve (Curve): The curve that the point lies on.
__mul__(scalar: int) Point

Multiply a Point on an elliptic curve by an integer.

Args:
self (Point): a point \(P\) on the curve
scalar (int): an integer \(d \in \mathbb{Z_q}\) where \(q\) is the order of the curve that \(P\) is on
Returns:

Point: A point \(R\) such that \(R = P * d\)

__neg__() Point

Return the negation of a Point i.e. the points reflection over the x-axis.

Args:
self (Point): a point \(P\) on the curve
Returns:

Point: A point \(R = (P_x, -P_y)\)

__repr__() str

Return repr(self).

__rmul__(scalar: int) Point

Multiply a Point on an elliptic curve by an integer.

Args:
self (Point): a point \(P\) on the curve
scalar (int): an integer \(d \in \mathbb{Z_q}\) where \(q\) is the order of the curve that \(P\) is on
Returns:

Point: A point \(R\) such that \(R = d * P\)

__str__() str

Return str(self).

__sub__(other: Point) Point

Subtract two points on the same elliptic curve.

Args:
self (Point): a point \(P\) on the curve
other (Point): a point \(Q\) on the curve
Returns:

Point: A point \(R\) such that \(R = P - Q\)

__weakref__

list of weak references to the object

fastecdsa.util

class fastecdsa.util.RFC6979(msg: str | bytes | bytearray, x: int, q: int, hashfunc: Callable, prehashed: bool = False)

Bases: object

Generate a nonce per RFC6979.

In order to avoid reusing a nonce with the same key when signing two different messages (which leaks the private key) RFC6979 provides a deterministic method for generating nonces. This is based on using a pseudo-random function (HMAC) to derive a nonce from the message and private key. More info here: http://tools.ietf.org/html/rfc6979.

Attributes:
msg (bytes): A message being signed.
x (int): An ECDSA private key.
q (int): The order of the generator point of the curve being used to sign the message.
hashfunc (_hashlib.HASH): The hash function used to compress the message.
prehashed (bool): Whether the signature is on a pre-hashed message.
gen_nonce() int

http://tools.ietf.org/html/rfc6979#section-3.2

fastecdsa.util.mod_sqrt(a: int, p: int) Tuple[int, int]

Compute the square root of \(a \pmod{p}\)

In other words, find a value \(x\) such that \(x^2 \equiv a \pmod{p}\).

Args:
a (int): The value whose root to take.
p (int): The prime whose field to perform the square root in.
Returns:

(int, int): the two values of \(x\) satisfying \(x^2 \equiv a \pmod{p}\).

fastecdsa.util.msg_bytes(msg: str | bytes | bytearray) bytes

Return bytes in a consistent way for a given message.

The message is expected to be either a string, bytes, or an array of bytes.

Args:
msg (str|bytes|bytearray): The data to transform.
Returns:

bytes: The byte encoded data.

Raises:

ValueError: If the data cannot be encoded as bytes.