Пример #1
0
def test_javascript_signatures():
    # The zero address will cause `approve` to default to valid signatures
    zero_address = "0x0000000000000000000000000000000000000000"
    accounts = ["0x776ba14735ff84789320718cf0aa43e91f7a8ce1", "0x095ce4e4240fa66ff90282c26847456e3f3b5002"]
    # The address that will receive the transaction
    recipient = "0x776ba14735ff84789320718cf0aa43e91f7a8ce1"
    # These are the matching sigs to the accounts
    raw_sigs = [
        "0x4a89507bf71749fb338ed13fba623a683d9ecab0fb9c389a4298525c043e38281a00ab65628bb18a382eb8c8b4fb4dae95ccc993cf49f617c60d8051180778601c",
        "0xc84fe5d2a600e033930e0cf73f26e78f4c65b134f9c9992f60f08ce0863abdbe0548a6e8aa2d952659f29c67106b59fdfcd64d67df03c1df620c70c85578ae701b"
    ]

    # Turns the raw sigs into sigs
    sigs = [(utils.big_endian_to_int(x[64:]), utils.big_endian_to_int(x[:32]), utils.big_endian_to_int(x[32:64])) for x in 
            map(lambda z: utils.decode_hex(z[2:]), raw_sigs)]

    h = utils.sha3(utils.encode_int32(0) + b'\x00' * 12 + utils.decode_hex(recipient[2:]) + utils.encode_int32(25) + b'')
    h2 = utils.sha3(b"\x19Ethereum Signed Message:\n32" + h)
    # Check to make sure the signatures are valid
    assert '0x'+utils.encode_hex(utils.sha3(utils.ecrecover_to_pub(h2, sigs[0][0], sigs[0][1], sigs[0][2]))[12:]) == accounts[0]
    assert '0x'+utils.encode_hex(utils.sha3(utils.ecrecover_to_pub(h2, sigs[1][0], sigs[1][1], sigs[1][2]))[12:]) == accounts[1]

    # Set the owners to zero addresses
    x2 = t.s.contract(open('examples/wallet/wallet.v.py').read(), args=[accounts + [t.a3, zero_address, zero_address], 2], language='viper')
    t.s.tx(sender=t.k1, to=x2.address, value=10**17)

    # There's no need to pass in signatures because the owners are 0 addresses causing them to default to valid signatures
    assert x2.approve(0, recipient, 25, "", sigs + [[0, 0, 0]] * 3, value=25, sender=t.k1)

    print("Javascript signature tests passed")
Пример #2
0
def ecrecover(data: List[int]) -> List[int]:
    """

    :param data:
    :return:
    """
    # TODO: Add type hints
    try:
        byte_data = bytearray(data)
        v = extract32(byte_data, 32)
        r = extract32(byte_data, 64)
        s = extract32(byte_data, 96)
    except TypeError:
        raise NativeContractException

    message = b"".join([ALL_BYTES[x] for x in byte_data[0:32]])
    if r >= secp256k1n or s >= secp256k1n or v < 27 or v > 28:
        return []
    try:
        pub = ecrecover_to_pub(message, v, r, s)
    except Exception as e:
        log.debug("An error has occured while extracting public key: " + str(e))
        return []
    o = [0] * 12 + [x for x in sha3(pub)[-20:]]
    return list(bytearray(o))
Пример #3
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 isinstance(signature, str):
        signature = data_decoder(signature)

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

    if v == 0 or v == 1:
        v += 27

    pub = ecrecover_to_pub(rawhash, v, r, s)

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

        return recaddr == address

    return recaddr
Пример #4
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 >= secp256k1n or s >= secp256k1n or v < 27 or v > 28:
        return 1, msg.gas - opcodes.GECRECOVER, []
    try:
        pub = utils.ecrecover_to_pub(message_hash, v, r, s)
    except Exception as e:
        return 1, msg.gas - gas_cost, []
    o = [0] * 12 + [safe_ord(x) for x in utils.sha3(pub)[-20:]]
    return 1, msg.gas - gas_cost, o
Пример #5
0
 def sender(self):
     if not self._sender:
         # Determine sender
         if self.r == 0 and self.s == 0:
             self._sender = null_address
         else:
             if self.v in (27, 28):
                 vee = self.v
                 sighash = utils.sha3(rlp.encode(self, UnsignedTransaction))
             elif self.v >= 37:
                 vee = self.v - self.network_id * 2 - 8
                 assert vee in (27, 28)
                 rlpdata = rlp.encode(rlp.infer_sedes(self).serialize(self)[
                                      :-3] + [self.network_id, '', ''])
                 sighash = utils.sha3(rlpdata)
             else:
                 raise InvalidTransaction("Invalid V value")
             if self.r >= secpk1n or self.s >= secpk1n or self.r == 0 or self.s == 0:
                 raise InvalidTransaction("Invalid signature values!")
             pub = ecrecover_to_pub(sighash, vee, self.r, self.s)
             if pub == b'\x00' * 64:
                 raise InvalidTransaction(
                     "Invalid signature (zero privkey cannot sign)")
             self._sender = utils.sha3(pub)[-20:]
     return self._sender
