/ test / functional / rpc_signmessagewithprivkey.py
rpc_signmessagewithprivkey.py
 1  #!/usr/bin/env python3
 2  # Copyright (c) 2016-2022 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().main()