Welcome to ECPy’s documentation!¶
Indices and tables¶
Status¶
- Version
1.0beta.
- Authors
Cedric Mesnil, <csalshm@gmail.com>
- License
Apache 2.0
Install¶
ECPy is originally coded for Python 3, but should run under python 2.7 by using future.
If you are running Python 2:
please install the future into the present:
pip install future
as python 2 is in ‘End Of Life’ status, consider to move your code to python 3, future release will may not support python 2.
Then install ECPy:
- From pypi (using pip or pip3)
pip install ECPy
- Rebuild from git clone:
python3 setup.py sdist
cd dist
tar xzvf ECPy-M.m.tar.gz
python3 setup install
- Install from dist package:
Download last dist tarball
tar xzvf ECPy-M.m.tar.gz
python3 setup.py install
Overview¶
ECPy (pronounced ekpy), is a pure python Elliptic Curve library. It provides ECDSA, EDDSA, ECSchnorr signature as well as Point operation.
ECDSA sample
from ecpy.curves import Curve,Point
from ecpy.keys import ECPublicKey, ECPrivateKey
from ecpy.ecdsa import ECDSA
cv = Curve.get_curve('secp256k1')
pu_key = ECPublicKey(Point(0x65d5b8bf9ab1801c9f168d4815994ad35f1dcb6ae6c7a1a303966b677b813b00,
0xe6b865e529b8ecbf71cf966e900477d49ced5846d7662dd2dd11ccd55c0aff7f,
cv))
pv_key = ECPrivateKey(0xfb26a4e75eec75544c0f44e937dcf5ee6355c7176600b9688c667e5c283b43c5,
cv)
signer = ECDSA()
sig = signer.sign(b'01234567890123456789012345678912',pv_key)
assert(signer.verify(b'01234567890123456789012345678912',sig,pu_key))
Point sample
from ecpy.curves import Curve,Point
cv = Curve.get_curve('secp256k1')
P = Point(0x65d5b8bf9ab1801c9f168d4815994ad35f1dcb6ae6c7a1a303966b677b813b00,
0xe6b865e529b8ecbf71cf966e900477d49ced5846d7662dd2dd11ccd55c0aff7f,
cv)
k = 0xfb26a4e75eec75544c0f44e937dcf5ee6355c7176600b9688c667e5c283b43c5
Q = k*P
R = P+Q
Supported Curves & Signature¶
- ECPy support the following curves
Short Weierstrass form: y²=x³+a*x+b
Twisted Edward form: a*x²+y2=1+d*x²*y²
Montgomery form: b.y²=x³+a*x²+x.
See pyec.Curve. get_curve_names
ECPy supports the following signature schemes:
ecdsa
eddsa
ecschnorr
Types¶
ECPY use binary bytes and int as primary types.
Other main types are Point
, Curve
, Key
, ECDSA
, EDDSA
, ECSchnorr
. Borromean
.
See API details…
API¶
curves module¶
Elliptic Curve and Point manipulation
-
class
ecpy.curves.
Curve
(parameters)[source]¶ Bases:
object
Elliptic Curve abstraction
You should not directly create such Object. Use get_curve to get the predefined curve or create a well-know type of curve with your parameters
- Supported well know elliptic curve are:
Short Weierstrass form: y²=x³+a*x+b
Twisted Edward a*x²+y2=1+d*x²*y²
Montgomery: b.y²=x³+a*x²+x.
-
b d
second curve parameter
- Type
-
add_point
(P, Q)[source]¶ Returns the sum of P and Q
- Parameters
- Returns
A new Point R = P+Q
- Return type
- Raises
ECPyException – with “Point not on curve”, if Point R is not on curve, thus meaning either P or Q was not on.
-
static
get_curve_names
()[source]¶ Returns all known curve names
- Returns
list of names as str
- Return type
-
is_on_curve
(P)[source]¶ Check if P is on this curve
This function ignores the default curve attach to P
-
mul_point
(k, P)[source]¶ Returns the scalar multiplication P with k.
This function ignores the default curve attach to P and Q, and assumes P and Q are on this curve.
- Parameters
- Returns
A new Point R = k*Q
- Return type
- Raises
ECPyException – with “Point not on curve”, if Point R is not
on curve, thus meaning P was not on. –
-
neg_point
(P)[source]¶ Returns R, R = -P.
- Parameters
P (Point) – point to mul_point
- Returns
A new Point R = -Q
- Return type
- Raises
ECPyException – with “Point not on curve”, if Point R is not
on curve, thus meaning P was not on. –
-
sub_point
(P, Q)[source]¶ Returns the difference of P and Q
- Parameters
- Returns
A new Point R = P-Q
- Return type
- Raises
ECPyException – with “Point not on curve”, if Point R is not on curve, thus meaning either P or Q was not on.
-
class
ecpy.curves.
MontgomeryCurve
(domain)[source]¶ Bases:
ecpy.curves.Curve
An elliptic curve defined by the equation: b.y²=x³+a*x²+x.
- The given domain must be a dictionary providing the following keys/values:
name (str) : curve unique name
size (int) : bit size
a (int) : a equation coefficient
b (int) : b equation coefficient
field (inf) : field value
generator (int[2]) : x,y coordinate of generator
order (int) : order of generator
Note: you should not use the constructor and only use
Curve.get_curve()
builder to ensure using supported curve.- Parameters
domain (dict) – a dictionary providing curve domain parameters
-
encode_point
(P)[source]¶ Encodes a point P according to RFC7748.
- Parameters
P – point to encode
- Returns
encoded point
- Return type
-
class
ecpy.curves.
Point
(x, y, curve, check=True)[source]¶ Bases:
object
Immutable Elliptic Curve Point.
A Point support the following operator:
- : Point Subtraction.
+ : Point Addition, with automatic doubling support.
* : Scalar multiplication, can write as k*P or P*k, with P :class:Point and k :class:int.
==: Point comparison.
- : Point negation (unary operator).
- Parameters
- Raises
ECPyException – if check=True and x,y is not on curve
-
static
infinity
()[source]¶ Return the unique (singleton) point at infinity
- Returns
infinity Point
- Return type
-
neg
()[source]¶ Return the opposite self point bycallinf Curve.neg function
- Returns
-self
- Return type
-
recover
(sign=0)[source]¶ Recvoer the missing corrdinate according to the know one and the provided sign of the missing one
- Parameters
sign (int) – zero or one
-
property
curve
Returned the curve on which this point is defined
- Returns
this point curve
- Return type
-
property
has_x
¶ Tell if this point has y coordinate
- Returns
Trueu if x coordinate is set, False else
-
property
has_y
¶ Tell if this point has y coordinate
- Returns
Trueu if y coordinate is set, False else
-
property
is_infinity
¶ Tell is this pointn is the inifinity one
- Returns
true if self is infinity
- Return type
-
property
is_on_curve
¶ ” Tells if this point is on the curve
- Returns
True if point on curve, False else
- Return type
-
property
x
X affine coordinate of this point
- Returns
x coordinate
- Raises
ECPyException – if point is infinity
ECPyException – if point has no x coordinate
-
property
y
Y affine coordinate of this point
- Returns
x coordinate
- Raises
ECPyException – if point is infinity
ECPyException – if point has no y coordinate
-
class
ecpy.curves.
TwistedEdwardCurve
(domain)[source]¶ Bases:
ecpy.curves.Curve
An elliptic curve defined by the equation: a*x²+y²=1+d*x²*y²
- The given domain must be a dictionary providing the following keys/values:
name (str) : curve unique name
size (int) : bit size
a (int) : a equation coefficient
d (int) : b equation coefficient
field (inf) : field value
generator (int[2]) : x,y coordinate of generator
order (int) : order of generator
Note: you should not use the constructor and only use
Curve.get_curve()
builder to ensure using supported curve.- Parameters
domain (dict) – a dictionary providing curve domain parameters
-
encode_point
(P)[source]¶ Encodes a point P according to draft_irtf-cfrg-eddsa-04.
- Parameters
P – point to encode
- Returns
encoded point
- Return type
-
class
ecpy.curves.
WeierstrassCurve
(domain)[source]¶ Bases:
ecpy.curves.Curve
An elliptic curve defined by the equation: y²=x³+a*x+b.
- The given domain must be a dictionary providing the following keys/values:
name (str) : curve unique name
size (int) : bit size
a (int) : a equation coefficient
b (int) : b equation coefficient
field (inf) : field value
generator (int[2]) : x,y coordinate of generator
order (int) : order of generator
cofactor (int) : cofactor
Note: you should not use the constructor and only use
Curve.get_curve()
builder to ensure using supported curve.- Parameters
domain (dict) – a dictionary providing curve parameters
-
encode_point
(P, compressed=False)[source]¶ Encodes a point P according to P1363-2000.
- Parameters
P – point to encode
- Returns
encoded point [04 | x | y] or [02 | x | sign]
- Return type
keys module¶
-
class
ecpy.keys.
ECPrivateKey
(d, curve)[source]¶ Bases:
object
Public EC key.
Can be used for both ECDSA and EDDSA signature
- Attributes
d (int) : private key scalar curve (Curve) : curve
ECDSA module¶
-
class
ecpy.ecdsa.
ECDSA
(fmt='DER')[source]¶ Bases:
object
ECDSA signer.
- Parameters
fmt (str) – in/out signature format. See
ecpy.formatters
-
sign
(msg, pv_key, canonical=False)[source]¶ Signs a message hash.
- Parameters
msg (bytes) – the message hash to sign
pv_key (ecpy.keys.ECPrivateKey) – key to use for signing
-
sign_k
(msg, pv_key, k, canonical=False)[source]¶ Signs a message hash with provided random
- Parameters
msg (bytes) – the hash of message to sign
pv_key (ecpy.keys.ECPrivateKey) – key to use for signing
k (ecpy.keys.ECPrivateKey) – random to use for signing
-
sign_rfc6979
(msg, pv_key, hasher, canonical=False)[source]¶ Signs a message hash according to RFC6979
- Parameters
msg (bytes) – the message hash to sign
pv_key (ecpy.keys.ECPrivateKey) – key to use for signing
hasher (hashlib) – hasher conform to hashlib interface
-
verify
(msg, sig, pu_key)[source]¶ Verifies a message signature.
- Parameters
msg (bytes) – the message hash to verify the signature
sig (bytes) – signature to verify
pu_key (ecpy.keys.ECPublicKey) – key to use for verifying
EDDSA module¶
-
class
ecpy.eddsa.
EDDSA
(hasher, hash_len=None, fmt='EDDSA')[source]¶ Bases:
object
EDDSA signer implemenation according to:
IETF draft-irtf-cfrg-eddsa-05.
- Parameters
hasher (hashlib) – callable constructor returning an object with update(), digest() interface. Example: hashlib.sha256, hashlib.sha512…
fmt (str) – in/out signature format. See
ecpy.formatters
.
-
static
get_public_key
(pv_key, hasher=<built-in function openssl_sha512>, hash_len=None)[source]¶ Returns the public key corresponding to this private key
This method compute the public key according to draft-irtf-cfrg-eddsa-05.
The hash parameter shall be the same as the one used for signing and verifying.
- Parameters
hasher (hashlib) – callable constructor returning an object with update(), digest() interface. Example: hashlib.sha256, hashlib.sha512…
pv_key (ecpy.keys.ECPrivateKey) – key to use for signing
- Returns
public key
- Return type
-
sign
(msg, pv_key)[source]¶ Signs a message.
- Parameters
msg (bytes) – the message to sign
pv_key (ecpy.keys.ECPrivateKey) – key to use for signing
-
verify
(msg, sig, pu_key)[source]¶ Verifies a message signature.
- Parameters
msg (bytes) – the message to verify the signature
sig (bytes) – signature to verify
pu_key (ecpy.keys.ECPublicKey) – key to use for verifying
ECSchnorr module¶
-
class
ecpy.ecschnorr.
ECSchnorr
(hasher, option='ISO', fmt='DER')[source]¶ Bases:
object
ECSchnorr signer implementation according to:
In order to select the specification to be conform to, choose the corresponding string option: “BSI”, “ISO”, “ISOx”, “LIBSECP”, “Z”
Signature:
- “BSI”: compute r,s according to to BSI :
k = RNG(1:n-1)
Q = [k]G
r = H(M ||Qx) If r = 0 mod n, goto 1.
s = k - r.d mod n If s = 0 goto 1.
Output (r, s)
- “ISO”: compute r,s according to ISO :
k = RNG(1:n-1)
Q = [k]G If r = 0 mod n, goto 1.
r = H(Qx||Qy||M).
s = (k + r.d) mod n If s = 0 goto 1.
Output (r, s)
- “ISOx”: compute r,s according to optimized ISO variant:
k = RNG(1:n-1)
Q = [k]G If r = 0 mod n, goto 1.
r = H(Qx||Qy||M).
s = (k + r.d) mod n If s = 0 goto 1.
Output (r, s)
- “LIBSECP”: compute r,s according to bitcoin lib:
k = RNG(1:n-1)
Q = [k]G if Qy is odd, negate k and goto 2
r = Qx % n
h = H(r || m). if h == 0 or h >= order goto 1
s = k - h.d.
Output (r, s)
- “Z”: compute r,s according to zilliqa lib:
Generate a random k from [1, …, order-1]
Compute the commitment Q = kG, where G is the base point
Compute the challenge r = H(Q, kpub, m) [CME: mod n according to pdf/code, Q and kpub compressed “02|03 x” according to code)
If r = 0 mod(order), goto 1
Compute s = k - r*kpriv mod(order)
If s = 0 goto 1.
Output (r, s)
Verification
- “BSI”: verify r,s according to to BSI :
Verify that r in {0, … , 2**t - 1} and s in {1, 2, … , n - 1}. If the check fails, output False and terminate.
Q = [s]G + [r]W If Q = 0, output Error and terminate.
v = H(M||Qx)
Output True if v = r, and False otherwise.
- “ISO”: verify r,s according to ISO :
check…
Q = [s]G - [r]W If Q = 0, output Error and terminate.
v = H(Qx||Qy||M).
Output True if v = r, and False otherwise.
- “ISOx”: verify r,s according to optimized ISO variant:
check…
Q = [s]G - [r]W If Q = 0, output Error and terminate.
v = H(Qx||M).
Output True if v = r, and False otherwise.
- “LIBSECP”:
Signature is invalid if s >= order. Signature is invalid if r >= p.
h = H(r || m). Signature is invalid if h == 0 or h >= order.
R = [h]Q + [s]G. Signature is invalid if R is infinity or R’s y coordinate is odd.
Signature is valid if the serialization of R’s x coordinate equals r.
- “Z”:
Check if r,s is in [1, …, order-1]
Compute Q = sG + r*kpub
If Q = O (the neutral point), return 0;
r’ = H(Q, kpub, m) [CME: mod n according to pdf/code, according to code), Q and kpub compressed “02|03 x”]
return r’ == r
Default is “ISO”
- Parameters
hasher (hashlib) – callable constructor returning an object with update(), digest() interface. Example: hashlib.sha256, hashlib.sha512…
option (str) – one of “BSI”,”ISO”,”ISOx”,”LIBSECP”
fmt (str) – in/out signature format. See
ecpy.formatters
-
sign
(msg, pv_key)[source]¶ Signs a message hash.
- Parameters
hash_msg (bytes) – the message hash to sign
pv_key (ecpy.keys.ECPrivateKey) – key to use for signing
-
sign_k
(msg, pv_key, k)[source]¶ Signs a message hash with provided random
- Parameters
hash_msg (bytes) – the message hash to sign
pv_key (ecpy.keys.ECPrivateKey) – key to use for signing
k (ecpy.keys.ECPrivateKey) – random to use for signing
-
verify
(msg, sig, pu_key)[source]¶ Verifies a message signature.
- Parameters
msg (bytes) – the message hash to verify the signature
sig (bytes) – signature to verify
pu_key (ecpy.keys.ECPublicKey) – key to use for verifying
Borromean module¶
-
class
ecpy.borromean.
Borromean
(fmt='BTUPLE')[source]¶ Bases:
object
Borromean Ring signer implementation according to:
https://github.com/Blockstream/borromean_paper/blob/master/borromean_draft_0.01_9ade1e49.pdf
ElementsProject implementation has some tweaks compared to PDF. This implementation is ElementsProject compliant.
For now, only secp256k1+sha256 is supported. This constraint will be release soon.
- Parameters
fmt (str) – in/out signature format. See
ecpy.formatters
. IGNORED.
-
sign
(msg, rings, pv_keys, pv_keys_index)[source]¶ Signs a message hash.
The public rings argument is a tuple of public key array. In other words each element of the ring tuple is an array containing the public keys list of that ring
A Private key must be given for each provided ring. For each private key, the corresponding public key is specified by its index in the ring.
- Exemple:
let r1 be the first ring with 2 keys: pu11, pu12 let 21 be the second ring with 3 keys: pu21,pu22,pu23 let say we want to produce a signature with sec12 and sec21 sign should be called as:
borromean.sign(m, ([pu11,pu12],[pu21,pu22,pu23]), [sec12, sec21], [1,0])
The return value is a tuple (e0, [s0,s1….]). Each value is encoded as binary (bytes).
- Parameters
msg (bytes) – the message hash to sign
rings (tuple of (ecpy.keys.ECPublicKey[]) – public key rings
pv_keys (ecpy.keys.ECPrivateKey[]) – key to use for signing
pv_keys_index (int[]) –
- Returns
signature
- Return type
(e0, [s0,s1….])
ecrand module¶
-
ecpy.ecrand.
rnd_rfc6979
(hashmsg, secret, q, hasher, V=None)[source]¶ Generates a deterministic value according to RF6979.
See https://tools.ietf.org/html/rfc6979#section-3.2
if V == None, this is the first try, so compute the initial value for V. Else it means the previous value has been rejected by the caller, so generate the next one!
Warning: the hashmsg parameter is the message hash, not the message itself. In other words, hashmsg is equal to h1 in the rfc6979, section-3.2, step a.
- Parameters
The function returns a couple (k,V) with k the expected value and V is the continuation value to pass to next cal if k is rejected.
- Returns
(k,V)
- Return type