Пример #6
0
    def sign(self, tx_hash: str) -> Tuple[int, int, int]:

        msg_bytes = bytes.fromhex(tx_hash)

        v, r, s = 0, 0, 0

        with self.token.open(user_pin=self.user_pin) as session:
            priv = session.get_key(key_type=pkcs11.KeyType.EC,
                                   object_class=pkcs11.ObjectClass.PRIVATE_KEY,
                                   label=self.label)
            signature = priv.sign(msg_bytes, mechanism=pkcs11.Mechanism.ECDSA)

            r = int.from_bytes(signature[0:32], byteorder='big')
            s = int.from_bytes(signature[32:], byteorder='big')

            secpk1n = 115792089237316195423570985008687907852837564279074904382605163141518161494337
            s = s if s * 2 < secpk1n else secpk1n - s

            v = 0

            for _v in range(27, 29):
                pub2 = ecrecover_to_pub(msg_bytes, _v, r, s)
                if pub2 == self.public_key:
                    v = _v

            if not v:
                raise ValueError("Failed to sign")

        return r, s, v
Пример #7
0
 def sender(self):
     if not self._sender:
         # Determine sender
         if self.r == 0 and self.s == 0:
             self._sender = null_address
         else:
             if self.v in (27, 28):
                 vee = self.v
                 sighash = utils.sha3(rlp.encode(self, UnsignedTransaction))
             elif self.v >= 37:
                 vee = self.v - self.network_id * 2 - 8
                 assert vee in (27, 28)
                 rlpdata = rlp.encode(rlp.infer_sedes(self).serialize(self)[
                                      :-3] + [self.network_id, '', ''])
                 sighash = utils.sha3(rlpdata)
             else:
                 raise InvalidTransaction("Invalid V value")
             if self.r >= secpk1n or self.s >= secpk1n or self.r == 0 or self.s == 0:
                 raise InvalidTransaction("Invalid signature values!")
             pub = ecrecover_to_pub(sighash, vee, self.r, self.s)
             if pub == b'\x00' * 64:
                 raise InvalidTransaction(
                     "Invalid signature (zero privkey cannot sign)")
             self._sender = utils.sha3(pub)[-20:]
     return self._sender
Пример #8
0
def get_sender(hash, sig):
    v = sig[64]
    if v < 27:
        v += 27
    r = u.bytes_to_int(sig[:32])
    s = u.bytes_to_int(sig[32:64])
    pub = u.ecrecover_to_pub(hash, v, r, s)
    return u.sha3(pub)[-20:]
 def get_signing_address(hash, v, r, s) -> str:
     """
     :return: checksum encoded address starting by 0x, for example `0x568c93675A8dEb121700A6FAdDdfE7DFAb66Ae4A`
     :rtype: str
     """
     encoded_64_address = ecrecover_to_pub(hash, v, r, s)
     address_bytes = sha3(encoded_64_address)[-20:]
     return checksum_encode(address_bytes)
