Bitcoin Forum
April 18, 2024, 02:45:02 PM *
News: Latest Bitcoin Core release: 26.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Bitcoin Message Tool - command-line signer & verifier  (Read 482 times)
witcher_sense (OP)
Legendary
*
Offline Offline

Activity: 2310
Merit: 4313

🔐BitcoinMessage.Tools🔑


View Profile WWW
January 31, 2023, 05:51:51 AM
Last edit: February 02, 2023, 02:30:18 PM by witcher_sense
Merited by ABCbits (20), Symmetrick (14), Welsh (12), NotATether (10), vapourminer (8), dkbit98 (5), NeuroticFish (3), RickDeckard (2), n0nce (2), mocacinno (1), DdmrDdmr (1), Financisto (1)
 #1

Introduction

A 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.mediawiki

Wallets 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.

Installation

1)To install with pip, run:

Code:
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):

Code:
poetry new bmt

Code:
cd ./bmt

Create a new virtual environment:

Code:
poetry install
Code:
poetry shell

Download the application from PyPi via this command:
Code:
poetry add bitcoin-message-tool

To run it from the terminal use this command:

Code:
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:

Code:
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:

Code:
pip install -r /path/to/requirements.txt

To run an application from the forked or cloned repo, you can simply use the following:

Code:
python3 /path/to/bmt.py -h

How to use Bitcoin Message Tool

The following doctest should give a clear picture about how to sign a nd verify messages with this CLI tool:

Basic usage:

Code:
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:

Code:
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

Code:
$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:

Code:
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:

Code:
-----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:

Code:
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

Code:
python bmt.py verify -a 175A5YsPUdM71mnNCC3i8faxxYJgBonjWL \
> -m ECDSA is the most fun I have ever experienced \
> -s HyiLDcQQ1p2bKmyqM0e5oIBQtKSZds4kJQ+VbZWpr0kYA6Qkam2MlUeTr+lm1teUGHuLapfa43JjyrRqdSA0pxs= \
> -v

Output:

Code:
True
Message verified to be from 175A5YsPUdM71mnNCC3i8faxxYJgBonjWL

More examples and source code can be found here: https://github.com/shadowy-pycoder/bitcoin_message_tool

Tests with Sparrow Wallet

Let's verify a SegWit signature created with real wallet:



Result:



Let's verify a SegWit signature created by this tool:



Result:


█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
1713451502
Hero Member
*
Offline Offline

Posts: 1713451502

View Profile Personal Message (Offline)

Ignore
1713451502
Reply with quote  #2

1713451502
Report to moderator
1713451502
Hero Member
*
Offline Offline

Posts: 1713451502

View Profile Personal Message (Offline)

Ignore
1713451502
Reply with quote  #2

1713451502
Report to moderator
1713451502
Hero Member
*
Offline Offline

Posts: 1713451502

View Profile Personal Message (Offline)

Ignore
1713451502
Reply with quote  #2

1713451502
Report to moderator
The Bitcoin network protocol was designed to be extremely flexible. It can be used to create timed transactions, escrow transactions, multi-signature transactions, etc. The current features of the client only hint at what will be possible in the future.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1713451502
Hero Member
*
Offline Offline

Posts: 1713451502

View Profile Personal Message (Offline)

Ignore
1713451502
Reply with quote  #2

1713451502
Report to moderator
1713451502
Hero Member
*
Offline Offline

Posts: 1713451502

View Profile Personal Message (Offline)

Ignore
1713451502
Reply with quote  #2

1713451502
Report to moderator
NotATether
Legendary
*
Offline Offline

Activity: 1582
Merit: 6670


bitcoincleanup.com / bitmixlist.org


View Profile WWW
January 31, 2023, 10:28:13 AM
Merited by NeuroticFish (2), Welsh (2), witcher_sense (2)
 #2

Really awesome stuff you made there.

