public function derivePublicKey(KeyPair $keyPair)
    {
        $buffer = new Buffer;

        // hash the secret key with Keccak SHA3 variation with 512-bit output (64 bytes)
        $hashedSecret = Encryption::hash("keccak-512", $keyPair->getSecretKey()->getBinary(), true); // raw=true

        // clamp bits of the scalar *before* scalar multiplication
        $safeSecret = Buffer::clampBits($hashedSecret);

        // do scalar multiplication for: `basePoint` * `safeSecret`
        // the result of this multiplication is the `publicKey`.
        // sk_to_pk() does scalarmult_base() and ge_p3_tobytes()
        $publicKey = ParagonIE_Sodium_Core_Ed25519::sk_to_pk($safeSecret);
        $publicBuf = new Buffer($publicKey, SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES);

        assert(SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES === $publicBuf->getSize());
        return $publicBuf;
    }