Пример #10
0
def get_signing_address(signed_hash: Union[bytes, str], v: int, r: int,
                        s: int) -> str:
    """
    :return: checksummed ethereum address, for example `0x568c93675A8dEb121700A6FAdDdfE7DFAb66Ae4A`
    :rtype: str
    """
    encoded_64_address = ecrecover_to_pub(HexBytes(signed_hash), v, r, s)
    address_bytes = sha3(encoded_64_address)[-20:]
    return checksum_encode(address_bytes)
 def get_signing_address(self) -> str:
     """
     :return: checksum encoded address starting by 0x, for example `0x568c93675A8dEb121700A6FAdDdfE7DFAb66Ae4A`
     :rtype: str
     """
     encoded_64_address = utils.ecrecover_to_pub(self.message_hash, self.v,
                                                 self.r, self.s)
     address_bytes = utils.sha3(encoded_64_address)[-20:]
     return utils.checksum_encode(address_bytes)
    def generateInvalidUnlockTx(self, userAddress, contractAddress,
                                maliciousAddress):
        commit, witness, R, S = generate_submarine_commit._generateRS(
            normalize_address(rec_hex(userAddress)),
            normalize_address(rec_hex(contractAddress)), UNLOCK_AMOUNT, b'',
            OURGASPRICE, OURGASLIMIT)

        unlockFunctionSelector = b"\xec\x9b\x5b\x3a"
        submarineData = unlockFunctionSelector + commit

        # need the unsigned TX hash for ECRecover
        unlock_tx_unsigned_object = transactions.UnsignedTransaction(
            0,  # nonce;
            OURGASPRICE,  # gasprice
            OURGASLIMIT,  # startgas
            normalize_address(maliciousAddress),  # to addr
            UNLOCK_AMOUNT,  # value
            submarineData,  # data
        )
        unlock_tx_unsigned_hash = sha3(
            rlp.encode(unlock_tx_unsigned_object,
                       transactions.UnsignedTransaction))

        unlock_tx_object = transactions.Transaction(
            0,  # nonce;
            OURGASPRICE,  # gasprice
            OURGASLIMIT,  # startgas
            normalize_address(maliciousAddress),  # to addr
            UNLOCK_AMOUNT,  # value
            submarineData,  # data
            27,  # v
            R,  # r
            S  # s
        )

        try:
            pub = ecrecover_to_pub(unlock_tx_unsigned_hash, 27, R, S)
            if pub == b"\x00" * 64:
                log.info("Address no good, retrying")
                return self.generateInvalidUnlockTx(userAddress,
                                                    contractAddress,
                                                    maliciousAddress)
            else:
                commit_addr = sha3(pub)[-20:]
                log.info("Fake Unlock TX Dict: {}".format(
                    unlock_tx_unsigned_object.as_dict()))
                log.info("Fake Unlock TX Commit B: {}".format(commit_addr))
                return unlock_tx_object, unlock_tx_unsigned_object, commit_addr, commit, witness

        except (ValueError, InvalidTransaction) as e:
            if isinstance(e, ValueError) and "VRS" not in str(e):
                raise
            log.info("Address no good (%s), retrying" % e)
            return self.generateInvalidUnlockTx(userAddress, contractAddress,
                                                maliciousAddress)
Пример #13
0
def create_urs_tx(shard_id, gasprice=GASPRICE):
    bytecode = get_urs_bytecode(shard_id)
    tx = Transaction(0, gasprice, 2000000, to=b'', value=0, data=bytecode)
    tx.v = 27
    tx.r = 10000
    tx.s = shard_id + 1
    tx_rawhash = get_tx_rawhash(tx)
    urs_sender_addr = utils.sha3(
        utils.ecrecover_to_pub(tx_rawhash, tx.v, tx.r, tx.s))[-20:]
    urs_addr = utils.mk_contract_address(urs_sender_addr, 0)
    return tx, urs_addr, urs_sender_addr
Пример #14
0
    def add_signatures(self, signatures):
        # sort signatures by lower case lexicographical order
        mapping = {}
        for signature in signatures:
            address = ecrecover_to_pub(self.hash, signature['v'],
                                       signature['r'], signature['s'])
            mapping[address.lower()] = signature

        sorted_signatures = []

        for address in sorted(mapping):
            sorted_signatures.append(mapping[address])

        self.signatures = sorted_signatures
Пример #15
0
 def validate(self, *args, **kwargs):
     signer, signature = self.get_authorization()
     signer = normalize_address(signer)
     signature = signature[-130:]
     r = int(signature[0:64], 16)
     s = int(signature[64:128], 16)
     v = int(signature[128:130], 16)
     if v not in (27, 28):
         v += 27
     message = self._message(signer)
     prefix = b'\x19Ethereum Signed Message:\n' + str(len(message)).encode()
     mhash = sha3(prefix + message)
     pubkey = ecrecover_to_pub(mhash, v, r, s)
     address = normalize_address(sha3(pubkey)[-20:])
     if signer != address:
         return self.get_authenticate()
Пример #16
0
def verify_sig(data, sig, trusted_addrs):
    data_hash = eth.sha3(data)
    sig_pubkey = eth.ecrecover_to_pub(data_hash, sig[0], sig[1], sig[2])
    addr = '0x' + eth.encode_hex(eth.sha3(sig_pubkey)[12:])

    cert = tx.get_cert_from_address(addr, trusted_addrs)
    if cert is None:
        logging.info('No certificate found on address {0}. Invalid '
                     'signature'.format(addr))
    else:
        if cert.status == 'valid':
            logging.info('The signature is valid.')
        else:
            logging.info('The signature is invalid.')

        logging.info('Certificate status: {}'.format(cert.status))
        logging.info('Certificate data: {}'.format(cert.data))
Пример #17
0
    def _sig_valid(self, signature, message_hash, signer):
        try:
            r = int(signature[0:66], 16)
            s = int(add_0x_prefix(signature[66:130]), 16)
            v = int(add_0x_prefix(signature[130:132]), 16)
            if v not in (27, 28):
                v += 27

            pubkey = ecrecover_to_pub(decode_hex(message_hash), v, r, s)

            msg_signer = encode_hex(sha3(pubkey)[-20:])

            valid = (msg_signer == signer.lower())
        except:
            print('exception in _sig_valid')
            valid = False

        return valid
