print("p2wpkh_p2sh:", address2.decode()) address3 = p2wpkh(pubkey) print(" p2wpkh:", address3.decode()) print("\n3. Sign message with no address (or with compressed p2pkh address):") sig1 = sign(msg, wif) print(f"rf1: {sig1[0]}") print(f" r1: {hex(sig1[1]).upper()}") print(f" s1: {hex(sig1[2]).upper()}") bsmsig1 = encode(*sig1) print("4. Serialized signature:") print(bsmsig1.decode()) print("5. Verify signature") print("Bitcoin Core p2pkh :", verify(msg, address1, sig1)) print("Electrum p2wpkh_p2sh:", verify(msg, address2, sig1)) print("Electrum p2wpkh :", verify(msg, address3, sig1)) print("\n3. Sign message with p2wpkh_p2sh address (BIP137):") sig2 = sign(msg, wif, address2) print(f"rf2: {sig2[0]}") print(f" r2: {hex(sig2[1]).upper()}") print(f" s2: {hex(sig2[2]).upper()}") bsmsig2 = encode(*sig2) print("4. Serialized signature:") print(bsmsig2.decode()) print("5. Verify signature") print("Bitcoin Core p2pkh:", verify(msg, address1, sig2))
print("valid ECDSA sig:", dsa_valid) # ECSSA print("\n ECSSA") ssa_prv, ssa_pub = ssa.gen_keys() print("prv", hex(ssa_prv)) print("pub", hex(ssa_pub)) ssa_sig = ssa.sign(msg, ssa_prv) print("r:", hex(ssa_sig[0])) print("s:", hex(ssa_sig[1])) ssa_valid = ssa.verify(msg, ssa_pub, ssa_sig) print("valid ECSSA sig:", ssa_valid) # ECBMS print("\n ECBMS") bms_prv, bms_pub = bms.gen_keys() print("prv", bms_prv) print("pub", bms_pub) bms_sig = bms.sign(msg, bms_prv) print("rf:", hex(bms_sig[0])) print("r:", hex(bms_sig[1])) print("s:", hex(bms_sig[2])) bms_valid = bms.verify(msg, bms_pub, bms_sig) print("valid ECBMS sig:", bms_valid)
def test_sign_strippable_message() -> None: wif = "Ky1XfDK2v6wHPazA6ECaD8UctEoShXdchgABjpU9GWGZDxVRDBMJ" address = "1DAag8qiPLHh6hMFVu9qJQm9ro1HtwuyK5" msg = "" exp_sig = "IFh0InGTy8lLCs03yoUIpJU6MUbi0La/4abhVxyKcCsoUiF3RM7lg51rCqyoOZ8Yt43h8LZrmj7nwwO3HIfesiw=" assert bms.verify(msg, address, exp_sig) sig = bms.sign(msg, wif) assert bms.verify(msg, address, sig) assert bms.encode(*sig) == exp_sig.encode() # Bitcoin Core exp_sig (Electrum does strip leading/trailing spaces) msg = " " exp_sig = "IEveV6CMmOk5lFP+oDbw8cir/OkhJn4S767wt+YwhzHnEYcFOb/uC6rrVmTtG3M43mzfObA0Nn1n9CRcv5IGyak=" assert bms.verify(msg, address, exp_sig) sig = bms.sign(msg, wif) assert bms.verify(msg, address, sig) assert bms.encode(*sig) == exp_sig.encode() # Bitcoin Core exp_sig (Electrum does strip leading/trailing spaces) msg = " " exp_sig = "H/QjF1V4fVI8IHX8ko0SIypmb0yxfaZLF0o56Cif9z8CX24n4petTxolH59pYVMvbTKQkGKpznSiPiQVn83eJF0=" assert bms.verify(msg, address, exp_sig) sig = bms.sign(msg, wif) assert bms.verify(msg, address, sig) assert bms.encode(*sig) == exp_sig.encode() msg = "test" exp_sig = "IJUtN/2LZjh1Vx8Ekj9opnIKA6ohKhWB95PLT/3EFgLnOu9hTuYX4+tJJ60ZyddFMd6dgAYx15oP+jLw2NzgNUo=" assert bms.verify(msg, address, exp_sig) sig = bms.sign(msg, wif) assert bms.verify(msg, address, sig) assert bms.encode(*sig) == exp_sig.encode() # Bitcoin Core exp_sig (Electrum does strip leading/trailing spaces) msg = " test " exp_sig = "IA59z13/HBhvMMJtNwT6K7vJByE40lQUdqEMYhX2tnZSD+IGQIoBGE+1IYGCHCyqHvTvyGeqJTUx5ywb4StuX0s=" assert bms.verify(msg, address, exp_sig) sig = bms.sign(msg, wif) assert bms.verify(msg, address, sig) assert bms.encode(*sig) == exp_sig.encode() # Bitcoin Core exp_sig (Electrum does strip leading/trailing spaces) msg = "test " exp_sig = "IPp9l2w0LVYB4FYKBahs+k1/Oa08j+NTuzriDpPWnWQmfU0+UsJNLIPI8Q/gekrWPv6sDeYsFSG9VybUKDPGMuo=" assert bms.verify(msg, address, exp_sig) sig = bms.sign(msg, wif) assert bms.verify(msg, address, sig) assert bms.encode(*sig) == exp_sig.encode() # Bitcoin Core exp_sig (Electrum does strip leading/trailing spaces) msg = " test" exp_sig = "H1nGwD/kcMSmsYU6qihV2l2+Pa+7SPP9zyViZ59VER+QL9cJsIAtu1CuxfYDAVt3kgr4t3a/Es3PV82M6z0eQAo=" assert bms.verify(msg, address, exp_sig) sig = bms.sign(msg, wif) assert bms.verify(msg, address, sig) assert bms.encode(*sig) == exp_sig.encode()
def test_ledger() -> None: """Hybrid ECDSA Bitcoin message signature generated by Ledger""" mnemonic = ( "barely sun snack this snack relief pipe attack disease boss enlist lawsuit" ) # non-standard leading 31 in DER serialization derivation_path = "m/1" msg = b"\xfb\xa3\x1f\x8cd\x85\xe29#K\xb3{\xfd\xa7<?\x95oL\xee\x19\xb2'oh\xa7]\xd9A\xfeU\xd8" dersig_hex_str = "3144022012ec0c174936c2a46dc657252340b2e6e6dd8c31dd059b6f9f33a90c21af2fba022030e6305b3ccf88009d419bf7651afcfcc0a30898b93ae9de9aa6ac03cf8ec56b" # pubkey derivation rprv = bip32.mxprv_from_bip39_mnemonic(mnemonic) xprv = bip32.derive(rprv, derivation_path) # the actual message being signed magic_msg = bms._magic_message(msg) # save key_id and patch dersig dersig = bytes.fromhex(dersig_hex_str) key_id = dersig[0] dersig = b"\x30" + dersig[1:] r, s = dsa.deserialize(dersig) # ECDSA signature verification of the patched dersig dsa.assert_as_valid(magic_msg, xprv, dersig, ec, hf) assert dsa.verify(magic_msg, xprv, dersig) # compressed address addr = base58address.p2pkh(xprv) # equivalent Bitcoin Message Signature (non-serialized) rec_flag = 27 + 4 + (key_id & 0x01) btcmsgsig = (rec_flag, r, s) # Bitcoin Message Signature verification bms.assert_as_valid(msg, addr, btcmsgsig) assert bms.verify(msg, addr, btcmsgsig) assert not bms.verify(magic_msg, addr, btcmsgsig) bms.sign(msg, xprv) # standard leading 30 in DER serialization derivation_path = "m/0/0" msg_str = "hello world" dersig_hex_str = "3045022100967dac3262b4686e89638c8219c5761017f05cd87a855edf034f4a3ec6b59d3d0220108a4ef9682b71a45979d8c75c393382d9ccb8eb561d73b8c5fc0b87a47e7d27" # pubkey derivation rprv = bip32.mxprv_from_bip39_mnemonic(mnemonic) xprv = bip32.derive(rprv, derivation_path) # the actual message being signed magic_msg = bms._magic_message(msg_str) # save key_id and patch dersig dersig = bytes.fromhex(dersig_hex_str) key_id = dersig[0] dersig = b"\x30" + dersig[1:] r, s = dsa.deserialize(dersig) # ECDSA signature verification of the patched dersig dsa.assert_as_valid(magic_msg, xprv, dersig, ec, hf) assert dsa.verify(magic_msg, xprv, dersig) # compressed address addr = base58address.p2pkh(xprv) # equivalent Bitcoin Message Signature (non-serialized) rec_flag = 27 + 4 + (key_id & 0x01) btcmsgsig = (rec_flag, r, s) # Bitcoin Message Signature verification bms.assert_as_valid(msg_str, addr, btcmsgsig) assert bms.verify(msg_str, addr, btcmsgsig) assert not bms.verify(magic_msg, addr, btcmsgsig)
def test_verify_p2pkh() -> None: msg = "Hello, world!" address = "1FEz167JCVgBvhJBahpzmrsTNewhiwgWVG" exp_sig = "G+WptuOvPCSswt/Ncm1upO4lPSCWbS2cpKariPmHvxX5eOJwgqmdEExMTKvaR0S3f1TXwggLn/m4CbI2jv0SCuM=" assert bms.verify(msg, address, exp_sig) # https://github.com/stequald/bitcoin-bms.sign-message msg = "test message" address = "14dD6ygPi5WXdwwBTt1FBZK3aD8uDem1FY" exp_sig = "IPn9bbEdNUp6+bneZqE2YJbq9Hv5aNILq9E5eZoMSF3/fBX4zjeIN6fpXfGSGPrZyKfHQ/c/kTSP+NIwmyTzMfk=" assert bms.verify(msg, address, exp_sig) # https://github.com/stequald/bitcoin-bms.sign-message msg = "test message" address = "1HUBHMij46Hae75JPdWjeZ5Q7KaL7EFRSD" exp_sig = "G0k+Nt1u5boTTUfLyj6x1T5flg1v9rUKGlhs/jPApaTWLHf3GVdAIOIHip6sVwXEuzQGPWIlS0VT+yryXiDaavw=" assert bms.verify(msg, address, exp_sig) # https://github.com/petertodd/python-bitcoinlib/blob/master/bitcoin/tests/test_signmessage.py msg = address = "1F26pNMrywyZJdr22jErtKcjF8R3Ttt55G" exp_sig = "H85WKpqtNZDrajOnYDgUY+abh0KCAcOsAIOQwx2PftAbLEPRA7mzXA/CjXRxzz0MC225pR/hx02Vf2Ag2x33kU4=" assert bms.verify(msg, address, exp_sig) # https://github.com/nanotube/supybot-bitcoin-marketmonitor/blob/master/GPG/local/bitcoinsig.py msg = "test message" address = "16vqGo3KRKE9kTsTZxKoJKLzwZGTodK3ce" exp_sig = "HPDs1TesA48a9up4QORIuub67VHBM37X66skAYz0Esg23gdfMuCTYDFORc6XGpKZ2/flJ2h/DUF569FJxGoVZ50=" assert bms.verify(msg, address, exp_sig) msg = "test message 2" assert not bms.verify(msg, address, exp_sig) msg = ( "freenode:#bitcoin-otc:b42f7e7ea336db4109df6badc05c6b3ea8bfaa13575b51631c5178a7" ) address = "1GdKjTSg2eMyeVvPV5Nivo6kR8yP2GT7wF" exp_sig = "GyMn9AdYeZIPWLVCiAblOOG18Qqy4fFaqjg5rjH6QT5tNiUXLS6T2o7iuWkV1gc4DbEWvyi8yJ8FvSkmEs3voWE=" assert bms.verify(msg, address, exp_sig) msg = "testtest" address = "1Hpj6xv9AzaaXjPPisQrdAD2tu84cnPv3f" exp_sig = "INEJxQnSu6mwGnLs0E8eirl5g+0cAC9D5M7hALHD9sK0XQ66CH9mas06gNoIX7K1NKTLaj3MzVe8z3pt6apGJ34=" assert bms.verify(msg, address, exp_sig) msg = "testtest" address = "18uitB5ARAhyxmkN2Sa9TbEuoGN1he83BX" exp_sig = "IMAtT1SjRyP6bz6vm5tKDTTTNYS6D8w2RQQyKD3VGPq2i2txGd2ar18L8/nvF1+kAMo5tNc4x0xAOGP0HRjKLjc=" assert bms.verify(msg, address, exp_sig) msg = "testtest" address = "1LsPb3D1o1Z7CzEt1kv5QVxErfqzXxaZXv" exp_sig = "H3I37ur48/fn52ZvWQT+Mj2wXL36gyjfaN5qcgfiVRTJb1eP1li/IacCQspYnUntiRv8r6GDfJYsdiQ5VzlG3As=" assert bms.verify(msg, address, exp_sig) # leading space exp_sig = " H3I37ur48/fn52ZvWQT+Mj2wXL36gyjfaN5qcgfiVRTJb1eP1li/IacCQspYnUntiRv8r6GDfJYsdiQ5VzlG3As=" assert bms.verify(msg, address, exp_sig) # trailing space exp_sig = "H3I37ur48/fn52ZvWQT+Mj2wXL36gyjfaN5qcgfiVRTJb1eP1li/IacCQspYnUntiRv8r6GDfJYsdiQ5VzlG3As= " assert bms.verify(msg, address, exp_sig) # leading and trailing spaces exp_sig = " H3I37ur48/fn52ZvWQT+Mj2wXL36gyjfaN5qcgfiVRTJb1eP1li/IacCQspYnUntiRv8r6GDfJYsdiQ5VzlG3As= " assert bms.verify(msg, address, exp_sig)
def test_exceptions() -> None: msg = "test" wif = "KwELaABegYxcKApCb3kJR9ymecfZZskL9BzVUkQhsqFiUKftb4tu" address = base58address.p2pkh(wif) exp_sig = "IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hSNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLNtoVc=" assert bms.verify(msg, address, exp_sig) _, r, s = bms.decode(exp_sig) err_msg = "invalid recovery flag: " with pytest.raises(BTClibValueError, match=err_msg): bms.encode(26, r, s) exp_sig = "IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLoVc=" err_msg = "wrong signature length: " with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, address, exp_sig) assert not bms.verify(msg, address, exp_sig) exp_sig = "GpNLHqEKSzwXV+KwwBfQthQ848mn5qSkmGDXpqshDuPYJELOnSuRYGQQgBR4PpI+w2tJdD4v+hxElvAaUSqv2eU=" err_msg = "invalid recovery flag: " with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, address, exp_sig) assert not bms.verify(msg, address, exp_sig) exp_sig = "QpNLHqEKSzwXV+KwwBfQthQ848mn5qSkmGDXpqshDuPYJELOnSuRYGQQgBR4PpI+w2tJdD4v+hxElvAaUSqv2eU=" with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, address, exp_sig) assert not bms.verify(msg, address, exp_sig) # compressed wif, uncompressed address wif = "Ky1XfDK2v6wHPazA6ECaD8UctEoShXdchgABjpU9GWGZDxVRDBMJ" address = b"19f7adDYqhHSJm2v7igFWZAqxXHj1vUa3T" err_msg = "mismatch between private key and address" with pytest.raises(BTClibValueError, match=err_msg): bms.sign(msg, wif, address) # uncompressed wif, compressed address wif = "5JDopdKaxz5bXVYXcAnfno6oeSL8dpipxtU1AhfKe3Z58X48srn" address = b"1DAag8qiPLHh6hMFVu9qJQm9ro1HtwuyK5" err_msg = "not a private or compressed public key for mainnet: " # FIXME puzzling error message with pytest.raises(BTClibValueError, match=err_msg): bms.sign(msg, wif, address) msg = "test" wif = "L4xAvhKR35zFcamyHME2ZHfhw5DEyeJvEMovQHQ7DttPTM8NLWCK" b58_p2pkh = base58address.p2pkh(wif) b58_p2wpkh = bech32address.p2wpkh(wif) b58_p2wpkh_p2sh = base58address.p2wpkh_p2sh(wif) wif = "Ky1XfDK2v6wHPazA6ECaD8UctEoShXdchgABjpU9GWGZDxVRDBMJ" err_msg = "mismatch between private key and address" with pytest.raises(BTClibValueError, match=err_msg): bms.sign(msg, wif, b58_p2pkh) with pytest.raises(BTClibValueError, match=err_msg): bms.sign(msg, wif, b58_p2wpkh) with pytest.raises(BTClibValueError, match=err_msg): bms.sign(msg, wif, b58_p2wpkh_p2sh) # Invalid recovery flag (39) for base58 address exp_sig = "IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hSNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLNtoVc=" _, r, s = bms.decode(exp_sig) sig = bms.encode(39, r, s) err_msg = "invalid recovery flag: " with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, b58_p2pkh, sig) # Invalid recovery flag (35) for bech32 address exp_sig = "IBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IOI0dpo3uGAEpCz9eepXLrA5kF35MXuU=" _, r, s = bms.decode(exp_sig) sig = bms.encode(35, r, s) err_msg = "invalid recovery flag: " with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, b58_p2wpkh, sig)
def test_one_prvkey_multiple_addresses() -> None: msg = "Paolo is afraid of ephemeral random numbers" # Compressed WIF wif = b"Kx45GeUBSMPReYQwgXiKhG9FzNXrnCeutJp4yjTd5kKxCitadm3C" addr_p2pkh_compressed = p2pkh(wif) addr_p2wpkh_p2sh = p2wpkh_p2sh(wif) addr_p2wpkh = p2wpkh(wif) # sign with no address sig1 = bms.sign(msg, wif) # True for Bitcoin Core bms.assert_as_valid(msg, addr_p2pkh_compressed, sig1) assert bms.verify(msg, addr_p2pkh_compressed, sig1) # True for Electrum p2wpkh_p2sh bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig1) assert bms.verify(msg, addr_p2wpkh_p2sh, sig1) # True for Electrum p2wpkh bms.assert_as_valid(msg, addr_p2wpkh, sig1) assert bms.verify(msg, addr_p2wpkh, sig1) # sign with no p2pkh address sig1 = bms.sign(msg, wif, addr_p2pkh_compressed) # True for Bitcoin Core bms.assert_as_valid(msg, addr_p2pkh_compressed, sig1) assert bms.verify(msg, addr_p2pkh_compressed, sig1) # True for Electrum p2wpkh_p2sh bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig1) assert bms.verify(msg, addr_p2wpkh_p2sh, sig1) # True for Electrum p2wpkh bms.assert_as_valid(msg, addr_p2wpkh, sig1) assert bms.verify(msg, addr_p2wpkh, sig1) err_msg = "invalid recovery flag: " # sign with p2wpkh_p2sh address (BIP137) sig2 = bms.sign(msg, wif, addr_p2wpkh_p2sh) # False for Bitcoin Core with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, addr_p2pkh_compressed, sig2) assert not bms.verify(msg, addr_p2pkh_compressed, sig2) # True for BIP137 p2wpkh_p2sh bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig2) assert bms.verify(msg, addr_p2wpkh_p2sh, sig2) # False for BIP137 p2wpkh with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, addr_p2wpkh, sig2) assert not bms.verify(msg, addr_p2wpkh, sig2) # sign with p2wpkh address (BIP137) sig3 = bms.sign(msg, wif, addr_p2wpkh) # False for Bitcoin Core with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, addr_p2pkh_compressed, sig3) assert not bms.verify(msg, addr_p2pkh_compressed, sig3) # False for BIP137 p2wpkh_p2sh with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig3) assert not bms.verify(msg, addr_p2wpkh_p2sh, sig3) # True for BIP137 p2wpkh bms.assert_as_valid(msg, addr_p2wpkh, sig3) assert bms.verify(msg, addr_p2wpkh, sig3) # uncompressed WIF / p2pkh address q, network, _ = prvkeyinfo_from_prvkey(wif) wif2 = wif_from_prvkey(q, network, False) addr_p2pkh_uncompressed = p2pkh(wif2) # sign with uncompressed p2pkh sig4 = bms.sign(msg, wif2, addr_p2pkh_uncompressed) # False for Bitcoin Core compressed p2pkh with pytest.raises(BTClibValueError, match="wrong p2pkh address: "): bms.assert_as_valid(msg, addr_p2pkh_compressed, sig4) assert not bms.verify(msg, addr_p2pkh_compressed, sig4) # False for BIP137 p2wpkh_p2sh # FIXME: puzzling error message # it should have been "wrong p2wpkh-p2sh address: " with pytest.raises(BTClibValueError, match="wrong p2pkh address: "): bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig4) assert not bms.verify(msg, addr_p2wpkh_p2sh, sig4) # False for BIP137 p2wpkh with pytest.raises(BTClibValueError, match=err_msg): bms.assert_as_valid(msg, addr_p2wpkh, sig4) assert not bms.verify(msg, addr_p2wpkh, sig4) # True for Bitcoin Core uncompressed p2pkh bms.assert_as_valid(msg, addr_p2pkh_uncompressed, sig4) assert bms.verify(msg, addr_p2pkh_uncompressed, sig4) # unrelated different wif wif3 = b"KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617" addr_p2pkh_compressed = p2pkh(wif3) addr_p2wpkh_p2sh = p2wpkh_p2sh(wif3) addr_p2wpkh = p2wpkh(wif3) # False for Bitcoin Core compressed p2pkh with pytest.raises(BTClibValueError, match="wrong p2pkh address: "): bms.assert_as_valid(msg, addr_p2pkh_compressed, sig1) assert not bms.verify(msg, addr_p2pkh_compressed, sig1) # False for BIP137 p2wpkh_p2sh with pytest.raises(BTClibValueError, match="wrong p2wpkh-p2sh address: "): bms.assert_as_valid(msg, addr_p2wpkh_p2sh, sig1) assert not bms.verify(msg, addr_p2wpkh_p2sh, sig1) # False for BIP137 p2wpkh with pytest.raises(BTClibValueError, match="wrong p2wpkh address: "): bms.assert_as_valid(msg, addr_p2wpkh, sig1) assert not bms.verify(msg, addr_p2wpkh, sig1) # FIXME: puzzling error message err_msg = "not a private or compressed public key for mainnet: " with pytest.raises(BTClibValueError, match=err_msg): bms.sign(msg, wif2, addr_p2pkh_compressed) err_msg = "mismatch between private key and address" with pytest.raises(BTClibValueError, match=err_msg): bms.sign(msg, wif, addr_p2pkh_uncompressed)
def test_one_prvkey_multiple_addresses(self): msg = "Paolo is afraid of ephemeral random numbers" # Compressed WIF wif = b'Kx45GeUBSMPReYQwgXiKhG9FzNXrnCeutJp4yjTd5kKxCitadm3C' pubkey, network = pubkey_info_from_prvkey(wif) address1 = p2pkh(pubkey, network) address2 = p2wpkh_p2sh(pubkey, network) address3 = p2wpkh(pubkey, network) # sign with no address (or compressed P2PKH) sig1 = bms.sign(msg, wif) # True for Bitcoin Core self.assertTrue(bms.verify(msg, address1, sig1)) # True for Electrum p2wpkh_p2sh self.assertTrue(bms.verify(msg, address2, sig1)) # True for Electrum p2wpkh self.assertTrue(bms.verify(msg, address3, sig1)) # sign with p2wpkh_p2sh address (BIP137) sig2 = bms.sign(msg, wif, address2) # False for Bitcoin Core self.assertFalse(bms.verify(msg, address1, sig2)) # True for BIP137 p2wpkh_p2sh self.assertTrue(bms.verify(msg, address2, sig2)) # False for BIP137 p2wpkh self.assertFalse(bms.verify(msg, address3, sig2)) # sign with p2wpkh address (BIP137) sig3 = bms.sign(msg, wif, address3) # False for Bitcoin Core self.assertFalse(bms.verify(msg, address1, sig3)) # False for BIP137 p2wpkh_p2sh self.assertFalse(bms.verify(msg, address2, sig3)) # True for BIP137 p2wpkh self.assertTrue(bms.verify(msg, address3, sig3)) # uncompressed WIF / P2PKH address q, network, _ = prvkey_info_from_prvkey(wif) wif2 = wif_from_prvkey(q, network, False) pubkey, network = pubkey_info_from_prvkey(wif2) address4 = p2pkh(pubkey, network) # sign with uncompressed P2PKH sig4 = bms.sign(msg, wif2, address4) # False for Bitcoin Core compressed p2pkh self.assertFalse(bms.verify(msg, address1, sig4)) # False for BIP137 p2wpkh_p2sh self.assertFalse(bms.verify(msg, address2, sig4)) # False for BIP137 p2wpkh self.assertFalse(bms.verify(msg, address3, sig4)) # True for Bitcoin Core uncompressed p2pkh self.assertTrue(bms.verify(msg, address4, sig4)) self.assertRaises(ValueError, bms.sign, msg, wif2, address1) self.assertRaises(ValueError, bms.sign, msg, wif, address4)
def test_exceptions(self): msg = 'test' wif = 'KwELaABegYxcKApCb3kJR9ymecfZZskL9BzVUkQhsqFiUKftb4tu' pubkey, _ = pubkey_info_from_prvkey(wif) address = base58address.p2pkh(pubkey) exp_sig = b'IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hSNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLNtoVc=' self.assertTrue(bms.verify(msg, address, exp_sig)) # Invalid recovery flag: 26 _, r, s = bms.deserialize(exp_sig) self.assertRaises(ValueError, bms.serialize, 26, r, s) #bms.serialize(26, r, s) # short exp_sig exp_sig = b'IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLoVc=' self.assertRaises(ValueError, bms._verify, msg, address, exp_sig) self.assertFalse(bms.verify(msg, address, exp_sig)) # Invalid recovery flag: 26 exp_sig = b'GpNLHqEKSzwXV+KwwBfQthQ848mn5qSkmGDXpqshDuPYJELOnSuRYGQQgBR4PpI+w2tJdD4v+hxElvAaUSqv2eU=' self.assertRaises(ValueError, bms._verify, msg, address, exp_sig) self.assertFalse(bms.verify(msg, address, exp_sig)) #bms._verify(msg, address, exp_sig) # Invalid recovery flag: 66 exp_sig = b'QpNLHqEKSzwXV+KwwBfQthQ848mn5qSkmGDXpqshDuPYJELOnSuRYGQQgBR4PpI+w2tJdD4v+hxElvAaUSqv2eU=' self.assertRaises(ValueError, bms._verify, msg, address, exp_sig) self.assertFalse(bms.verify(msg, address, exp_sig)) #bms._verify(msg, address, exp_sig) # Pubkey mismatch: compressed wif, uncompressed address wif = 'Ky1XfDK2v6wHPazA6ECaD8UctEoShXdchgABjpU9GWGZDxVRDBMJ' address = '19f7adDYqhHSJm2v7igFWZAqxXHj1vUa3T' self.assertRaises(ValueError, bms.sign, msg, wif, address) #bms.sign(msg, wif, address) # Pubkey mismatch: uncompressed wif, compressed address wif = '5JDopdKaxz5bXVYXcAnfno6oeSL8dpipxtU1AhfKe3Z58X48srn' address = '1DAag8qiPLHh6hMFVu9qJQm9ro1HtwuyK5' self.assertRaises(ValueError, bms.sign, msg, wif, address) #bms.sign(msg, wif, address) msg = 'test' wif = 'L4xAvhKR35zFcamyHME2ZHfhw5DEyeJvEMovQHQ7DttPTM8NLWCK' pubkey, _ = pubkey_info_from_prvkey(wif) p2pkh = base58address.p2pkh(pubkey) p2wpkh = bech32address.p2wpkh(pubkey) p2wpkh_p2sh = base58address.p2wpkh_p2sh(pubkey) wif = 'Ky1XfDK2v6wHPazA6ECaD8UctEoShXdchgABjpU9GWGZDxVRDBMJ' # Mismatch between p2pkh address and key pair self.assertRaises(ValueError, bms.sign, msg, wif, p2pkh) # bms.sign(msg, wif, p2pkh) # Mismatch between p2wpkh address and key pair self.assertRaises(ValueError, bms.sign, msg, wif, p2wpkh) # bms.sign(msg, wif, p2wpkh) # Mismatch between p2wpkh_p2sh address and key pair self.assertRaises(ValueError, bms.sign, msg, wif, p2wpkh_p2sh) # bms.sign(msg, wif, p2wpkh_p2sh) # Invalid recovery flag (39) for base58 address exp_sig = b'IHdKsFF1bUrapA8GMoQUbgI+Ad0ZXyX1c/yAZHmJn5hSNBi7J+TrI1615FG3g9JEOPGVvcfDWIFWrg2exLNtoVc=' _, r, s = bms.deserialize(exp_sig) sig = bms.serialize(39, r, s) self.assertRaises(ValueError, bms._verify, msg, p2pkh, sig) #bms._verify(msg, p2pkh, sig) # Invalid recovery flag (35) for bech32 address exp_sig = b'IBFyn+h9m3pWYbB4fBFKlRzBD4eJKojgCIZSNdhLKKHPSV2/WkeV7R7IOI0dpo3uGAEpCz9eepXLrA5kF35MXuU=' _, r, s = bms.deserialize(exp_sig) sig = bms.serialize(35, r, s) self.assertRaises(ValueError, bms._verify, msg, p2wpkh, sig)