#include <crypto/mac.h>
#include <crypto/kdf.h>
#include <crypto/kem.h>
#include <crypto/dem.h>

#define STR_AUX(a) #a
#define STR(a) STR_AUX(a)

NTL_CLIENT


int main()
{
	ostring mssg = "the rain in spain falls mainly on the plain";
        ostring label = "test";
        ostring decoded;

#if !defined(MHash)
#error "Error - MHash not defined."
#endif

#if (MHash == 1)
	SHA1 mhash(20);
	HMAC mac(mhash, 20, 20);
	ostring key = "d460d0340f5a7d533d79ce5ce59b5c778c2874f3330e03e02056";
#elif (MHash == 2)
	SHA256 mhash(20);
	HMAC mac(mhash, 32, 20);
	ostring key = "d460d0340f5a7d533d79ce5ce59b5c778c2874f3330e03e02056abdefdsabdfe";
#elif (MHash == 3)
	MD5 mhash(16);
	HMAC mac(mhash, 20, 16);
	ostring key = "d460d0340f5a7d533d79ce5ce59b5c778c2874f3330e03e02056";
#else
#error "Error - MHash value not defined."
#endif

        AES bc(32);

#if (SymC == 1)
	SC1 sc(bc);
#elif (SymC == 2)
	#if !defined(Kdf)
	#error "Error - Kdf not defined."
	#endif

	#if !defined(Hash)
	#error "Error - Hash not defined."
	#endif

	#if (Hash == 1)
		SHA1 hash(20);
		Kdf kdf(hash);
	#elif (Hash == 2)
		SHA256 hash(20);
	        Kdf kdf(hash);
	#elif (Hash == 3)
		MD5 hash(16);
		Kdf kdf(hash);
	#else
	#error "Error - Hash value not defined."
	#endif

        SC2 sc(kdf, 32);
#else
#error "Error - SymC value not defined."
#endif

        DEM1 dem(sc, mac);

	ofstream io(STR(DESC));
        ofstream trace(STR(TRACE));

        dem.PrettyPrint(io);
        dem.logfile = &trace;

	ostring code = dem.encrypt(key, label, mssg);

	//code[code.size()-1] =  (unsigned char) code[code.size()-1] ^ ((unsigned char) 1);

	try {

		decoded = dem.decrypt(key, label, code);

		if(decoded != mssg)
		cout << " FAILED " << endl;
		else cout << "\nSUCCESS " << endl;

	}
	catch (Decrypt_error) {
		cout << " ERROR " << endl;
	}
}