Пример #18
0
def valid_metamask_message(address, message, signature):
    #address = attrs['address']
    #message = attrs['msg']
    #signature = attrs['signed_msg']

    r = int(signature[0:66], 16)
    s = int(add_0x_prefix(signature[66:130]), 16)
    v = int(add_0x_prefix(signature[130:132]), 16)
    if v not in (27, 28):
        v += 27

    message_hash = defunct_hash_message(text=message)
    pubkey = ecrecover_to_pub(decode_hex(message_hash.hex()), v, r, s)
    signer_address = encode_hex(sha3(pubkey)[-20:])

    if signer_address != address.lower():
        raise ValidationError({'result': 'Incorrect signature'}, code=400)

    return True
Пример #19
0
def ecrecover(data):

    try:
        data = bytearray(data)
        v = extract32(data, 32)
        r = extract32(data, 64)
        s = extract32(data, 96)
    except TypeError:
        raise NativeContractException

    message = b"".join([ALL_BYTES[x] for x in data[0:32]])
    if r >= secp256k1n or s >= secp256k1n or v < 27 or v > 28:
        return []
    try:
        pub = ecrecover_to_pub(message, v, r, s)
    except Exception as e:
        logging.info("An error has occured while extracting public key: " + e)
        return []
    o = [0] * 12 + [x for x in sha3(pub)[-20:]]
    return o
Пример #20
0
def ecrecover(h, v, r, s):
    pub = ecrecover_to_pub(h, v, r, s)
    addr = keccak(pub)[-20:]
    addr = encode_hex(addr)
    addr = to_checksum_address(addr)
    return addr
Пример #21
0
]
recipient = "0x776ba14735ff84789320718cf0aa43e91f7a8ce1"
raw_sigs = [
    "0x4a89507bf71749fb338ed13fba623a683d9ecab0fb9c389a4298525c043e38281a00ab65628bb18a382eb8c8b4fb4dae95ccc993cf49f617c60d8051180778601c",
    "0xc84fe5d2a600e033930e0cf73f26e78f4c65b134f9c9992f60f08ce0863abdbe0548a6e8aa2d952659f29c67106b59fdfcd64d67df03c1df620c70c85578ae701b"
]
sigs = [(utils.big_endian_to_int(x[64:]), utils.big_endian_to_int(x[:32]),
         utils.big_endian_to_int(x[32:64]))
        for x in map(lambda z: utils.decode_hex(z[2:]), raw_sigs)]

h = utils.sha3(
    utils.encode_int32(0) + b'\x00' * 12 + utils.decode_hex(recipient[2:]) +
    utils.encode_int32(25) + b'')
h2 = utils.sha3(b"\x19Ethereum Signed Message:\n32" + h)

assert '0x' + utils.encode_hex(
    utils.sha3(utils.ecrecover_to_pub(h2, sigs[0][0], sigs[0][1],
                                      sigs[0][2]))[12:]) == accounts[0]
assert '0x' + utils.encode_hex(
    utils.sha3(utils.ecrecover_to_pub(h2, sigs[1][0], sigs[1][1],
                                      sigs[1][2]))[12:]) == accounts[1]

x2 = c.contract(open('wallet.v.py').read(),
                args=[accounts + [t.a3, zero_address, zero_address], 2],
                language='viper')
c.tx(sender=t.k1, to=x2.address, value=10**17)

assert x2.approve(0, recipient, 25, "", sigs + [[0, 0, 0]] * 3)

print("Javascript signature tests passed")
Пример #22
0
def extract_sender_from_tx(tx):
    tx_rawhash = get_tx_rawhash(tx)
    return utils.sha3(utils.ecrecover_to_pub(tx_rawhash, tx.v, tx.r,
                                             tx.s))[-20:]
Пример #23
0
def recover_to_addr(msg, sig):
    msghash = hash_personal_message(msg)
    vrs = sig_to_vrs(sig)
    return '0x' + sha3.keccak_256(ecrecover_to_pub(msghash, *
                                                   vrs)).hexdigest()[24:]
Пример #24
0
from ethereum.utils import sha3, ecrecover_to_pub
from eth_utils import decode_hex
import sys


if len(sys.argv) != 5:
    print("Wrong number of arguments. Should be ecrecovery.py msghash v r s.")
    print(sys.argv)
    sys.exit()

prog, hash, vstr, rstr, str = sys.argv

msg_hash = decode_hex(hash)
v = int(vstr)
r = int(rstr)
s = int(str)

pubkey = ecrecover_to_pub(msg_hash, v, r, s)
addr = sha3(pubkey)[-20:].hex()
print('0x' + addr)