btclib-ecc¶
Elliptic curve arithmetic, and the signature, key-agreement and commitment schemes built on it, in typed Python.
It is fully annotated and ships py.typed.
What is here¶
modular arithmetic: inverse, blinded and variable-time, Legendre symbol, square root (
number_theory)the elliptic curve class, over any curve in short Weierstrass form
Jacobian coordinates, and the secp256k1 endomorphism
double and multi scalar multiplication (Straus’s algorithm and Bos-Coster’s)
SEC 1 octet encodings of points and scalars
the SEC 2 v1 and v2, NIST and Brainpool curves, and low cardinality test curves
ECDSA, with DER encoding, public key recovery, low-R grinding and RFC 6979 deterministic nonces
BIP340 Schnorr signatures, and their batch verification
the anti-exfil protocol, and the sign-to-contract commitment it rests on, for both signature schemes
MuSig2 multi-signatures and FROST (draft BIP445) threshold signatures, one primitive per round of each protocol
Diffie-Hellman, and the BIP324 ElligatorSwift encoding of a public key
BIP374 discrete logarithm equality proofs
ECIES in the BIE1 layout, the block cipher supplied by the caller
Pedersen commitments, Borromean ring signatures and the range proofs of libsecp256k1-zkp
the ANSI X9.63 key derivation function and HKDF (
kdf), and the BIP340 tagged hash (hashes)
For secp256k1 the arithmetic is delegated to
btclib-secp256k1,
bindings to Bitcoin Core’s
libsecp256k1, wherever a
call’s own guard admits them. They are the secp256k1 extra below.
Without them, or with the delegation turned off, every call still
answers, on the Python arithmetic, which is slower and not constant-time;
that Python arithmetic serves every other curve anyway, and the suite
validates it against the bindings.
SECURITY.md’s “Limitations, not vulnerabilities” states
which calls delegate and what the Python path does and does not hide.
The suite answers to vectors their authors publish – the BIPs’ own, Wycheproof’s and libsecp256k1-zkp’s – and tests/_data/README.md pins each vendored file to the upstream commit it was copied from.
Installing¶
python -m pip install --upgrade "btclib-ecc[secp256k1]"
The secp256k1 extra installs the
libsecp256k1 bindings.
The quotes are for zsh, which reads the brackets as a glob.
First use¶
An ECDSA signature, verified from the DER octets a peer would send, and a BIP340 Schnorr signature:
from btclib_ecc.curves import sec_point
from btclib_ecc.ecc import dsa, ssa
prv_key = 0xB7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF
_, pub_key = dsa.gen_keys(prv_key)
assert sec_point.bytes_from_point(pub_key).hex() == (
"02dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659"
)
sig = dsa.sign(b"hello", prv_key)
assert dsa.verify(b"hello", pub_key, sig.serialize())
assert not dsa.verify(b"HELLO", pub_key, sig.serialize())
msg = bytes.fromhex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
_, x_pub_key = ssa.gen_keys(prv_key)
assert x_pub_key == int(
"DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", 16
)
assert ssa.verify_(msg, x_pub_key, ssa.sign_(msg, prv_key))
The private key and the message are test vector 1 of
BIP340,
and tests/readme_test.py runs every Python block of this file.
Security¶
SECURITY.md says how to report a vulnerability, which versions are supported, and how a published file is traced back to the run that built it. ASSURANCE_CASE.md argues why the security it states holds: the threat model, the trust boundaries, the design principles and the weaknesses countered.
Contributing¶
CONTRIBUTING.md has the commands each CI job runs,
verbatim. uv sync creates the environment; uv is the only tool that has
to be installed. REVIEWING.md is what a pull request is
answered against.
How the organization decides, and who holds which role, is its GOVERNANCE.md; what it intends to do, and what it deliberately does not, is its ROADMAP.md.
Links¶
Documentation: https://btclib-ecc.readthedocs.io/
CHANGELOG.md, and RELEASE_NOTES.md for what a release asks a user to act on
The btclib organization and its projects are actively supported by DGI and CheckSig.