btclib package

Submodules

btclib.alias module

Aliases

mypy aliases, documenting also coding imput conventions.

class btclib.alias.BIP32KeyDict

Bases: dict

btclib.amount module

Proper handling of monetary amounts.

Monetary amounts are expressed as number of satoshis in the Bitcoin Core client and this python library (e.g. 1 BTC is 100,000,000). Instead, monetary values are express as double-precision floats in the JSON API (e.g. 1 BTC is 1.00000000).

One needs to be aware of possible floating-point conversion issues: as example, with floats 1.1 + 2.2 != 3.3; algebra with bitcoin amounts should always be performed using satoshis.

The provided functions properly handle conversion between satoshi amounts and float monetary values.

btclib.amount.float_from_sat(amount: int) → float

Return the float monetary value equivalent of a satoshi amount.

btclib.amount.sat_from_float(value: float) → int

Return the satoshi amount equivalent of a float monetary value.

btclib.base58 module

Base58 encoding and decoding functions.

Binary-to-text encoding schemes are used to transport binary data across channels designed to deal with textual data. In Bitcoin they are mostly used to represent large integers as alphanumeric text.

Base58 is similar to Base64, which uses 10 digits, 26 lowercase characters, 26 uppercase characters, ‘+’ (plus sign), and ‘/’ (forward slash). Base58 omits the similar-looking letters 0 (zero), O (capital o), I (capital i), and l (lower case L) to avoid ambiguity when printed; moreover, it removes ‘+’ and ‘/’ so that a double-click does select the whole string.

Base58Check is the checksummed version of Base58, using hash256(v)[:4] as checksum suffix before encoding; at the decoding stage the checksum validity ensure data integrity.

This implementation of Base58 and Base58Check is originally from https://github.com/keis/base58, with the following modifications:

  • type annotated python3
  • using native python3 int.from_bytes() and i.to_bytes()
  • added optional check on output size for b58decode()
  • interface mimics the native python3 base64 interface, i.e. it supports encoding bytes-like objects to ASCII bytes, and decoding ASCII bytes-like objects or ASCII strings to bytes.
btclib.base58.b58decode(v: Union[bytes, str], out_size: Optional[int] = None) → bytes

Decode a Base58Check encoded bytes-like object or ASCII string.

Optionally, it also ensures required output size.

btclib.base58.b58encode(v: Union[bytes, str], in_size: Optional[int] = None) → bytes

Encode a bytes-like object using Base58Check.

btclib.base58address module

Base58 address functions.

Base58 encoding of public keys and scripts as addresses.

btclib.base58address.address_from_scriptPubKey(s: Union[bytes, str, List[Union[int, str, bytes]]], network: str = 'mainnet') → bytes

Return the bech32/base58 address from the input scriptPubKey.

btclib.base58address.b58address_from_h160(prefix: Union[bytes, str], h160: Union[bytes, str], network: str) → bytes

Encode a base58 address from the payload.

btclib.base58address.b58address_from_witness(wp: Union[bytes, str], network: str = 'mainnet') → bytes

Encode a legacy base58 p2sh-wrapped SegWit address.

btclib.base58address.h160_from_b58address(b58addr: Union[bytes, str]) → Tuple[bytes, bytes, str, bool]

Return the payload from a base58 address.

btclib.base58address.has_segwit_prefix(addr: Union[bytes, str]) → bool
btclib.base58address.p2pkh(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], network: Optional[str] = None, compressed: Optional[bool] = None) → bytes

Return the p2pkh base58 address corresponding to a public key.

btclib.base58address.p2sh(script: Union[bytes, str, List[Union[int, str, bytes]]], network: str = 'mainnet') → bytes

Return the p2sh base58 address corresponding to a script.

btclib.base58address.p2wpkh_p2sh(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], network: Optional[str] = None) → bytes

Return the p2wpkh-p2sh base58 address corresponding to a pubkey.

btclib.base58address.p2wsh_p2sh(wscript: Union[bytes, str, List[Union[int, str, bytes]]], network: str = 'mainnet') → bytes

Return the p2wsh-p2sh base58 address corresponding to a script.

btclib.base58address.scriptPubKey_from_address(addr: Union[bytes, str]) → Tuple[bytes, str]

Return (scriptPubKey, network) from the input bech32/base58 address

btclib.base58wif module

btclib.base58wif.wif_from_prvkey(prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], network: Optional[str] = None, compressed: Optional[bool] = None) → bytes

Return the WIF encoding of a private key.

btclib.bech32 module

Bech32 encoding and decoding functions.

BIP173: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki

This implementation of bech32 is originally from https://github.com/sipa/bech32/tree/master/ref/python, with the following modifications:

  • splitted the original segwit_addr.py file in bech32.py and segwitaddress.py
  • type annotated python3
  • avoided returning (None, None), throwing ValueError instead
  • removed the 90-chars limit for bech32 string, enforced by segwitaddr instead
  • detailed error messages
  • interface mimics the native python3 base64 interface, i.e. it supports encoding bytes-like objects to ASCII bytes, and decoding ASCII bytes-like objects or ASCII strings to bytes.
btclib.bech32.b32decode(bech: Union[bytes, str]) → Tuple[str, List[int]]

Validate a bech32 string, and determine HRP and data.

btclib.bech32.b32encode(hrp: str, data: List[int]) → bytes

Compute a bech32 string given HRP and data values.

btclib.bech32address module

SegWit address functions.

Some of these functions were originally from https://github.com/sipa/bech32/tree/master/ref/python, with the following modifications:

  • moved bech32 stuff into bech32.py
  • type annotated python3
  • avoided returning None or (None, None), throwing ValueError instead
  • detailed error messages and exteded safety checks
  • check that bech32 addresses are not longer than 90 characters (as this is not enforced by bech32.b32decode anymore)
btclib.bech32address.b32address_from_witness(wv: int, wp: Union[bytes, str], network: str = 'mainnet') → bytes

Encode a bech32 native SegWit address from the witness.

btclib.bech32address.p2wpkh(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], network: Optional[str] = None) → bytes

Return the p2wpkh bech32 address corresponding to a public key.

btclib.bech32address.p2wsh(wscript: Union[bytes, str, List[Union[int, str, bytes]]], network: str = 'mainnet') → bytes

Return the p2wsh bech32 address corresponding to a script.

btclib.bech32address.witness_from_b32address(b32addr: Union[bytes, str]) → Tuple[int, bytes, str, bool]

Return the witness from a bech32 native SegWit address.

btclib.bip32 module

BIP32 Hierarchical Deterministic Wallet functions.

A deterministic wallet is a hash-chain of private/public key pairs that derives from a single root, which is the only element requiring backup. Moreover, there are schemes where public keys can be calculated without accessing private keys.

