HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen) { tSmallUInt trailingBits; tSmallUInt len; if ( (state->bytesInQueue == 0xFF) || (state->trailingBitsInQueue != 0) ) { /* Final() already called or bits already in queue not modulo 8. */ return ( FAIL ); } trailingBits = (unsigned char)databitlen & 7; databitlen >>= 3; /* becomes byte length */ /* If already data in queue, continue queuing first */ if ( (state->bytesInQueue != 0) && (databitlen != 0) ) { len = cKeccakR_SizeInBytes - state->bytesInQueue; if ( databitlen < len ) { len = (unsigned char)databitlen; } data = xorBytes( state->state + state->bytesInQueue, data, len ); databitlen -= len; if ( (state->bytesInQueue += len) == cKeccakR_SizeInBytes ) { KeccakF( (tKeccakLane *)state->state ); state->bytesInQueue = 0; } } /* Absorb complete blocks */ for ( /* */; databitlen >= cKeccakR_SizeInBytes; databitlen -= cKeccakR_SizeInBytes ) { data = xorLanes( state->state, data, cKeccakR_SizeInBytes / 8 ); KeccakF( (tKeccakLane *)state->state ); } /* Queue remaining data bytes */ if ( (unsigned char)databitlen != 0 ) { data = xorBytes( state->state, data, (unsigned char)databitlen ); state->bytesInQueue = (unsigned char)databitlen; } /* Queue eventual remaining data bits plus add first padding bit */ if ( trailingBits != 0 ) { state->trailingBitsInQueue = 1; state->state[state->bytesInQueue++] ^= (*data >> (8 - trailingBits)) | (1 << trailingBits); }
int crypto_hash( unsigned char *out, const unsigned char *in, unsigned long long inlen ) { #if 1 tSmallUInt i; tSmallUInt len; unsigned char * pState; tKeccakLane state[5 * 5]; memset( state, 0, sizeof(state) ); /* Full blocks */ for ( /* empty */; inlen >= cKeccakR_SizeInBytes; inlen -= cKeccakR_SizeInBytes ) { in = xorLanes( state, in, cKeccakR_SizeInBytes / 8 ); KeccakF( state ); } /* Last uncomplete block */ len = (tSmallUInt)inlen; xorBytes( state, in, len ); pState = (unsigned char*)state + len; /* Padding */ for ( i = 0; i < 4; /* empty */ ) { *(pState++) ^= pgm_read_byte(&KeccakPadding[i++]); if ( ++len == cKeccakR_SizeInBytes ) { KeccakF( state ); pState = (unsigned char*)state; len = 0; } } if ( len != 0 ) { KeccakF( state ); } memcpy( out, state, crypto_hash_BYTES ); return ( 0 ); #else hashState state; Init( &state ); Update( &state, in, inlen * 8 ); return (Final( &state, out, crypto_hash_BYTES ) ); #endif }
int main(int argc, char *argv[]) { int bytesLen1 = 0; char *bytes1 = hexStrToBytes(sInputStr1, &bytesLen1); if (!bytes1) { printf("Failure! Couldn't convert hex to bytes for first input.\n"); return 1; } int bytesLen2 = 0; char *bytes2 = hexStrToBytes(sInputStr2, &bytesLen2); if (!bytes2) { printf("Failure! Couldn't convert hex to bytes for second input.\n"); return 1; } char *xorResultStr = malloc(bytesLen1); if (!xorResultStr) { printf("Failure! Couldn't alloc buffer for xor result string.\n"); return 1; } if (bytesLen1 != bytesLen2) { printf("Failure! The lengths of both inputs are different.\n"); return 1; } xorBytes(bytes1, bytes2, xorResultStr, bytesLen1); char *aHexStr = malloc(bytesLen1 * 2); if (!aHexStr) { printf("Failure! Couldn't alloc buffer for hex string.\n"); return 1; } bytesToHexStr(xorResultStr, aHexStr, bytesLen1); if (strcmp(aHexStr, sOutputStr) == 0) { printf("Success!\n"); } else { printf("Failure!\n"); } free(xorResultStr); free(aHexStr); return 0; }