Skip to content

Instantly share code, notes, and snippets.

View qlrd's full-sized avatar
🏠
Working from home

qlrd qlrd

🏠
Working from home
View GitHub Profile
@qlrd
qlrd / verify-decorators.py
Last active June 19, 2026 12:22
Verify decorators behaviour both on Cpython an Micropython
#!/usr/bin/env python3
#
# Usage:
# uv run python3 verify-decorators.py
# uv run micropython verify-decorators.py
import sys
TITLE = "verify __new__ decorators"
@qlrd
qlrd / test_bip137_p2tr.py
Created June 1, 2026 20:46
krux PR #866 — does pre-PR taproot BIP-137 signing round-trip through a lenient verifier? (pytest)
"""test_bip137_p2tr.py — does the pre-PR krux taproot message-signing
path round-trip through a "lenient" BIP-137 verifier?
Context (selfcustody/krux PR #866):
On `develop`, single-sig P2TR message signing flows through
`_sign_at_address` -> `Key.sign_at`. The signature is over the
standard Bitcoin-signed-message commitment, produced as an
ECDSA-recoverable sig over the BIP-86 INTERNAL key (the raw
m/86'/.../ private scalar). The header byte stays in 31-34
@qlrd
qlrd / bip137_old_vs_new.py
Last active May 29, 2026 00:22
krux BIP-137 — compare pre-fix vs post-fix signing for P2PKH / P2SH-P2WPKH / P2WPKH
#!/usr/bin/env python3
"""bip137_old_vs_new.py — pre-fix vs post-fix krux BIP-137 message signing.
Reproduces the two krux signing variants side-by-side:
- "old": the pre-fix behavior. `key.sign_at` emits a header byte in the
P2PKH-compressed range (31-34) regardless of the wallet's actual
script type, so signatures for P2WPKH / P2SH-P2WPKH addresses
are non-compliant with BIP-137 §"Header byte".

Keybase proof

I hereby claim:

  • I am qlrd on github.
  • I am qlrd (https://keybase.io/qlrd) on keybase.
  • I have a public key ASB_YwZ61fpD7VSXOlE5REPV2Wr5IszndPbhg4Z_9AIW_go

To claim this, I am signing this object:

@qlrd
qlrd / solution.py
Last active February 20, 2025 19:10
"""
solution.py
Read:
- https://gist.github.com/qlrd/0eed0c8a56aeab3f8894c6d67694d690
- https://gist.github.com/qlrd/d1696dd63e15d89ecbc191fa2d734b36
- https://gist.github.com/qlrd/1b6f6edc99915acee72f7c73b3e649f0
- https://gist.github.com/qlrd/aca897acb42f0b6cbd07d7337f16c790

a derivation path m/48'/0'/0'/<index>'

Once you have entered the passphrase, you will need to select a miniscript policy with a specific type of descriptor (either P2WSH or P2TR), and a custom derivation path m/48'/0'/0'/<index>' to spend the funds.

Basically, the index is a number that you will need to figure out to construct the given descriptor:

# <descriptor> : wsh || tr
#  -&gt; 0, 1, 2, 3 ... who knows?

Find a password to decrypt a qrcode;

After finding the mnemonic, you must find a 13th/25th word for this mnemonic. To find that, you will do the same thing as in the first part of this challenge:

derive_this_to_generate_the_passphrase = b" ".join([
    b"word 1",
    b"word 2",
    b"word 3",
 b"word 4",

Get the correct mnemonic

To solve this puzzle, it is useful to know that krux supports:

  • BIP39 with and without passphrases;
  • DoubleMnemonic (a valid 24w BIP39 mnemonic where the first and second halves are both valid mnemonics);
  • BIP85 derived 12w and 24w BIP39 mnemonics

A password to decrypt a qrcode

Scan this qrcode and type a sequence of characters that decrypt the QR code.

5ef3b16a pic.twitter.com/2P3G7ux3KE

— qlrd (@qlrddev) February 20, 2025

To find out the "password", you will need to edit solution.py. It have a line where you'll find a certain variable that require a byte string as input to the solution function. The output of solution will be the key to decrypt the mnemonic.

For example:

Miniscript challenge

Build a simple inheritance scheme on Liana and try to spend a ~170000 sats.

Prelude

During the workshop at BTC++ in 2025, the speaker created a simple inheritance scheme and put you as his heir. He can spend at any time, but you only can spend after some time.

Preliminary instructions