Updating skeinsum with a new scheme for reading large files, simplifying command...
[skeinsum.git] / skein256.c
index 66d31f3109115fc2142e5dd796e840bcb6ae4a20..2a18caffd5e089f1e92682b8192c53ecb7bb9245 100644 (file)
@@ -1,772 +1 @@
-/* Copyright (C) 2014, 2015 Jason Self <j@jxself.org>
-
-This file is part of skeinsum.
-
-skeinsum is free software: you can redistribute it and/or modify it 
-under the terms of the GNU General Public License as published by 
-the Free Software Foundation, either version 3 of the License, or 
-(at your option) any later version.
-
-skeinsum is distributed in the hope that it will be useful, but 
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with skeinsum. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <getopt.h>
-#include <malloc.h>
-#include <math.h>
-#include <glob.h>
-#include <sys/stat.h>
-#include "SHA3api_ref.h"
-
-#define hashbitlen 256
-#define MaxNmberFiles 10
-#define skeinVersion "1.3"
-
-
-char invalidOption = 0;
-
-enum
-{
-  QUIET_OPTION = 11,
-  STATUS_OPTION,
-  TAG_OPTION,
-  HELP_OPTION,
-  VERSION_OPTION
-};
-
-static struct option const long_options[] =
-{
-  { "binary", no_argument, NULL, 'b' },
-  { "check", no_argument, NULL, 'c' },
-  { "quiet", no_argument, NULL, QUIET_OPTION },
-  { "status", no_argument, NULL, STATUS_OPTION },
-  { "text", no_argument, NULL, 't' },
-  { "warn", no_argument, NULL, 'w' },
-  { "tag", no_argument, NULL, TAG_OPTION },
-  { "help", no_argument, NULL, HELP_OPTION },
-  { "version", no_argument, NULL, VERSION_OPTION },
-  { NULL, 0, NULL, 0 }
-};
-
-void printHexMsg(unsigned char *ptr, int size, char result[])
-{
-       int i = 0;
-       int j = 0;
-       char High, Low;
-       for (i = 0 ; i < size ; i ++)
-       {
-               High = ptr[i]>>4;
-               Low = ptr[i]&0x0F;
-
-               if (High >= 0xA && High <= 0xF)
-                       High += 0x37;
-               else if(High >= 0x0 && High <= 0x9)
-                       High += 0x30;
-
-               if (Low >= 0xA && Low <= 0xF)
-                       Low += 0x37;
-               else if(Low >= 0x0 && Low <= 0x9)
-                       Low += 0x30;
-
-               result[j++] = High;
-               result[j++] = Low;
-       }
-       result[i] = 0;
-}
-
-int HashTextMode(char file_name[], char MsgDigest[])
-{
-       FILE *fp_in = fopen(file_name,"r");
-       struct stat st;
-       stat(file_name, &st);
-       long size_fp_in = st.st_size;
-
-       if(fp_in == NULL)
-       {
-               printf("skein%dsum:  %s: No such file or directory\n",hashbitlen,file_name);
-               printf(" %s FAILED open or read\n",file_name);
-               return -1 ;
-       }
-
-       char *hello;
-       hello = (char*) malloc (size_fp_in);
-       fgets(hello,size_fp_in,fp_in);
-
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,(unsigned char*) hello,size_fp_in,output);
-
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-
-       fclose(fp_in);
-       return 1;
-}
-
-int HashBinaryMode(char file_name[],char MsgDigest[])
-{
-       FILE *fp_in = fopen(file_name,"rb");
-       struct stat st;
-       stat(file_name, &st);
-       long size_fp_in = st.st_size;
-
-       if(fp_in == NULL)
-       {
-               printf("skein%dsum:  %s: No such file or directory\n",hashbitlen,file_name);
-               printf(" %s FAILED open or read\n",file_name);
-               return -1 ;
-       }
-
-       unsigned char *hello;
-       hello = (unsigned char*) malloc (size_fp_in);
-       fread(hello,size_fp_in,1,fp_in);
-
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,hello,size_fp_in,output);
-
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-
-       fclose(fp_in);
-       return 1;
-}
-
-int HashStringMode(char Msg[],char MsgDigest[])
-{
-       unsigned char output[hashbitlen/4];
-       Hash(hashbitlen,(unsigned char*) Msg,sizeof(Msg),output);
-       printHexMsg(output,hashbitlen/4,MsgDigest);
-       return 1;
-}
-
-/*
- *  return 1 : is File
- *  return 2 : is Directory
- *  return -1 : Something else.
- */
-int isFile(char argument[])
-{
-       struct stat s;
-       if( stat(argument,&s) == 0 )
-       {
-           if( s.st_mode & S_IFDIR )
-           {
-               return 2;
-           }
-           else if( s.st_mode & S_IFREG )
-           {
-               return 1;
-           }
-       }
-       else
-               return -1;
-       return 0;
-}
-
-int isProper(char MsgDigest[])
-{
-       if ((strlen(MsgDigest) - hashbitlen/4) != 0)
-               return 0;
-       int index = 0;
-       char c = 0;
-       for(index = 0; index < strlen(MsgDigest);index++)
-       {
-               c = MsgDigest[index];
-               if(!(( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'F')))
-                       return 0;
-       }
-
-       return 1;
-}
-
-
-int decomposeHashLine(char hash[], char MsgDigest_tmp[], char file_tmp[])
-{
-       char c = 0;
-       int i = 0 , j =0;
-       int isTagFile = 0;
-       char alg[20];
-       char tmp[1000];
-       while(((c = hash[i])!=' ')&&((c = hash[i])!='_'))
-       {
-               tmp[i] = hash[i];
-               i++;
-       }
-       tmp[i] = 0;
-
-       sprintf(alg,"skein%d",hashbitlen);
-       if(!strcmp(alg,tmp))
-       {
-               isTagFile = 1;
-       }
-
-       if(isTagFile == 0)
-       {
-               strcpy(MsgDigest_tmp,tmp);
-               i++;
-               while((c = hash[i])!= '\n')
-               {
-                       file_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               file_tmp[j] = 0;
-       }
-       else if((hash[i]=='_')&&(hash[i+1]=='v'))
-       {
-               i = i + 2;
-               j = 0;
-               char version[5];
-               while((c = hash[i])!=' ')
-               {
-                       version[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               version[i] = 0;
-               float vers = 0, skeinVers = 0;
-               sscanf(version,"%f",&vers);
-               sscanf(skeinVersion,"%f",&skeinVers);
-
-               j = 0;
-               i = i + 2;
-               while((c = hash[i])!=')')
-               {
-                       file_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               file_tmp[j] = 0;
-
-               i = i + 4;
-               j = 0;
-               while((c = hash[i])!='\n')
-               {
-                       MsgDigest_tmp[j] = hash[i];
-                       i++;
-                       j++;
-               }
-               MsgDigest_tmp[j] = 0;
-
-               if(skeinVers < vers)
-               {//version newer than mine
-                       return (-1);
-               }
-               else if (skeinVers > vers)
-               {//going to use older version than mine
-                       return (0) ;
-               }
-               else
-               { //versions match
-                       return (1);
-               }
-       }
-       return 1;
-
-}
-
-
-
-int main(int argc, char** argv)
-{
-       char MsgDigest[hashbitlen/2];
-       char **list_files = (char**) malloc(MaxNmberFiles* sizeof(char*));
-       int number_files = 0;
-       int binary = -1,
-                check = -1,
-                quiet = -1,
-                warn = -1,
-                status = -1,
-                help = -1,
-                version = -1,
-                tag = -1,
-                hashString = -1,
-                badParam = -1;
-
-       int errorFound = 0;
-       int opt = 0;
-/*****************************************************************************************
- ************************************* GETTING DATA ***********************************
- *****************************************************************************************/
-  while ((opt = getopt_long (argc, argv, "bctw", long_options, NULL)) != -1)
-  {
-         switch (opt)
-         {
-                       case 'b' :
-                       {
-                               binary = 1;
-                               break;
-                       }
-                       case 't' :
-                       {
-                               binary = 0;
-                               break;
-                       }
-                       case 'c' :
-                       {
-                               check = 1;
-                               break;
-                       }
-                       case QUIET_OPTION :
-                       {
-                               quiet = 1;
-                               break;
-                       }
-                       case 'w' :
-                       {
-                               warn = 1;
-                               break;
-                       }
-                       case STATUS_OPTION :
-                       {
-                               status = 1;
-                               break;
-                       }
-                       case HELP_OPTION :
-                       {
-                               help = 1;
-                               break;
-                       }
-                       case VERSION_OPTION :
-                       {
-                               version = 1;
-                               break;
-                       }
-                       case TAG_OPTION :
-                       {
-                               tag = 1;
-                               break;
-                       }
-                       case 0 :
-                       {
-                               hashString = 1;
-                               break;
-                       }
-                       default :
-                       {
-                               badParam = 1;
-                               break;
-                       }
-         }
-       }
-
-  if(badParam == 1)
-       {
-               printf("Try `skein%dsum --help' for more information.\n",hashbitlen);
-               exit(1);
-       }
-
-  for (; optind < argc; ++optind)
-  {
-               switch (opt)
-               {
-                       case -1:
-                       {// no options found, test if there is a file and hash it
-                               if(isFile(argv[optind]) == 1)
-                               {
-                                       char *file_name = malloc(sizeof(argv[optind]));
-                                       file_name = argv[optind];
-                                       list_files[number_files] = (char*) malloc (sizeof(file_name));
-                                       list_files[number_files] = file_name;
-                                       number_files ++;
-                               }
-                               else if (isFile(argv[optind]) == 2)
-                               {
-                                       printf("skein%dsum: %s Is a directory\n",hashbitlen,argv[optind]);
-                                       errorFound = 1;
-                               }
-                               else
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,argv[optind]);
-                                       errorFound = 1;
-                               }
-                               break;
-                       }
-               }
-       }
-/*****************************************************************************************
- ************************************* PROCESSING DATA ***********************************
- *****************************************************************************************/
-       if(argc > 1 && version == 1)
-       {
-               printf("skein256sum 1.0\n");
-               printf("License GPLv3+: GNU GPL version 3 or later\n");
-               printf("<http://gnu.org/licenses/gpl.html>\n");
-               printf("This is free software: you are free to change and redistribute it.\n");
-               printf("There is NO WARRANTY, to the extent permitted by law.\n");
-               exit(1);
-       }
-       if(argc > 1 && help == 1)
-       {
-
-               printf("Usage: skein%dsum [OPTION]... [FILE]...\n",hashbitlen);
-               printf("Print or check skein (%d-bit) checksums.\n",hashbitlen);
-               printf("With no FILE, or when FILE is -, read standard input.\n");
-               printf("\n");
-               printf("-b, --binary         read in binary mode\n");
-               printf("-c, --check          read skein sums from the FILEs and check them\n");
-               printf("--tag            create a BSD-style checksum\n");
-               printf("-t, --text           read in text mode (default)\n");
-               printf("\n");
-               printf("The following three options are useful only when verifying checksums:\n");
-               printf("--quiet          don't print OK for each successfully verified file\n");
-               printf("--status         don't output anything, status code shows success\n");
-               printf("-w, --warn           warn about improperly formatted checksum lines\n");
-               printf("\n");
-               printf("--strict         with --check, exit non-zero for any invalid input\n");
-               printf("--help     display this help and exit\n");
-               printf("--version  output version information and exit\n");
-               printf("\n");
-               printf("The sums are computed as described in version 1.3 of the Skein\n");
-               printf("specification. When checking, the input should be a former output of\n");
-               printf("this program. The default mode is to print a line with checksum, a\n");
-               printf("character indicating input mode ('*' for binary, space for text), and\n");
-               printf("name for each FILE.\n");
-               exit(1);
-       }
-
-       if(argc > 1 && binary == 1)
-       {
-               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
-               {
-                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
-                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                       exit(0);
-               }
-               if(number_files > 0)
-               {
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               if(hashString == 1)
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,list_files[index_files]);
-                                       index_files++;
-                                       continue;
-                               }
-                               if(HashBinaryMode(list_files[index_files],MsgDigest)!=-1)
-                               {
-                                       if(tag == 1)
-                                       {
-                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               printf("%s ",MsgDigest);
-                                               printf("*%s\n",list_files[index_files]);
-                                       }
-                               }
-                               index_files++;
-                       }
-               }
-               else if(errorFound != 1)
-               { // read stdin for strings
-                       char stri[100];
-                       char longstring[1000];
-                       longstring[0] = 0;
-                       while((fgets(stri,100,stdin))!=NULL)
-                       {
-                               strcat(longstring,stri);
-                       }
-                       HashStringMode(longstring,MsgDigest);
-                       if(tag == 1)
-                       {
-                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                       }
-                       else
-                       {
-                               printf("%s *-\n",MsgDigest);
-                       }
-               }
-       }
-
-       else if (argc > 1 && binary == 0) // Text Mode
-       {
-               if (check == 1 || quiet == 1 || warn == 1 || status == 1)
-               {
-                       printf("skein%dsum: the --binary and --text options are meaningless when verifying checksums\n",hashbitlen);
-                       printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                       exit(0);
-               }
-               if(number_files > 0)
-               {
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
-                               {
-                                       if(tag == 1)
-                                       {
-                                               printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               printf("%s ",MsgDigest);
-                                               printf("%s\n",list_files[index_files]);
-                                       }
-                               }
-                               index_files++;
-                       }
-               }
-               else if(errorFound != 1)
-               { // read stdin for strings
-                       char stri[100];
-                       char longstring[1000];
-                       longstring[0] = 0;
-                       while((fgets(stri,100,stdin))!=NULL)
-                       {
-                               strcat(longstring,stri);
-                       }
-                       HashStringMode(longstring,MsgDigest);
-                       if(tag == 1)
-                       {
-                               printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                       }
-                       else
-                       {
-                               printf("%s -\n",MsgDigest);
-                       }
-               }
-       }
-
-       else if (argc > 1 && binary == -1)
-       {
-               if(check == -1)
-               {// hashing stdin entries
-                       if(quiet == 1 || status == 1 || warn == 1)
-                       {
-                               if(quiet == 1)
-                                       printf("skein%dsum: the --quiet option is meaningful only when verifying checksums\n",hashbitlen);
-                               if(status ==1)
-                                       printf("skein%dsum: the --status option is meaningful only when verifying checksums\n",hashbitlen);
-                               if(warn == 1)
-                                       printf("skein%dsum: the --warn option is meaningful only when verifying checksums\n",hashbitlen);
-
-                               printf("Try 'skein%dsum --help' for more information.\n",hashbitlen);
-                               exit(1);
-                       }
-                       if(number_files > 0)
-                       {// hashing files
-                               int index_files = 0;
-                               while(index_files < number_files)
-                               {
-                                       if(HashTextMode(list_files[index_files],MsgDigest)!=-1)
-                                       {
-                                               if(tag == 1)
-                                               {
-                                                       printf("skein%d_v%s (%s) = %s\n",hashbitlen,skeinVersion,list_files[index_files],MsgDigest);
-                                               }
-                                               else
-                                               {
-                                                       printf("%s ",MsgDigest);
-                                                       printf("%s\n",list_files[index_files]);
-                                               }
-                                       }
-                                       index_files++;
-                               }
-                       }
-                       else if(errorFound != 1)
-                       { // hasing strings read from  stdin
-                               char stri[100];
-                               char longstring[1000];
-                               longstring[0] = 0;
-                               while((fgets(stri,100,stdin))!=NULL)
-                               {
-                                       strcat(longstring,stri);
-                               }
-                               HashStringMode(longstring,MsgDigest);
-                               if(tag == 1)
-                               {
-                                       printf("skein%d_v%s (-) = %s\n",hashbitlen,skeinVersion,MsgDigest);
-                               }
-                               else
-                               {
-                                       printf("%s -\n",MsgDigest);
-                               }
-                       }
-               }
-               else if(check == 1)
-               {
-                       if(tag == 1)
-                       {
-                               printf("skein%dsum: the --tag option is meaningless when verifying checksums\n",hashbitlen);
-                               printf("Try 'skein%dsum --help' for more information\n",hashbitlen);
-                               exit(1);
-                       }
-                       int index_files = 0;
-                       while(index_files < number_files)
-                       {
-                               FILE *fp;
-                               char hash[500], file_name[100], file_tmp[100], MsgDigest_tmp[hashbitlen/2];
-                               int NoMatch = 0, NotProper = 0, Computed = 0;
-                               strcpy(file_name,list_files[index_files]);
-                               //show everything
-                               int line = 0;
-                               fp = fopen(file_name,"r");
-                               if(fp!=NULL)
-                               {
-                                       while(fgets(hash,500,fp)!=NULL)
-                                       {
-                                               line ++;
-                                               Computed++;
-                                               unsigned int hashVersion = decomposeHashLine(hash,MsgDigest_tmp,file_tmp);
-                                               if(hashVersion == -1)
-                                               {
-                                                       printf("skein%d: %s is using newer version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
-                                                       printf("You should update your algorithm\n");
-                                                       continue;
-                                               }
-                                               else if( hashVersion == 0)
-                                               {
-                                                       printf("skein%d: %s is using an older version of skein%d algorithm\n",hashbitlen,file_tmp,hashbitlen);
-                                                       printf("You should use the older algorithm\n");
-                                                       continue;
-                                               }
-                                               else
-                                               {
-                                                       if(!isProper(MsgDigest_tmp))
-                                                       {
-                                                               if(status != 1 && warn == 1)
-                                                               {
-                                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_tmp,line,hashbitlen);
-                                                               }
-                                                               NotProper ++;
-                                                               NoMatch ++;
-                                                               continue;
-                                                       }
-                                                       if(file_tmp[0] == '*')
-                                                       {
-                                                               int index_file_tmp = 0;
-                                                               for( ; file_tmp[index_file_tmp+1]!=0 ; index_file_tmp++)
-                                                               {
-                                                                       file_tmp[index_file_tmp] = file_tmp[index_file_tmp + 1];
-                                                               }
-                                                               file_tmp[index_file_tmp] = 0;
-                                                               HashBinaryMode(file_tmp,MsgDigest);
-                                                       }
-                                                       else
-                                                       {
-                                                               HashTextMode(file_tmp,MsgDigest);
-                                                       }
-
-                                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
-                                                       {
-                                                               if(quiet != 1)
-                                                               {
-                                                                       printf("%s: OK\n",file_tmp);
-                                                               }
-                                                       }
-                                                       else
-                                                       {
-                                                               printf("%s: FAILED\n",file_tmp);
-                                                               NoMatch ++;
-                                                       }
-                                               }
-                                       }
-                                       if(NoMatch)
-                                       {
-                                               printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
-                                                               hashbitlen,NoMatch,Computed);
-                                       }
-                                       if(NotProper)
-                                       {
-                                               printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
-                                       }
-                               }
-                               else
-                               {
-                                       printf("skein%dsum: %s: No such file or directory\n",hashbitlen,file_name);
-                               }
-                               index_files++;
-
-                       }
-
-                       if(number_files  == 0)
-                       {
-                               char longstring[1000];
-                               char file_name[30];
-                               char MsgDigest_tmp[hashbitlen/2];
-                               int Computed = 0, NotProper = 0, NoMatch = 0 , line = 0;
-                               while((fgets(longstring,1000,stdin))!=NULL)
-                               {
-                                       Computed++;
-                                       line ++;
-                                       decomposeHashLine(longstring,MsgDigest_tmp,file_name);
-                                       if(!isProper(MsgDigest_tmp))
-                                       {
-                                               if(status != 1 && warn == 1)
-                                               {
-                                                       printf("skein%dsum: %s: %d: improperly formatted skein%d checksum line\n",hashbitlen,file_name,line,hashbitlen);
-                                               }
-                                               NotProper ++;
-                                               NoMatch ++;
-                                               continue;
-                                       }
-                                       if(file_name[0] == '*')
-                                       {
-                                               int index_file_tmp = 0;
-                                               for( ; file_name[index_file_tmp+1]!=0 ; index_file_tmp++)
-                                               {
-                                                       file_name[index_file_tmp] = file_name[index_file_tmp + 1];
-                                               }
-                                               file_name[index_file_tmp] = 0;
-                                               HashBinaryMode(file_name,MsgDigest);
-                                       }
-                                       else
-                                       {
-                                               HashTextMode(file_name,MsgDigest);
-                                       }
-
-                                       if(!strcmp(MsgDigest,MsgDigest_tmp))
-                                       {
-                                               if(quiet != 1)
-                                               {
-                                                       printf("%s: OK\n",file_name);
-                                               }
-                                       }
-                                       else
-                                       {
-                                               printf("%s: FAILED\n",file_name);
-                                               NoMatch ++;
-                                       }
-                               }
-                               if(NoMatch)
-                               {
-                                       printf("skein%dsum: WARNING: %d of %d computed checksums did NOT match\n",
-                                                       hashbitlen,NoMatch,Computed);
-                               }
-                               if(NotProper)
-                               {
-                                       printf("skein%dsum: WARNING: %d line is improperly formatted\n",hashbitlen,NotProper);
-                               }
-
-                       }
-
-
-               }
-       }
-
-       if ((errorFound != 1) && (argc == 1 || (hashString == 1 && number_files == 0)))
-       {
-               char stri[100];
-               char longstring[1000];
-               longstring[0] = 0;
-               while((fgets(stri,100,stdin))!=NULL)
-               {
-                               strcat(longstring,stri);
-               }
-               HashStringMode(longstring,MsgDigest);
-               printf("%s -\n",MsgDigest);
-       }
-
-       return 1;
-}
+const int hashbitlen = 256;