private static function build(string $data, string $pass, int $cost, string $salt = null): string
    {
        // Generate salt if needed
        $salt = $salt ?? \random_bytes(16);

        // Generate a deterministic hash of the password
        $pkey = \hash_pbkdf2(self::ALGO, $pass, $salt, $cost, 0, true);

        // HMAC the input parameter with the generated key
        $hash = \hash_hmac(self::ALGO, $data, $pkey, true);

        // Covert cost value to byte array and encrypt
        $cost = self::costEncrypt($cost, $salt, $pass);

        // Create a hash of the cost to prevent DOS attacks caused by
        // flipping bits in the cost area of the blob and then requesting validation
        $chsh = self::costHash($cost, $pass);

        // Return the salt + cost + hmac as a single string
        return $salt . $chsh . $cost . $hash;
    }