コード例 #1
0
def test_go_sig():
    """
    go client started with:

    ethereum -port="40404" -loglevel=5  -nodekeyhex="9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658" -bootnodes="enode://2da47499d52d9161a778e4c711e22e8651cb90350ec066452f9516d1d11eb465d1ec42bb27ec6cd4488b8b6a1a411cb5ef83c16cbb8bee194624bb65fef0f7fd@127.0.0.1:30303"
    """

    r_pubkey = "ab16b8c7fc1febb74ceedf1349944ffd4a04d11802451d02e808f08cb3b0c1c1a9c4e1efb7d309a762baa4c9c8da08890b3b712d1666b5b630d6c6a09cbba171".decode(
        'hex')
    d = {
        'signed_data':
        'a061e5b799b5bb3a3a68a7eab6ee11207d90672e796510ac455e985bd206e240',
        'cmd':
        'find_node',
        'body':
        '03f847b840ab16b8c7fc1febb74ceedf1349944ffd4a04d11802451d02e808f08cb3b0c1c1a9c4e1efb7d309a762baa4c9c8da08890b3b712d1666b5b630d6c6a09cbba1718454e869b1',
        'signature':
        '0de032c62e30f4a9f9f07f25ac5377c5a531116147617a6c08f946c97991f351577e53ae138210bdb7447bab53f3398d746d42c64a9ce67a6248e59353f1bc6e01'
    }

    priv_seed = 'test'
    priv_key = mk_privkey(priv_seed)
    assert priv_key == "9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658".decode(
        'hex')
    my_pubkey = privtopub(priv_key)
    assert my_pubkey == r_pubkey, (my_pubkey, r_pubkey)
    go_body = d['body'].decode('hex')  # cmd_id, rlp.encoded
    import rlp
    target_node_id, expiry = rlp.decode(go_body[1:])
    assert target_node_id == r_pubkey  # lookup for itself
    go_signed_data = d['signed_data'].decode('hex')
    go_signature = d['signature'].decode('hex')

    b_signature = bitcoin.ecdsa_sign(go_signed_data,
                                     priv_key)  # base64 encoded!

    # https://github.com/vbuterin/pybitcointools/blob/master/bitcoin/main.py#L500
    my_signature = ecdsa_sign(go_signed_data, priv_key)
    assert my_signature == ecdsa_sign(go_signed_data,
                                      priv_key)  # deterministic k

    assert len(go_signed_data) == 32  # sha3()
    assert len(go_signature) == 65
    assert len(my_signature) == 65  # length is okay

    try:
        assert my_signature == go_signature
        failed = False
    except:
        "expected fail, go signatures are not generated with deterministic k"
        failed = True
        pass
    assert failed

    # decoding works when we signed it
    assert my_pubkey == ecdsa_recover(go_signed_data, my_signature)

    # problem we can not decode the pubkey from the go signature
    # and go can not decode ours
    ecdsa_recover(go_signed_data, go_signature)
コード例 #2
0
def test_go_sig():
    """
    go client started with:

    ethereum -port="40404" -loglevel=5  -nodekeyhex="9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658" -bootnodes="enode://2da47499d52d9161a778e4c711e22e8651cb90350ec066452f9516d1d11eb465d1ec42bb27ec6cd4488b8b6a1a411cb5ef83c16cbb8bee194624bb65fef0f7fd@127.0.0.1:30303"
    """

    r_pubkey = "ab16b8c7fc1febb74ceedf1349944ffd4a04d11802451d02e808f08cb3b0c1c1a9c4e1efb7d309a762baa4c9c8da08890b3b712d1666b5b630d6c6a09cbba171".decode(
        'hex')
    d = {'signed_data': 'a061e5b799b5bb3a3a68a7eab6ee11207d90672e796510ac455e985bd206e240',
         'cmd': 'find_node',
         'body': '03f847b840ab16b8c7fc1febb74ceedf1349944ffd4a04d11802451d02e808f08cb3b0c1c1a9c4e1efb7d309a762baa4c9c8da08890b3b712d1666b5b630d6c6a09cbba1718454e869b1',
         'signature': '0de032c62e30f4a9f9f07f25ac5377c5a531116147617a6c08f946c97991f351577e53ae138210bdb7447bab53f3398d746d42c64a9ce67a6248e59353f1bc6e01'}

    priv_seed = 'test'
    priv_key = mk_privkey(priv_seed)
    assert priv_key == "9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658".decode(
        'hex')
    my_pubkey = privtopub(priv_key)
    assert my_pubkey == r_pubkey, (my_pubkey, r_pubkey)
    go_body = d['body'].decode('hex')  # cmd_id, rlp.encoded
    import rlp
    target_node_id, expiry = rlp.decode(go_body[1:])
    assert target_node_id == r_pubkey  # lookup for itself
    go_signed_data = d['signed_data'].decode('hex')
    go_signature = d['signature'].decode('hex')

    my_signature = ecdsa_sign(go_signed_data, priv_key)
    assert my_signature == ecdsa_sign(go_signed_data, priv_key)  # deterministic k

    assert len(go_signed_data) == 32  # sha3()
    assert len(go_signature) == 65
    assert len(my_signature) == 65  # length is okay

    try:
        assert my_signature == go_signature
        failed = False
    except:
        "expected fail, go signatures are not generated with deterministic k"
        failed = True
        pass
    assert failed

    # decoding works when we signed it
    assert my_pubkey == ecdsa_recover(go_signed_data, my_signature)

    # problem we can not decode the pubkey from the go signature
    # and go can not decode ours
    ecdsa_recover(go_signed_data, go_signature)
