Ejemplo n.º 1
0
    def sender(self):

        if not self._sender:
            # Determine sender
            if self.v:
                if self.r >= N or self.s >= N or self.v < 27 or self.v > 28 \
                or self.r == 0 or self.s == 0:
                    raise InvalidTransaction("Invalid signature values!")
                log.debug('recovering sender')
                rlpdata = rlp.encode(self, UnsignedTransaction)
                rawhash = utils.sha3(rlpdata)

                pk = PublicKey(flags=ALL_FLAGS)
                try:
                    pk.public_key = pk.ecdsa_recover(
                        rawhash,
                        pk.ecdsa_recoverable_deserialize(
                            zpad(utils.bytearray_to_bytestr(int_to_32bytearray(self.r)), 32) + zpad(utils.bytearray_to_bytestr(int_to_32bytearray(self.s)), 32),
                            self.v - 27
                        ),
                        raw=True
                    )
                    pub = pk.serialize(compressed=False)
                except Exception:
                    raise InvalidTransaction("Invalid signature values (x^3+7 is non-residue)")

                if pub[1:] == b"\x00" * 32:
                    raise InvalidTransaction("Invalid signature (zero privkey cannot sign)")
                pub = encode_pubkey(pub, 'bin')
                self._sender = utils.sha3(pub[1:])[-20:]
                assert self.sender == self._sender
            else:
                self._sender = 0
        return self._sender
Ejemplo n.º 2
0
class Secp256k1_compact(object):
    def __init__(self):
        self.priv_key = PrivateKey()
        self.pub_key = PublicKey(pubkey=None, raw=False, flags=secp256k1.ALL_FLAGS)

    def ecdsa_compact_sign(self, msg32, privkey):
        if type(privkey) == unicode:
            privkey = privkey.encode('utf-8')
        self.priv_key.set_raw_privkey(privkey)
        sig = self.priv_key.ecdsa_sign_recoverable(msg32, raw=True)
        return self.priv_key.ecdsa_recoverable_serialize(sig)

    def ecdsa_compact_recover(self, msg32, sign):
        if not len(sign) == 2:
            sign = (sign[:64], ord(sign[64]))
        assert len(sign) == 2
        deserialized_sig = self.pub_key.ecdsa_recoverable_deserialize(sign[0], sign[1])
        self.pub_key.public_key = self.pub_key.ecdsa_recover(msg32, deserialized_sig, raw=True)
        return self.pub_key.serialize(compressed=False)

    def ecdsa_compact_verify(self, msg32, sign, pub):
        # Check if pubkey has been bin_electrum encoded.
        # If so, append \04 to the front of the key, to make sure the length is 65
        if len(pub) == 64:
            pub = '\04'+pub
        pub_k = PublicKey().deserialize(pub)
        pub_key = PublicKey(pub_k, raw=False, flags=secp256k1.ALL_FLAGS)
        der_sig = pub_key.ecdsa_recoverable_deserialize(sign[0], sign[1])
        raw_sig = pub_key.ecdsa_recoverable_convert(der_sig)
        return pub_key.ecdsa_verify(msg32, raw_sig, raw=True)
Ejemplo n.º 3
0
def verify(base64sig, msg, address, ctx=None, net=BC):
    if len(base64sig) != 88:
        raise Exception("Invalid base64 signature length")

    msg = msg.encode('utf8')
    fullmsg = (varint(len(net.msgprefix)) + net.msgprefix + varint(len(msg)) +
               msg)
    hmsg = shasha(fullmsg).digest()

    sigbytes = base64.b64decode(base64sig)
    if len(sigbytes) != 65:
        raise Exception("Invalid signature length")

    compressed = (ord(sigbytes[0:1]) - 27) & 4 != 0
    rec_id = (ord(sigbytes[0:1]) - 27) & 3

    p = PublicKey(ctx=ctx, flags=ALL_FLAGS)
    sig = p.ecdsa_recoverable_deserialize(sigbytes[1:], rec_id)

    # Recover the ECDSA public key.
    recpub = p.ecdsa_recover(hmsg, sig, raw=True)
    pubser = PublicKey(recpub, ctx=ctx).serialize(compressed=compressed)

    addr = pubkey_to_addr(pubser, net)
    return addr == address
Ejemplo n.º 4
0
    def verifyData(self, data):
        # verify hash
        msg_hash = data[:32]
        if msg_hash != keccak256(data[32:]):
            print " First 32 bytes are not keccak256 hash of the rest."
            return
        else:
            print " Verified message hash."

        # verify signature
        signature = data[32:97]
        signed_data = data[97:]
        deserialized_sig = self.priv_key.ecdsa_recoverable_deserialize(signature[:64], ord(signature[64]))

        remote_pubkey = self.priv_key.ecdsa_recover(keccak256(signed_data), deserialized_sig, raw = True)

        pub = PublicKey()
        pub.public_key = remote_pubkey

        verified = pub.ecdsa_verify(keccak256(signed_data),
                            pub.ecdsa_recoverable_convert(deserialized_sig),
                            raw = True)

        if not verified:
            print " Signature invalid"
            return False
        else:
            print " Verified signature."
            return True
