protected override byte[] FinalHash(IQmhHukState hashState) { var size = 8; if (this._bitLen == 384) { size = 6; } byte[] result = new byte[size * 8]; QmhHuk512State state = (QmhHuk512State)hashState; for (int h = 0, p = 0; h < size; h++, p += 8) { var hState = state.H[h]; result[p + 0] = (byte)(hState >> 56); result[p + 1] = (byte)(hState >> 48); result[p + 2] = (byte)(hState >> 40); result[p + 3] = (byte)(hState >> 32); result[p + 4] = (byte)(hState >> 24); result[p + 5] = (byte)(hState >> 16); result[p + 6] = (byte)(hState >> 8); result[p + 7] = (byte)(hState); } return(result); }
protected override void Compress(IQmhHukState hashState, byte[] buffer) { // Init Message Schedule array (W) UInt64[] W = new UInt64[64]; for (int t = 0, j = 0; t < 16; ++t, j += 8) { W[t] = ((UInt64)buffer[j] << 56) | ((UInt64)buffer[j + 1] << 48) | ((UInt64)buffer[j + 2] << 40) | ((UInt64)buffer[j + 3] << 32) | ((UInt64)buffer[j + 4] << 24) | ((UInt64)buffer[j + 5] << 16) | ((UInt64)buffer[j + 6] << 8) | ((UInt64)buffer[j + 7]); } for (int t = 16; t < 64; ++t) { W[t] = Wsigma1(W[t - 2]) + W[t - 7] + Wsigma0(W[t - 15]) + W[t - 16]; } QmhHuk512State state = (QmhHuk512State)hashState; // Init working variables UInt64 a = state.H[0]; UInt64 b = state.H[1]; UInt64 c = state.H[2]; UInt64 d = state.H[3]; UInt64 e = state.H[4]; UInt64 f = state.H[5]; UInt64 g = state.H[6]; UInt64 h = state.H[7]; // 64 rounds for (int r = 0; r < 64; ++r) { UInt64 T1 = h + Sigma1(e) + Choice(e, f, g) + K[r] + W[r]; UInt64 T2 = Sigma0(a) + Majority(a, b, c); UInt64 T3 = a + Sigma1(d) + Choice(c, b, a) + K[r] + W[r]; UInt64 T4 = Sigma0(h) + Majority(h, g, f); h = g; g = f ^ T1; f = e; e = T3 + T4; d = c; c = b ^ T3; b = a; a = T1 + T2; } // Update hash state state.H[0] ^= a; state.H[1] ^= b; state.H[2] ^= c; state.H[3] ^= d; state.H[4] ^= e; state.H[5] ^= f; state.H[6] ^= g; state.H[7] ^= h; }
protected override void Compress(IQmhHukState hashState, byte[] buffer) { // Init Message Schedule array (W) UInt32[] W = new UInt32[56]; for (int t = 0, j = 0; t < 16; ++t, j += 4) { W[t] = (UInt32)((buffer[j] << 24) | (buffer[j + 1] << 16) | (buffer[j + 2] << 8) | (buffer[j + 3])); } for (int t = 16; t < 56; ++t) { W[t] = Wsigma1(W[t - 2]) + W[t - 7] + Wsigma0(W[t - 15]) + W[t - 16]; } QmhHuk256State state = (QmhHuk256State)hashState; // Init working variables UInt32 a = state.H[0]; UInt32 b = state.H[1]; UInt32 c = state.H[2]; UInt32 d = state.H[3]; UInt32 e = state.H[4]; UInt32 f = state.H[5]; UInt32 g = state.H[6]; UInt32 h = state.H[7]; // 56 rounds for (int r = 0; r < 56; ++r) { UInt32 T1 = h + Sigma1(e) + Choice(e, f, g) + K[r] + W[r]; UInt32 T2 = Sigma0(a) + Majority(a, b, c); UInt32 T3 = a + Sigma1(d) + Choice(c, b, a) + K[r] + W[r]; UInt32 T4 = Sigma0(h) + Majority(h, g, f); h = g; g = f ^ T1; f = e; e = T3 + T4; d = c; c = b ^ T3; b = a; a = T1 + T2; } // Update hash state state.H[0] ^= a; state.H[1] ^= b; state.H[2] ^= c; state.H[3] ^= d; state.H[4] ^= e; state.H[5] ^= f; state.H[6] ^= g; state.H[7] ^= h; }
protected override byte[] FinalHash(IQmhHukState hashState) { var size = 8; if (this._bitLen == 224) { size = 7; } byte[] result = new byte[size * 4]; QmhHuk256State state = (QmhHuk256State)hashState; for (int h = 0, p = 0; h < size; h++, p += 4) { var hState = state.H[h]; result[p + 0] = (byte)(hState >> 24); result[p + 1] = (byte)(hState >> 16); result[p + 2] = (byte)(hState >> 8); result[p + 3] = (byte)(hState); } return(result); }
/// <summary> /// Init hsha state /// </summary> /// <param name="hashState"></param> protected override void InitState(out IQmhHukState hashState) { if (this._bitLen == 512) { hashState = new QmhHuk512State() { H = new UInt64[] { 0x7830769755FE0B0A, 0x84AE4B7CB79286A4, 0xC2B2B7559233F645, 0xCF03D20E5ACFA987, 0xF3CBB117DBF3C297, 0x79C450F6CE64CB45, 0x308AF161F4A4E085, 0x60A7A9985B936A57 } } } ; else { hashState = new QmhHuk512State() { H = new UInt64[] { 0x788D9812FBEB2197, 0x84769B42A93033FE, 0x9C34F0620BFEF64A, 0xE2D564C44CA0D2CD, 0xAE469BE46D4C8CA9, 0x2894C1073A16F2FE, 0x569B58C652391DBE, 0x6D7B3939EC6A09C2 } } }; }
/// <summary> /// Init hsha state /// </summary> /// <param name="hashState"></param> protected override void InitState(out IQmhHukState hashState) { if (this._bitLen == 256) { hashState = new QmhHuk256State() { H = new UInt32[] { // 419..457 0x78307697, 0x84AE4B7C, 0xC2B2B755, 0xCF03D20E, 0xF3CBB117, 0x79C450F6, 0x308AF161, 0x60A7A998 } } } ; else { hashState = new QmhHuk256State() { H = new UInt32[] { // 461..503 0x788D9812, 0x84769B42, 0x9C34F062, 0xE2D564C4, 0xAE469BE4, 0x2894C107, 0x569B58C6, 0x6D7B3939 } } }; }
/// <summary> /// Initialize Hash State /// </summary> /// <param name="hashState">Hash State initialized</param> protected abstract void InitState(out IQmhHukState hashState);
protected abstract byte[] FinalHash(IQmhHukState hashState);
/// <summary> /// Compress data from buffer /// </summary> /// <param name="hashState"></param> /// <param name="buffer"></param> protected abstract void Compress(IQmhHukState hashState, byte[] buffer);