コード例 #3
0
ファイル: rlpxcipher.py プロジェクト: jamesqiuhaorna/hgfrr
    def decode_authentication(self, ciphertext):
        """
        3. optionally, remote decrypts and verifies auth
            (checks that recovery of signature == H(ephemeral-pubk))
        4. remote generates authAck from remote-ephemeral-pubk and nonce
            (authAck = authRecipient handshake)

        optional: remote derives secrets and preemptively sends protocol-handshake (steps 9,11,8,10)
        """
        assert not self.is_initiator
        if len(ciphertext) < 307:
            raise FormatError("Ciphertext too short")
        try:
            (size, sig, initiator_pubkey, nonce,
             version) = self.decode_auth_plain(ciphertext)
        except AuthenticationError:
            (size, sig, initiator_pubkey, nonce,
             version) = self.decode_auth_eip8(ciphertext)
            self.got_eip8_auth = True
        self.auth_init = ciphertext[:size]
        # recover initiator ephemeral pubkey from sig
        #     S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        token = self.ecc.get_ecdh_key(initiator_pubkey)
        self.remote_ephemeral_pubkey = ecdsa_recover(sxor(token, nonce), sig)
        if not self.ecc.is_valid_key(self.remote_ephemeral_pubkey):
            raise InvalidKeyError('invalid remote ephemeral pubkey')
        self.initiator_nonce = nonce
        self.remote_pubkey = initiator_pubkey
        self.remote_version = version
        return ciphertext[size:]
コード例 #4
0
ファイル: discovery.py プロジェクト: gvsurenderreddy/pydevp2p
 def unpack(self, message):
     """
     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:])
     """
     mdc = message[:32]
     assert mdc == crypto.sha3(message[32:])
     signature = message[32:97]
     assert len(signature) == 65
     signed_data = crypto.sha3(message[97:])
     remote_pubkey = crypto.ecdsa_recover(signed_data, signature)
     assert len(remote_pubkey) == 512 / 8
     if not crypto.verify(remote_pubkey, signature, signed_data):
         raise InvalidSignature()
     cmd_id = self.decoders['cmd_id'](message[97])
     assert cmd_id in self.cmd_id_map.values()
     payload = rlp.decode(message[98:])
     assert isinstance(payload, list)
     expiration = self.decoders['expiration'](payload.pop())
     if time.time() > expiration:
         raise PacketExpired()
     return remote_pubkey, cmd_id, payload, mdc
コード例 #5
0
 def unpack(self, message):
     """
     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:])
     """
     mdc = message[:32]
     if mdc != crypto.sha3(message[32:]):
         log.warn('packet with wrong mcd')
         raise WrongMAC()
     signature = message[32:97]
     assert len(signature) == 65
     signed_data = crypto.sha3(message[97:])
     remote_pubkey = crypto.ecdsa_recover(signed_data, signature)
     assert len(remote_pubkey) == 512 / 8
     if not crypto.verify(remote_pubkey, signature, signed_data):
         raise InvalidSignature()
     cmd_id = self.decoders['cmd_id'](message[97])
     assert cmd_id in self.cmd_id_map.values()
     payload = rlp.decode(message[98:])
     assert isinstance(payload, list)
     expiration = self.decoders['expiration'](payload.pop())
     if time.time() > expiration:
         raise PacketExpired()
     return remote_pubkey, cmd_id, payload, mdc
コード例 #6
0
ファイル: test_crypto.py プロジェクト: jnnk/pydevp2p
def recover_1kb(times=1000):
    alice = get_ecc('secret1')
    message = ''.join(chr(random.randrange(0, 256)) for i in range(1024))
    signature = alice.sign(message)
    for i in range(times):
        recovered_pubkey = crypto.ecdsa_recover(message, signature)
    assert recovered_pubkey == alice.raw_pubkey
