Skip to content

Instantly share code, notes, and snippets.

AdamISZ /
Last active July 17, 2024 02:08
Chaumian ecash designs, notes

Chaumian cash in a Bitcoin world - cashu, Fedimint

What's this for?

  • More scalable/faster than a blockchain (not enough utxos)
  • Much better privacy security model than a blockchain
  • Same or better theft security model than TTP but much worse than a blockchain

If it's so great, why hasn't it been done yet?

AdamISZ /
Created December 27, 2018 18:48
Basic payjoin/p2ep protocol for Joinmarket wallets

Described here is a variant of what has previously been published under the name "P2EP" or Pay-to-endpoint, in which A pays B but B contributes utxos, i.e. it's a coinjoin-payment.

I'm using the term "payjoin" here to refer to using that idea, but not including a URI/endpoint specific to B, and not allowing (as a merchant would) arbitrary payments, which opens up certain problems around snooping attackers (more on this below). So payjoin just means "A pays B but B actively participates and passes across utxos as extra inputs".

I'll defer a more features-focused and non-tech friendly description of what this means to a later blogpost.

AdamISZ /
Last active June 25, 2024 03:19
Forgery with a fake key in MuSig2

As per footnote 2 in the draft BIP here, it is possible in MuSig2 to create a partial signature which verifies correctly to the other participants, even though the adversary does not know the secret key corresponding to the given public key, but only by the adversary taking the role of at least one other participant, and in that case it is not possible to create a partial signature for that other public key, even if the corresponding private key is known.

The purpose of this gist is to work through the mathematical details of the above statement, as it isn't, probably, obvious to most readers (although it may be at least somewhat intuitive - think about 'free variables').

Setup: keyset $L = X_1 , X_2 , X_3 , X_4 , X_5$. The adversary will take the roles of indices 4 and 5, and will forge a partial signature on key $X_4$, not knowing the corresponding secret $x_4$, on a given message $m$. Assume the adversary does kn

AdamISZ /
Created April 25, 2021 16:24
MuSig2 toy implementation in Python for learning purposes
As for reading it, start with the `__main__`
section at the bottom and go from there.
Comments are, deliberately, voluminous.
If you want to run the example, just:
(a) install Joinmarket (else see the notes on import)
AdamISZ /
Created November 22, 2021 19:53
Testing script path spending in taproot with python-bitcointx
import bitcointx as btc
from bitcointx.wallet import CCoinKey
from bitcointx.core import COutPoint, CTxIn, CTxOut, CMutableTransaction, CTxInWitness
from bitcointx.core.script import (CScript, OP_CHECKSIGADD, OP_CHECKSIG, OP_NUMEQUAL,
TaprootScriptTree, CScriptWitness)
from bitcointx.wallet import P2TRCoinAddress
from binascii import hexlify, unhexlify
AdamISZ / electrumx-regtest-setup-notes.txt
Created December 25, 2017 18:03
Electrum X regtest setup (very rough notes)
pre-requisite: a Bitcoin Core instance, set up regtest and start running it.
Before starting run, set up a bitcoin conf in say ~/bitcoin.conf and put:
Then, ./bitcoind -regtest -daemon -conf=/home/username/bitcoin.conf
or whatever. Make sure to generate some blocks.
AdamISZ /
Created February 1, 2021 12:55
Concise instructions on setting up Joinmarket for testing on signet

Concise instructions on setting up Joinmarket for testing on signet

  • Install Bitcoin Core v0.21.0+ from
  • Edit the bitcoin.conf file (create a new version/back up normal conf file), and put a [signet] section, in which your rpc wallet file is set using a line wallet=..
  • Start bitcoind: ./bitcoind -signet
  • To check when it's synced you can tail -f ~/.bitcoin/signet/debug.log to watch the sync happen. It should be fast; only took perhaps a couple of minutes for me, even though I have a slow internet connection.
  • Once synced configure Joinmarket. As with bitcoind, create a new config file to use by copying an existing mainnet or testnet config file joinmarket.cfg. Settings:
    • rpc_port = 38332
    • network = signet
AdamISZ /
Last active January 16, 2024 10:20
On chain contracting - privacy enhancing use-cases

On-chain contracting for privacy

(thanks to @fivepiece for significant contributions to these ideas)

"On chain contracting" is of course a very generic term; it applies to multisignature, coinjoin, coinswap or other exotic transactions that involve more than one party in one transaction (coinjoin, multisig) or multiple transactions (swaps with atomic-via-secret).

Here we're going to focus on a broader model that may allow more complex setups, with a focus on how they may apply to gaining privacy, although this model may well be useful in other ways too.

AdamISZ /
Last active November 17, 2023 02:31



Before we begin: this post describes a very limited protocol idea. It's possible that what we describe here is a start towards, or a component of, something genuinely useful, but in itself it's really more of a toy, albeit it's fun.

Non-interactive digital cash

Since the 90s, there was a dream that cash could be sent online just like email. We've basically been experimenting with tradeoffs against this pure vision ever since. Sometimes the tradeoff is: there's a central party we have to trust (either with our privacy or our money or the management or inflation or..), but otherwise we get the goal. Often the tradeoff includes: we have to interact with the receiver. In pretty much every case there's an online-ness requirement: we have to exchange messages with a p2p network of active nodes (bitcoin) or a central server and our counterparty, or at least, directly with our counterparty (e.g. Lightning) in the payment transaction.

AdamISZ /
Created September 13, 2023 00:40
How to prove you're Satoshi
# A reminder of how to "prove" you're Satoshi.
# ("reminder" - this was done (with tongue in cheek, presumably)
# by someone on Twitter a few years ago).
# 1. We need the public key of the receiving address of (e.g.) block 1.
# it is on the blockchain in uncompressed form (P2PK):
block1_uncompressed_output_key_hex = "0496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858ee"