Ejemplo n.º 5
0
    def __validate_icx_signature(self, tx_hash, signature, address) -> bool:
        """

        :param tx_hash:
        :param signature:
        :param address:
        :return:
        """
        try:
            origin_signature, recover_code = signature[:-1], signature[-1]
            recoverable_sig = self.__pri.ecdsa_recoverable_deserialize(origin_signature, recover_code)
            pub = self.__pri.ecdsa_recover(binascii.unhexlify(tx_hash),
                                           recover_sig=recoverable_sig,
                                           raw=True,
                                           digest=hashlib.sha3_256)

            public_key = PublicKey(pub, ctx=self.__ctx_cached)
            hash_pub = hashlib.sha3_256(public_key.serialize(compressed=False)[1:]).hexdigest()
            expect_address = f"hx{hash_pub[-40:]}"
            if expect_address != address:
                logging.info(f"tx address validate fail expect : {expect_address} input : {address}")
                raise TransactionInvalidAddressNotMatchError(tx_hash, address, expect_address)
            return True
        except TransactionInvalidAddressNotMatchError as e:
            raise e

        except Exception as e:
            logging.error(f"tx signature validate fail cause {e}")
            traceback.print_exc()
            raise TransactionInvalidSignatureError(tx_hash, signature, address)
Ejemplo n.º 6
0
def _recover_key(msg_hash: bytes, signature: bytes,
                 compressed: bool) -> Optional[bytes]:
    """Returns the public key from message hash and recoverable signature

    :param msg_hash: 32 bytes data
    :param signature: signature_data(64) + recovery_id(1)
    :param compressed: the type of public key to return
    :return: public key recovered from msg_hash and signature
        (compressed: 33 bytes key, uncompressed: 65 bytes key)
    """
    if isinstance(msg_hash, bytes) \
            and len(msg_hash) == 32 \
            and isinstance(signature, bytes) \
            and len(signature) == 65:
        internal_recover_sig = _public_key.ecdsa_recoverable_deserialize(
            ser_sig=signature[:64], rec_id=signature[64])
        internal_pubkey = _public_key.ecdsa_recover(msg_hash,
                                                    internal_recover_sig,
                                                    raw=True,
                                                    digest=None)

        public_key = PublicKey(internal_pubkey, raw=False, ctx=_public_key.ctx)
        return public_key.serialize(compressed)

    return None
Ejemplo n.º 7
0
def verify(base64sig, msg, address, ctx=None, net=BC):
    if len(base64sig) != 88:
        raise Exception("Invalid base64 signature length")

    msg = msg.encode('utf8')
    fullmsg = (varint(len(net.msgprefix)) + net.msgprefix +
               varint(len(msg)) + msg)
    hmsg = shasha(fullmsg).digest()

    sigbytes = base64.b64decode(base64sig)
    if len(sigbytes) != 65:
        raise Exception("Invalid signature length")

    compressed = (ord(sigbytes[0:1]) - 27) & 4 != 0
    rec_id = (ord(sigbytes[0:1]) - 27) & 3

    p = PublicKey(ctx=ctx, flags=ALL_FLAGS)
    sig = p.ecdsa_recoverable_deserialize(sigbytes[1:], rec_id)

    # Recover the ECDSA public key.
    recpub = p.ecdsa_recover(hmsg, sig, raw=True)
    pubser = PublicKey(recpub, ctx=ctx).serialize(compressed=compressed)

    addr = pubkey_to_addr(pubser, net)
    return addr == address
Ejemplo n.º 8
0
def ecdsa_verify(pubkey, signature, message):
    assert len(signature) == 65
    assert len(pubkey) == 64
    pk = PublicKey('\04' + pubkey, raw=True, ctx=ctx)
    return pk.ecdsa_verify(message,
                           pk.ecdsa_recoverable_convert(
                               pk.ecdsa_recoverable_deserialize(
                                   signature[:64], ord(signature[64]))),
                           raw=True)
Ejemplo n.º 9
0
 def ecdsa_compact_verify(self, msg32, sign, pub):
     # Check if pubkey has been bin_electrum encoded.
     # If so, append \04 to the front of the key, to make sure the length is 65
     if len(pub) == 64:
         pub = '\04'+pub
     pub_k = PublicKey().deserialize(pub)
     pub_key = PublicKey(pub_k, raw=False, flags=secp256k1.ALL_FLAGS)
     der_sig = pub_key.ecdsa_recoverable_deserialize(sign[0], sign[1])
     raw_sig = pub_key.ecdsa_recoverable_convert(der_sig)
     return pub_key.ecdsa_verify(msg32, raw_sig, raw=True)