コード例 #7
0
 def unpack(self, message):
     """
     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:])
     """
     mdc = message[:32]
     if mdc != crypto.sha3(message[32:]):
         log.warn('packet with wrong mcd')
         raise WrongMAC()
     signature = message[32:97]
     assert len(signature) == 65
     signed_data = crypto.sha3(message[97:])
     remote_pubkey = crypto.ecdsa_recover(signed_data, signature)
     assert len(remote_pubkey) == 512 / 8
     # if not crypto.verify(remote_pubkey, signature, signed_data):
     #     raise InvalidSignature()
     cmd_id = self.decoders['cmd_id'](message[97])
     cmd = self.rev_cmd_id_map[cmd_id]
     payload = rlp.decode(message[98:], strict=False)
     assert isinstance(payload, list)
     # ignore excessive list elements as required by EIP-8.
     payload = payload[:self.cmd_elem_count_map.get(cmd, len(payload))]
     return remote_pubkey, cmd_id, payload, mdc
コード例 #8
0
ファイル: test_crypto.py プロジェクト: RomanZacharia/pydevp2p
def recover_1kb(times=1000):
    alice = get_ecc('secret1')
    message = ''.join(chr(random.randrange(0, 256)) for i in range(1024))
    signature = alice.sign(message)
    for i in range(times):
        recovered_pubkey = crypto.ecdsa_recover(message, signature)
    assert recovered_pubkey == alice.raw_pubkey
コード例 #9
0
def test_recover():
    alice = get_ecc(b'secret1')
    message = crypto.sha3(b'hello bob')
    signature = alice.sign(message)
    assert len(signature) == 65
    assert crypto.verify(alice.raw_pubkey, signature, message) is True
    recovered_pubkey = crypto.ecdsa_recover(message, signature)
    assert len(recovered_pubkey) == 64
    assert alice.raw_pubkey == recovered_pubkey
コード例 #10
0
ファイル: test_crypto.py プロジェクト: RomanZacharia/pydevp2p
def test_recover():
    alice = get_ecc('secret1')
    message = 'hello bob'
    signature = alice.sign(message)
    assert len(signature) == 65
    assert crypto.verify(alice.raw_pubkey, signature, message) is True
    recovered_pubkey = crypto.ecdsa_recover(message, signature)
    assert len(recovered_pubkey) == 64
    assert alice.raw_pubkey == recovered_pubkey
コード例 #11
0
    def decode_authentication(self, ciphertext):
        """
        3. optionally, remote decrypts and verifies auth
            (checks that recovery of signature == H(ephemeral-pubk))
        4. remote generates authAck from remote-ephemeral-pubk and nonce
            (authAck = authRecipient handshake)

        optional: remote derives secrets and preemptively sends protocol-handshake (steps 9,11,8,10)
        """
        assert not self.is_initiator

        self.auth_init = ciphertext
        try:
            auth_message = self.ecc.ecies_decrypt(ciphertext)
        except RuntimeError as e:
            raise AuthenticationError(e)

        # S || H(ephemeral-pubk) || pubk || nonce || 0x[0|1]
        assert len(
            auth_message
        ) == 65 + 32 + 64 + 32 + 1 == 194 == self.auth_message_length
        signature = auth_message[:65]
        H_initiator_ephemeral_pubkey = auth_message[65:65 + 32]
        initiator_pubkey = auth_message[65 + 32:65 + 32 + 64]
        if not self.ecc.is_valid_key(initiator_pubkey):
            raise InvalidKeyError('invalid initiator pubkey')
        self.remote_pubkey = initiator_pubkey
        self.initiator_nonce = auth_message[65 + 32 + 64:65 + 32 + 64 + 32]
        known_flag = bool(ord(auth_message[65 + 32 + 64 + 32:]))

        # token or new ecdh_shared_secret
        if known_flag:
            self.remote_token_found = True
            # what todo if remote has token, but local forgot it.
            #   reply with token not found. FIXME!!!
            token = self.token_by_pubkey.get(initiator_pubkey)
            assert token  # FIXME continue session with ecdh_key and send flag in auth_ack
        else:
            token = self.ecc.get_ecdh_key(initiator_pubkey)

        # verify auth
        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        signed = sxor(token, self.initiator_nonce)

        # recover initiator ephemeral pubkey
        self.remote_ephemeral_pubkey = ecdsa_recover(signed, signature)
        if not self.ecc.is_valid_key(self.remote_ephemeral_pubkey):
            raise InvalidKeyError('invalid remote ephemeral pubkey')
        if not ecdsa_verify(self.remote_ephemeral_pubkey, signature, signed):
            raise AuthenticationError('could not verify signature')

        # checks that recovery of signature == H(ephemeral-pubk)
        assert H_initiator_ephemeral_pubkey == sha3(
            self.remote_ephemeral_pubkey)