A hierarchical deterministic wallet is a tree of multiple hash-chains, derived from a single root, allowing for selective sharing of keypair chains.

Here, the HD wallet is implemented according to BIP32 bitcoin standard https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki.

A BIP32 extended key is 78 bytes:

  • [ : 4] version
  • [ 4: 5] depth in the derivation path
  • [ 5: 9] parent fingerprint
  • [ 9:13] index
  • [13:45] chain code
  • [45:78] compressed pubkey or [0x00][prvkey]
btclib.bip32.crack_prvkey(parent_xpub: Union[btclib.alias.BIP32KeyDict, bytes, str], child_xprv: Union[btclib.alias.BIP32KeyDict, bytes, str]) → bytes
btclib.bip32.derive(xkey: Union[btclib.alias.BIP32KeyDict, bytes, str], der_path: Union[str, Iterable[int], int, bytes], forced_version: Union[bytes, str, None] = None) → bytes

Derive a BIP32 key across a path spanning multiple depth levels.

Derivation is according to:

  • absolute derivation path as “m/44h/0’/1H/0/10” string
  • relative derivation path as “./0/10” string
  • relative derivation path as iterable integer indexes
  • relative one level child derivation with single integer index
  • relative one level child derivation with single 4-bytes index

Path is case/blank/extra-slash insensitive (e.g. “M /44h / 0’ /1H // 0/ 10 / “).

btclib.bip32.derive_from_account(account_xkey: Union[btclib.alias.BIP32KeyDict, bytes, str], branch: int, address_index: int, more_than_two_branches: bool = False) → bytes
btclib.bip32.deserialize(xkey: Union[btclib.alias.BIP32KeyDict, bytes, str]) → btclib.alias.BIP32KeyDict
btclib.bip32.indexes_from_path(der_path: Union[str, Iterable[int], int, bytes]) → Tuple[List[bytes], bool]
btclib.bip32.mxprv_from_bip39_mnemonic(mnemonic: str, passphrase: str = '', network: str = 'mainnet') → bytes

Return BIP32 root master extended private key from BIP39 mnemonic.

btclib.bip32.mxprv_from_electrum_mnemonic(mnemonic: str, passphrase: str = '', network: str = 'mainnet') → bytes

Return BIP32 master extended private key from Electrum mnemonic.

Note that for a “standard” mnemonic the derivation path is “m”, for a “segwit” mnemonic it is “m/0h” instead.

btclib.bip32.rootxprv_from_seed(seed: Union[bytes, str], version: Union[bytes, str] = b'\x04\x88\xad\xe4') → bytes

Return BIP32 root master extended private key from seed.

btclib.bip32.serialize(d: btclib.alias.BIP32KeyDict) → bytes
btclib.bip32.xpub_from_xprv(xprv: Union[btclib.alias.BIP32KeyDict, bytes, str]) → bytes

Neutered Derivation (ND).

Derivation of the extended public key corresponding to an extended private key (“neutered” as it removes the ability to sign transactions).

btclib.bip39 module

BIP39 entropy / mnemonic / seed functions.

https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki.

Checksummed entropy (ENT+CS) is converted from/to mnemonic.

  • bits per word = bpw = 11
  • ENT = raw entropy
  • CS = checksum = ENT / 32
  • MS = words in the mnemonic sentence = (ENT+CS) / bpw
ENT CS ENT+CS MS
128 4 132 12
160 5 165 15
192 6 198 18
224 7 231 21
256 8 264 24
btclib.bip39.entropy_from_mnemonic(mnemonic: str, lang: str = 'en') → str

Return the entropy from the BIP39 checksummed mnemonic sentence.

btclib.bip39.mnemonic_from_entropy(entropy: Union[str, int, bytes], lang: str = 'en') → str

Convert input entropy to BIP39 checksummed mnemonic sentence.

Input entropy can be expressed as binary 0/1 string, bytes-like, or integer; it must be 128, 160, 192, 224, or 256 bits.

In the case of binary 0/1 string and bytes-like, leading zeros are not considered redundant padding.

In the case of integer, where leading zeros cannot be represented, if the bit length is not an allowed value, then the binary 0/1 string is padded with leading zeros up to the next allowed bit length; if the integer bit length is longer than the maximum length, then only the leftmost bits are retained.

btclib.bip39.seed_from_mnemonic(mnemonic: str, passphrase: str, verify_checksum=True) → bytes

Return the seed from the provided BIP39 mnemonic sentence.

The mnemonic checksum verification can be skipped if needed.

btclib.bms module

Bitcoin message signing (BMS).

Bitcoin uses a P2PKH address-based scheme for message signature: such a signature does prove the control of the private key corresponding to the address and, consequently, of the associated bitcoins (if any). Message signature adopts a custom compact 65-bytes (fixed size) serialization format (i.e. not the ASN.1 DER format used for transactions, which would results in 71-bytes average signature).

One should never sign a vague statement that could be reused out of the context it was intended for. Always include at least:

  • name (nickname, customer id, e-mail, etc.)
  • date and time
  • who the message is intended for (name, business name, e-mail, etc.)
  • specific purpose of the message

To mitigate the risk of signing a possibly deceiving message, for any given message a magic “Bitcoin Signed Message:n” prefix is added, then the hash of the resulting message is signed.

This BMS scheme relies on ECDSA, i.e. it works with private/public key pairs, not addresses: the address is only used to identify a key pair. At signing time, a wallet infrastructure is required to access the private key corresponding to a given address; alternatively, the private key must be provided explicitly.

To verify the ECDSA signature the public key is not needed because (EC)DSA allows public key recovery: public keys that correctly verify the signature can be implied from the signature itself. In the case of the Bitcoin secp256k1 curve, two public keys are recovered (up to four with non-zero but negligible probability); at verification time the address must match that public key in the recovery set marked as the right one at signature time.

The (r, s) DSA signature is serialized as [1-byte recovery flag][32-bytes r][32-bytes s], in a compact 65-bytes (fixed-size) encoding.

The serialized signature is then base64-encoded to transport it across channels that are designed to deal with textual data. Base64-encoding uses 10 digits, 26 lowercase characters, 26 uppercase characters, ‘+’ (plus sign), and ‘/’ (forward slash). The equal sign ‘=’ is used as encoding end marker.

The recovery flag is used at verification time to discriminate among recovered public keys (and among address types in the case of scheme extension beyond P2PKH). Explicitly, the recovery flag value is:

key_id + (4 if compressed else 0) + 27

where:

  • key_id is the index in the [0, 3] range identifying which of the recovered public keys is the one associated to the address;
  • compressed indicates if the address is the hash of the compressed public key representation
  • 27 identify a P2PKH address, which is the only kind of address supported by Bitcoin Core; when the recovery flag is in the [31, 34] range of compressed addresses, Electrum also check for P2WPKH-P2SH and P2WPKH (SegWit always uses compressed public keys); BIP137 (Trezor) uses, instead, 35 and 39 instead of 27 for P2WPKH-P2SH and P2WPKH (respectively).
rec

flag

key
id
address type
27 0 P2PKH uncompressed
28 1 P2PKH uncompressed
29 2 P2PKH uncompressed
30 3 P2PKH uncompressed
31 0 P2PKH compressed (also Electrum P2WPKH-P2SH/P2WPKH)
32 1 P2PKH compressed (also Electrum P2WPKH-P2SH/P2WPKH)
33 2 P2PKH compressed (also Electrum P2WPKH-P2SH/P2WPKH)
34 3 P2PKH compressed (also Electrum P2WPKH-P2SH/P2WPKH)
35 0 BIP137 (Trezor) P2WPKH-P2SH
36 1 BIP137 (Trezor) P2WPKH-P2SH
37 2 BIP137 (Trezor) P2WPKH-P2SH
38 3 BIP137 (Trezor) P2WPKH-P2SH
39 0 BIP137 (Trezor) P2WPKH
40 1 BIP137 (Trezor) P2WPKH
41 2 BIP137 (Trezor) P2WPKH
42 3 BIP137 (Trezor) P2WPKH

This implementation endorses the Electrum approach: a signature generated with a compressed WIF (i.e. without explicit address or with a compressed P2PKH address) is valid also for the P2WPKH-P2SH and P2WPKH addresses derived from the same WIF.

Nonetheless, it is possible to obtain the BIP137 behaviour if at signing time the compressed WIF is supplemented with a P2WPKH-P2SH or P2WPKH address: in this case the signature will be valid only for that same address.

https://github.com/bitcoin/bitcoin/pull/524

https://github.com/bitcoin/bips/blob/master/bip-0137.mediawiki

btclib.bms.assert_as_valid(msg: Union[bytes, str], addr: Union[bytes, str], sig: Union[Tuple[int, int, int], bytes, str]) → None
btclib.bms.deserialize(sig: Union[Tuple[int, int, int], bytes, str]) → Tuple[int, int, int]

Return the verified components of the provided BSM signature.

The address-based BSM signature can be represented as (rf, r, s) tuple or as base64-encoding of the compact format [1-byte rf][32-bytes r][32-bytes s].

btclib.bms.gen_keys(prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict] = None, network: Optional[str] = None, compressed: Optional[bool] = None) → Tuple[bytes, bytes]