Ejemplo n.º 10
0
    def sender(self):
        if not self._sender:
            if not is_bitcoin_available() or not is_secp256k1_available():
                raise ImportError(
                    "In order to derive the sender for transactions the "
                    "`bitcoin` and `secp256k1` packages must be installed."
                )
            from bitcoin import N
            from secp256k1 import PublicKey, ALL_FLAGS

            # Determine sender
            if self.v:
                has_invalid_signature_values = (
                    self.r >= N or
                    self.s >= N or
                    self.v < 27 or
                    self.v > 28 or
                    self.r == 0 or
                    self.s == 0
                )
                if has_invalid_signature_values:
                    raise ValueError("Invalid signature values!")
                rlpdata = rlp.encode(self, UnsignedTransaction)
                rawhash = decode_hex(sha3(rlpdata))

                pk = PublicKey(flags=ALL_FLAGS)
                try:
                    pk.public_key = pk.ecdsa_recover(
                        rawhash,
                        pk.ecdsa_recoverable_deserialize(
                            pad_left(
                                int_to_big_endian(self.r),
                                32,
                                b'\x00',
                            ) + pad_left(
                                int_to_big_endian(self.s),
                                32,
                                b'\x00',
                            ),
                            self.v - 27
                        ),
                        raw=True
                    )
                    pub = pk.serialize(compressed=False)
                except Exception:
                    raise ValueError("Invalid signature values (x^3+7 is non-residue)")

                if pub[1:] == b"\x00" * (len(pub) - 1):
                    raise ValueError("Invalid signature (zero privkey cannot sign)")

                self._sender = to_address(sha3(pub[1:])[-40:])
                assert self.sender == self._sender
            else:
                self._sender = 0
        return self._sender
Ejemplo n.º 11
0
    def receive(self, data, addr):
        """
        macSize  = 256 / 8 = 32
        sigSize  = 520 / 8 = 65
        headSize = macSize + sigSize = 97
        hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:]
        shouldhash := crypto.Sha3(buf[macSize:])
        """
        # verify hash
        msg_hash = data[:32]
        if msg_hash != keccak256(data[32:]):
            print " First 32 bytes are not keccak256 hash of the rest."
            return
        else:
            print " Verified message hash."

        # verify signature
        signature = data[32:97]
        signed_data = data[97:]
        deserialized_sig = self.priv_key.ecdsa_recoverable_deserialize(signature[:64],
                                                                       ord(signature[64]))

        remote_pubkey = self.priv_key.ecdsa_recover(keccak256(signed_data),
                                                    deserialized_sig,
                                                    raw=True)

        pub = PublicKey()
        pub.public_key = remote_pubkey

        verified = pub.ecdsa_verify(keccak256(signed_data),
                                    pub.ecdsa_recoverable_convert(deserialized_sig),
                                    raw=True)

        if not verified:
            print " Signature invalid"
            return
        else:
            print " Verified signature."

        response_types = {
            PingNode.packet_type: self.receive_ping,
            Pong.packet_type: self.receive_pong,
            FindNeighbors.packet_type: self.receive_find_neighbors,
            Neighbors.packet_type: self.receive_neighbors
        }

        try:
            packet_type = data[97]
            dispatch = response_types[packet_type]
        except KeyError:
            print " Unknown message type: " + data[97]
            return

        payload = data[98:]
        dispatch(payload, msg_hash, addr)
Ejemplo n.º 12
0
 def verify(self, message):
     pub = PublicKey(self.pub_key, raw=True)
     message = VarInt(len(message)).encode() + message
     # LOGGER.debug("Comparing with %r" % (MESSAGE_TEMPLATE % message))
     try:
         sig_raw = pub.ecdsa_deserialize(self.sig_ser)
         good = pub.ecdsa_verify(MESSAGE_TEMPLATE % message, sig_raw)
     except Exception:
         LOGGER.exception("Verification failed")
         good = False
     return good
def check_sig(public_key, signature, message):
    raw = bytes(bytearray.fromhex(public_key))
    sig = bytes(bytearray.fromhex(signature))
    pub = PublicKey(raw, raw=True)
    try:
        sig_raw = pub.ecdsa_deserialize(sig)
        good = pub.ecdsa_verify(bytes(bytearray.fromhex(message)), sig_raw)
    except:
        good = False
    print(u"{}\n".format(good))
    return 0 if good else 1
Ejemplo n.º 14
0
def verify_message(message):
    """验证信息有效性"""
    # 验证公钥
    if message.sender != pubkey2address(message.pubkey):
        return False
    # 验证签名
    ecc_pubkey = PublicKey(bytes(bytearray.fromhex(message.pubkey)), raw=True)
    # print(ecc_pubkey)
    sign = ecc_pubkey.ecdsa_deserialize(binascii.unhexlify(message.sign))
    verified = ecc_pubkey.ecdsa_verify(binascii.unhexlify(message.content), sign)
    # print(verified)
    return verified
Ejemplo n.º 15
0
def verify_sign(message, pubkey, address, sign):
    """verify message sign"""
    # verify public key
    if address != pubkey2address(pubkey):
        return False
    # verify sign
    ecc_pubkey = PublicKey(bytes(bytearray.fromhex(pubkey)), raw=True)
    # print(ecc_pubkey)
    sign = ecc_pubkey.ecdsa_deserialize(binascii.unhexlify(sign))
    verified = ecc_pubkey.ecdsa_verify(binascii.unhexlify(message), sign)
    # print(verified)
    return verified
