Skip to content

Commit

Permalink
new release (#116)
Browse files Browse the repository at this point in the history
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/asottile/pyupgrade: v3.8.0 → v3.9.0](asottile/pyupgrade@v3.8.0...v3.9.0)
- [github.com/PyCQA/docformatter: v1.7.3 → v1.7.4](PyCQA/docformatter@v1.7.3...v1.7.4)
- [github.com/psf/black: 23.3.0 → 23.7.0](psf/black@23.3.0...23.7.0)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Upgrade pre-commit

* Update history

* Update documentation

* Bump version

* assorted fixes

* fixed

* Test taproot script byte serialization

* Remove some type: ignore

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Giacomo Caironi <[email protected]>
Co-authored-by: fametrano <[email protected]>
  • Loading branch information
3 people authored Jul 12, 2023
1 parent dc546f0 commit 600cb13
Show file tree
Hide file tree
Showing 21 changed files with 144 additions and 52 deletions.
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ repos:
language: python
types: [python]
- repo: https://github.com/asottile/pyupgrade
rev: v3.8.0
rev: v3.9.0
hooks:
- id: pyupgrade
args: [--py37-plus]
Expand All @@ -70,7 +70,7 @@ repos:
language: python
types: [python]
- repo: https://github.com/PyCQA/docformatter
rev: v1.7.3
rev: v1.7.5
hooks:
- id: docformatter
description: "Formats docstrings to follow PEP 257."
Expand Down Expand Up @@ -103,7 +103,7 @@ repos:
language: python
types: [python]
- repo: https://github.com/psf/black
rev: 23.3.0
rev: 23.7.0
hooks:
- id: black
name: black (in place fixes)
Expand Down
11 changes: 9 additions & 2 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@ Notable changes to the codebase are documented here.
Release names follow *[calendar versioning](https://calver.org/)*:
full year, short month, short day (YYYY-M-D)

## v2023.6 (work in progress, not released yet)
## v2023.7.12

This is the last release supporting py37.

Major changes include:

- add descriptor util functions
- added first draft implementation of descriptors
- added first draft implementation of script engine
- added taproot psbt fields
- improved bip32 derivation (speeded-up, added one more test)
- supported py3.12 with btclib_libsecp256k1
- updated toolchain

## v2023.5.30

Expand Down
2 changes: 1 addition & 1 deletion btclib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"""__init__ module for the btclib package."""

name = "btclib"
__version__ = "2023.5.30"
__version__ = "2023.7.12"
__author__ = "The btclib developers"
__author_email__ = "[email protected]"
__copyright__ = "Copyright (C) 2017-2023 The btclib developers"
Expand Down
2 changes: 1 addition & 1 deletion btclib/block/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def height(self) -> int | None:
script_sig.
https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki
Block 227,835 (2013-03-24 15
Block 227,835 (2013-03-24 15
:49: 13 GMT) was the last version 1 block.
"""
if not self.transactions[0].is_coinbase():
Expand Down
6 changes: 3 additions & 3 deletions btclib/ec/curve_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,9 +703,9 @@ def _multi_mult(
Use Bos-Coster's algorithm for efficient computation.
The input points are assumed to be on curve,
the scalar coefficients are assumed to have been reduced mod n
if appropriate (e.g. cyclic groups of order n).
The input points are assumed to be on curve, the scalar coefficients
are assumed to have been reduced mod n if appropriate (e.g. cyclic
groups of order n).
"""
# source: https://cr.yp.to/badbatch/boscoster2.py
if len(scalars) != len(jac_points):
Expand Down
9 changes: 6 additions & 3 deletions btclib/psbt/psbt.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,16 @@ def to_dict(self, check_validity: bool = True) -> dict[str, Any]:
def from_dict(
cls: type[Psbt], dict_: Mapping[str, Any], check_validity: bool = True
) -> Psbt:
hd_key_paths = cast(
Mapping[Octets, BIP32KeyOrigin],
decode_from_bip32_derivs(dict_["bip32_derivs"]),
)
return cls(
Tx.from_dict(dict_["tx"]),
[PsbtIn.from_dict(psbt_in, False) for psbt_in in dict_["inputs"]],
[PsbtOut.from_dict(psbt_out, False) for psbt_out in dict_["outputs"]],
dict_["version"],
# FIXME
decode_from_bip32_derivs(dict_["bip32_derivs"]), # type: ignore[arg-type]
hd_key_paths,
dict_["unknown"],
check_validity,
)
Expand Down Expand Up @@ -483,7 +486,7 @@ def _sort_or_shuffle_together(
if ordering_func is None:
random.shuffle(tmp)
else:
tmp.sort(key=lambda t: ordering_func(t[0])) # type: ignore
tmp.sort(key=lambda t: ordering_func(t[0])) # type: ignore[misc]
tuple_a, tuple_b = zip(*tmp)
return list(tuple_a), list(tuple_b)

Expand Down
21 changes: 15 additions & 6 deletions btclib/psbt/psbt_in.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# Standard library imports
from dataclasses import dataclass
from typing import Any, Mapping
from typing import Any, List, Mapping, Tuple, cast

from btclib.alias import Octets
from btclib.bip32.key_origin import (
Expand Down Expand Up @@ -54,7 +54,6 @@
serialize_hd_key_paths,
serialize_leaf_scripts,
serialize_taproot_bip32,
taproot_bip32_from_dict,
taproot_bip32_to_dict,
)
from btclib.script import Witness
Expand Down Expand Up @@ -319,6 +318,14 @@ def to_dict(self, check_validity: bool = True) -> dict[str, Any]:
def from_dict(
cls: type[PsbtIn], dict_: Mapping[str, Any], check_validity: bool = True
) -> PsbtIn:
hd_key_paths = cast(
Mapping[Octets, BIP32KeyOrigin],
decode_from_bip32_derivs(dict_["bip32_derivs"]),
)
taproot_hd_key_paths = cast(
Mapping[Octets, Tuple[List[Octets], BIP32KeyOrigin]],
decode_from_bip32_derivs(dict_["taproot_hd_key_paths"]),
)
return cls(
Tx.from_dict(dict_["non_witness_utxo"], False)
if dict_["non_witness_utxo"]
Expand All @@ -330,8 +337,7 @@ def from_dict(
dict_["sig_hash"],
dict_["redeem_script"],
dict_["witness_script"],
# FIXME
decode_from_bip32_derivs(dict_["bip32_derivs"]), # type: ignore
hd_key_paths,
dict_["final_script_sig"],
Witness.from_dict(dict_["final_script_witness"], False),
dict_["ripemd160_preimages"],
Expand All @@ -341,7 +347,7 @@ def from_dict(
dict_["taproot_key_spend_signature"],
dict_["taproot_script_spend_signatures"],
dict_["taproot_leaf_scripts"],
taproot_bip32_from_dict(dict_["taproot_hd_key_paths"]), # type: ignore
taproot_hd_key_paths,
dict_["taproot_internal_key"],
dict_["taproot_merkle_root"],
dict_["unknown"],
Expand Down Expand Up @@ -526,7 +532,10 @@ def parse(
elif k[:1] == PSBT_IN_TAP_LEAF_SCRIPT:
taproot_leaf_scripts[k[1:]] = parse_leaf_script(v)
elif k[:1] == PSBT_IN_TAP_BIP32_DERIVATION:
taproot_hd_key_paths[k[1:]] = parse_taproot_bip32(v) # type: ignore
taproot_hd_key_path = cast(
Tuple[List[Octets], BIP32KeyOrigin], parse_taproot_bip32(v)
)
taproot_hd_key_paths[k[1:]] = taproot_hd_key_path
elif k[:1] == PSBT_IN_TAP_INTERNAL_KEY:
taproot_internal_key = deserialize_bytes(k, v, "taproot internal key")
elif k[:1] == PSBT_IN_TAP_MERKLE_ROOT:
Expand Down
22 changes: 14 additions & 8 deletions btclib/psbt/psbt_out.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Mapping, Sequence
from typing import Any, List, Mapping, Sequence, Tuple, cast

from btclib.alias import Octets
from btclib.bip32 import (
Expand Down Expand Up @@ -126,15 +126,21 @@ def to_dict(self, check_validity: bool = True) -> dict[str, Any]:
def from_dict(
cls: type[PsbtOut], dict_: Mapping[str, Any], check_validity: bool = True
) -> PsbtOut:
hd_key_paths = cast(
Mapping[Octets, BIP32KeyOrigin],
decode_from_bip32_derivs(dict_["bip32_derivs"]),
)
taproot_hd_key_paths = cast(
Mapping[Octets, Tuple[List[bytes], BIP32KeyOrigin]],
taproot_bip32_from_dict(dict_["taproot_hd_key_paths"]),
)
return cls(
dict_["redeem_script"],
dict_["witness_script"],
# FIXME
decode_from_bip32_derivs(dict_["bip32_derivs"]), # type: ignore
hd_key_paths,
dict_["taproot_internal_key"],
dict_["taproot_tree"],
# FIXME
taproot_bip32_from_dict(dict_["taproot_hd_key_paths"]), # type: ignore
taproot_hd_key_paths,
dict_["unknown"],
check_validity,
)
Expand Down Expand Up @@ -195,7 +201,7 @@ def parse(
hd_key_paths: dict[Octets, BIP32KeyOrigin] = {}
taproot_internal_key = b""
taproot_tree: list[tuple[int, int, bytes]] = []
taproot_hd_key_paths: dict[Octets, tuple[list[Octets], BIP32KeyOrigin]] = {}
taproot_hd_key_paths: dict[Octets, tuple[list[bytes], BIP32KeyOrigin]] = {}
unknown: dict[Octets, Octets] = {}

for k, v in output_map.items():
Expand All @@ -212,7 +218,7 @@ def parse(
taproot_tree = parse_taproot_tree(v)
elif k[:1] == PSBT_OUT_TAP_BIP32_DERIVATION:
#  parse just one hd key path at time :-(
taproot_hd_key_paths[k[1:]] = parse_taproot_bip32(v) # type: ignore
taproot_hd_key_paths[k[1:]] = parse_taproot_bip32(v)
else: # unknown
unknown[k] = v

Expand All @@ -222,7 +228,7 @@ def parse(
hd_key_paths,
taproot_internal_key,
taproot_tree,
taproot_hd_key_paths, # type: ignore
taproot_hd_key_paths,
unknown,
check_validity,
)
2 changes: 0 additions & 2 deletions btclib/script/engine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

from __future__ import annotations

from typing import cast

from btclib.alias import Command, ScriptList
from btclib.exceptions import BTClibValueError
from btclib.hashes import sha256
Expand Down
4 changes: 2 additions & 2 deletions btclib/script/engine/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
try:
from btclib_libsecp256k1.dsa import verify as dsa_verify
except ImportError:
from btclib.ecc.dsa import verify_ as dsa_verify # type: ignore
from btclib.ecc.dsa import verify_ as dsa_verify # type: ignore[assignment]

from btclib.alias import ScriptList
from btclib.ecc.dsa import Sig
Expand Down Expand Up @@ -125,7 +125,7 @@ def op_checksig(
msg_hash = sig_hash.segwit_v0(script_code, tx, i, signature[-1], prevout_value)
else:
msg_hash = sig_hash.legacy(script_code, tx, i, signature[-1])
return dsa_verify(msg_hash, pub_key, signature[:-1]) # type: ignore
return bool(dsa_verify(msg_hash, pub_key, signature[:-1]))


def script_op_count(count: int, increment: int):
Expand Down
4 changes: 2 additions & 2 deletions btclib/script/engine/tapscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def verify_key_path(
pub_key = type_and_payload(script_pub_key)[1]
msg_hash = sig_hash.taproot(tx, i, prevouts, sighash_type, 0, annex, b"")

if not ssa_verify(msg_hash, pub_key, signature[:64]): # type: ignore
if not ssa_verify(msg_hash, pub_key, signature[:64]):
raise BTClibValueError()


Expand Down Expand Up @@ -93,7 +93,7 @@ def op_checksig(
tapleaf_hash = tagged_hash(b"TapLeaf", preimage)
ext = tapleaf_hash + b"\x00" + codesep_pos.to_bytes(4, "little")
msg_hash = sig_hash.taproot(tx, i, prevouts, sighash_type, 1, annex, ext)
if not ssa_verify(msg_hash, pub_key, signature[:64]): # type: ignore
if not ssa_verify(msg_hash, pub_key, signature[:64]):
raise BTClibValueError()
stack.append(_from_num(int(bool(signature))))
return budget
Expand Down
37 changes: 37 additions & 0 deletions docs/source/btclib.script.engine.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
btclib.script.engine package
============================

Submodules
----------

btclib.script.engine.script module
----------------------------------

.. automodule:: btclib.script.engine.script
:members:
:undoc-members:
:show-inheritance:

btclib.script.engine.script\_op\_codes module
---------------------------------------------

.. automodule:: btclib.script.engine.script_op_codes
:members:
:undoc-members:
:show-inheritance:

btclib.script.engine.tapscript module
-------------------------------------

.. automodule:: btclib.script.engine.tapscript
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------

.. automodule:: btclib.script.engine
:members:
:undoc-members:
:show-inheritance:
16 changes: 16 additions & 0 deletions docs/source/btclib.script.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
btclib.script package
=====================

Subpackages
-----------

.. toctree::
:maxdepth: 4

btclib.script.engine

Submodules
----------

btclib.script.op\_codes\_tapscript module
-----------------------------------------

.. automodule:: btclib.script.op_codes_tapscript
:members:
:undoc-members:
:show-inheritance:

btclib.script.script module
---------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
project = "btclib"
project_copyright = "2017-2023 The btclib developers"
author = "The btclib developers"
release = "2023.5.30"
release = "2023.7.12"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# or distributed except according to the terms contained in the LICENSE file.
"""Build script for setuptools."""

from setuptools import find_packages, setup # type: ignore
from setuptools import find_namespace_packages, setup # type: ignore[import]

import btclib

Expand All @@ -34,7 +34,7 @@
description="A library for 'bitcoin cryptography'",
long_description=longdescription,
long_description_content_type="text/markdown",
packages=find_packages(exclude=["tests", "tests.*"]),
packages=find_namespace_packages(exclude=["tests", "tests.*"]),
include_package_data=True,
# test_suite="btclib.tests",
install_requires=["btclib_libsecp256k1"],
Expand Down
8 changes: 5 additions & 3 deletions tests/ecc/test_rfc6979.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from os import path

from btclib.ec import mult
from btclib.ec.curve import CURVES
from btclib.ec.curve import CURVES, Curve
from btclib.ecc import dsa
from btclib.ecc.rfc6979_nonce import rfc6979_nonce_
from btclib.hashes import reduce_to_hlen
Expand All @@ -31,7 +31,9 @@ def test_rfc6979() -> None:


def test_rfc6979_nonce_example() -> None:
class _helper: # pylint: disable=too-few-public-methods
class _helper(
Curve
): # pylint: disable=too-few-public-methods, super-init-not-called
def __init__(self, n: int) -> None:
self.n = n
self.nlen = n.bit_length()
Expand All @@ -43,7 +45,7 @@ def __init__(self, n: int) -> None:
msg = b"sample"
msg_hash = hashlib.sha256(msg).digest()
k = 0x23AF4074C90A02B3FE61D286D5C87F425E6BDD81B
assert k == rfc6979_nonce_(msg_hash, x, fake_ec) # type: ignore[arg-type]
assert k == rfc6979_nonce_(msg_hash, x, fake_ec)


def test_rfc6979_nonce_tv() -> None:
Expand Down
Loading

0 comments on commit 600cb13

Please sign in to comment.