コード例 #12
0
ファイル: rlpxcipher.py プロジェクト: RomanZacharia/pydevp2p
    def decode_authentication(self, ciphertext):
        """
        3. optionally, remote decrypts and verifies auth
            (checks that recovery of signature == H(ephemeral-pubk))
        4. remote generates authAck from remote-ephemeral-pubk and nonce
            (authAck = authRecipient handshake)

        optional: remote derives secrets and preemptively sends protocol-handshake (steps 9,11,8,10)
        """
        assert not self.is_initiator

        self.auth_init = ciphertext
        try:
            auth_message = self.ecc.ecies_decrypt(ciphertext)
        except RuntimeError as e:
            raise AuthenticationError(e)

        # S || H(ephemeral-pubk) || pubk || nonce || 0x[0|1]
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194 == self.auth_message_length
        signature = auth_message[:65]
        H_initiator_ephemeral_pubkey = auth_message[65:65 + 32]
        initiator_pubkey = auth_message[65 + 32:65 + 32 + 64]
        if not self.ecc.is_valid_key(initiator_pubkey):
            raise InvalidKeyError('invalid initiator pubkey')
        self.remote_pubkey = initiator_pubkey
        self.initiator_nonce = auth_message[65 + 32 + 64:65 + 32 + 64 + 32]
        known_flag = bool(ord(auth_message[65 + 32 + 64 + 32:]))

        # token or new ecdh_shared_secret
        if known_flag:
            self.remote_token_found = True
            # what todo if remote has token, but local forgot it.
            #   reply with token not found. FIXME!!!
            token = self.token_by_pubkey.get(initiator_pubkey)
            assert token  # FIXME continue session with ecdh_key and send flag in auth_ack
        else:
            token = self.ecc.get_ecdh_key(initiator_pubkey)

        # verify auth
        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        signed = sxor(token, self.initiator_nonce)

        # recover initiator ephemeral pubkey
        self.remote_ephemeral_pubkey = ecdsa_recover(signed, signature)
        if not self.ecc.is_valid_key(self.remote_ephemeral_pubkey):
            raise InvalidKeyError('invalid remote ephemeral pubkey')
        if not ecdsa_verify(self.remote_ephemeral_pubkey, signature, signed):
            raise AuthenticationError('could not verify signature')

        # checks that recovery of signature == H(ephemeral-pubk)
        assert H_initiator_ephemeral_pubkey == sha3(self.remote_ephemeral_pubkey)
コード例 #13
0
ファイル: encryption.py プロジェクト: jnnk/pydevp2p
    def receive_authentication(self, ciphertext):
        """
        3. optionally, remote decrypts and verifies auth
            (checks that recovery of signature == H(ephemeral-pubk))
        4. remote generates authAck from remote-ephemeral-pubk and nonce
            (authAck = authRecipient handshake)

        optional: remote derives secrets and preemptively sends protocol-handshake (steps 9,11,8,10)
        """
        auth_message = self.node.ecies_decrypt(ciphertext)
        # S || H(ephemeral-pubk) || pubk || nonce || 0x[0|1]
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194
        signature = auth_message[:65]
        H_remote_ephemeral_pubkey = auth_message[65:65 + 32]
        remote_pubkey = auth_message[65 + 32:65 + 32 + 64]
        nonce = auth_message[65 + 32 + 64:65 + 32 + 64 + 32]
        known_flag = auth_message[65 + 32 + 64 + 32:]

        # token or new ecdh_shared_secret
        token_database = dict()  # FIXME
        token_found = False
        if known_flag == 1:
            token = token_database.get(remote_pubkey)
            if token:
                token_found = True
        else:
            token = ecdh_shared_secret = self.node.get_ecdh_key(remote_pubkey)

        # verify auth
        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        ecdh_shared_secret = self.node.get_ecdh_key(remote_pubkey)
        signed = sxor(ecdh_shared_secret, nonce)

        # recover remote ephemeral pubkey
        remote_ephemeral_pubkey = ecdsa_recover(signed, signature)

        assert ecdsa_verify(remote_ephemeral_pubkey, signature, signed)

        # checks that recovery of signature == H(ephemeral-pubk)
        assert H_remote_ephemeral_pubkey == sha3(remote_ephemeral_pubkey)

        return dict(remote_ephemeral_pubkey=remote_ephemeral_pubkey,
                    token=token,
                    token_found=token_found,
                    ecdh_shared_secret=ecdh_shared_secret,
                    remote_pubkey=remote_pubkey,
                    nonce=nonce,
                    known_flag=known_flag)