Ejemplo n.º 16
0
    def receive(self):

        print "listening..."
        data, addr = self.sock.recvfrom(1024)
        print "received message[", addr, "]"

        ## verify hash
        msg_hash = data[:32]
        if msg_hash != keccak256(data[32:]):
            print " First 32 bytes are not keccak256 hash of the rest."
            return
        else:
            print " Verified message hash."

        ## verify signature
        signature = data[32:97]
        signed_data = data[97:]
        deserialized_sig = self.priv_key.ecdsa_recoverable_deserialize(
            signature[:64], ord(signature[64]))

        remote_pubkey = self.priv_key.ecdsa_recover(keccak256(signed_data),
                                                    deserialized_sig,
                                                    raw=True)

        pub = PublicKey()
        pub.public_key = remote_pubkey

        verified = pub.ecdsa_verify(
            keccak256(signed_data),
            pub.ecdsa_recoverable_convert(deserialized_sig),
            raw=True)

        if not verified:
            print " Signature invalid"
            return
        else:
            print " Verified signature."

        response_types = {
            PingNode.packet_type: self.receive_ping,
            Pong.packet_type: self.receive_pong
        }

        try:
            packet_type = data[97]
            dispatch = response_types[packet_type]
        except KeyError:
            print " Unknown message type: " + data[97]
            return

        payload = data[98:]
        dispatch(payload)
Ejemplo n.º 17
0
def _test_signature(public_key, private_key, msg):
    print('uncompressed pub key %i bytes: %s' %
          (len(public_key), public_key.hex()))
    comp_pubkey = Key.from_sec(public_key)
    print('compressed pub key: %s' %
          comp_pubkey.sec_as_hex(use_uncompressed=False))
    secp_pubkey = PublicKey(public_key, raw=True)
    secp_privkey = PrivateKey(private_key, raw=True)
    print('checking signature')
    signature = secp_privkey.ecdsa_sign(msg)
    if (secp_pubkey.ecdsa_verify(msg, signature)):
        print('signature OK')
    else:
        raise Exception('signature test failed')
Ejemplo n.º 18
0
def _recover_key(msg_hash: bytes, signature: bytes, compressed: bool) -> Optional[bytes]:
    if isinstance(msg_hash, bytes) \
            and len(msg_hash) == 32 \
            and isinstance(signature, bytes) \
            and len(signature) == 65:
        internal_recover_sig = _public_key.ecdsa_recoverable_deserialize(
            ser_sig=signature[:64], rec_id=signature[64])
        internal_pubkey = _public_key.ecdsa_recover(
            msg_hash, internal_recover_sig, raw=True, digest=None)

        public_key = PublicKey(internal_pubkey, raw=False, ctx=_public_key.ctx)
        return public_key.serialize(compressed)

    return None
Ejemplo n.º 19
0
def getDeployedSecret(dongle, masterPrivate, targetid):
	testMaster = PrivateKey(bytes(masterPrivate))
	testMasterPublic = bytearray(testMaster.pubkey.serialize(compressed=False))
	targetid = bytearray(struct.pack('>I', targetid))

	# identify
	apdu = bytearray([0xe0, 0x04, 0x00, 0x00]) + bytearray([len(targetid)]) + targetid
	dongle.exchange(apdu)

	# walk the chain 
	batch_info = bytearray(dongle.exchange(bytearray.fromhex('E050000000')))
	cardKey = batch_info[5:5 + batch_info[4]]

	# if not found, get another pair
	#if cardKey <> testMasterPublic:
	#	raise Exception("Invalid batch public key")

	# provide the ephemeral certificate
	ephemeralPrivate = PrivateKey()
	ephemeralPublic = bytearray(ephemeralPrivate.pubkey.serialize(compressed=False))
	print "Using ephemeral key " + str(ephemeralPublic).encode('hex')
	signature = testMaster.ecdsa_sign(bytes(ephemeralPublic))
	signature = testMaster.ecdsa_serialize(signature)
	certificate = bytearray([len(ephemeralPublic)]) + ephemeralPublic + bytearray([len(signature)]) + signature
	apdu = bytearray([0xE0, 0x51, 0x00, 0x00]) + bytearray([len(certificate)]) + certificate
	dongle.exchange(apdu)

	# walk the device certificates to retrieve the public key to use for authentication
	index = 0
	last_pub_key = PublicKey(bytes(testMasterPublic), raw=True)
	while True:
		certificate = bytearray(dongle.exchange(bytearray.fromhex('E052000000')))
		if len(certificate) == 0:
			break
		certificatePublic = certificate[1 : 1 + certificate[0]]
		certificateSignature = last_pub_key.ecdsa_deserialize(bytes(certificate[2 + certificate[0] :]))		
		if not last_pub_key.ecdsa_verify(bytes(certificatePublic), certificateSignature):
			if index == 0:
				# Not an error if loading from user key
				print "Broken certificate chain - loading from user key"
			else:
				raise Exception("Broken certificate chain")
		last_pub_key = PublicKey(bytes(certificatePublic), raw=True)
		index = index + 1

	# Commit device ECDH channel
	dongle.exchange(bytearray.fromhex('E053000000'))
	secret = last_pub_key.ecdh(bytes(ephemeralPrivate.serialize().decode('hex')))
	return str(secret[0:16])
