rpc_signmessagewithprivkey.py raw
1 #!/usr/bin/env python3
2 # Copyright (c) 2016-present The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 """Test RPC commands for signing messages with private key."""
6
7 from test_framework.descriptors import (
8 descsum_create,
9 )
10 from test_framework.test_framework import BitcoinTestFramework
11 from test_framework.util import (
12 assert_equal,
13 assert_raises_rpc_error,
14 )
15
16
17 class SignMessagesWithPrivTest(BitcoinTestFramework):
18 def set_test_params(self):
19 self.setup_clean_chain = True
20 self.num_nodes = 1
21
22 def addresses_from_privkey(self, priv_key):
23 '''Return addresses for a given WIF private key in legacy (P2PKH),
24 nested segwit (P2SH-P2WPKH) and native segwit (P2WPKH) formats.'''
25 descriptors = f'pkh({priv_key})', f'sh(wpkh({priv_key}))', f'wpkh({priv_key})'
26 return [self.nodes[0].deriveaddresses(descsum_create(desc))[0] for desc in descriptors]
27
28 def run_test(self):
29 message = 'This is just a test message'
30
31 self.log.info('test signing with priv_key')
32 priv_key = 'cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N'
33 expected_signature = 'INbVnW4e6PeRmsv2Qgu8NuopvrVjkcxob+sX8OcZG0SALhWybUjzMLPdAsXI46YZGb0KQTRii+wWIQzRpG/U+S0='
34 signature = self.nodes[0].signmessagewithprivkey(priv_key, message)
35 assert_equal(expected_signature, signature)
36
37 self.log.info('test that verifying with P2PKH address succeeds')
38 addresses = self.addresses_from_privkey(priv_key)
39 assert_equal(addresses[0], 'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB')
40 assert self.nodes[0].verifymessage(addresses[0], signature, message)
41
42 self.log.info('test that verifying with non-P2PKH addresses throws error')
43 for non_p2pkh_address in addresses[1:]:
44 assert_raises_rpc_error(-3, "Address does not refer to key", self.nodes[0].verifymessage, non_p2pkh_address, signature, message)
45
46 self.log.info('test parameter validity and error codes')
47 # signmessagewithprivkey has two required parameters
48 for num_params in [0, 1, 3, 4, 5]:
49 param_list = ["dummy"]*num_params
50 assert_raises_rpc_error(-1, "signmessagewithprivkey", self.nodes[0].signmessagewithprivkey, *param_list)
51 # verifymessage has three required parameters
52 for num_params in [0, 1, 2, 4, 5]:
53 param_list = ["dummy"]*num_params
54 assert_raises_rpc_error(-1, "verifymessage", self.nodes[0].verifymessage, *param_list)
55 # invalid key or address provided
56 assert_raises_rpc_error(-5, "Invalid private key", self.nodes[0].signmessagewithprivkey, "invalid_key", message)
57 assert_raises_rpc_error(-5, "Invalid address", self.nodes[0].verifymessage, "invalid_addr", signature, message)
58 # malformed signature provided
59 assert_raises_rpc_error(-3, "Malformed base64 encoding", self.nodes[0].verifymessage, 'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB', "invalid_sig", message)
60
61
62 if __name__ == '__main__':
63 SignMessagesWithPrivTest(__file__).main()
64