std::string BlockModes::TrippleDES_cbc_decrypt(std::string cipherTextStr, std::bitset<64> key1, std::bitset<64> key2, std::bitset<64> key3, std::bitset<64> IV){
// convert to binary
	std::string cipherText(Util::toBinary(cipherTextStr));

	int cipherTextLength = cipherText.length();
	int numOfBlocks = std::ceil(cipherTextLength / 64);

	std::stringstream plainText;
	std::bitset<64> IV_i = IV;
	std::bitset<64> oldC;

	for (int n = 0; n < numOfBlocks; n++){

		std::bitset<64> c;
		for (int i = 63; i >= 0; i--)
			c.set(i, (cipherText[n*BLOCKSIZE + 63 - i] == '1' ? 1 : 0));
		oldC = c;
		std::bitset<64> plaintextBitset = DES::TrippleDecrypt(c, key1, key2, key3);
		std::bitset<64> xored = plaintextBitset^IV_i;
		IV_i = oldC;

		std::string p = Util::bitsetToAscii(xored);
		plainText << p;
	}

	return plainText.str();

}
std::string BlockModes::ctr_decrypt(std::string cipherTextStr, std::bitset<64> key, std::bitset<64> counter){
	// convert to binary
	std::string cipherText(Util::toBinary(cipherTextStr));

	int cipherTextLength = cipherText.length();
	int numOfBlocks = std::ceil(cipherTextLength / 64);

	std::stringstream plainText;
	std::bitset<64> counter_i = counter;

	for (int n = 0; n < numOfBlocks; n++){

		std::bitset<64> c;
		for (int i = 63; i >= 0; i--)
			c.set(i, (cipherText[n*BLOCKSIZE + 63 - i] == '1' ? 1 : 0));

		std::bitset<64> blockKey = DES::encrypt(counter_i, key);

		counter_i = Util::increment<64>(counter_i);	// Increment counter

		std::string p = Util::bitsetToAscii(blockKey^c);	// XOR plaintext with the key
		plainText << p;
	}

	return plainText.str();
}
// FIXME: We should change data to Vector<uint8_t> type once WebKitSubtleCrypto is deprecated.
// https://bugs.webkit.org/show_bug.cgi?id=164939
static ExceptionOr<Vector<uint8_t>> encryptRSA_OAEP(CryptoAlgorithmIdentifier hash, const Vector<uint8_t>& label, const PlatformRSAKey key, size_t keyLength, const uint8_t* data, size_t dataLength)
{
    CCDigestAlgorithm digestAlgorithm;
    if (!getCommonCryptoDigestAlgorithm(hash, digestAlgorithm))
        return Exception { OperationError };

    Vector<uint8_t> cipherText(keyLength / 8); // Per Step 3.c of https://tools.ietf.org/html/rfc3447#section-7.1.1
    size_t cipherTextLength = cipherText.size();
    if (CCRSACryptorEncrypt(key, ccOAEPPadding, data, dataLength, cipherText.data(), &cipherTextLength, label.data(), label.size(), digestAlgorithm))
        return Exception { OperationError };

    return WTFMove(cipherText);
}
void CryptoAlgorithmRSA_OAEP::platformEncrypt(const CryptoAlgorithmRsaOaepParams& parameters, const CryptoKeyRSA& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback, ExceptionCode& ec)
{
    CCDigestAlgorithm digestAlgorithm;
    if (!getCommonCryptoDigestAlgorithm(parameters.hash, digestAlgorithm)) {
        ec = NOT_SUPPORTED_ERR;
        return;
    }

    Vector<uint8_t> cipherText(1024);
    size_t cipherTextLength = cipherText.size();
    ASSERT(parameters.hasLabel || parameters.label.isEmpty());
    CCCryptorStatus status = CCRSACryptorEncrypt(key.platformKey(), ccOAEPPadding, data.first, data.second, cipherText.data(), &cipherTextLength, parameters.label.data(), parameters.label.size(), digestAlgorithm);
    if (status) {
        failureCallback();
        return;
    }

    cipherText.resize(cipherTextLength);
    callback(cipherText);
}
std::string BlockModes::ecb_decrypt(std::string cipherTextStr, std::bitset<64> key){
	// convert to binary
	std::string cipherText(Util::toBinary(cipherTextStr));

	int cipherTextLength = cipherText.length();
	int numOfBlocks = std::ceil(cipherTextLength / 64);

	std::stringstream plainText;

	for (int n = 0; n < numOfBlocks; n++){
		std::bitset<64> c;
		for (int i = 63; i >= 0; i--)		
			c.set(i, (cipherText[n*BLOCKSIZE + 63 - i] == '1' ? 1 : 0));

		auto plaintextBitset = DES::decrypt(c, key);
		std::string p = Util::bitsetToAscii(plaintextBitset);
		plainText << p;
	}

	return plainText.str();

}