Return a private/public key pair.

The private key is a WIF, the public key is a base58 P2PKH address.

btclib.bms.serialize(rf: int, r: int, s: int) → bytes

Return the BSM address-based signature as base64-encoding.

First off, the signature is serialized in the [1-byte rf][32-bytes r][32-bytes s] compact format, then it is base64-encoded.

btclib.bms.sign(msg: Union[bytes, str], prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], addr: Union[bytes, str, None] = None) → Tuple[int, int, int]

Generate address-based compact signature for the provided message.

btclib.bms.verify(msg: Union[bytes, str], addr: Union[bytes, str], sig: Union[Tuple[int, int, int], bytes, str]) → bool

Verify address-based compact signature for the provided message.

btclib.borromean module

btclib.borromean.assert_as_valid(msg: bytes, e0: bytes, s: Dict[int, List[int]], pubk_rings: Dict[int, Sequence[Tuple[int, int]]]) → bool
btclib.borromean.sign(msg: Union[bytes, str], ks: Sequence[int], sign_key_idx: Sequence[int], sign_keys: Sequence[int], pubk_rings: Dict[int, Sequence[Tuple[int, int]]]) → Tuple[bytes, Dict[int, List[int]]]

Borromean ring signature - signing algorithm

https://github.com/ElementsProject/borromean-signatures-writeup https://github.com/Blockstream/borromean_paper/blob/master/borromean_draft_0.01_9ade1e49.pdf

inputs: - msg: message to be signed (bytes) - sign_key_idx: list of indexes representing each signing key per ring - sign_keys: list containing the whole set of signing keys (one per ring) - pubk_rings: dictionary of sequences representing single rings of pubkeys

btclib.borromean.verify(msg: Union[bytes, str], e0: bytes, s: Dict[int, List[int]], pubk_rings: Dict[int, Sequence[Tuple[int, int]]]) → bool

Borromean ring signature - verification algorithm

inputs:

  • msg: message to be signed (bytes)
  • e0: pinned e-value needed to start the verification algorithm
  • s: s-values, both real (one per ring) and forged
  • pubk_rings: dictionary of sequences representing single rings of pubkeys

btclib.curve module

Elliptic curve classes.

class btclib.curve.Curve(p: Union[bytes, str, int], a: Union[bytes, str, int], b: Union[bytes, str, int], G: Tuple[int, int], n: Union[bytes, str, int], h: int, weakness_check: bool = True)

Bases: btclib.curve.CurveSubGroup

Prime order subgroup of the points of an elliptic curve over Fp.

class btclib.curve.CurveGroup(p: Union[bytes, str, int], a: Union[bytes, str, int], b: Union[bytes, str, int])

Bases: object

Finite group of the points of an elliptic curve over Fp.

The elliptic curve is the set of points (x, y) that are solutions to a Weierstrass equation y^2 = x^3 + a*x + b, with x, y, a, and b in Fp (p being a prime), together with a point at infinity INF. The constants a, b must satisfy the relationship 4 a^3 + 27 b^2 ≠ 0.

The group is defined by the point addition group law.

add(Q1: Tuple[int, int], Q2: Tuple[int, int]) → Tuple[int, int]

Return the sum of two points.

The input points must be on the curve.

has_square_y(Q: Union[Tuple[int, int], Tuple[int, int, int]]) → bool

Return True if the affine y-coordinate is a square.

The input point is not checked to be on the curve.

is_on_curve(Q: Tuple[int, int]) → bool

Return True if the point is on the curve.

negate(Q: Union[Tuple[int, int], Tuple[int, int, int]]) → Union[Tuple[int, int], Tuple[int, int, int]]

Return the opposite point.

The input point is not checked to be on the curve.

require_on_curve(Q: Tuple[int, int]) → None

Require the input curve Point to be on the curve.

An Error is raised if not.

require_p_ThreeModFour() → None

Require the field prime p to be equal to 3 mod 4.

An Error is raised if not.

y(x: int) → int

Return the y coordinate from x, as in (x, y).

y_low(x: int, low1high0: int = 1) → int

Return the low/high affine y-coordinate associated to x.

y_odd(x: int, odd1even0: int = 1) → int

Return the odd/even affine y-coordinate associated to x.

y_quadratic_residue(x: int, quad_res: int = 1) → int

Return the quadratic residue affine y-coordinate.

