// Remove // of the next line if you want to test this module. //#define testSSInnnhash // main() in this module will be used (-> SSI192hash is // tested), and do not change any lines below. //#define SSInnnhashEx //Extended version of SSInnnhash (using rSSI32 RNG) //Resistance to attack is increased /***** Select a hash-type *****/ //#define SSI64hash //#define SSI160hash //#define SSI192hash //#define SSI256hash //#define SSI384hash //#define SSI512hash //#define SSI1024hash //#define SSI2048hash #ifdef testSSInnnhash #define SSI192hash #endif /******************/ #include #include #ifdef SSI64hash #define HS_name "SSI64h12" #endif #ifdef SSI160hash #define HS_name "SSI160h12" #endif #ifdef SSI192hash #define HS_name "SSI192h12" #endif #ifdef SSI256hash #define HS_name "SSI256h12" #endif #ifdef SSI384hash #define HS_name "SSI384h12" #endif #ifdef SSI512hash #define HS_name "SSI512h12" #endif #ifdef SSI1024hash #define HS_name "SSI1024h12" #endif #ifdef SSI2048hash #define HS_name "SSI2048h12" #endif /******************************/ #define HSBufSize 1024 #define mIntMSB 0x80000000 #define mIntBaseM1 0xffffffff #define mIntBaseBits 32 #ifdef SSI64hash #define HSHashBitSize 64 // L=8(byte)(must be int size) #define HScompXsizeByte 4 // M=4(byte) #define HSCharsInOneComp 2 // E=2(byte) #define HScompEPosByte 2 // P=2(byte)(pos. starting from 1) #define HSshiftByteInOneComp 1 // D=1(byte) int HSscrYsizeByte = 4; // Q=4(byte)(must be int size) int HSscrBitShiftSize = 6; // S=6/8(byte) int HSscrBitShiftTimes = 16; int HSHashBgnBit = 16; // Q/2(byte) //----------------------------// #define mIntIntSize 3 #define mIntIndexMin 1 #define mIntIndexMax 2 //----------------------------// #endif #ifdef SSI160hash #define HSHashBitSize 160 // L=20(byte) #define HScompXsizeByte 8 // M=8(byte) #define HSCharsInOneComp 8 // E=8(byte) #define HScompEPosByte 5 // P=5(byte)(pos. starting from 1) #define HSshiftByteInOneComp 4 // D=4(byte) int HSscrYsizeByte = 8; // Q=8(byte)(must be int size) int HSscrBitShiftSize = 16; // S=2(byte) int HSscrBitShiftTimes = 16; int HSHashBgnBit = 32; // Q/2(byte) //----------------------------// #define mIntIntSize 6 #define mIntIndexMin 1 #define mIntIndexMax 5 //----------------------------// #endif #ifdef SSI192hash #define HSHashBitSize 192 // L=24(byte) #define HScompXsizeByte 8 // M=8(byte) #define HSCharsInOneComp 8 // E=8(byte) #define HScompEPosByte 5 // P=5(byte)(pos. starting from 1) #define HSshiftByteInOneComp 4 // D=4(byte) int HSscrYsizeByte = 8; // Q=8(byte)(must be int size) int HSscrBitShiftSize = 16; // S=2(byte) int HSscrBitShiftTimes = 16; int HSHashBgnBit = 32; // Q/2(byte) //----------------------------// #define mIntIntSize 7 #define mIntIndexMin 1 #define mIntIndexMax 6 //----------------------------// #endif #ifdef SSI256hash #define HSHashBitSize 256 // L=32(byte)(must be int size) #define HScompXsizeByte 8 // M=8(byte) #define HSCharsInOneComp 8 // E=8(byte) #define HScompEPosByte 5 // P=5(byte)(pos. starting from 1) #define HSshiftByteInOneComp 4 // D=4(byte) int HSscrYsizeByte = 8; // Q=8(byte)(must be int size) int HSscrBitShiftSize = 24; // S=3(byte) int HSscrBitShiftTimes = 16; int HSHashBgnBit = 32; // Q/2(byte) //----------------------------// #define mIntIntSize 9 #define mIntIndexMin 1 #define mIntIndexMax 8 //----------------------------// #endif #ifdef SSI384hash #define HSHashBitSize 384 // L=48(byte)(must be int size) #define HScompXsizeByte 12 // M=12(byte) #define HSCharsInOneComp 16 // E=16(byte) #define HScompEPosByte 9 // P=9(byte)(pos. starting from 1) #define HSshiftByteInOneComp 8 // D=8(byte) int HSscrYsizeByte = 12; // Q=12(byte)(must be int size) int HSscrBitShiftSize = 32; // S=4(byte) int HSscrBitShiftTimes = 16; int HSHashBgnBit = 48; // Q/2(byte) //----------------------------// #define mIntIntSize 13 #define mIntIndexMin 1 #define mIntIndexMax 12 //----------------------------// #endif #ifdef SSI512hash #define HSHashBitSize 512 // L=64(byte)(must be int size) #define HScompXsizeByte 12 // M=12(byte) #define HSCharsInOneComp 16 // E=16(byte) #define HScompEPosByte 9 // P=9(byte)(pos. starting from 1) #define HSshiftByteInOneComp 8 // D=8(byte) int HSscrYsizeByte = 16; // Q=16(byte)(must be int size) int HSscrBitShiftSize = 48; // S=6(byte) int HSscrBitShiftTimes = 16; int HSHashBgnBit = 62; // Q/2(byte) //----------------------------// #define mIntIntSize 17 #define mIntIndexMin 1 #define mIntIndexMax 16 //----------------------------// #endif #ifdef SSI1024hash #define HSHashBitSize 1024 // L=128(byte)(must be int size) #define HScompXsizeByte 20 // M=20(byte) #define HSCharsInOneComp 32 // E=32(byte) #define HScompEPosByte 17 // P=17(byte)(pos. starting from 1) #define HSshiftByteInOneComp 16 // D=16(byte) int HSscrYsizeByte = 28; // Q=28(byte)(must be int size) int HSscrBitShiftSize = 96; // S=12(byte) int HSscrBitShiftTimes = 16; int HSHashBgnBit = 112; // Q/2(byte) //----------------------------// #define mIntIntSize 33 #define mIntIndexMin 1 #define mIntIndexMax 32 //----------------------------// #endif #ifdef SSI2048hash #define HSHashBitSize 2048 // L=256(byte)(must be int size) #define HScompXsizeByte 36 // M=36(byte) #define HSCharsInOneComp 64 // E=64(byte) #define HScompEPosByte 33 // P=33(byte)(pos. starting from 1) #define HSshiftByteInOneComp 32 // D=32(byte) int HSscrYsizeByte = 52; // Q=52(byte)(must be int size) int HSscrBitShiftSize = 192; // S=24(byte) int HSscrBitShiftTimes = 16; int HSHashBgnBit = 208; // Q/2(byte) //----------------------------// #define mIntIntSize 65 #define mIntIndexMin 1 #define mIntIndexMax 64 //----------------------------// #endif /********************** type def for mInt *********************/ typedef struct { unsigned int mIdgt[mIntIntSize]; } mInt; typedef struct { unsigned int mIdgt[1+mIntIndexMax*2]; } mIntD; #ifndef SSI_LLHL #define SSI_LLHL typedef struct /* Intel's MPU only */ { unsigned int L; unsigned int H; } uiHL; typedef union { unsigned long long int I; uiHL HL; } uiLLHL; typedef union { unsigned long long int I; uiHL HL; double Dbl; } uiLLHL_Dbl; #endif typedef union { unsigned int ui[mIntIntSize]; unsigned char uc[mIntIntSize*sizeof(int)]; } HS; typedef union { unsigned int ui[1+mIntIndexMax*2]; unsigned char uc[(1+mIntIndexMax*2)*sizeof(int)]; } HSD; /*************** constant for hashing *********************/ //1.2718281828459... MSB = 1 BaseForm[N[1+E/10,750]*8,16] unsigned int HSconst1_2400bits[1+75] = { 0, 0xa2cb4411, 0xba257552, 0x232c1139, 0xa172a5c9, 0xf8252780, 0xc2d5d7b7, 0x88603e0d, 0x04140a65, 0x8f50b929, 0x3a8572fe, 0xb2a32d7a, 0x47027df8, 0x314d239a, 0x22f4137e, 0xf72c9fc4, 0x5dff7aad, 0x073d976c, 0xac9ae2f6, 0x8113e111, 0x0c629efd, 0x8aab03df, 0xb3118ea4, 0x51a968e3, 0x602e1be4, 0xc6ee1b92, 0x30c994e3, 0x9f96ab53, 0x7155fb0a, 0xa355c20f, 0xdb3ee518, 0x8c022380, 0x8a3a98ad, 0x29ce8842, 0x56f4fa65, 0x8b7bc557, 0xe02b30e1, 0x9f764087, 0x2c71dc64, 0x22de2f94, 0xad7d589e, 0x9bce54c1, 0xc9354916, 0x860098f9, 0xf5fe6095, 0xc00a675c, 0x3b3da313, 0x837d661f, 0x61e780cc, 0xb60fd070, 0x9630804d, 0x8d993f05, 0x75afef7d, 0x725798f2, 0x6fc06ccd, 0xf44fc9e7, 0x190480bd, 0x5afd753a, 0xf38a2ffe, 0xe81573a4, 0xe0398ff8, 0xf93ddf0b, 0xe10500ab, 0xf270fdc6, 0x31ec0071, 0xad24165b, 0x91615b67, 0xe55e9f6e, 0x1d3197fc, 0x784f5698, 0x8d1af838, 0xefcc6a35, 0x1a9d83b0, 0x2403cf50, 0xbf40b1da, 0x9765da76 }; // for HS compression HS HScompXM, HScompFM; unsigned int HSCharLenOld, HSInCharNo; int HSxorStartPosInt, HSxorEndPosInt, HSxorSizeInt; int HSxorStartPosC, HSxorStartPosCrev; HS HSstoreCharsInOneComp; int HSxorClrStartPosIntrev; int HSCmpShift_IntSize, HSCmpShift_ByteSize, HSCmpShift_ByteSizeC; /******** to debug mInt ********/ void DumpMint(mInt *M, char c) { int i; printf("%c ", c); for (i=mIntIndexMin-1; i<=mIntIndexMax; i++) {printf("%08x ", M->mIdgt[i]);} printf("\n"); } void DumpMintD(mIntD *MD, char c) { int i; printf("%c ", c); for (i=mIntIndexMin-1; i<=mIntIndexMax*2; i++) {printf("%08x ", MD->mIdgt[i]);} printf("\n"); } /*===============================================================*/ int mIntMUL_HL(mInt *U, mInt *V, mIntD *UVD) { uiLLHL LLHLu, LLHLv, LLHLw; int i, j, iPj; unsigned long long int c, uv; uiLLHL LLMulAddWk; if (U->mIdgt[mIntIndexMin-1] != 0) {return(1);} if (V->mIdgt[mIntIndexMin-1] != 0) {return(2);} memset(UVD, 0, sizeof(mIntD)); LLHLu.I = 0; LLHLv.I = 0; LLHLw.I = 0; for (j=mIntIndexMax; j>=mIntIndexMin; j--) /* V */ { if (V->mIdgt[j] == 0) { UVD->mIdgt[j] = 0; continue; } c=0; LLHLv.HL.L = V->mIdgt[j]; for (i=mIntIndexMax; i>=mIntIndexMin; i--) /* U */ { iPj = i+j; LLHLu.HL.L = U->mIdgt[i]; uv = LLHLv.I * LLHLu.I; /* u*v */ LLMulAddWk.I = (uv & mIntBaseM1); LLHLw.HL.L = UVD->mIdgt[iPj]; LLMulAddWk.I += LLHLw.I; LLMulAddWk.I += c; UVD->mIdgt[iPj] = LLMulAddWk.HL.L; c = (uv >> mIntBaseBits); c += (LLMulAddWk.I >> mIntBaseBits); } UVD->mIdgt[j] = (unsigned int)c; } return(0); } /*****************/ void SSIhashInit(void) { int HScompXsizeInt, HScompXsizeByteRmdr, wk; unsigned long long int uiWk; int InitValBytes; int A=sizeof(mInt), B=sizeof(HSconst1_2400bits); if (A>B) {InitValBytes=B;} else {InitValBytes=A;} memset(&HScompFM, 0, sizeof(mInt)); memcpy(&HScompFM, HSconst1_2400bits, InitValBytes); memset(&HScompXM, 0, sizeof(mInt)); HScompXsizeInt = HScompXsizeByte/(mIntBaseBits/8); HScompXsizeByteRmdr = HScompXsizeByte%(mIntBaseBits/8); //printf("HScompXsizeByte : %d HScompXsizeInt : %d HScompXsizeByteRmdr : %d\n", // HScompXsizeByte, HScompXsizeInt, HScompXsizeByteRmdr); //debug if (HScompXsizeByteRmdr) { HScompXsizeInt++; memcpy(&HScompXM, &HSconst1_2400bits, (HScompXsizeInt+1)*(mIntBaseBits/8)); wk = ((mIntBaseBits/8)-HScompXsizeByteRmdr)*8; HScompXM.ui[HScompXsizeInt] >>= wk; HScompXM.ui[HScompXsizeInt] <<= HScompXsizeByteRmdr*8; uiWk = mIntMSB; uiWk >>= (HScompXsizeByteRmdr*8-1); HScompXM.ui[HScompXsizeInt] |= uiWk; //LSB } else { memcpy(&HScompXM, &HSconst1_2400bits, (HScompXsizeInt+1)*(mIntBaseBits/8)); HScompXM.ui[HScompXsizeInt] |= 1; //LSB } HScompXM.ui[mIntIndexMin] |= mIntMSB; //MSB //DumpMint((mInt *)&HScompXM, 'x'); //debug HSxorStartPosInt = ((HScompEPosByte-1)/(mIntBaseBits/8))+1; HSxorSizeInt = ((HSCharsInOneComp*3)/2)/(mIntBaseBits/8); if (((HSCharsInOneComp*3)/2) % (mIntBaseBits/8)) {HSxorSizeInt++;} HSxorEndPosInt = HSxorStartPosInt+HSxorSizeInt-1; if (HSxorEndPosInt>mIntIndexMax) {printf("HSxorEndPosInt>mIntIndexMax\n");} HSxorStartPosC = HScompEPosByte-1+(mIntBaseBits/8); HSxorStartPosCrev = mIntIntSize*(mIntBaseBits/8) - HSxorStartPosC -1; HSxorClrStartPosIntrev = mIntIndexMax - HSxorStartPosInt - HSxorSizeInt + 1; //printf("HScompEPosByte : %d HSCharsInOneComp : %d EXT-HSCharsInOneComp %d\n", // HScompEPosByte, HSCharsInOneComp, (HSCharsInOneComp*3)/2); //debug //printf("HSxorStartPosInt : %d HSxorEndPosInt : %d HSxorSizeInt: %d\n", // HSxorStartPosInt, HSxorEndPosInt, HSxorSizeInt); //debug //printf("HSxorStartPosC : %d HSxorStartPosCrev : %d\n", HSxorStartPosC, HSxorStartPosCrev); //debug //printf("HSxorClrStartPosIntrev : %d HScompXsizeByte %d\n", HSxorClrStartPosIntrev, HScompXsizeByte); //debug HSCmpShift_IntSize = HSshiftByteInOneComp/(mIntBaseBits/8); HSCmpShift_ByteSize = HSshiftByteInOneComp % (mIntBaseBits/8); HSCmpShift_ByteSizeC = (mIntBaseBits/8)- HSCmpShift_ByteSize; //printf("HSCmpShift_IntSize : %d HSCmpShift_ByteSize : %d HSCmpShift_ByteSizeC : %d\n", // HSCmpShift_IntSize, HSCmpShift_ByteSize, HSCmpShift_ByteSizeC); //debug memset(&HSstoreCharsInOneComp, 0, sizeof(mInt)); //memset(&HSstoreCharsInOneComp, 0xff, sizeof(mInt)); //debug //DumpMint((mInt *)&HSstoreCharsInOneComp, 's'); //debug HSCharLenOld=HSBufSize; HSInCharNo=0; } /*****************/ int SSIhashCompress(unsigned char *HSBuf, int CharLen) { int i, j, k, p, kekka; HSD HSWkMD; int storeCharPos, mod3; if (CharLen==0) {return(1);} if (CharLen<0) { printf("Err: CharLen<0 (%d) \n", CharLen); return(2); } if (HSCharLenOld != HSBufSize) { printf("Err: Previous CharLen(%d) != HSBufSize(%d)\n", HSCharLenOld, HSBufSize); return(3); } HSCharLenOld = CharLen; for(j=0; j>(HSCmpShift_ByteSizeC*8)); } } //DumpMint((mInt *)&HScompFM, 'F'); //debug } return(0); } /****************/ int SSIhashGenVal(HS *HashValueM) { int i, j, k, mIntResult; int HSBitShift_IntSize, HSBitShift_BitSizeRmdr, HSBitShift_BitSizeRmdrC; int HSHashBgnInt, HSHashBgnBitRmdr; HS scrFM, scrYM; HSD scrWk1MD; int wk1, wk2; int HScompEPosByteRmdr; unsigned int uiWk1; int HSscrYsizeByteRmdr, HSscrYsizeInt, scrYMucRelPos; uiLLHL uiLLHL1, uiLLHL2; HSscrYsizeInt = HSscrYsizeByte/(mIntBaseBits/8); HSscrYsizeByteRmdr = HSscrYsizeByte % (mIntBaseBits/8); //HSscrYsizeInt = HSscrYsizeByte/sizeof(int); //SSIhash12 //printf("HSscrYsizeByte : %d HSscrYsizeInt : %d HSscrYsizeBytreRmdr : %d\n", // HSscrYsizeByte, HSscrYsizeInt, HSscrYsizeByteRmdr); //debug memcpy(&scrFM, &HScompFM, sizeof(mInt)); //DumpMint((mInt *)&scrFM, 'f'); //debug // xor HSInCharNo //memset(&scrFM, 0, sizeof(mInt)); //debug //HSInCharNo = 0xf123456d; //debug uiWk1 = HSInCharNo; HScompEPosByteRmdr = ((HScompEPosByte-1)%(mIntBaseBits/8)); if (HScompEPosByteRmdr == 0) { scrFM.ui[HSxorStartPosInt] ^= HSInCharNo; } else { wk1 = HScompEPosByteRmdr*8; uiWk1 >>= wk1; scrFM.ui[HSxorStartPosInt] ^= uiWk1; uiWk1 = HSInCharNo; //wk2 = ((sizeof(int) - HScompEPosByteRmdr))*8; //SSIhash12 wk2 = ( ( (mIntBaseBits/8) - HScompEPosByteRmdr ) )*8; uiWk1 <<= wk2; scrFM.ui[HSxorStartPosInt+1] ^= uiWk1; } //DumpMint((mInt *)&scrFM, 'g'); //debug // prepare scrYM memset(&scrYM, 0, sizeof(mInt)); //memset(&scrFM, 0x01, sizeof(mInt)); //debug //DumpMint((mInt *)&scrYM, 'Y'); //debug //DumpMint((mInt *)&scrFM, 'F'); //debug if (HSscrYsizeByteRmdr==0) { for (i=0; i=HSscrYsizeByte) {scrYMucRelPos=0;} scrYM.uc[(wk1+mIntIndexMin)*(mIntBaseBits/8)+(mIntBaseBits/8)-wk2-1] ^= scrWk1MD.uc[k]; } //DumpMint((mInt *)&scrYM, 'y'); //debug } wk2 = ( ( (mIntBaseBits/8) - HSscrYsizeByteRmdr ) )*8; scrYM.ui[mIntIndexMin+HSscrYsizeInt] >>= wk2; scrYM.ui[mIntIndexMin+HSscrYsizeInt] |= 1; //LSB (HSscrYsizeByteRmdr!=0) scrYM.ui[mIntIndexMin+HSscrYsizeInt] <<= wk2; } //DumpMint((mInt *)&scrYM, 'y'); //debug //memset(&scrYM, 0, sizeof(mInt)); //debug scrYM.ui[mIntIndexMin] |= mIntMSB; //scrYM.ui[HSscrYsizeInt] |= 1; //LSB (HSscrYsizeByteRmdr=0) //DumpMint((mInt *)&scrYM, 'Y'); //debug // scramble main HSBitShift_IntSize = HSscrBitShiftSize / mIntBaseBits; HSBitShift_BitSizeRmdr = HSscrBitShiftSize % mIntBaseBits; HSBitShift_BitSizeRmdrC = mIntBaseBits-HSBitShift_BitSizeRmdr; //printf("HSBitShift_IntSize : %d HSBitShift_BitSizeRmdr : %d\n", // HSBitShift_IntSize, HSBitShift_BitSizeRmdr); //debug //printf("HSBitShift_BitSizeRmdrC : %d\n", HSBitShift_BitSizeRmdrC); //debug for (i=1; i<=HSscrBitShiftTimes; i++) //for (i=1; i<=1; i++) //debug { //memset(&scrFM, 0, sizeof(mInt)); //debug scrFM.ui[mIntIndexMin] |= mIntMSB; scrFM.ui[mIntIndexMax] |= 1; //DumpMint((mInt *)&scrFM, 'f'); //debug mIntResult = mIntMUL_HL((mInt *)&scrFM, (mInt *)&scrYM, (mIntD *)&scrWk1MD); if (mIntResult != 0) {return(3000+mIntResult);} //DumpMintD((mIntD *)&scrWk1MD, 'D'); //debug for (j=1; j<=mIntIndexMax; j++) { if (HSBitShift_BitSizeRmdr==0) { scrFM.ui[j] = scrWk1MD.ui[j+HSBitShift_IntSize]; } else { scrFM.ui[j] = (scrWk1MD.ui[j+HSBitShift_IntSize]<>HSBitShift_BitSizeRmdrC); } } //DumpMint((mInt *)&scrFM, 'F'); //debug } //DumpMint((mInt *)&scrFM, 'F'); //debug // take out random number //DumpMintD((mIntD *)&scrWk1MD, 'D'); //debug HSHashBgnInt = HSHashBgnBit/mIntBaseBits; HSHashBgnBitRmdr = HSHashBgnBit % mIntBaseBits; //printf("HSHashBgnBit : %d HSHashBgnInt : %d HSHashBgnBitRmdr : %d\n", // HSHashBgnBit, HSHashBgnInt, HSHashBgnBitRmdr); //debug for (j=1; j<=mIntIndexMax; j++) { if (HSHashBgnBitRmdr==0) { HashValueM->ui[j] = scrWk1MD.ui[j+HSHashBgnInt]; } else { HashValueM->ui[j] = (scrWk1MD.ui[HSHashBgnInt+j] << HSHashBgnBitRmdr); HashValueM->ui[j] |= (scrWk1MD.ui[HSHashBgnInt+j+1] >> (mIntBaseBits-HSHashBgnBitRmdr)); } } HashValueM->ui[mIntIndexMin-1]=0; //DumpMint((mInt *)HashValueM, 'H'); //debug return(0); } /********************* testSSInnnhash ***********************/ // SSInnnhash should be used such as // // unsigned char Msg_Buf[HSBufSize] // HSBufSize=1024 // HS HashValue; // store hash value // // SSIhashInit(); //initialize SSIhash // SSIhashCompress(Msg_Buf, HSBufSize); //send data to SSIhash // ..... // SSIhashCompress(Msg_Buf, HSBufSize); // SSIhashCompress(Msg_Buf, kk); // 0 < kk <= HSBufSize // SSIhashGenVal(&HashValue); //generate a hash value #ifdef testSSInnnhash int main() { int i; unsigned char Msg_Buf[HSBufSize] = "01234567"; // HSBufSize=1024 HS HashValue; for (i=8; i