#include <sstream>
using namespace std;

#include <passwordverifier001.h>
#include <print.h>


void passwordverifier001::eval( ZZ & val ) const
{
  // The password must be less than n1
  // to go into the PowerMod funtion.
  // Further having it greater than n1
  // is meaningless.
  assert(password < n1);

//cout << SHOW(password) << endl;
//cout << SHOW(j1) << endl;
//cout << SHOW(n1) <<endl;
  ZZ w;
  PowerMod(w,password%n1,j1,n1);
//cout << SHOW(w) << endl;
  w += k1;
//cout << SHOW(w) << endl;
  PowerMod(val,w%n2,j2,n2);
}

void passwordverifier001::eval( string & val ) const
{
  ZZ w;
  eval(w);

  stringstream ss;
  ss << w;
  val = ss.str();
}
  
boolc passwordverifier001::verify
( 
  stringc & attempt 
) const
{
  string val;
  eval(val);
  
  return (attempt == val);
}

void passwordverifier001::parameters_get
(
  string & parameters 
)
{
  parameters = "";

  string str;
  convInverse(str,j1);
  parameters += (str + " ");
  convInverse(str,j2);
  parameters += (str + " ");
  convInverse(str,n1);
  parameters += (str + " ");
  convInverse(str,n2);
  parameters += (str + " ");
  convInverse(str,k1);
  parameters += str;
}

void passwordverifier001::convInverse
(
  string & wstr, 
  ZZ const w 
)
{
  stringstream ss;
  ss << w;
  wstr = ss.str();
}

void passwordverifier001::parameters_set
(
  stringc & parameters 
)
{
  stringstream ss(parameters);
  string str;

  ss >> str;
  conv(j1,str.c_str());

  ss >> str;
  conv(j2,str.c_str());

  ss >> str;
  conv(n1,str.c_str());

  ss >> str;
  conv(n2,str.c_str());

  ss >> str;
  conv(k1,str.c_str());
}

void passwordverifier001::random(ZZ & num, uintc nb)
{
  RandomBits(num,nb);
  ZZ n2;
  ZZ x;
  conv(x,"2"); 
  power(n2,x,nb);
  if (num<n2)
    num += n2;
}

void passwordverifier001::generatePassword()
{
  random(password,nbits-1);
}

void passwordverifier001::generateRandomFunction()
{
  random(j1,nbits);
  random(j2,nbits);
  random(n1,nbits);
  random(n2,nbits);
  random(k1,nbits);
}


