예제 #1
0
def encode_signature(tx_v, tx_r, tx_s) -> bytes:
    """
    Calculates byte representation of ECC signature from parameters
    :param tx_v:
    :param tx_r:
    :param tx_s:
    :return: bytes of ECC signature
    """
    if not isinstance(tx_v, int):
        raise ValueError("v is expected to be int")

    if tx_v > eth_common_constants.EIP155_CHAIN_ID_OFFSET:
        if tx_v % 2 == 0:
            tx_v = 28
        else:
            tx_v = 27

    if tx_v not in (27, 28):
        raise ValueError("v is expected to be int or long in range (27, 28)")

    # pyre-fixme[16]: Module `bitcoin` has no attribute `encode`.
    # pyre-fixme[16]: Module `bitcoin` has no attribute `encode`.
    v_bytes, r_bytes, s_bytes = rlp_utils.ascii_chr(tx_v - 27), bitcoin.encode(
        tx_r, 256), bitcoin.encode(tx_s, 256)
    return _left_0_pad_32(r_bytes) + _left_0_pad_32(s_bytes) + v_bytes
예제 #2
0
    def create_auth_message(self):
        """
        Generates authentication message bytes

        1. initiator generates ecdhe-random and nonce and creates auth
        2. initiator connects to remote and sends auth

        New:
        E(remote-pubk,
            S(ephemeral-privk, ecdh-shared-secret ^ nonce) ||
            H(ephemeral-pubk) || pubk || nonce || 0x0
        )
        Known:
        E(remote-pubk,
            S(ephemeral-privk, token ^ nonce) || H(ephemeral-pubk) || pubk || nonce || 0x1)

        :param remote_pubkey: public key of remote node
        :param nonce: nonce
        :return: authentication message bytes
        """

        assert self._is_initiator

        ecdh_shared_secret = self._ecc.get_ecdh_key(self._remote_pubkey)
        token = ecdh_shared_secret
        flag = 0x0
        self._initiator_nonce = eth_common_utils.keccak_hash(
            rlp_utils.int_to_big_endian(random.randint(0, sys.maxsize)))
        assert len(
            self._initiator_nonce) == eth_common_constants.SHA3_LEN_BYTES

        token_xor_nonce = crypto_utils.string_xor(token, self._initiator_nonce)
        assert len(token_xor_nonce) == eth_common_constants.SHA3_LEN_BYTES

        ephemeral_pubkey = self._ephemeral_ecc.get_raw_public_key()
        assert len(ephemeral_pubkey) == eth_common_constants.PUBLIC_KEY_LEN
        if not self._ecc.is_valid_key(ephemeral_pubkey):
            raise InvalidKeyError("Invalid ephemeral pubkey")

        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        S = self._ephemeral_ecc.sign(token_xor_nonce)
        assert len(S) == eth_common_constants.SIGNATURE_LEN

        # S || H(ephemeral-pubk) || pubk || nonce || 0x0
        auth_message = S + eth_common_utils.keccak_hash(ephemeral_pubkey) + self._ecc.get_raw_public_key() + \
                       self._initiator_nonce + rlp_utils.ascii_chr(flag)
        return auth_message