public static function deriveEncryptionKeyPair(
        HiddenString $password,
        string $salt,
        string $level = self::INTERACTIVE,
        int $alg = SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13
    ): EncryptionKeyPair {
        $kdfLimits = self::getSecurityLevels($level, $alg);
        // VERSION 2+ (argon2)
        if (Binary::safeStrlen($salt) !== \SODIUM_CRYPTO_PWHASH_SALTBYTES) {
            // @codeCoverageIgnoreStart
            throw new InvalidSalt(
                'Expected ' . \SODIUM_CRYPTO_PWHASH_SALTBYTES . ' bytes, got ' . Binary::safeStrlen($salt)
            );
            // @codeCoverageIgnoreEnd
        }
        // Diffie Hellman key exchange key pair
        /** @var string $seed */
        $seed = @\sodium_crypto_pwhash(
            \SODIUM_CRYPTO_BOX_SEEDBYTES,
            $password->getString(),
            $salt,
            $kdfLimits[0],
            $kdfLimits[1],
            $alg
        );
        $keyPair = \sodium_crypto_box_seed_keypair($seed);
        $secretKey = \sodium_crypto_box_secretkey($keyPair);
        
        // Let's wipe our $kp variable
        \sodium_memzero($keyPair);
        return new EncryptionKeyPair(
            new EncryptionSecretKey(
                new HiddenString($secretKey)
            )
        );
    }