Ejemplo n.º 20
0
def recover_publickey(messagedata, signature):
    if len(signature) != 65:
        raise ValueError('invalid signature')

    key = PublicKey(flags=ALL_FLAGS)  # FLAG_SIGN is required to recover publickeys
    signature_data = key.ecdsa_recoverable_deserialize(
        signature[:64],
        ord(signature[64]),
    )

    message_hash = sha3(messagedata)
    publickey_data = key.ecdsa_recover(message_hash, signature_data, raw=True)
    publickey = PublicKey(publickey_data).serialize(compressed=False)

    return publickey
Ejemplo n.º 21
0
    def verify_signature(self, tx: 'Transaction'):
        recoverable_sig = self._ecdsa.ecdsa_recoverable_deserialize(
            tx.signature.signature(),
            tx.signature.recover_id())
        raw_public_key = self._ecdsa.ecdsa_recover(tx.hash,
                                                   recover_sig=recoverable_sig,
                                                   raw=True,
                                                   digest=hashlib.sha3_256)

        public_key = PublicKey(raw_public_key, ctx=self._ecdsa.ctx)
        hash_pub = hashlib.sha3_256(public_key.serialize(compressed=False)[1:]).digest()
        expect_address = hash_pub[-20:]
        if expect_address != tx.from_address:
            raise RuntimeError(f"tx from address {tx.from_address.hex_xx()}, "
                               f"expected {ExternalAddress(expect_address).hex_xx()}")
Ejemplo n.º 22
0
    def verify_signature(self, block: 'Block'):
        recoverable_sig = self._ecdsa.ecdsa_recoverable_deserialize(
            block.header.signature.signature(),
            block.header.signature.recover_id())
        raw_public_key = self._ecdsa.ecdsa_recover(block.header.hash,
                                                   recover_sig=recoverable_sig,
                                                   raw=True,
                                                   digest=hashlib.sha3_256)

        public_key = PublicKey(raw_public_key, ctx=self._ecdsa.ctx)
        hash_pub = hashlib.sha3_256(public_key.serialize(compressed=False)[1:]).digest()
        expect_address = hash_pub[-20:]
        if expect_address != block.header.peer_id:
            exception = RuntimeError(f"block peer id {block.header.peer_id.hex_xx()}, "
                                     f"expected {ExternalAddress(expect_address).hex_xx()}")
            self._handle_exception(exception)
Ejemplo n.º 23
0
 def __init__(self, data, raw=True):
     """
     Refer to https://github.com/ludbb/secp256k1-py api documents.
     :param data: 65 bytes data which PublicKey.serialize() returns.
     :param raw: if False, it is assumed that pubkey has gone through PublicKey.deserialize already, otherwise it must be specified as bytes.
     """
     self.__pubkey = PublicKey(data, raw, FLAG_VERIFY)
Ejemplo n.º 24
0
 def validate(self, transaction, unspent_tx_outs):
     if not self.validate_struct():
         return False
     utx_out = None
     for unspent_tx_out in unspent_tx_outs:
         if unspent_tx_out.tx_out_id == self.tx_out_id and unspent_tx_out.tx_out_index == self.tx_out_index:
             utx_out = unspent_tx_out
     if utx_out is None:
         return False
     pubkey = PublicKey(unhexlify(utx_out.address), raw=True)
     if not pubkey.ecdsa_verify(
             unhexlify(transaction.id),
             pubkey.ecdsa_deserialize(unhexlify(self.signature))):
         logging.error("invalid tx_in signature")
         return False
     return True
Ejemplo n.º 25
0
def add_node(gid, pubkey, plugin=None):
    """Add a mesh-connected node to the routing table.
    arg: gid: integer within valid goTenna GID range
    arg: pubkey: a node's lightning pubkey
    """
    # Check that GID and pubkey are valid
    _gid = int(gid)
    if not 0 <= _gid <= GID_MAX:
        return f"GID {_gid} not in range 0 <= n <= {GID_MAX}"
    try:
        _pubkey = PublicKey(pubkey=bytes.fromhex(pubkey), raw=True)
    except Exception as e:
        logger.exception("Error with pubkey")
        return f"Error with pubkey: {e}"

    # Add to router
    _node = network.Node(_gid, str(pubkey))

    # Check for dupes
    if _gid in router:
        return (f"GID {_gid} already in router, remove before adding again: "
                f"{router.get_node(_gid)}")
    elif pubkey in router:
        return (
            f"Pubkey {pubkey} already in router, remove before adding again: "
            f"{router.get_node(router.get_gid(pubkey))}")
    else:
        router.add(_node)
        return f"{_node} added to gotenna plugin router."
