#include "User.h"
#include <iostream>

using namespace std;

User::User(string s1, string s2) {
	
	name = s1;
	if (s1 != "")
		if (s2 == "")
			email = s1 + "@ime.usp.br";
		else
			email = s2;
	key = 0;
	ta = TA::getInstance();
}

void User::setName(string s) {
	name = s;
}

void User::setEmail(string s) {
	email = s;
}

string User::getName(void) {
	return name;
}

string User::getEmail(void) {
	return email;
}

void User::createKey(void) {

	key = ta->userKeyGeneration(email);
}

pair<uint32, uint32> User::signatureGeneration(string msg) {
	
	uint32 t, s, r;
	pair<uint32, uint32> sign;	

	cout << "Generating message signature...";

	do {
		r = (uint32)((double)rand() / RAND_MAX * (ta->getN() - 1) + 1);
	} while (Util::gcd(r, ta->getN()) != 1);

	t = Util::powMod(r, ta->getExponent(), ta->getN());
	s = Util::hash(Util::uint32ToString(t) + msg) % ta->getPhiN();
	s = Util::powMod(r, s, ta->getN());
	s = (uint32)((uint64)key * s % ta->getN());

	sign.first = s;
	sign.second = t;

	cout << " done." << endl << endl;

	return sign;
}

bool User::signatureVerification(uint32 ID, pair<uint32, uint32> sign, string msg) {

	uint32 h;

	cout << "Verifying message signature...";

	h = Util::hash(Util::uint32ToString(sign.second) + msg) % ta->getPhiN();
	h = Util::powMod(sign.second, h, ta->getN());
	h = (uint32)((uint64)ID * h % ta->getN());

	cout << " done." << endl << endl;

	return Util::powMod(sign.first, ta->getExponent(), ta->getN()) == h;

}