Disclaimer: This is an educational exercise. This Python code is for testing and should not be used in production or with mainnet Bitcoin. A private key of 3
is absolutely insecure.
There are two Python files in the BIPs repo reference.py
and test_vectors.py
which you can view by cloning the BIPs repo.
git clone https://github.com/bitcoin/bips.git
These two files are in /bitcoin/bips/tree/master/bip-0340
.
If you run python3 test-vectors.py
from within the bip-0340 directory you will get the output and error messages that are in the CSV file test-vectors.csv
.
If you open test-vectors.py
with your text editor e.g. vim test-vectors.py
you can edit any of the test vectors' secret key (private key), message, auxiliary randomness.
For example vector0
has the secret key 3
.
seckey = bytes_from_int(3)
You could change the secret from 3
to 4
.
seckey = bytes_from_int(4)
Save and close your text editor and then run python3 test-vectors.py
again.
This will generate an AssertionError.
Traceback (most recent call last): File "test-vectors.py", line 253, in <module> vector0(), File "test-vectors.py", line 31, in vector0 assert(not has_square_y(pubkey_point)) AssertionError
There is an assert that checks that for a particular public key (X,Y) (calculated from the secret (private) key) the Y coordinate isn't square. This is a check implemented due to a previous design decision to use squaredness as the tiebreaker for two Y coordinates. The tiebreaker is now evenness rather than squaredness. This test is included to catch when an implementer is mistakenly using squaredness rather than evenness. In this case the public key has a square Y coordinate.
Every private key (scalar) maps to a single corresponding public key (point). In BIP 340 we restrict ourselves to public keys with an even Y coordinate. This could lead to only half of the public keys being valid and hence only half of the private keys being valid too. Instead we say that every private key has a public key and if d.G
has an odd Y coordinate we effectively sign with -d (the negated private key) instead.
Negated means taking the complement with the group order n
-m = n-m (mod n)
With that change you could say that every scalar is a valid private key but there are two private keys that map to the same public key. Only one private key maps to a public key with an even Y coordinate though. (Only one BIP 340 private key maps to a BIP 340 public key.)
Remember when you are finished experimenting you can use this to reset:
git reset --hard HEAD
This will discard the changes you have made and go back to the state of the code before you started experimenting.
Thanks to Pieter Wuille on IRC for some additions.
You can get bonuses upto $100 FREE BONUS when you:
π° Install these recommended apps:
π² SocialGood - 100% Crypto Back on Everyday Shopping
π² xPortal - The DeFi For The Next Billion
π² CryptoTab Browser - Lightweight, fast, and ready to mine!
π° Register on these recommended exchanges:
π‘ Binanceπ‘ Bitfinexπ‘ Bitmartπ‘ Bittrexπ‘ Bitget
π‘ CoinExπ‘ Crypto.comπ‘ Gate.ioπ‘ Huobiπ‘ Kucoin.
Comments