/* p8: 8 bit Multi-Purpose Hash Function with Pseudo-Random Function Algorithm/Source Code */ /* Copyright(c) 2016, Karl-Uwe Frank All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #** p8 algorithm designed and developed by Karl-Uwe Frank */ //********************************************************************** /* ------------------------------------------------------------------ p8 Test vectors ------------------------------------------------------------------ Message : Hash : b2c01b7e3885ddef4f06823f8812aac6 ------------------------------------------------------------------ Message : test Hash : 61b68858e259fc831dad93d1006164a3 ------------------------------------------------------------------ Message : A quick brown fox jumps over the lazy dog Hash : 3c89d45fe2430fde8dfd224c115854f2 ------------------------------------------------------------------ Message : A quick brown fox jumps over the lazy dog. Hash : 0f85404487ad0dfd0ebdbf7178586e5c ------------------------------------------------------------------ Hash Size : 128 Seed (Hex): 00f75bce Key (Hex): 50617373776f7264 Message : Hash : 6b68051da328b1fa5a0763637dedd768 -------------------------------------------------------------------- Hash Size : 128 Seed (Hex): 00f75bce Key (Hex): 50617373776f7264 Message : a test string Hash : 7aef1c7f6e5e26ebbf210166fb9d313a ------------------------------------------------------------------- echo -en "The quick brown fox jumps over the lazy dog" | ./p8 3c89d45fe2430fde8dfd224c115854f2 echo -en "" | ./p8 128 0x00f75bce 50617373776f7264 6b68051da328b1fa5a0763637dedd768 */ // rm -f ./p8; gcc -std=c99 -O3 -fomit-frame-pointer -mtune=native p8.c -o p8 #include #include #include #include // needed to generate uint32 on a 64bit OS #include /////////////////////////////////////////// #define swap(X,Y) { uint8_t T = X; X = Y; Y = T; } static uint8_t a, b, c, d, j; static uint8_t SBox[256]; void SBox8_PIA(uint32_t seed); void SBox8_KSA(uint8_t Key[], uint16_t keyLen); uint8_t SBox8_PRGA(); //----------------------------------------- // PIA = Permutation Initialisation Algorithm // void SBox8_PIA(uint32_t seed) { if (seed == 0) { a = 14; b = 59; c = 23; d = 77; } else { a = ( seed & 0xff); b = ((seed >> 8) & 0xff); c = ((seed >> 16) & 0xff); d = ((seed >> 24) & 0xff); } // Shifting to the next odd Value of each Variable // in Order to generate an alternating Permutation uint8_t t = ((b ^ c) + d); t |= 1; // Initialise the alternating Permutation for (int i=0; i<256; i++) { a += t; SBox[i] = a; } } //----------------------------------------- // KSA = Key Schedule Algorithm // void SBox8_KSA(uint8_t Key[], uint16_t keyLen) { // Shuffle the Key into the Permutation for (int i=0; i<256; i++) { d = i % keyLen; a += SBox[b]; b += SBox[a]; c = a + b + i + Key[d]; swap(SBox[c], SBox[i]); } j=0; } //----------------------------------------- // PRGA = Pseudo-Random Generation Algorithm // uint8_t SBox8_PRGA() { a += SBox[b]; b += SBox[a]; c = a + b + j + SBox[j]; swap(SBox[c], SBox[j]); d = SBox[(SBox[c] + SBox[d]) &0xff]; j++; return ((a + b) ^ (c + d)); } int main (int argc, char *argv[]) { uint32_t seed = 0; uint16_t keyLen = 0; uint8_t Key[256]; uint8_t KeyHash[256]; memset(Key, 0, sizeof(Key)); memset(KeyHash, 0, sizeof(KeyHash)); // Minimum Hash Size is 128bit uint16_t hSize = 16; // Check if a Seed and a Key is passed through if (argc < 1) { fprintf(stderr, "\nUsage : %s file_to_hash [optional: Hash Size(in Bit) Seed(as 32bit Hex) Key(in Hex)]\n", argv[0]); fprintf(stderr, "\nExample: %s file_to_hash [optional: 128 78e68cf3 7d0ef66789aca2cfa6c76db7560554]\n", argv[0]); fprintf(stderr, "\n echo -en \"test\" | %s [optional: 128 78e68cf3 7d0ef66789aca2cfa6c76db7560554]\n\n", argv[0]); return 1; } // Define the Hash Size in Byte if (argc > 1){ hSize = (int)strtoul(argv[1], NULL, 10); hSize = hSize/8; } //----------------------------------------- // seed for the permutation initialisation // if (argc > 2) seed = (int)strtoul(argv[2], NULL, 16); if ((seed > 0) && (argc == 4)) strncpy(KeyHash, argv[3], strlen(argv[3])); // Initialisation of SBoxes SBox8_PIA(seed); // If a Seed is passed, but no Key, // use the Seed additionally as Initial Key if ((seed > 0) && (argc == 3)){ // Build the 4 Byte Key[] always Big Endian 04030201 Key[0] = ((seed >> 24) & 0xff); Key[1] = ((seed >> 16) & 0xff); Key[2] = ((seed >> 8) & 0xff); Key[3] = ( seed & 0xff); // Shuffle the Key into the SBox Permutation SBox8_KSA(Key, 4); } // Read from STDIN int bufferRead; const int BUF_SIZE = 4096; unsigned char inBuffer[BUF_SIZE]; memset(inBuffer, 0, sizeof(inBuffer)); // Offset for j j = 0; fflush(stdin); fflush(stdout); while ((bufferRead = fread(&inBuffer, sizeof(char), BUF_SIZE, stdin)) > 0) { for (int i=0; i 0){ uint8_t hex[3]; memset(hex, 0, 3); // Build up the Key keyLen = strlen(KeyHash); keyLen = keyLen/2; for (uint16_t i=0; i