Ejemplo n.º 26
0
async def verify_signature(address_bytes, random_bytes, sign_bytes, private_key):
    recoverable_sig = private_key.ecdsa_recoverable_deserialize(
        ser_sig=sign_bytes[:-1],
        rec_id=sign_bytes[-1]
    )
    raw_public_key = private_key.ecdsa_recover(
        msg=random_bytes,
        recover_sig=recoverable_sig,
        raw=True,
        digest=hashlib.sha3_256
    )
    public_key = PublicKey(raw_public_key)
    hash_pub = hashlib.sha3_256(public_key.serialize(compressed=False)[1:]).digest()
    expect_address = hash_pub[-20:]
    if expect_address != address_bytes:
        raise RuntimeError
Ejemplo n.º 27
0
def recover_publickey(messagedata, signature):
    if len(signature) != 65:
        raise ValueError('invalid signature')

    key = PublicKey(
        flags=ALL_FLAGS)  # FLAG_SIGN is required to recover publickeys
    signature_data = key.ecdsa_recoverable_deserialize(
        signature[:64],
        ord(signature[64]),
    )

    message_hash = sha3(messagedata)
    publickey_data = key.ecdsa_recover(message_hash, signature_data, raw=True)
    publickey = PublicKey(publickey_data).serialize(compressed=False)

    return publickey
Ejemplo n.º 28
0
def _convert_key(public_key: bytes, compressed: bool) -> Optional[bytes]:
    """Convert key between compressed and uncompressed keys

    :param public_key: compressed or uncompressed key
    :return: the counterpart key of a given public_key
    """
    public_key = PublicKey(public_key, raw=True, flags=NO_FLAGS, ctx=_public_key.ctx)
    return public_key.serialize(compressed=not compressed)
Ejemplo n.º 29
0
def recover(message: Union[bytes, str],
            signature: str,
            hex: bool = True) -> str:
    """Signs input data with provided private key

    Args:
        message (str): Message to recover address from
        signature (str): Signature with recovery bit
        hex (bool): Hex string is provided as input message

    Returns:
        signature (str): Recoverable signature with appended recovery bit
    """
    if type(message) == str and hex:
        data = bytes.fromhex(message)
    elif type(message) == str:
        data = message.encode("utf-8")
    else:
        data = message
    pub_key = PublicKey(flags=ALL_FLAGS)
    signature = bytes.fromhex(signature)
    signature = pub_key.ecdsa_recoverable_deserialize(
        signature[:-1], int.from_bytes(signature[-1:], "big"))
    pub_key = PublicKey(pub_key.ecdsa_recover(data, signature,
                                              digest=sha3_256))
    return address_from_public(pub_key.serialize(False).hex()[2:])
Ejemplo n.º 30
0
 def check_signature(message: bytes, signature: str, pub_key: str):
     try:
         pub_key = PublicKey(bytes(bytearray.fromhex(pub_key)), raw=True)
         sig = pub_key.ecdsa_deserialize_compact(
             bytes(bytearray.fromhex(signature)))
         return pub_key.ecdsa_verify(message, sig)
     except Exception as ex:
         log.exception(ex)
         return False
Ejemplo n.º 31
0
def extract_ecdsa_signer(msg_hash, signature):
    msg_hash_bytes = decode_hex(msg_hash) if msg_hash.startswith(b'0x') else msg_hash
    signature_bytes = decode_hex(signature) if signature.startswith(b'0x') else signature

    pk = PublicKey(flags=ALL_FLAGS)
    rec_id = signature_bytes[64]
    if is_string(rec_id):
        rec_id = ord(rec_id)
    pk.public_key = pk.ecdsa_recover(
        msg_hash_bytes,
        pk.ecdsa_recoverable_deserialize(
            signature_bytes[:64], rec_id,
        ),
        raw=True,
    )
    pk_serialized = pk.serialize(compressed=False)
    address = add_0x_prefix(sha3(encode_pubkey(pk_serialized, 'bin')[1:])[-40:])
    return address
Ejemplo n.º 32
0
def proc_ecrecover(ext, msg):
    # print('ecrecover proc', msg.gas)
    OP_GAS = opcodes.GECRECOVER
    gas_cost = OP_GAS
    if msg.gas < gas_cost:
        return 0, 0, []

    message_hash_bytes = [0] * 32
    msg.data.extract_copy(message_hash_bytes, 0, 0, 32)
    message_hash = b''.join(map(ascii_chr, message_hash_bytes))

    # TODO: This conversion isn't really necessary.
    # TODO: Invesitage if the check below is really needed.
    v = msg.data.extract32(32)
    r = msg.data.extract32(64)
    s = msg.data.extract32(96)

    if r >= bitcoin.N or s >= bitcoin.N or v < 27 or v > 28:
        return 1, msg.gas - opcodes.GECRECOVER, []

    signature_bytes = [0] * 64
    msg.data.extract_copy(signature_bytes, 0, 64, 32)
    msg.data.extract_copy(signature_bytes, 32, 96, 32)
    signature = b''.join(map(ascii_chr, signature_bytes))

    pk = PublicKey(flags=ALL_FLAGS)
    try:
        pk.public_key = pk.ecdsa_recover(
            message_hash,
            pk.ecdsa_recoverable_deserialize(
                signature,
                v - 27
            ),
            raw=True
        )
    except Exception:
        # Recovery failed
        return 1, msg.gas - gas_cost, []

    pub = pk.serialize(compressed=False)
    o = [0] * 12 + [safe_ord(x) for x in utils.sha3(pub[1:])[-20:]]
    return 1, msg.gas - gas_cost, o
