#include <crypto/hc.h>
#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(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

        AES bc(32);

#if (SymC == 1)
        SC1 sc(bc);
#elif (SymC == 2)
        SC2 sc(kdf, 32);
#else
#error "Error - SymC value not defined."
#endif

        HMAC mac(hash, 20, 20);
        DEM1 dem(sc, mac);

#if (GRP != 1 && GRP != 2 && GRP != 3) || !defined(GRP)
#error "Error - GRP not defined."
#endif

        // for reading group keys from file
#if (GRP == 1)
        ifstream ifile("grp.txt");
        modp_group grp(ifile);

        ACEKEM<modp_group> kem(0, kdf, hash, dem.keylen, grp);

#elif (GRP == 2)
        ifstream ifile("192.txt");
        ecmodp_group grp(ifile);

        ACEKEM<ecmodp_group> kem(0, kdf, hash, dem.keylen, grp);

#else
        ifstream ifile("163.txt");
        ecgf2_group grp(ifile);

        ACEKEM<ecgf2_group> kem(0, kdf, hash, dem.keylen, grp);

#endif

        if (!ifile) cout << " cannot open input file ";

	HC hc(kem, dem);

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

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

	ostring code = hc.encrypt(mssg,label);

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

	try {

		decoded = hc.decrypt(code,label);

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

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

