#include <stdio.h>
#include <stdint.h>
#include "Integer.h"


const char* secretMessage =
	"b3bb321dd5ba49a6dc3003d47d769e0b8001154fb7e785c567e68986"
	"cf6caadd1f57c8f0b5bd33553ab25b519f8f59637d2913e21ba6c2c4"
	"f8cc1e4b933507191352acbbbca4774b82471bd052dfd9f95f17e644"
	"cd0efdfbe692ea54d78fcdb79e6aa6ae9d6c100d7dd1f72bb68ae8e7"
	"2fe3886e90aa89268c5c8eb961df316b568acd8c1e78cb20ec1ebd3e"
	"ef01828e271093a9c83380b62187f2a92f0d191ba463307de661c5ad"
	"0ac229cc347d8dd932a639dc1d724a707d2f5528ca75005a126877e9"
	"b58e7e139854dae90e43dcdfb3d2373f412aafa2e1a977addc9be9a8"
	"c1e959af236dcd42e76f1fefd577c6211f7b033da9c2b683f131a7c7"
	"0d96038b";


const char* publicModulus =
	"C595751A3ECF23F251F42D53053E2A88B195F79FAA370EBDA69D4C0E"
	"8535E9DCBD1A28CD726CB097504B041807FB0755228B180F4EC82907"
	"2BF716A4DD0948917B09308509916A7AB1F4D5C2D65444284FB734AB"
	"7F161AE2FACC6962EC0CF12559BD81E34E945B8A5BDE6276EAD96F7B"
	"1ECBE0BFD1D8266261AF6C6CF6D72F0962002FC774A0FB43C5A7EA3E"
	"FFBFC5EF95703CB408BA414E0C280611F03A8423C3A5A827D49B8CB8"
	"5E92513C7A68870701B16D0511EE1A8EA1998A519DAA3BFFCB926236"
	"D94658C57E413B49E8F7881B7000DF05655487E9B0D9D82F077EEC1F"
	"8533816D074AE6B347430C5F3F98E5350A0A3121B243ED1C1CFA9408"
	"BA64E00D";


const char* publicExponent = "010001";


template <typename T>
void rsa_test(bool debug)
{
	printf("\nRSA test:\n");
	T data(secretMessage);
	T exponent(publicExponent);
	T modulus(publicModulus);
	T result = T::ExpMod(data, exponent, modulus);
    size_t siz = result.Size();
    if (debug)
    {
	  printf("\ndata:     "); data.Print();
	  printf("\nexponent: "); exponent.Print();
	  printf("\nmodulus:  "); modulus.Print();
	  printf("\nresult:   "); result.Print();
	  printf("\nsize:     %i", int(siz));
    }
	printf("\nmessage: \n");
    for (size_t i = 0; i < siz; i++)
    {
	  unsigned int val = result[siz-1-i];
	  if (isprint(val) || isspace(val))
        printf("%c", val);
    }
	printf("\n");
}


int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    printf("Usage:  %s  loops\n", argv[0]);
    return -1;
  }
  int loops = atoi(argv[1]);
  for (int i = 0; i < loops; i++)
  {
    rsa_test<uint2048_t>(false);
  }
  return 0;
}