Ejemplo n.º 33
0
def verify_recoverable_message(signature, message, recid):
    """ Verifies a signature of a hash and returns the address that signed it.
    If no address is returned, signature is bad.
    """
    empty = PublicKey(flags=ALL_FLAGS)
    sig = empty.ecdsa_recoverable_deserialize(signature, args.recid)
    msg = MESSAGE_TEMPLATE.format(message)
    pubkey = empty.ecdsa_recover(msg, sig)
    addr_hash = public_key_to_hash(pubkey.serialize())
    address = address_from_hash(address)

    try:
        sig_raw = pub.ecdsa_deserialize(signature)
        good = pub.ecdsa_verify(message, sig_raw)
    except:
        good = False

    if good:
        return address
    else:
        return None
Ejemplo n.º 34
0
def ecrecover(msg, signature, address=None):
    """
    Returns None on failure, returns the recovered address on success.
    If address is provided: Returns True if the recovered address matches it,
    otherwise False.
    """
    rawhash = sha3(msg)

    if len(signature) >= 65:
        v = safe_ord(signature[64]) + 27
        r = big_endian_to_int(signature[0:32])
        s = big_endian_to_int(signature[32:64])
    else:
        if address:
            return False
        else:
            return None

    pk = PublicKey(flags=ALL_FLAGS)
    pk.public_key = pk.ecdsa_recover(
        rawhash,
        pk.ecdsa_recoverable_deserialize(
            zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32) +
            zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32), v - 27),
        raw=True)
    pub = pk.serialize(compressed=False)

    recaddr = data_encoder(sha3(pub[1:])[-20:])
    if address:
        if not address.startswith("0x"):
            recaddr = recaddr[2:]

        return recaddr == address

    return recaddr
Ejemplo n.º 35
0
 def recover_sender(self):
     if self.v:
         if self.r >= N or self.s >= P or self.v < 27 or self.v > 28 \
            or self.r == 0 or self.s == 0:
             raise InvalidSignature()
         rlpdata = rlp.encode(self, self.__class__.exclude(['v', 'r', 's']))
         rawhash = sha3(rlpdata)
         pk = PublicKey(flags=ALL_FLAGS)
         try:
             pk.public_key = pk.ecdsa_recover(
                 rawhash,
                 pk.ecdsa_recoverable_deserialize(
                     zpad(
                         "".join(
                             chr(c)
                             for c in int_to_32bytearray(self.r)), 32) +
                     zpad(
                         "".join(
                             chr(c)
                             for c in int_to_32bytearray(self.s)), 32),
                     self.v - 27),
                 raw=True)
             pub = pk.serialize(compressed=False)
         except Exception:
             raise InvalidSignature()
         if pub[1:] == "\x00" * 32:
             raise InvalidSignature()
         pub = encode_pubkey(pub, 'bin')
         return sha3(pub[1:])[-20:]
Ejemplo n.º 36
0
    def sender(self):

        if not self._sender:
            # Determine sender
            if self.v:
                if self.r >= N or self.s >= N or self.v < 27 or self.v > 28 \
                or self.r == 0 or self.s == 0:
                    raise InvalidTransaction("Invalid signature values!")
                log.debug('recovering sender')
                rlpdata = rlp.encode(self, UnsignedTransaction)
                rawhash = utils.sha3(rlpdata)

                pk = PublicKey(flags=ALL_FLAGS)
                try:
                    pk.public_key = pk.ecdsa_recover(
                        rawhash,
                        pk.ecdsa_recoverable_deserialize(
                            zpad(utils.bytearray_to_bytestr(int_to_32bytearray(self.r)), 32) + zpad(utils.bytearray_to_bytestr(int_to_32bytearray(self.s)), 32),
                            self.v - 27
                        ),
                        raw=True
                    )
                    pub = pk.serialize(compressed=False)
                except Exception:
                    raise InvalidTransaction("Invalid signature values (x^3+7 is non-residue)")

                if pub[1:] == b"\x00" * 32:
                    raise InvalidTransaction("Invalid signature (zero privkey cannot sign)")
                pub = encode_pubkey(pub, 'bin')
                self._sender = utils.sha3(pub[1:])[-20:]
                assert self.sender == self._sender
            else:
                self._sender = 0
        return self._sender
