/************************************************************* This program is a test driver demonstraiting the SHA C++ classes I adapted from a C version written by Aaron D. Gifford (as of 11/22/2004 his code could be found at http://www.adg.us/computers/sha.html). Attempts to contact him were unsuccessful. I make use of his input files for testing. The format should be flexible enough to add any number of test files, the only restriction is that they be in a subdirectory called 'testvectors' and all the files begin with 'vector'. The program can be called with a 'verbose' mode to provide details of each test (not all tests are available for all bit-lengths of each hash). With verbose off only a pass/fail message is written. For your amusement you can also run a speed test of the algorithm. It generates the hash for a user-defined number of iterations (default is 1 iteration) on a 16 megabyte (2^24) string of 'a's. To execute the program with the speed test run it with 'speedtest' on the command line. If you use this implementation somewhere I would like to be credited with my work (a link to my page below is fine). I add no license restriction beyond any that is made by the original author. This code comes with no warrenty expressed or implied, use at your own risk! Keith Oxenrider koxenrider[at]sol[dash]biotech[dot]com The latest version of this code should be available via the page sol-biotech.com/code. *************************************************************/ #include #include #include #include #include #include #ifdef WIN32 #include #pragma warning(disable: 4786) //useful with Visual Studio C++ version 6 #else //presumed *nix #include #include #endif #include "sha2.h" using namespace std; #ifdef WIN32 void listDir(const char * sdir, vector < string > &vectData){ string str, strDir; struct _finddata_t c_file; long hFile; // Find first file in current directory str = sdir + (string) "\\*"; if( (hFile = _findfirst( str.c_str(), &c_file )) == -1L ){ cerr << "Error opening " << str << "!\n"; return; } do{ //skip if find . and .. if ((strcmp(c_file.name, ".") == 0 || strcmp(c_file.name, "..") == 0)) continue; if (c_file.attrib & _A_SUBDIR) continue; if (strncmp(c_file.name, "vector", 6)) continue; str = sdir + (string) "\\" + (string) c_file.name; vectData.push_back(str); }while(_findnext( hFile, &c_file ) == 0); _findclose( hFile ); return; } #else //presume *nix void listDir(const char * sdir, vector < string > &vectData){ string str, strDir; struct dirent *dptr; struct stat st; DIR *dirp; if( (dirp = opendir(sdir)) == NULL ) { cerr << "Error opening " << sdir; perror(": "); return; } while(dptr = readdir(dirp)) { //skip if find . and .. if ((strcmp(dptr->d_name, ".") == 0 || strcmp(dptr->d_name, "..") == 0)) { continue; } strDir = sdir + (string)"/" + (string)dptr->d_name; int statRet = stat(strDir.c_str(), &st); if (statRet != -1 && S_ISDIR(st.st_mode)) continue; if (strncmp(dptr->d_name, "vector", 6)) continue; vectData.push_back(strDir); } closedir(dirp); } #endif enum SHA_FILE_TYPES{ enuSHA1 = sha2::enuSHA1, enuSHA224 = sha2::enuSHA224, enuSHA256 = sha2::enuSHA256, enuSHA384 = sha2::enuSHA384, enuSHA512 = sha2::enuSHA512, enuNOTYPE, enuDESCR, enuASCII, enuHEX, enuREPEAT, enuRANGE, enuLAST }; void test(bool verbose, bool validate, bool speedtest, unsigned int ITERS){ string strBuf, strTmp; fstream fin; string strData[enuLAST]; SHA_FILE_TYPES type = enuNOTYPE, tmpType; unsigned int i, j, cnt, hextmp; bool passed, tmppassed; unsigned char hexstr[3]; sha2 mySha2; vector < string > vectData; hexstr[2] = '\0'; if (mySha2.IsBigEndian()) cout << "This machine is Big Endian.\n"; else cout << "This machine is Little Endian.\n"; if (validate){ listDir("testvectors", vectData); for (i=0; i> strTmp; switch(type){ case enuDESCR: break; case enuSHA1: strData[enuSHA1] += strTmp; break; case enuSHA224: strData[enuSHA224] += strTmp; break; case enuSHA256: strData[enuSHA256] += strTmp; break; case enuSHA384: strData[enuSHA384] += strTmp; break; case enuSHA512: strData[enuSHA512] += strTmp; break; case enuASCII: { //erase leading spaces while (isspace(strBuf[0])) strBuf.erase(0, 1); //erase trailing spaces while (isspace(strBuf[0])) strBuf.erase(strBuf.size()-1, 1); //erase leading and trailing quotes if (strBuf[0] == '"') strBuf.erase(0, 1); if (strBuf[strBuf.size()-1] == '"') strBuf.erase(strBuf.size()-1, 1); strData[enuASCII] += strBuf; break; } case enuHEX: { for (j=2; j "; cerr << " \n"; cerr << "\tYou must choose either 'validate', 'speedtest' or both\n"; cout << "Press return to exit\n"; cin.sync(); cin.get(); exit(1); } int main(int argc, char *argv[]){ bool verbose = false, validate = false, speedtest = false; unsigned int speedTestIters = 1; int tmp; if (argc > 1){ for (int i=1; i 1) speedTestIters = tmp; } } }else usage(argv[0]); if (verbose) cout << "Verbose is set.\n"; if (validate) cout << "Validate is set.\n"; if (speedtest){ cout << "Speedtest is set, running " << speedTestIters << " iterations.\n"; } if (!validate && !speedtest){ usage(argv[0]); } test(verbose, validate, speedtest, speedTestIters); cout << "Press return to exit\n"; cin.sync(); cin.get(); return 0; }