In the case of Segwit addresses and BIP137, you can use this draft BIP I made a while ago (https://notatether.com/notabips/bip-notatether-messageverify/) that assigns some integer values for P2WPKH messages (39-42 for P2WPKH and even 43-46 for P2TR). It's unfortunate that it was never considered for numbering though (Luke didn't see the need for it).

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
witcher_sense (OP)
Legendary
*
Offline Offline

Activity: 2310
Merit: 4313

🔐BitcoinMessage.Tools🔑


View Profile WWW
January 31, 2023, 01:31:15 PM
Merited by Welsh (2), ABCbits (1)
 #3

Really awesome stuff you made there.

In the case of Segwit addresses and BIP137, you can use this draft BIP I made a while ago (https://notatether.com/notabips/bip-notatether-messageverify/) that assigns some integer values for P2WPKH messages (39-42 for P2WPKH and even 43-46 for P2TR). It's unfortunate that it was never considered for numbering though (Luke didn't see the need for it).
This tool actually recognizes Taproot headers and doesn't necessarily consider them "invalid". Here is the code snippet:

Code:
def verify_message(address: str, message: str, signature: str, /) -> tuple[bool, str, str]:
    ...
    if header < 27 or header > 46:
        raise SignatureError('Header byte out of range:', header)
    ...
    uncompressed = False
    addr_type = 'p2pkh'
    if header >= 43:
        header -= 16
        addr_type = ''
    ...
    if addr_type:
        addr, _ = derive_address(pubkey, addr_type)
    else:
        raise SignatureError('Unknown address type')
   ...

When headers are within 42-46 range, addr_type variable is assigned to an empty string instead of 'p2tr' because derive_address function has no idea how to handle this type of addresses. Honestly, I don't know much about Taproot addresses, but I think that implementing it requires additional non-ECDSA functions for signature signing and verification.

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
witcher_sense (OP)
Legendary
*
Offline Offline

Activity: 2310
Merit: 4313

🔐BitcoinMessage.Tools🔑


View Profile WWW
February 02, 2023, 02:23:27 PM
 #4

Added experimental support for Electrum signatures. In order to sign and verify messages recognizable by Electrum wallet, specify a new flag:

Code:
-e/--electrum

Some examples:


Message signing:

First, we create the signature in Bitcoin Message Tool:



Second, check if Electrum understands what we feed it:



Message verification:

First we sign our message in Electrum wallet:



Check if we can verify it:



In all examples, I specified -e flag, otherwise, neither I nor Electrum would understand each other.
Please note, however, Electrum will verify BIP137 signatures (without the -e flag), but it can't create them (we can't verify them without the -e flag specified). This is for Segwit only: legacy addresses should work with or without the -e flag.

More information can be found here: https://github.com/spesmilo/electrum/pull/7668

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
witcher_sense (OP)
Legendary
*
Offline Offline

Activity: 2310
Merit: 4313

🔐BitcoinMessage.Tools🔑


View Profile WWW
August 14, 2023, 11:48:08 AM
 #5

Really awesome stuff you made there.

In the case of Segwit addresses and BIP137, you can use this draft BIP I made a while ago (https://notatether.com/notabips/bip-notatether-messageverify/) that assigns some integer values for P2WPKH messages (39-42 for P2WPKH and even 43-46 for P2TR). It's unfortunate that it was never considered for numbering though (Luke didn't see the need for it).
Since people on GitHub started requesting to add Taproot support in the bitcoin message tool, I am considering implementing the algorithm described in your proposal. But I ran into two problems: the first one is that the link you provided doesn't work anymore, and the second one, which is more serious, is that I completely unfamiliar with the Taproot algorithm, especially with the parts that describe how it deals with address creation, signature verification, and signature signing. Could you explain in very layman's terms how your algorithm is different from standard Legacy/Segwit ones?

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
NotATether
Legendary
*
Offline Offline

Activity: 1582
Merit: 6670


bitcoincleanup.com / bitmixlist.org


View Profile WWW
August 15, 2023, 08:32:19 AM
Last edit: August 15, 2023, 08:49:37 AM by NotATether
Merited by witcher_sense (4), vapourminer (1)
 #6

Really awesome stuff you made there.

In the case of Segwit addresses and BIP137, you can use this draft BIP I made a while ago (https://notatether.com/notabips/bip-notatether-messageverify/) that assigns some integer values for P2WPKH messages (39-42 for P2WPKH and even 43-46 for P2TR). It's unfortunate that it was never considered for numbering though (Luke didn't see the need for it).
Since people on GitHub started requesting to add Taproot support in the bitcoin message tool, I am considering implementing the algorithm described in your proposal. But I ran into two problems: the first one is that the link you provided doesn't work anymore, and the second one, which is more serious, is that I completely unfamiliar with the Taproot algorithm, especially with the parts that describe how it deals with address creation, signature verification, and signature signing. Could you explain in very layman's terms how your algorithm is different from standard Legacy/Segwit ones?

Ah shit, looks like my website is down again since yesterday, so I'm going to have to diagnose that pronto.

Edit: A plugin crashed, got rid of it and it works now.

As for your second question:

Message signing is only "officially" defined for Legacy address types, as it was added by Satoshi himself and there is not even a BIP for it.

It basically works by doing a standard ECDSA with the private key and the message setting a value based on whether the address is compressed legacy or uncompressed legacy - this value is stored as bytes before the R and S values.

In the case of Taproot, it is using Schnorr algorithm, not ECDSA. So all that is necessary to do is make a change of algorithm, and define new values for indicating Taproot (and segwit) addresses, and that's pretty much what this BIP does.

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
witcher_sense (OP)
Legendary
*
Offline Offline

Activity: 2310
Merit: 4313

🔐BitcoinMessage.Tools🔑


View Profile WWW
August 15, 2023, 03:18:21 PM
 #7

In the case of Taproot, it is using Schnorr algorithm, not ECDSA. So all that is necessary to do is make a change of algorithm, and define new values for indicating Taproot (and segwit) addresses, and that's pretty much what this BIP does.
I am reading your proposal and also https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki but still fail to understand what such notations like BIP0340/challenge, BIP0340/aux, BIP0340/nonce actually mean. How are they calculated or where should I take them from? Also, what is tagged hash in layman terms?

Just for reference, here is a python implementation of bech32m addresses: https://github.com/sipa/bech32/blob/master/ref/python/segwit_addr.py

Someone published it on PyPi: https://pypi.org/project/bech32m/

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
Financisto
Hero Member
*****
Offline Offline

Activity: 630
Merit: 767

BTC⇆⚡⇄BTC


View Profile WWW
March 26, 2024, 04:30:44 AM
Last edit: March 28, 2024, 04:40:51 PM by Financisto
 #8

Is it possible (in the near future) to provide a single AppImage file (or single binary file, or single executable file, etc) as a Github-release?

P.S. Your project reminded me of this HTML/Javascript Brainwallet (WarpWallet's fork) turned into a single CLI executable file: https://github.com/moncho/warpwallet

Providing that option would be great for UX!

Last but not least: your CLI BTC msg tool is awesome!

Congratulations and keep it evolving!

Cheers!

BitcoinTalk's ESCROW Providers: Ranking & BlacklistCompilation of (open-source) BRAINWALLET projectsBTC ⇆⚡⇄ BTCBTC aka BTC: 16MBvhaJoRBxW3Vk6apnvz3UYT9HAgraVS ⚡ PGP: 2680207AA9A1B69FE7A033D80DE0F221074384C4 ⚡ If you think freedom matters, please support the development of these privacy projects→DONATE some sats: TailsQubes OSWhonixVeraCryptPicocryptKryptorSimpleX Chat
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!