public static InitiatorHandshakeMessageV1 decode(final Bytes bytes, final NodeKey nodeKey) {
    checkState(bytes.size() == MESSAGE_LENGTH);

    int offset = 0;
    final SECPSignature signature =
        SIGNATURE_ALGORITHM
            .get()
            .decodeSignature(bytes.slice(offset, ECIESHandshaker.SIGNATURE_LENGTH));
    final Bytes32 ephPubKeyHash =
        Bytes32.wrap(
            bytes.slice(
                offset += ECIESHandshaker.SIGNATURE_LENGTH, ECIESHandshaker.HASH_EPH_PUBKEY_LENGTH),
            0);
    final SECPPublicKey pubKey =
        SIGNATURE_ALGORITHM
            .get()
            .createPublicKey(
                bytes.slice(
                    offset += ECIESHandshaker.HASH_EPH_PUBKEY_LENGTH,
                    ECIESHandshaker.PUBKEY_LENGTH));
    final Bytes32 nonce =
        Bytes32.wrap(
            bytes.slice(offset += ECIESHandshaker.PUBKEY_LENGTH, ECIESHandshaker.NONCE_LENGTH), 0);
    final boolean token = bytes.get(offset) == 0x01;

    final Bytes32 staticSharedSecret = nodeKey.calculateECDHKeyAgreement(pubKey);
    final SECPPublicKey ephPubKey =
        SIGNATURE_ALGORITHM
            .get()
            .recoverPublicKeyFromSignature(staticSharedSecret.xor(nonce), signature)
            .orElseThrow(() -> new RuntimeException("Could not recover public key from signature"));

    return new InitiatorHandshakeMessageV1(
        pubKey, signature, ephPubKey, ephPubKeyHash, nonce, token);
  }
Decodes this message.

@param bytes The raw bytes.
@param nodeKey The nodeKey used to calculate ECDH key agreements.
@return The decoded message.
ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/handshake/ecies/InitiatorHandshakeMessageV1.java