def test_msg_signing(self): msg1 = b'Chancellor on brink of second bailout for banks' msg2 = b'Electrum' 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( 'XDL8kYsDheEviC7EYMNbo3Myy1txzKyfhZFZBaYUSPDPm9BZZae8', msg1) addr1 = 'PUFpXCipFhCM1n3CvY1pdJnsuBYGXopNoZ' sig2 = sign_message_with_wif_privkey( 'XDsEyEN6HvL8TMJzi285YhCvQbEAAwr1X3WcrYHjnTk4q3GM4JvW', msg2) addr2 = 'PAXaycHBoaQSGrjgurCnuihGRozuWbzors' sig1_b64 = base64.b64encode(sig1) sig2_b64 = base64.b64encode(sig2) self.assertEqual( sig1_b64, b'HxotOszC5f11BXHmUCedMJiMMIm1LJjq99MXXydPB5xjOAYgS0Nu6Aa2dPsxzxBAXJIVrpXGwlXHuzlI17Q+IxQ=' ) self.assertEqual( sig2_b64, b'IPTzdPgV0VAO/XS5H4K/qFC8I18KYPtysrzLnYIBwh8YHBtUUXS2kv9yhwKRi9Ii0xHUfLW1BNp8P6hENgH13SY=' ) 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))
def sign_message(self, sequence, message, password): sig = None try: message = message.encode('utf8') inputPath = self.get_derivation() + "/%d/%d" % sequence msg_hash = Hash(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
def test_create_and_sign(self): collateral_pub = '0218864d879997fefbb2846e54ac4db0df99029b91cd12be32312d7e0da45029a8' # PUFpXCipFhCM1n3CvY1pdJnsuBYGXopNoZ delegate_pub = '0329e04e958045a2866e59d13423772e16551cc1bedc50adb0e10b33ae28146cfc' # P9h6zCz253jmc4TvqgKPRNpkx5qELdNWWT protocol_version = 70103 ip = '0.0.0.0' port = 20000 addr = NetworkAddress(ip=ip, port=port) vin = { 'prevout_hash': '00' * 32, 'prevout_n': 0, 'scriptSig': '', 'sequence': 0xffffffff } last_ping = MasternodePing(vin=vin, block_hash='ff' * 32) announce = MasternodeAnnounce(vin=vin, addr=addr, collateral_key=collateral_pub, delegate_key=delegate_pub, protocol_version=protocol_version, last_ping=last_ping) collateral_wif = 'XDL8kYsDheEviC7EYMNbo3Myy1txzKyfhZFZBaYUSPDPm9BZZae8' delegate_wif = 'XFsDL1FgC4VWQWZQu1NZAs5ri1rUP8mu1CviQYBbXedBTK37uppF' announce.last_ping.sign(delegate_wif, bfh(delegate_pub), 1461858375) sig = announce.sign(collateral_wif, 1461858375) address = 'PUFpXCipFhCM1n3CvY1pdJnsuBYGXopNoZ' self.assertTrue(announce.verify(address)) self.assertTrue( ecc.verify_message_with_address(address, sig, announce.serialize_for_sig()))
async def get_update_info(self): async with make_aiohttp_session(proxy=self.main_window.network.proxy) 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": { # "1Lqm1HphuhxKZQEawzPse8gJtgjm9kUKT4": "IA+2QG3xPRn4HAIFdpu9eeaCYC7S5wS/sDxn54LJx6BdUTBpse3ibtfq8C43M7M1VfpGkD5tsdwl5C6IfpZD/gQ=" # } # } 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 version_num.strip()
def test_sign(self): vin = { 'prevout_hash': '00' * 32, 'prevout_n': 0, 'scriptSig': '', 'sequence': 0xffffffff } block_hash = 'ff' * 32 current_time = 1461858375 ping = MasternodePing(vin=vin, block_hash=block_hash, sig_time=current_time) expected_sig = 'H6k0M7G15GLnJ7i7Zcs8uCHcVRsn1P0hKK4lVMkgY4byaOvUECCsfxA9ktUiFT8scfFYYb/sxkcD8ifU/SEnBUg=' wif = 'XCbhXBc2N9q8kxqBF41rSuLWVpVVbDm7P1oPv9GxcrS9QXYBWZkB' sig = ping.sign(wif, current_time=current_time) address = bitcoin.address_from_private_key(wif) self.assertTrue( ecc.verify_message_with_address(address, sig, ping.serialize_for_sig())) self.assertEqual(expected_sig, base64.b64encode(sig).decode('utf-8'))