/*---------------------------------------------------------------------------------------------
Signature Generation of (Unbalanced) Oil and Vinegar
loads private key from UOV/private_key.txt and generates an UOV aignature for a randomly chosen message
signature is stored in UOV/signature.txt 
-------------------------------------------------------------------------------------------*/

printf "***************************************************** \n";
printf "***  Signature Scheme - Signature Generation *** \n";
printf "***************************************************** \n \n";

clear ;
timet := Cputime() ;

load "private_key.txt";


Hashspace:=VectorSpace(GF,o);
Signspace:=VectorSpace(GF,o+v);
hashvalue:=Random(Hashspace);
printf "message:= %o \n \n", hashvalue;



//invert central map Q -----------------------------------------------------
repeat
	Q1:=Q;
	// choosing Vinegar variables and simplifying the system
	vin:=[];
	for i:= 1 to v do
		vin[i]:=P!Random(GF);
		for loop:=1 to o do
			Q1[loop]:=Evaluate(Q1[loop],y[i],vin[i]);
		end for;
	end for;

	printf "vin:= %o \n \n", ChangeUniverse(vin,GF);

	// Solving the system for the Oil variables
	Qseq:=[]; c_Q:=[];
	for loop:=1 to o do
		c_Q:= c_Q cat [MonomialCoefficient(Q1[loop],1)];
		for i:=v+1 to n do
			Qseq:=Qseq cat [MonomialCoefficient(Q1[loop],y[i])];
		end for;
	end for;
	MatrixQ:=Matrix(GF,o,o,Qseq);
	c_Q:=Hashspace!(c_Q);

	tr,Y,_:=IsConsistent(Transpose(MatrixQ), hashvalue-c_Q);

	if tr eq false then
		printf "Found no solution. Choose other values for the Vinegar variables \n \n";
	else
		printf "Found solution %o \n \n", Y;
	end if;

until tr ;

y1:=vin cat Eltseq(Y);
Y:= Signspace!(y1);

// invert T -----------------------------------------------------------
MT:=Matrix(GF,n,n,MT);
cT:=Signspace!(cT);

_,signature,_:=IsConsistent(Transpose(MT), Y-cT);

// Output ---------------------------------------------------------------

printf "F^(-1)(message):= %o \n \n", Y;
printf "signature := %o  \n \n", signature;

printf "Balanced OV time for signing: %o\n\n",Cputime(timet);

printf"Write signature.txt \n \n";
SetOutputFile("signature.txt":Overwrite:=true);
printf "Hashspace:=VectorSpace(GF,o); \n \n";
printf "Signspace:=VectorSpace(GF,n); \n \n";
printf "hashvalue:= Hashspace!(%o) ; \n \n", Eltseq(hashvalue);
printf "signature:=Signspace!(%o) ; \n \n", Eltseq(signature);
UnsetOutputFile();



