IntroductionA lightweight fully open-source CLI tool for signing and verification of bitcoin messages. Bitcoin message is the most straightforward and natural way to prove ownership over a given address without revealing any confidential information.
This tool closely follows specification described in BIP137:
"...While there was no BIP written for how to digitally sign messages with Bitcoin private keys with P2PKH addresses it is a fairly well understood process, however with the introduction of Segwit (both in the form of P2SH and bech32) addresses, it is unclear how to distinguish a P2PKH, P2SH, or bech32 address from one another. This BIP proposes a standard signature format that will allow clients to distinguish between the different address formats."
Please note that:
"since this format includes P2PKH keys, it is backwards compatible, but keep in mind some software has checks for ranges of headers and will report the newer segwit header types as errors."More info:
https://github.com/bitcoin/bips/blob/master/bip-0137.mediawikiWallets that fully support BIP137 type of signatures:
1) Trezor
2) Sparrow Wallet
3) Coldcard?
4) ...
This tool is basically an attempt to expand the use of this standard.
Installation1)To install with pip, run:
pip install bitcoin-message-tool
You can create a virtual environment for this application and run it from there, for example using Poetry.
Create a new folder (bmt is short for Bitcoin Message Tool or you can choose whatever you want):
Create a new virtual environment:
Download the application from PyPi via this command:
poetry add bitcoin-message-tool
To run it from the terminal use this command:
python3 -m bitcoin_message_tool
When you run the app without arguments, you will see a help message.
2) Alternatively, you can download the source code directly from GitHub via this command:
git clone https://github.com/shadowy-pycoder/bitcoin_message_tool.git
or you can fork the repo and than clone the forked version
Install requirements via this command:
pip install -r /path/to/requirements.txt
To run an application from the forked or cloned repo, you can simply use the following:
python3 /path/to/bmt.py -h
How to use Bitcoin Message ToolThe following doctest should give a clear picture about how to sign a nd verify messages with this CLI tool:
Basic usage:
python -m bitcoin_message_tool -h
or
python bmt.py -h
usage: python3 bmt.py [-h] {sign,verify} ...
Bitcoin message signing/verification tool
positional arguments:
{sign,verify}
options:
-h, --help show this help message and exit
Message signing:
python bmt.py sign -h
usage: python3 bmt.py sign [-h] -p -a {p2pkh,p2wpkh-p2sh,p2wpkh} -m [MESSAGE ...] [-d] [-v]
options:
-h, --help show this help message and exit
Sign messsage:
-p, --privkey private key in wallet import format (WIF)
-a {p2pkh,p2wpkh-p2sh,p2wpkh}, --addr_type {p2pkh,p2wpkh-p2sh,p2wpkh}
type of bitcoin address
-m [MESSAGE ...], --message [MESSAGE ...]
Message to sign
-d, --deterministic sign deterministtically (RFC6979)
-v, --verbose print prettified message
Example: Non-deterministic signature for compressed private key and p2pkh address
$python bmt.py sign -p -a p2pkh -m ECDSA is the most fun I have ever experienced
PrivateKey(WIF): <insert private key here>
Please note that private key won't show up on the terminal.
Output:
Bitcoin address: 175A5YsPUdM71mnNCC3i8faxxYJgBonjWL
Message: ECDSA is the most fun I have ever experienced
Signature: IBuc5GXSJCr6m7KevsBAoCiX8ToOjW2CDZMr6PCEbiHwQJ237LZTj/REbDHI1/yelY6uBWEWXiOWoGnajlgvO/A=
The same output with -v/--verbose flag:
-----BEGIN BITCOIN SIGNED MESSAGE-----
ECDSA is the most fun I have ever experienced
-----BEGIN BITCOIN SIGNATURE-----
175A5YsPUdM71mnNCC3i8faxxYJgBonjWL
IBuc5GXSJCr6m7KevsBAoCiX8ToOjW2CDZMr6PCEbiHwQJ237LZTj/REbDHI1/yelY6uBWEWXiOWoGnajlgvO/A=
-----END BITCOIN SIGNATURE-----
Message verification:
python bmt.py verify -h
usage: python3 bmt.py verify [-h] -a ADDRESS -m [MESSAGE ...] -s SIGNATURE [-v] [-r]
options:
-h, --help show this help message and exit
Verify messsage:
-a ADDRESS, --address ADDRESS
specify bitcoin address
-m [MESSAGE ...], --message [MESSAGE ...]
Message to verify
-s SIGNATURE, --signature SIGNATURE
bitcoin signature in base64 format
-v, --verbose print full message
-r, --recpub recover public key
Example: Message verification in verbose mode
python bmt.py verify -a 175A5YsPUdM71mnNCC3i8faxxYJgBonjWL \
> -m ECDSA is the most fun I have ever experienced \
> -s HyiLDcQQ1p2bKmyqM0e5oIBQtKSZds4kJQ+VbZWpr0kYA6Qkam2MlUeTr+lm1teUGHuLapfa43JjyrRqdSA0pxs= \
> -v
Output:
True
Message verified to be from 175A5YsPUdM71mnNCC3i8faxxYJgBonjWL
More examples and source code can be found here:
https://github.com/shadowy-pycoder/bitcoin_message_toolTests with Sparrow WalletLet's verify a SegWit signature created with real wallet:
![](https://ip.bitcointalk.org/?u=https%3A%2F%2Fi.ibb.co%2FhHxnG0V%2FIMG-20230131-081915-189.png&t=665&c=HUZvnhfX5vd38g)
Result:
![](https://ip.bitcointalk.org/?u=https%3A%2F%2Fi.ibb.co%2FMC5knZ3%2FScreenshot-2023-01-31-08-28-49-549-edit-com-termux.jpg&t=665&c=5iyfkzN34sTwlA)
Let's verify a SegWit signature created by this tool:
![](https://ip.bitcointalk.org/?u=https%3A%2F%2Fi.ibb.co%2FD1CKJ5G%2FScreenshot-2023-01-31-08-43-47-964-edit-com-termux.jpg&t=665&c=SkgWsNKyijQoPA)
Result:
![](https://ip.bitcointalk.org/?u=https%3A%2F%2Fi.ibb.co%2Ft2syZsH%2FIMG-20230131-084712-671.png&t=665&c=Vw3Ooufrri92cw)