Skip to content

v0.7.1.2

Choose a tag to compare

@github-actions github-actions released this 07 Aug 12:10
· 16 commits to master since this release

The same
libsecp256k1 0.7.1
(1a53f49) as v0.7.1: no breaking changes — nothing in the public API
moved, and the one wrapper whose behaviour changed changed the text of an
error message. What a fourth number carries here is one new function, the
contract of every function where a caller reads it, a static extension
compiled the way the interpreter compiles its own, and metadata that says
what the wheels are.

  • keys.pubkey_from_prvkey is the public key of a private key,
    compressed by default, and the 65 bytes of mult.mult_ with
    compressed=False — which is what mult_ now is. Generator
    multiplication was the one producer here that could not answer the
    compressed form, so a caller who wanted the 33 bytes had to parse and
    re-serialize what libsecp256k1 had just serialized, or slice the parity
    out of the 65 bytes themselves. mult_ answers exactly what it did;
    the one thing to know is that the ValueError of a scalar outside
    [1, n-1] now names a private key, which is what
    secp256k1_ec_pubkey_create calls its argument, so code matching on
    that message matches on the new text.
  • Every function documents its arguments, its return value and what it
    raises.
    That contract used to be prose in the README, several hundred
    lines from the functions it applies to, which for a package shipped as
    a compiled wheel is all a reader of help() or of an IDE tooltip
    could have had. mult.mult_ and mult.mult, which shared a docstring
    verbatim while returning 65 uncompressed bytes and a pair of ints, now
    each say which. A pydoclint hook keeps it that way.
  • The README opens with a Quickstart — sign and verify, ECDSA and
    BIP340 — and every example in it, and in every docstring, is executed
    by the suite on each interpreter and each kind of wheel. An example
    that stops working fails a build instead of sitting there.
  • The static extension is faster on Unix, and correct on universal2.
    It was compiled without the interpreter's own CFLAGS: no
    optimization at all, unlike everything CMake builds beside it, and on
    a universal2 interpreter a single-arch object inside a dual-arch
    bundle.
  • A wheel whose extensions disagree on static or dynamic is refused
    rather than reported. It would have been tagged py3-none-<platform>
    while holding an ABI-specific extension: installable on any
    interpreter of that platform, and broken on most of them.
  • The classifiers say what the package is: the three systems the
    wheels are built for instead of OS Independent, and Typing :: Typed, which is the classifier PyPI users filter on.
  • More of the library is held to published vectors: BIP324 for
    ellswift encoding and the ellswift_xdh shared secret, BIP327 for
    every step of MuSig2 aggregation, the four long BIP340 messages
    through ssa.sign_custom, and recovery ids 2 and 3, which no test had
    ever reached.
  • Two hooks that were passing without reading a file now read one.
    The copyright notice hook was checking only newly added staged files,
    so on a clean checkout — every run in CI — it checked nothing; the
    entropy detectors of detect-secrets were off for the whole tree
    rather than for the vector files that motivated it.
  • The release path checks before it builds what it used to discover
    after uploading
    : that the tag is on master, and that this file has
    a section for it. A rehearsal re-run gets a version of its own instead
    of colliding with itself on TestPyPI, and no longer shares a
    concurrency group with a push to the branch it was dispatched from.