//
// sha1.cxx
// 
// tests the SHA1 implementation
// test data is from Wei Dai's Crypto++2.0
//
// Copyright (C) 1997 by Leonard Janke (janke@unixg.ubc.ca)

#include <chnhash/sha1.hxx>
#include <iostream.h>
#include <iomanip.h>
#include <cstring>

void main(int, char**)
{
  const char* t1="abc";
  const char* t2="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
  const u8 exp1[20]={ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 
                      0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0,
                      0xd8, 0x9d };
  const u8 exp2[20]={ 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 0xba, 
                      0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5, 0xe5, 0x46, 
                      0x70, 0xf1 };
  const u8 exp3[20]={ 0x34, 0xaa, 0x97, 0x3c, 0xd4, 0xc4, 0xda, 0xa4, 0xf6, 
                      0x1e, 0xeb, 0x2b, 0xdb, 0xad, 0x27, 0x31, 0x65, 0x34, 
                      0x01, 0x6f };
  u8 res[20];

  SHA1 hashor;

  cout <<"Testing the SHA1 hash function"<<endl;
  cout <<"Bits per block= "<<hashor.bitsPerBlock()<<endl;
  cout <<"Bits in hash=   "<<hashor.bitsInHash()<<endl;

  cout <<"Hashing ->"<<t1<<"<-"<<endl;
  hashor.ProcessFinalBlock(t1,strlen(t1));
  hashor.ChainVariables(res);

  cout <<"res1=     0x";
  for (int i=0; i<20; i++)
    cout <<hex<<setw(2)<<setfill('0')<<int(res[i]);
  cout <<endl;

  if ( memcmp(exp1,res,20) )
    cout <<"*****Failed!*****"<<endl;
  else
    cout <<"*****Passed!*****"<<endl;

  hashor.Reset();

  cout <<"Hashing ->"<<t2<<"<-"<<endl;
  hashor.ProcessFinalBlock(t2,strlen(t2));
  hashor.ChainVariables(res);

  cout <<"res2=     0x";
  for (int i=0; i<20; i++)
    cout <<hex<<setw(2)<<setfill('0')<<int(res[i]);
  cout <<endl;
  if ( memcmp(exp2,res,20) )
    cout <<"*****Failed!*****"<<endl;
  else
    cout <<"*****Passed!*****"<<endl;
 
 hashor.Reset();

  cout <<"Hashing ->One million \'a\' \'s<-"<<endl;

  char aBlock[64];
  for (int i=0; i<64; i++)
    aBlock[i]='a';

  for (int i=0; i<15625; i++)
  hashor.ProcessMiddleBlock(aBlock);
  hashor.ProcessFinalBlock(NULL,0);
  hashor.ChainVariables(res);

  cout <<"res3=     0x";
  for (int i=0; i<20; i++)
    cout <<hex<<setw(2)<<setfill('0')<<int(res[i]);
  cout <<endl;
  if ( memcmp(exp3,res,20) )
    cout <<"*****Failed!*****"<<endl;
  else
    cout <<"*****Passed!*****"<<endl;
}
