#include <cassert>
#include <iostream>
#include <fstream>
using namespace std;


#include <NTL/ZZ.h>
using namespace NTL;

#include <aclock.h>
#include <commandline.h>
#include <primegen.h>
#include <rsa.h>
#include <rsatest.h>
#include <streamconversion.h>


int rsatest::unittest01()
{
  cout << "Small RSA example with maths library." << endl;

  ZZ p;
  conv(p,"47");
  ZZ q;
  conv(q,"71");
  ZZ n = p*q;
  ZZ n2 = (p-1)*(q-1);

  ZZ e;
  conv(e,"79");
 
  ZZ d;
  InvMod(d,e,n2);

  cout << "d=" << d << endl;

  ZZ m;
  conv(m,"688");
  cout << "m=" << m << endl;

  ZZ c;
  PowerMod(c,m,e,n);
  cout << "c=" << c << endl;

  ZZ m2;
  PowerMod(m2,c,d,n);
  cout << "D(c)=" << m2 << endl;

  if (m!=m2)
    return 1;

  return 0;
}

int rsatest::unittest02()
{
  cout << "Small RSA example with rsa classes." << endl;
  rsaE E;
  conv(E.e,"79");
  conv(E.n,"3337");  //47*71=3337

  string m1("688");
  string c1;
  E(c1,m1);
  cout << "c1=" << c1 << endl;

  rsaD D;
  conv(D.e,"79");
  conv(D.p,"47");
  conv(D.q,"71");
  D.init();


  string m2;
  D(m2,c1);
  cout << "m2=" << m2 << endl;

  if (m1!=m2)
    return 1;

  return 0;
}

void rsatest::test01()
{
  string s;
  ifstream f1("main.cpp");
  asciitodig::forward(s,f1);
  ofstream f2("tmp11.txt");
  asciitodig::reverse(f2,s);

  digdiv d;
  d.blksz = 5;
  d.forward(s);
//  printv(d.v);
  ofstream f3("tmp12.txt");
  string s2;
  d.reverse(s2);
  asciitodig::reverse(f3,s2);
}

void rsatest::test02(int argc, char** argv)
{
  commandline c(argc,argv);
  unsigned int nbits(200);
  c.mapvar(nbits,"nbits");

  largePrimeGenerator p;

  aclock clk;
  clk.measure();
  ZZ n;
  unsigned int imax=30;
  for ( unsigned int i=0; i<imax; ++i )
  {
    p.findprime_sequentially(n,nbits);
    cout << n << endl;
  }
  clk.measure();
  cout << "sequential time(s)=" << clk.diff_s() << endl;

  for ( unsigned int i=0; i<imax; ++i )
  {
    p.findprime_randomly(n,nbits);
    cout << n << endl;
  }
  clk.measure();
  cout << "random time(s)=" << clk.diff_s() << endl;
}



