示例#1
0
    def test_msg_signing(self):
        msg1 = b'wakiyama tamami chan'
        msg2 = b'tottemo kawaii'

        def sign_message_with_wif_privkey(wif_privkey, msg):
            txin_type, privkey, compressed = deserialize_privkey(wif_privkey)
            key = ecc.ECPrivkey(privkey)
            return key.sign_message(msg, compressed)

        sig1 = sign_message_with_wif_privkey(
            'T8UqLXgii9iBbQAoypL8Yz7Zta7w8QTt2qq66ViLSGXGQCGbo7rv', msg1)
        addr1 = 'MRHx4jW2KAQeEDMuK7pGLUGWvPRQT1Epmj'
        sig2 = sign_message_with_wif_privkey(
            'T3o9vVd82bASRouYDpSHo2KyFR82LB7FezpZAFDpLcbNd7AGuEJQ', msg2)
        addr2 = 'MLBCmvG4A7AqCD6MMYjf7YdV96YK5teZ5N'

        sig1_b64 = base64.b64encode(sig1)
        sig2_b64 = base64.b64encode(sig2)

        self.assertEqual(
            sig1_b64,
            b'IDldTozCVViZ/m/gzvSf6EmZZ3ItDdM+RsI4PAxZdsb6ZQUmv3IgaJK+U4naOExaoTIVn0IY3Hoky0MWFAO6ac4='
        )
        self.assertEqual(
            sig2_b64,
            b'IOr6v1UPcFEoeon11dPNo+TbbLuAu8k8ccG527zmmDf/a26W6z+yAbsfTt01PKF7/UGhwJeCwybdnRXpPC2x4Hk='
        )

        self.assertTrue(ecc.verify_message_with_address(addr1, sig1, msg1))
        self.assertTrue(ecc.verify_message_with_address(addr2, sig2, msg2))

        self.assertFalse(ecc.verify_message_with_address(
            addr1, b'wrong', msg1))
        self.assertFalse(ecc.verify_message_with_address(addr1, sig2, msg1))
示例#2
0
    def sign_message(self, sequence, message, password):
        sig = None
        try:
            message = message.encode('utf8')
            inputPath = self.get_derivation_prefix() + "/%d/%d" % sequence
            msg_hash = sha256d(msg_magic(message))
            inputHash = to_hexstr(msg_hash)
            hasharray = []
            hasharray.append({'hash': inputHash, 'keypath': inputPath})
            hasharray = json.dumps(hasharray)

            msg = ('{"sign":{"meta":"sign message", "data":%s}}' % hasharray).encode('utf8')

            dbb_client = self.plugin.get_client(self)

            if not dbb_client.is_paired():
                raise Exception(_("Could not sign message."))

            reply = dbb_client.hid_send_encrypt(msg)
            self.handler.show_message(_("Signing message ...") + "\n\n" +
                                      _("To continue, touch the Digital Bitbox's blinking light for 3 seconds.") + "\n\n" +
                                      _("To cancel, briefly touch the blinking light or wait for the timeout."))
            reply = dbb_client.hid_send_encrypt(msg) # Send twice, first returns an echo for smart verification (not implemented)
            self.handler.finished()

            if 'error' in reply:
                raise Exception(reply['error']['message'])

            if 'sign' not in reply:
                raise Exception(_("Could not sign message."))

            if 'recid' in reply['sign'][0]:
                # firmware > v2.1.1
                sig_string = binascii.unhexlify(reply['sign'][0]['sig'])
                recid = int(reply['sign'][0]['recid'], 16)
                sig = ecc.construct_sig65(sig_string, recid, True)
                pubkey, compressed = ecc.ECPubkey.from_signature65(sig, msg_hash)
                addr = public_key_to_p2pkh(pubkey.get_public_key_bytes(compressed=compressed))
                if ecc.verify_message_with_address(addr, sig, message) is False:
                    raise Exception(_("Could not sign message"))
            elif 'pubkey' in reply['sign'][0]:
                # firmware <= v2.1.1
                for recid in range(4):
                    sig_string = binascii.unhexlify(reply['sign'][0]['sig'])
                    sig = ecc.construct_sig65(sig_string, recid, True)
                    try:
                        addr = public_key_to_p2pkh(binascii.unhexlify(reply['sign'][0]['pubkey']))
                        if ecc.verify_message_with_address(addr, sig, message):
                            break
                    except Exception:
                        continue
                else:
                    raise Exception(_("Could not sign message"))


        except BaseException as e:
            self.give_error(e)
        return sig
示例#3
0
 async def get_update_info(self):
     # note: Use long timeout here as it is not critical that we get a response fast,
     #       and it's bad not to get an update notification just because we did not wait enough.
     async with make_aiohttp_session(proxy=self.network.proxy, timeout=120) as session:
         async with session.get(UpdateCheck.url) as result:
             signed_version_dict = await result.json(content_type=None)
             # example signed_version_dict:
             # {
             #     "version": "3.9.9",
             #     "signatures": {
             #         "MRkEwoPcvSPaC5WNtQMa7NGPy2tBKbp3Bm": "H84UFTdaBswxTrNty0gLlWiQEQhJA2Se5xVdhR9zFirKYg966IXEkC7km6phIJq+2CT3KwvKuj8YKaSCy1fErwg="
             #     }
             # }
             version_num = signed_version_dict['version']
             sigs = signed_version_dict['signatures']
             for address, sig in sigs.items():
                 if address not in UpdateCheck.VERSION_ANNOUNCEMENT_SIGNING_KEYS:
                     continue
                 sig = base64.b64decode(sig)
                 msg = version_num.encode('utf-8')
                 if ecc.verify_message_with_address(address=address, sig65=sig, message=msg,
                                                    net=constants.BitcoinMainnet):
                     self.logger.info(f"valid sig for version announcement '{version_num}' from address '{address}'")
                     break
             else:
                 raise Exception('no valid signature for version announcement')
             return LooseVersion(version_num.strip())