class btclib.curve.CurveSubGroup(p: Union[bytes, str, int], a: Union[bytes, str, int], b: Union[bytes, str, int], G: Tuple[int, int])

Bases: btclib.curve.CurveGroup

Subgroup of the points of an elliptic curve over Fp generated by G.

btclib.curvegroupf module

CurveGroup explorer functions.

These functions are meant to explore low-cardinality CurveGroup, for didactical (and fun) reason only.

btclib.curvegroupf.find_all_points(ec: btclib.curve.CurveGroup) → List[Tuple[int, int]]

Attemp to find all group points, if p is low.

Very unsofisticated walk-through approach, for didactical sake only.

btclib.curvegroupf.find_subgroup_points(ec: btclib.curve.CurveGroup, G: Tuple[int, int]) → List[Tuple[int, int]]

Attemp to count all G-generated subgroup points, if p is low.

Very unsofisticated walk-through approach, for didactical sake only.

btclib.curvemult module

Elliptic curve point multiplication functions.

btclib.curvemult.double_mult(u: Union[bytes, str, int], H: Tuple[int, int], v: Union[bytes, str, int], Q: Tuple[int, int], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Shamir trick for efficient computation of u*H + v*Q

btclib.curvemult.mult(m: Union[bytes, str, int], Q: Tuple[int, int] = None, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Point multiplication, implemented using ‘double and add’.

Computations use Jacobian coordinates and binary decomposition of m.

btclib.curvemult.multi_mult(scalars: Sequence[Union[bytes, str, int]], Points: Sequence[Tuple[int, int]], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Return the multi scalar multiplication u1*Q1 + … + un*Qn.

Use Bos-Coster’s algorithm for efficient computation.

btclib.curves module

Elliptic curves.

btclib.der module

Strict ASN.1 DER format for ECDSA signature representation.

The original Bitcoin implementation used OpenSSL to verify ECDSA signatures in ASN.1 DER representation. However, OpenSSL does not do strict validation (e.g. extra padding is ignored) and this changes the transaction hash value, leading to transaction malleability. This was fixed by BIP66, activated on block 363,724.

source: https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki

BIP66 mandates a strict DER format:

Format: [0x30][data-size] [0x02][r-size][r] [0x02][s-size][s] [sighash]

  • 0x30 header byte to indicate compound structure
  • data-size: 1-byte size descriptor of the following data,
    excluding the sighash byte
  • 0x02 header byte indicating an integer
  • r-size: 1-byte size descriptor of the r value that follows
  • r: arbitrary-size big-endian r value.
    It must use the shortest possible encoding for a positive integers (which means no null bytes at the start, except a single one when the next byte has its highest bit set to avoid being interpreted as a negative number)
  • 0x02 header byte indicating an integer
  • s-size: 1-byte size descriptor of the s value that follows
  • s: arbitrary-size big-endian s value. Same rules as for r apply
  • sighash: 1-byte value indicating what data is hashed
    (not part of the DER signature)

There are 7 bytes of meta-data:

  • compound header, compound size,
  • value header, r-value size,
  • value header, s-value size
  • sighash type (optional)

The ECDSA signature (r, s) should be 64 bytes, r and s being 32 bytes integers each; however, integers in DER are signed, so if the value being encoded is greater than 2^128, a 33rd byte is added in front. Bitcoin has a “low s” rule for the s value to be below ec.n, but it is only a standardness rule miners are allowed to ignore. Moreover, no such rule exists for r.

btclib.dh module

Diffie-Hellman elliptic curve key agreement scheme.

Implementation of the Diffie-Hellman key agreement scheme using elliptic curve cryptography. A key agreement scheme is used by two entities to establish shared keying data, which will be later utilized e.g. in symmetric cryptographic scheme.

The two entities must agree on the elliptic curve and key derivation function to use.

btclib.dh.ansi_x963_kdf(z: bytes, size: int, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → bytes

Return keying data according to ANS-X9.63-KDF.

Return a keying data octet sequence of the requested size according to ANS-X9.63-KDF specifications for the key derivation function.

http://www.secg.org/sec1-v2.pdf, section 3.6.1

btclib.dh.diffie_hellman(kdf: Callable[[bytes, int, btclib.curve.Curve, Callable[[], Any]], Any], dU: int, QV: Tuple[int, int], size: int, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → bytes

Diffie-Hellman elliptic curve key agreement scheme.

http://www.secg.org/sec1-v2.pdf, section 6.1

btclib.dsa module

Elliptic Curve Digital Signature Algorithm (ECDSA).

Implementation according to SEC 1 v.2:

http://www.secg.org/sec1-v2.pdf

specialized with bitcoin canonical ‘low-s’ encoding.

btclib.dsa.assert_as_valid(msg: Union[bytes, str], P: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], sig: Union[Tuple[int, int], bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → None
btclib.dsa.challenge(msg: Union[bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → int
btclib.dsa.crack_prvkey(msg1: Union[bytes, str], sig1: Union[Tuple[int, int], bytes, str], msg2: Union[bytes, str], sig2: Union[Tuple[int, int], bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → Tuple[int, int]
btclib.dsa.deserialize(sig: Union[Tuple[int, int], bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Return the verified components of the provided ECDSA signature.

The ECDSA signature can be represented as (r, s) tuple or as strict ASN.1 DER binary representation.

btclib.dsa.gen_keys(prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict] = None, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, Tuple[int, int]]

Return a private/public (int, Point) key-pair.

btclib.dsa.recover_pubkeys(msg: Union[bytes, str], sig: Union[Tuple[int, int], bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → List[Tuple[int, int]]

ECDSA public key recovery (SEC 1 v.2 section 4.1.6).

See also: https://crypto.stackexchange.com/questions/18105/how-does-recovering-the-public-key-from-an-ecdsa-signature-work/18106#18106

btclib.dsa.serialize(r: int, s: int, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → bytes

Return the ECDSA signature as strict ASN.1 DER representation.

btclib.dsa.sign(msg: Union[bytes, str], prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], k: Union[int, bytes, str, btclib.alias.BIP32KeyDict, None] = None, low_s: bool = True, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → Tuple[int, int]

ECDSA signature with canonical low-s encoding.

Implemented according to SEC 1 v.2 The message msg is first processed by hf, yielding the value

m = hf(msg),

a sequence of bits of length hlen.

Normally, hf is chosen such that its output length hlen is roughly equal to nlen, the bit-length of the group order n, since the overall security of the signature scheme will depend on the smallest of hlen and nlen; however, the ECDSA standard supports all combinations of hlen and nlen.

RFC6979 is used for deterministic nonce.

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

btclib.dsa.verify(msg: Union[bytes, str], P: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], sig: Union[Tuple[int, int], bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → bool

ECDSA signature verification (SEC 1 v.2 section 4.1.4).

btclib.electrum module

Electrum entropy / mnemonic / seed functions.

Electrum mnemonic is versioned, conveying BIP32 derivation rule too.

btclib.electrum.entropy_from_mnemonic(mnemonic: str, lang: str = 'en') → str

Return the entropy from the Electrum versioned mnemonic sentence.

btclib.electrum.mnemonic_from_entropy(entropy: Union[str, int, bytes], version_str: str = 'standard', lang: str = 'en') → str

Convert input entropy to Electrum versioned mnemonic sentence.

Input entropy can be expressed as binary 0/1 string, bytes-like, or integer.

In the case of binary 0/1 string and bytes-like, leading zeros are considered redundant padding.

btclib.electrum.version_from_mnemonic(mnemonic: str) → Tuple[str, str]

Return the (Electrum version, clean mnemonic) tuple.

The clean mnemonic is free from spurious whitespace characters (extra spaces, tab, newline, return, formfeed, etc.)

btclib.entropy module

Entropy conversion functions.

Depending on the function, input entropy can be expressed as raw (i.e. binary 0/1 string), bytes, or integer and their equivalent representations.

Leading zeros in raw or bytes entropy are never considered redundant padding.

Output entropy is always raw.

btclib.entropy.binstr_from_binstr(str_entropy: str, bits: Union[int, Iterable[int]] = (128, 160, 192, 224, 256, 512)) → str

Return raw entropy from the input raw entropy.

Input entropy must be expressed as raw entropy; it is never padded to satisfy the bit-size requirement.

If more bits than required are provided, the leftmost ones are retained.

Default bit-sizes are 128, 160, 192, 224, 256, or 512 bits.

btclib.entropy.binstr_from_bytes(bytes_entropy: Union[bytes, str], bits: Union[int, Iterable[int]] = (128, 160, 192, 224, 256, 512)) → str

Return raw entropy from the input Octets entropy.

Input entropy can be expressed as hex-string or bytes; it is never padded to satisfy the bit-size requirement.

If more bits than required are provided, the leftmost ones are retained.

Default bit-sizes are 128, 160, 192, 224, 256, or 512 bits.

btclib.entropy.binstr_from_entropy(entr: Union[str, int, bytes], bits: Union[int, Iterable[int]] = (128, 160, 192, 224, 256, 512)) → str

Return raw entropy from the input entropy.

Input entropy can be expressed as:

  • raw (i.e. binary 0/1 string) entropy
  • bytes (no hex-string, as they would conflict with raw entropy representation)
  • integer (int, no string starting with “0b”/”0x”)

In the case of raw entropy and bytes, entropy is never padded to satisfy the bit-size requirement; instead, integer entropy is front-padded with zeros digits as much as necessary to satisfy the bit-size requirement.

In all cases if more bits than required are provided, the leftmost ones are retained.

Default bit-sizes are 128, 160, 192, 224, 256, or 512 bits.

btclib.entropy.binstr_from_int(int_entropy: int, bits: Union[int, Iterable[int]] = (128, 160, 192, 224, 256, 512)) → str

Return raw entropy from the input integer entropy.

Input entropy can be expressed as int or string starting with “0x”/”0b”; it is front-padded with zeros digits as much as necessary to satisfy the bit-size requirement.

If more bits than required are provided, the leftmost ones are retained.

Default bit-sizes are 128, 160, 192, 224, 256, or 512 bits.

btclib.entropy.binstr_from_rolls(bits: int, dice_sides: int, rolls: List[int], shuffle: bool = True) → str

Return raw entropy from the input dice rolls.

Dice rolls are represented by integers in the [1-dice_sides] range; there must be enough rolls to satisfy the bit-size requirement.

Only rolls having value in the [1-base] range are used, with base being the highest power of 2 that is lower than the dice_sides (e.g. for a traditional D6 dice, only rolls having value in [1-4] are used; for a D20 dice, only rolls having value in [1-16] are used; etc.). Rolls can also be shuffled.

If more bits than required are provided, the leftmost ones are retained.

btclib.entropy.collect_rolls(bits: int) → Tuple[int, List[int]]
btclib.entropy.randbinstr(bits: int, entropy: Optional[str] = None, hash: bool = True) → str

Return CSPRNG raw entropy XOR-ed with input raw entropy.

The input raw entropy is used as initialization value; if not provided, then entropy is generated with the system cryptographically strong pseudo-random number generator (CSPRNG).

Then, this entropy is:

  • XOR-ed with CSPRNG system entropy
  • possibly hashed (if requested)

btclib.hashes module

Hash based helper functions.

btclib.hashes.fingerprint(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], network: Optional[str] = None) → bytes

Return the public key fingerprint from a private/public key.

The fingerprint is the last four bytes of the compressed public key HASH160.

btclib.hashes.hash160_from_key(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], network: Optional[str] = None, compressed: Optional[bool] = None) → Tuple[bytes, str]

Return (public key HASH160, nettwork) from a private/public key.

HASH160 is RIPEMD160(SHA256).

btclib.hashes.hash160_from_script(script: Union[bytes, str, List[Union[int, str, bytes]]]) → bytes

Return the script HASH160 from a private/public key.

HASH160 is RIPEMD160(SHA256).

btclib.hashes.hash256_from_script(script: Union[bytes, str, List[Union[int, str, bytes]]]) → bytes

Return the script HASH256 from a private/public key.

HASH256 is SHA256(SHA256).

btclib.hashes.reduce_to_hlen(msg: Union[bytes, str], hf: Callable[[], Any]) → bytes

btclib.mnemonic module

Entropy conversion from/to mnemonic word-list sentence.

Entropy must be represented as binary 0/1 string.

Warning: these functions are not meant for end-users which are better served by the bip39 and electrum module functions.

class btclib.mnemonic.WordLists

Bases: object

Class for word-lists to be used in entropy/mnemonic conversions.

Word-lists are from:

More word-lists can be added using the load_lang method.

Word-lists are loaded only if needed and read only once from disk.

language_length(lang: str) → int

Return the number of words in the language word-list.

load_lang(lang: str, filename: str = None) → None

Load/add a language word-list if not loaded/added yet.

The language file has to be provided for adding new languages beyond those already provided.

wordlist(lang: str) → List[str]

Return the language word-list.

btclib.network module

Network constants and associated functions.

class btclib.network.Network

Bases: dict

btclib.network.curve_from_xkeyversion(xkeyversion: bytes) → btclib.curve.Curve
btclib.network.network_from_key_value(key: str, prefix: Union[str, bytes, btclib.curve.Curve]) → str

Return network string from (key, value) pair.

Warning: when used on ‘regtest’ it mostly returns ‘testnet’, which is not a problem as long as it is used for WIF/Base58Address/BIP32xkey because the two networks share the same prefixes.

btclib.network.network_from_xkeyversion(xkeyversion: bytes) → str

Return network string from the xkey version prefix.

Warning: when used on ‘regtest’ it returns ‘testnet’, which is not a problem as long as it is used for WIF/Base58Address/BIP32Key because the two networks share the same prefixes.

btclib.network.xprvversions_from_network(network: str) → List[bytes]
btclib.network.xpubversions_from_network(network: str) → List[bytes]

btclib.numbertheory module

Number theory and modular arithmetic functions.

Implementations originally from https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm and https://codereview.stackexchange.com/questions/43210/tonelli-shanks-algorithm-implementation-of-prime-modular-square-root/43267 with the following modifications:

  • type annotated python3
  • minor improvements
  • added extensive unit test
btclib.numbertheory.legendre_symbol(a, p) → int

Compute the Legendre symbol a|p using Euler’s criterion.

p is a prime, a is relatively prime to p (if p divides a, then a|p = 0). It returns 1 if a has a square root modulo p, -1 otherwise.

https://codereview.stackexchange.com/questions/43210/tonelli-shanks-algorithm-implementation-of-prime-modular-square-root/43267

btclib.numbertheory.mod_inv(a: int, m: int) → int

Return the inverse of a (mod m). m does not have to be a prime.

Based on Extended Euclidean Algorithm, see: https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm

btclib.numbertheory.mod_sqrt(a: int, p: int) → int

Return a quadratic residue (mod p) of a; p must be a prime.

Solve the equation:
x^2 = a mod p

and return x. Note that p - x is also a root.

If a simple solution is not available for p, then the Tonelli-Shanks algorithm is used.

https://codereview.stackexchange.com/questions/43210/tonelli-shanks-algorithm-implementation-of-prime-modular-square-root/43267

btclib.numbertheory.tonelli(a: int, p: int) → int

Return a quadratic residue (mod p) of a; p must be a prime.

The Tonelli-Shanks algorithm is used.

https://codereview.stackexchange.com/questions/43210/tonelli-shanks-algorithm-implementation-of-prime-modular-square-root/43267

btclib.numbertheory.xgcd(a: int, b: int) → Tuple[int, int, int]

Return (g, x, y) such that a*x + b*y = g = gcd(x, y).

based on Extended Euclidean Algorithm, see https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm

btclib.pedersen module

Pedersen commitment functions.

In a commitment scheme the committer:

  • decides (or is given) a secret message v
  • decides a random secret r
  • commits to v by applying the public commitment scheme algorithm and producing a commitment C=Commit(r,v)
  • makes C public

Later, when he reveals r and v, the verifier opens the commitment checking if indeed C=Commit(r,v).

Pedersen commitment uses a public group of large order n in which the discrete logarithm is hard. In the case of an elliptic curve group, the generator G is supplemented with a second random generator H and the commitment algorithm is Commit(r,v)=rG+vH. It is crucial for H to be Nothing-Up-My-Sleeve (NUMS), i.e. the discrete logarithm of H with respect to G must be unknown.

btclib.pedersen.commit(r: int, v: int, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → Tuple[int, int]

Commit to r, returning rG+vH.

Commit to r, returning rG+vH. H is the second Nothing-Up-My-Sleeve (NUMS) generator of the curve.

btclib.pedersen.open(r: int, v: int, C: Tuple[int, int], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → bool

Open the commitment C and return True if valid.

btclib.pedersen.second_generator(ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → Tuple[int, int]

Second (with respect to G) elliptic curve generator.

Second (with respect to G) Nothing-Up-My-Sleeve (NUMS) elliptic curve generator.

The hash of G is coerced it to a point (hx, hy). If the resulting point is not on the curve, keep on incrementing hx until a valid curve point (hx, hy) is obtained.

idea: https://crypto.stackexchange.com/questions/25581/second-generator-for-secp256k1-curve

source: https://github.com/ElementsProject/secp256k1-zkp/blob/secp256k1-zkp/src/modules/rangeproof/main_impl.h

btclib.rfc6979 module

Deterministic generation of the ephemeral key following RFC6979.

https://tools.ietf.org/html/rfc6979:

ECDSA and ECSSA need to produce, for each signature generation, a fresh random value (ephemeral key, hereafter designated as k). For effective security, k must be chosen randomly and uniformly from a set of modular integers, using a cryptographically secure process. Even slight biases in that process may be turned into attacks on the signature schemes.

The need for a cryptographically secure source of randomness proves to be a hindranceand and makes implementations harder to test. Moreover, reusing the same ephemeral key for a different message signed with the same private key reveal the private key!

RFC6979 turns ECDSA into deterministic schemes by using a deterministic process for generating the “random” value k. The process fulfills the cryptographic characteristics in order to maintain the properties of verifiability and unforgeability expected from signature schemes; namely, for whoever does not know the signature private key, the mapping from input messages to the corresponding k values is computationally indistinguishable from what a randomly and uniformly chosen function (from the set of messages to the set of possible k values) would return.

btclib.rfc6979.rfc6979(msg: Union[bytes, str], prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → int

Return a deterministic ephemeral key following RFC 6979.

btclib.script module

Bitcoin Script.

https://en.bitcoin.it/wiki/Script

Scripts are represented by List[Token], where Token = Union[int, str, bytes]:

  • int [-1, 16] are shorcuts for ‘OP_1NEGATE’, ‘OP_0’ - ‘OP_16’
  • str are for opcodes (e.g. ‘OP_HASH160’) or hexstring data
  • bytes are for data (but integers are often casted to int)
btclib.script.decode(script: Union[bytes, str]) → List[Union[int, str, bytes]]
btclib.script.deserialize(stream: Union[BinaryIO, bytes, str]) → List[Union[int, str, bytes]]
btclib.script.encode(script: List[Union[int, str, bytes]]) → bytes
btclib.script.serialize(script: List[Union[int, str, bytes]]) → bytes

btclib.scriptpubkey module

ScriptPubKey functions.

btclib.scriptpubkey.nulldata(data: Union[bytes, str]) → bytes

Return the nulldata scriptPubKey of the provided data.

btclib.scriptpubkey.p2ms(keys: List[Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]]], m: int, lexicographic_sort: bool = True, compressed: Optional[bool] = None) → bytes

Return the m-of-n multi-sig scriptPubKey of the provided pubkeys.

btclib.scriptpubkey.p2pk(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]]) → bytes

Return the p2pk scriptPubKey of the provided pubkey.

btclib.scriptpubkey.p2pkh(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], compressed: Optional[bool] = None) → bytes

Return the p2pkh scriptPubKey of the provided pubkey.

btclib.scriptpubkey.p2sh(script: Union[bytes, str, List[Union[int, str, bytes]]]) → bytes

Return the p2sh scriptPubKey of the provided script.

btclib.scriptpubkey.p2wpkh(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]]) → bytes

Return the p2wpkh scriptPubKey of the provided pubkey.

btclib.scriptpubkey.p2wsh(wscript: Union[bytes, str, List[Union[int, str, bytes]]]) → bytes

Return the p2wsh scriptPubKey of the provided script.

btclib.scriptpubkey.payload_from_nulldata_scriptPubKey(script: Union[bytes, str, List[Union[int, str, bytes]]]) → Tuple[str, Union[bytes, List[bytes]], int]
btclib.scriptpubkey.payload_from_pms_scriptPubKey(script: Union[bytes, str, List[Union[int, str, bytes]]]) → Tuple[str, Union[bytes, List[bytes]], int]
btclib.scriptpubkey.payload_from_scriptPubKey(script: Union[bytes, str, List[Union[int, str, bytes]]]) → Tuple[str, Union[bytes, List[bytes]], int]

Return (scriptPubKey type, payload, m) from the input script.

btclib.scriptpubkey.scriptPubKey_from_payload(s_type: str, payloads: Union[bytes, str, List[Union[bytes, str]]], m: int = 0, lexicographic_sort: bool = True) → bytes

Return the requested scriptPubKey for the provided payload.

Multi-signature payloads can be lexicographically sorted. BIP67 endorses key sorting according to compressed key representation: this implementation is BIP67 compliant.

Note that sorting uncompressed keys (leading 0x04 byte) results in a different order than sorting the same keys in compressed (leading 0x02 or 0x03 bytes) representation. This implementation sorts uncompressed key according to their uncompressed representation, i.e. 04 leading byte being equal according to the point x-coordinate

https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki

btclib.secpoint module

SEC compressed/uncompressed point representation.

btclib.secpoint.bytes_from_point(Q: Tuple[int, int], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), compressed: bool = True) → bytes

Return a point as compressed/uncompressed octet sequence.

Return a point as compressed (0x02, 0x03) or uncompressed (0x04) octet sequence, according to SEC 1 v.2, section 2.3.3.

btclib.secpoint.point_from_octets(pubkey: Union[bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Return a tuple (Px, Py) that belongs to the curve.

Return a tuple (Px, Py) that belongs to the curve according to SEC 1 v.2, section 2.3.4.

btclib.signtocontract module

Include a commitment inside an elliptic curve DSA/SSA signature.

Let c be the commitment value and R a curve point, then

e = hash(R||c)

is a commitment operation.

When signing, an ephemeral secret key k is generated and its corresponding curve point R = kG is used. Here, instead of using (k, R), compute the commitment to c

e = hash(R||c),

tweak k with e and consequently substistute R with W = (k+e)G = R+eG, the proceed signing in the standard way, using (k+e, W).

When the committer/signer will reveal R and c, the verifier will check that

W.x = (R+eG).x

with e = hash(R||c)) and W.x being known from the signature.

btclib.signtocontract.ecdsa_commit_sign(c: Union[bytes, str], m: Union[bytes, str], prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], k: Union[int, bytes, str, btclib.alias.BIP32KeyDict, None] = None, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → Tuple[Tuple[int, int], Tuple[int, Tuple[int, int]]]

Include a commitment c inside an ECDSA signature.

btclib.signtocontract.ecssa_commit_sign(c: Union[bytes, str], m: Union[bytes, str], prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], k: Union[int, bytes, str, btclib.alias.BIP32KeyDict, None] = None, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → Tuple[Tuple[int, int], Tuple[int, Tuple[int, int]]]

Include a commitment c inside an ECSSA signature.

btclib.signtocontract.verify_commit(c: Union[bytes, str], receipt: Tuple[int, Tuple[int, int]], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → bool

Open the commitment c inside an EC DSA/SSA signature.

btclib.slip132 module

SLIP132 address.

https://github.com/satoshilabs/slips/blob/master/slip-0132.md

btclib.slip132.address_from_xkey(xkey: Union[btclib.alias.BIP32KeyDict, bytes, str]) → bytes

Return the SLIP132 base58/bech32 address.

The address is always derived from the compressed public key, as this is the default public key representation in BIP32.

btclib.slip132.address_from_xpub(xpub: Union[btclib.alias.BIP32KeyDict, bytes, str]) → bytes

Return the SLIP132 base58/bech32 address.

The address is always derived from the compressed public key, as this is the default public key representation in BIP32.

btclib.ssa module

Elliptic Curve Schnorr Signature Algorithm (ECSSA).

This implementation is according to BIP340-Schnorr:

https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki

Differently from ECDSA, the BIP340-Schnorr scheme supports messages of size hsize only.

It also uses as public key the x-coordinate (field element) of the curve point associated to the private key 0 < q < n. Therefore, for sepcp256k1 the public key size is 32 bytes. Arguably, the knowledge of q as the discrete logarithm of Q also implies the knowledge of n-q as discrete logarithm of -Q. As such, {q, n-q} can be considered a single private key and {Q, -Q} the associated public key characterized by the shared x_Q.

Also, BIP340 advocates its own SHA256 modification as hash function: TaggedHash(tag, x) = SHA256(SHA256(tag)||SHA256(tag)||x) The rationale is to make BIP340 signatures invalid for anything else but Bitcoin and vice versa.

TaggedHash is used for both the challenge (with tag ‘BIPSchnorr’) and the deterministic nonce (with tag ‘BIPSchnorrDerive’).

To allow for secure batch verification of multiple signatures, BIP340-Schnorr uses a challenge that prevents public key recovery from signature: c = TaggedHash(‘BIPSchnorr’, x_k||x_Q||msg).

A custom deterministic algorithm for the ephemeral key (nonce) is used for signing, instead of the RFC6979 standard: k = TaggedHash(‘BIPSchnorrDerive’, q||msg)

Finally, BIP340-Schnorr adopts a robust [r][s] custom serialization format, instead of the loosely specified ASN.1 DER standard. The signature size is p-size*n-size, where p-size is the field element (curve point coordinate) byte size and n-size is the scalar (curve point multiplication coefficient) byte size. For sepcp256k1 the resulting signature size is 64 bytes.

btclib.ssa.assert_as_valid(msg: Union[bytes, str], Q: Union[int, bytes, str, btclib.alias.BIP32KeyDict], sig: Union[Tuple[int, int], bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → None
btclib.ssa.batch_verify(m: Sequence[Union[bytes, str]], Q: Sequence[Union[int, bytes, str, btclib.alias.BIP32KeyDict]], sig: Sequence[Union[Tuple[int, int], bytes, str]], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → bool

Batch verification of BIP340 signatures.

btclib.ssa.challenge(msg: Union[bytes, str], xQ: Union[int, bytes, str, btclib.alias.BIP32KeyDict], r: int, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → int
btclib.ssa.deserialize(sig: Union[Tuple[int, int], bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Return the verified components of the provided BIP340 signature.

The BIP340 signature can be represented as (r, s) tuple or as binary [r][s] compact representation.

btclib.ssa.det_nonce(msg: Union[bytes, str], prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → Tuple[int, int]

Return a BIP340 deterministic ephemeral key (nonce).

btclib.ssa.gen_keys(prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict] = None, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Return a BIP340 private/public (int, int) key-pair.

btclib.ssa.point_from_bip340pubkey(x_Q: Union[int, bytes, str, btclib.alias.BIP32KeyDict], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Return a verified-as-valid BIP340 public key as Point tuple.

It supports:

  • BIP32 extended keys (bytes, string, or BIP32KeyDict)
  • SEC Octets (bytes or hex-string, with 02, 03, or 04 prefix)
  • BIP340 Octets (bytes or hex-string, p-size Point x-coordinate)
  • native tuple
btclib.ssa.serialize(x_K: int, s: int, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → bytes

Return the BIP340 signature as [r][s] compact representation.

btclib.ssa.sign(msg: Union[bytes, str], prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], k: Union[int, bytes, str, btclib.alias.BIP32KeyDict, None] = None, ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → Tuple[int, int]

Sign message according to BIP340 signature algorithm.

The message msg is first processed by hf, yielding the value

m = hf(msg),

a sequence of bits of length hlen.

Normally, hf is chosen such that its output length hlen is roughly equal to nlen, the bit-length of the group order n, since the overall security of the signature scheme will depend on the smallest of hlen and nlen; however, ECSSA supports all combinations of hlen and nlen.

btclib.ssa.verify(msg: Union[bytes, str], Q: Union[int, bytes, str, btclib.alias.BIP32KeyDict], sig: Union[Tuple[int, int], bytes, str], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1), hf: Callable[[], Any] = <built-in function openssl_sha256>) → bool

ECDSA signature verification (SEC 1 v.2 section 4.1.4).

btclib.to_prvkey module

btclib.to_prvkey.int_from_prvkey(prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → int

Return a verified-as-valid private key integer.

It supports:

  • WIF (bytes or string)
  • BIP32 extended keys (bytes, string, or BIP32KeyDict)
  • SEC Octets (bytes or hex-string, with 02, 03, or 04 prefix)
  • integer (native int or hex-strin)

Network and compressed informations from the input key are not used.

btclib.to_prvkey.prvkeyinfo_from_prvkey(prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], network: Optional[str] = None, compressed: Optional[bool] = None) → Tuple[int, str, bool]

btclib.to_pubkey module

btclib.to_pubkey.point_from_key(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Return a point tuple from any possible key representation.

It supports:

  • BIP32 extended keys (bytes, string, or BIP32KeyDict)
  • SEC Octets (bytes or hex-string, with 02, 03, or 04 prefix)
  • native tuple
btclib.to_pubkey.point_from_pubkey(pubkey: Union[bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], ec: btclib.curve.Curve = Curve('FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F', 0, 7, ('79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798', '483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8'), 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141', 1)) → Tuple[int, int]

Return an elliptic curve point tuple from a public key.

btclib.to_pubkey.pubkeyinfo_from_key(key: Union[int, bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], network: Optional[str] = None, compressed: Optional[bool] = None) → Tuple[bytes, str]

Return the pub key tuple (SEC-bytes, network) from a pub/prv key.

btclib.to_pubkey.pubkeyinfo_from_prvkey(prvkey: Union[int, bytes, str, btclib.alias.BIP32KeyDict], network: Optional[str] = None, compressed: Optional[bool] = None) → Tuple[bytes, str]

Return the pub key tuple (SEC-bytes, network) from a private key.

btclib.to_pubkey.pubkeyinfo_from_pubkey(pubkey: Union[bytes, str, btclib.alias.BIP32KeyDict, Tuple[int, int]], network: Optional[str] = None, compressed: Optional[bool] = None) → Tuple[bytes, str]

Return the pub key tuple (SEC-bytes, network) from a public key.

btclib.utils module

Assorted conversion utilities.

Most conversions from SEC 1 v.2 2.3 are included.

https://www.secg.org/sec1-v2.pdf

btclib.utils.bytes_from_octets(o: Union[bytes, str], out_size: Union[int, Iterable[int], None] = None) → bytes

Return bytes from a hex-string, stripping leading/trailing spaces.

If the input is not a string, then it goes untouched. Optionally, it also ensures required output size.

btclib.utils.ensure_is_power_of_two(n: int, var_name: str = None) → None
btclib.utils.hash160(o: Union[bytes, str]) → bytes

Return the HASH160=RIPEMD160(SHA256) of the input octet sequence.

btclib.utils.hash256(o: Union[bytes, str]) → bytes

Return the SHA256(SHA256(*)) of the input octet sequence.

btclib.utils.hex_string(i: Union[bytes, str, int]) → str
btclib.utils.int_from_bits(o: Union[bytes, str], nlen: int) → int

Return the leftmost nlen bits.

Take as input a sequence of blen bits and calculate a non-negative integer i that is less than 2^nlen according to SEC 1 v.2 section 4.1.3 (5). Note that an additional reduction modulo n would be required to ensure that 0 < i < n.

int_from_bits is not the reverse of i.to_bytes, even for input sequences of length nlen: i.to_bytes will add some bits on the left, while int_from_bits will discard some bits on the right. i.to_bytes is the reverse of int_from_bits only when nlen is a multiple of 8 and bit sequences already have length nlen. See https://tools.ietf.org/html/rfc6979#section-2.3.5.

btclib.utils.int_from_integer(i: Union[bytes, str, int]) → int
btclib.utils.sha256(o: Union[bytes, str]) → bytes

Return the SHA256(*) of the input octet sequence.

btclib.varint module

Varint encoding and decoding functions.

A varint (variable integer) is variable-length quantity that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. It is usually a base-128 (7 bits) representation of an unsigned integer with the addition of the eighth bit to mark continuation of bytes; it is used to save additional space for a resource constrained system.

This is the slightly different Bitcoin implementation, used in transaction data to indicate the number of upcoming fields or the length of the upcoming field.

Up to 0xfc, a varint is just 1 byte; however, if the integer is greater than 0xfc, then it is expanded as [1 byte prefix][number]:

  • prefix 0xfd markes the next two bytes as the number;
  • prefix 0xfe markes the next four bytes as the number;
  • prefix 0xff markes the next eight bytes as the number.
btclib.varint.decode(stream: Union[BinaryIO, bytes, str]) → int

Return the variable-length integer read from a stream.

btclib.varint.encode(i: int) → bytes

Return the varint bytes encoding of an integer.

Module contents