Ejemplo n.º 37
0
    def handlePacket(self, data, addr):
        # print("received message[" +  str(addr) + "]")
        msg_hash = data[:32]  # 32 Byte Hash
        raw_sig = data[32:97]  # 64 Byte + 1 Byte Signature
        ptype = data[97]  # 1 Byte packet_type
        pdata = data[98:]  # Rest is rlp-encoded data
        decdata = rlp.decode(pdata)
        signedData = data[97:]

        # Verify hash
        if msg_hash != keccak256(data[32:]):
            print("Invalid message hash!")
            exit(0)

        # Verify signature
        deserialized_sig = self.priv_key.ecdsa_recoverable_deserialize(
            raw_sig[:64], raw_sig[64])
        remote_pubkey = self.priv_key.ecdsa_recover(keccak256(signedData),
                                                    deserialized_sig,
                                                    raw=True)
        pub = PublicKey()
        pub.public_key = remote_pubkey
        verified = pub.ecdsa_verify(
            keccak256(signedData),
            pub.ecdsa_recoverable_convert(deserialized_sig),
            raw=True)

        if not verified:
            print("Signature invalid!")
            exit(0)
        else:
            print("Public Key: " + pub.serialize().hex())

        packet_type = bytes([ptype])
        if packet_type == PingPacket.packet_type:
            print("Got ping.")
            recv_ping = PingPacket.unpack(rlp.decode(pdata))
            print(str(recv_ping))
            # self.pong(msg_hash, recv_ping.To())
            # TODO: Find out the correct endpoint
            self.pong(self.theirEndpoint, msg_hash)

        if packet_type == PongPacket.packet_type:
            print("Got pong.")
            recv_pong = PongPacket.unpack(decdata)
            print(str(recv_pong))
            # self.ping(self.theirEndpoint)

        if packet_type == FindNodePacket.packet_type:
            print("Got FindNodePacket.")
            recv_findnode = FindNodePacket.unpack(rlp.decode(pdata))
            target = recv_findnode.target
            print("Target: " + str(target.hex()))
            self.neighbors(self.theirEndpoint, target)

        if packet_type == NeighborsPacket.packet_type:
            print("Got NeighborsPacket.")
            recv_neighbors = NeighborsPacket.unpack(rlp.decode(pdata))
            print("# Neighbors: " + str(len(recv_neighbors.neighbors)))
Ejemplo n.º 38
0
    def valid(self):
        """Check if this object is valid or not"""
        if not self.signature:
            return False

        assert isinstance(self.signature, bytes)
        assert 70 <= len(self.signature) <= 71
        assert isinstance(self.user_public_key, bytes)
        assert len(self.user_public_key) == 33
        assert isinstance(self.user_address, str)
        assert re.match(r'^(?:0[xX])?[0-9a-fA-F]{40}$', self.user_address)
        public_key = PublicKey(self.user_public_key, raw=True)
        verified = public_key.ecdsa_verify(
            self.serialize(include_signature=False),
            public_key.ecdsa_deserialize(self.signature))
        if not verified:
            return False

        if get_address(public_key) != self.user_address:
            return False

        return self.id == self.hash
Ejemplo n.º 39
0
 def verify_signature(self, origin_data: bytes, signature: bytes, is_hash: bool):
     try:
         origin_signature, recover_code = signature[:-1], signature[-1]
         recoverable_sig = self._pri.ecdsa_recoverable_deserialize(origin_signature, recover_code)
         pub = self._pri.ecdsa_recover(origin_data,
                                       recover_sig=recoverable_sig,
                                       raw=is_hash,
                                       digest=hashlib.sha3_256)
         extract_pub = PublicKey(pub, ctx=self._base.ctx).serialize(compressed=False)
         return self.verify_address(extract_pub)
     except Exception as e:
         raise RuntimeError(f"signature verification fail : {origin_data} {signature}\n"
                            f"{e}")
Ejemplo n.º 40
0
 def __init__(self):
     self.priv_key = PrivateKey()
     self.pub_key = PublicKey(pubkey=None, raw=False, flags=secp256k1.ALL_FLAGS)
Ejemplo n.º 41
0
		break
	textToSign += data + "\n"

dongle = getDongle(True)
publicKey = dongle.exchange(bytes("8004000000".decode('hex')))
print "publicKey " + str(publicKey).encode('hex')
try:
	offset = 0
	while offset <> len(textToSign):
		if (len(textToSign) - offset) > 255:
			chunk = textToSign[offset : offset + 255] 
		else:
			chunk = textToSign[offset:]
		if (offset + len(chunk)) == len(textToSign):
			p1 = 0x80
		else:
			p1 = 0x00
		apdu = bytes("8002".decode('hex')) + chr(p1) + chr(0x00) + chr(len(chunk)) + bytes(chunk)
		signature = dongle.exchange(apdu)
		offset += len(chunk)  	
	print "signature " + str(signature).encode('hex')
	publicKey = PublicKey(bytes(publicKey), raw=True)
	signature = publicKey.ecdsa_deserialize(bytes(signature))
	print "verified " + str(publicKey.ecdsa_verify(bytes(textToSign), signature))
except CommException as comm:
	if comm.sw == 0x6985:
		print "Aborted by user"
	else:
		print "Invalid status " + comm.sw