/// <remarks> /// Convert to big endian integers, increment and convert back /// </remarks> private void Rotate(byte[] Counter) { // rotate the counter at 32 or 64 bit intervals if (RotationalAlignment == CounterAlignmentSizes.RAP32) { for (int i = 0; i < Counter.Length; i += 4) { IntUtils.Be32ToBytes(IntUtils.BytesToBe32(Counter, i) + 1, Counter, i); } } else { for (int i = 0; i < Counter.Length; i += 8) { IntUtils.Be64ToBytes(IntUtils.BytesToBe64(Counter, i) + 1, Counter, i); } } }
/// <summary> /// Do final processing and get the hash value /// </summary> /// /// <param name="Output">The Hash value container</param> /// <param name="OutOffset">The starting offset within the Output array</param> /// /// <returns>Size of Hash value, Always 32 bytes</returns> /// /// <exception cref="CryptoHashException">Thrown if Output array is too small</exception> public int DoFinal(byte[] Output, int OutOffset) { if (Output.Length - OutOffset < DigestSize) { throw new CryptoHashException("SHA256:DoFinal", "The Output buffer is too short!", new ArgumentOutOfRangeException()); } Finish(); IntUtils.Be32ToBytes(m_H0, Output, OutOffset); IntUtils.Be32ToBytes(m_H1, Output, OutOffset + 4); IntUtils.Be32ToBytes(m_H2, Output, OutOffset + 8); IntUtils.Be32ToBytes(m_H3, Output, OutOffset + 12); IntUtils.Be32ToBytes(m_H4, Output, OutOffset + 16); IntUtils.Be32ToBytes(m_H5, Output, OutOffset + 20); IntUtils.Be32ToBytes(m_H6, Output, OutOffset + 24); IntUtils.Be32ToBytes(m_H7, Output, OutOffset + 28); Reset(); return(DIGEST_SIZE); }
private void Encrypt16(byte[] Input, int InOffset, byte[] Output, int OutOffset) { int LRD = _expKey.Length - 5; int keyCtr = -1; // input round uint R0 = IntUtils.BytesToBe32(Input, InOffset + 12); uint R1 = IntUtils.BytesToBe32(Input, InOffset + 8); uint R2 = IntUtils.BytesToBe32(Input, InOffset + 4); uint R3 = IntUtils.BytesToBe32(Input, InOffset); // process 8 round blocks do { R0 ^= _expKey[++keyCtr]; R1 ^= _expKey[++keyCtr]; R2 ^= _expKey[++keyCtr]; R3 ^= _expKey[++keyCtr]; Sb0(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= _expKey[++keyCtr]; R1 ^= _expKey[++keyCtr]; R2 ^= _expKey[++keyCtr]; R3 ^= _expKey[++keyCtr]; Sb1(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= _expKey[++keyCtr]; R1 ^= _expKey[++keyCtr]; R2 ^= _expKey[++keyCtr]; R3 ^= _expKey[++keyCtr]; Sb2(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3);; R0 ^= _expKey[++keyCtr]; R1 ^= _expKey[++keyCtr]; R2 ^= _expKey[++keyCtr]; R3 ^= _expKey[++keyCtr]; Sb3(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= _expKey[++keyCtr]; R1 ^= _expKey[++keyCtr]; R2 ^= _expKey[++keyCtr]; R3 ^= _expKey[++keyCtr]; Sb4(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= _expKey[++keyCtr]; R1 ^= _expKey[++keyCtr]; R2 ^= _expKey[++keyCtr]; R3 ^= _expKey[++keyCtr]; Sb5(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= _expKey[++keyCtr]; R1 ^= _expKey[++keyCtr]; R2 ^= _expKey[++keyCtr]; R3 ^= _expKey[++keyCtr]; Sb6(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= _expKey[++keyCtr]; R1 ^= _expKey[++keyCtr]; R2 ^= _expKey[++keyCtr]; R3 ^= _expKey[++keyCtr]; Sb7(ref R0, ref R1, ref R2, ref R3); // skip on last block if (keyCtr != LRD) { LinearTransform(ref R0, ref R1, ref R2, ref R3); } }while (keyCtr != LRD); // last round IntUtils.Be32ToBytes(_expKey[++keyCtr] ^ R0, Output, OutOffset + 12); IntUtils.Be32ToBytes(_expKey[++keyCtr] ^ R1, Output, OutOffset + 8); IntUtils.Be32ToBytes(_expKey[++keyCtr] ^ R2, Output, OutOffset + 4); IntUtils.Be32ToBytes(_expKey[++keyCtr] ^ R3, Output, OutOffset); }
/// <summary> /// Do final processing and get the hash value /// </summary> /// /// <param name="Output">The Hash value container</param> /// <param name="OutOffset">The starting offset within the Output array</param> /// /// <returns>Size of Hash value</returns> /// /// <exception cref="CryptoHashException">Thrown if Output array is too small</exception> public int DoFinal(byte[] Output, int OutOffset) { if (Output.Length - OutOffset < DigestSize) { throw new CryptoHashException("Blake256:DoFinal", "The Output buffer is too short!", new ArgumentOutOfRangeException()); } byte[] msgLen = new byte[8]; ulong len = _T + ((ulong)_dataLen << 3); IntUtils.Be32ToBytes((uint)((len >> 32) & 0xFFFFFFFFU), msgLen, 0); IntUtils.Be32ToBytes((uint)(len & 0xFFFFFFFFU), msgLen, 4); // special case of one padding byte if (_dataLen == PAD_LENGTH) { _T -= 8; BlockUpdate(new byte[1] { 0x81 }, 0, 1); } else { if (_dataLen < PAD_LENGTH) { // enough space to fill the block if (_dataLen == 0) { _isNullT = true; } _T -= TN_440 - ((ulong)_dataLen << 3); BlockUpdate(_Padding, 0, PAD_LENGTH - _dataLen); } else { // not enough space, need 2 compressions _T -= TN_512 - ((ulong)_dataLen << 3); BlockUpdate(_Padding, 0, 64 - _dataLen); _T -= TN_440; BlockUpdate(_Padding, 1, PAD_LENGTH); _isNullT = true; } BlockUpdate(new byte[1] { 0x01 }, 0, 1); _T -= 8; } _T -= 64; BlockUpdate(msgLen, 0, 8); byte[] digest = new byte[32]; IntUtils.Be32ToBytes(_hashVal[0], digest, 0); IntUtils.Be32ToBytes(_hashVal[1], digest, 4); IntUtils.Be32ToBytes(_hashVal[2], digest, 8); IntUtils.Be32ToBytes(_hashVal[3], digest, 12); IntUtils.Be32ToBytes(_hashVal[4], digest, 16); IntUtils.Be32ToBytes(_hashVal[5], digest, 20); IntUtils.Be32ToBytes(_hashVal[6], digest, 24); IntUtils.Be32ToBytes(_hashVal[7], digest, 28); Buffer.BlockCopy(digest, 0, Output, OutOffset, digest.Length); Reset(); return(Output.Length); }
private void Decrypt16(byte[] Input, int InOffset, byte[] Output, int OutOffset) { int LRD = 4; int keyCtr = _expKey.Length; // input round uint R3 = _expKey[--keyCtr] ^ IntUtils.BytesToBe32(Input, InOffset); uint R2 = _expKey[--keyCtr] ^ IntUtils.BytesToBe32(Input, InOffset + 4); uint R1 = _expKey[--keyCtr] ^ IntUtils.BytesToBe32(Input, InOffset + 8); uint R0 = _expKey[--keyCtr] ^ IntUtils.BytesToBe32(Input, InOffset + 12); // process 8 round blocks do { Ib7(ref R0, ref R1, ref R2, ref R3); R3 ^= _expKey[--keyCtr]; R2 ^= _expKey[--keyCtr]; R1 ^= _expKey[--keyCtr]; R0 ^= _expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib6(ref R0, ref R1, ref R2, ref R3); R3 ^= _expKey[--keyCtr]; R2 ^= _expKey[--keyCtr]; R1 ^= _expKey[--keyCtr]; R0 ^= _expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib5(ref R0, ref R1, ref R2, ref R3); R3 ^= _expKey[--keyCtr]; R2 ^= _expKey[--keyCtr]; R1 ^= _expKey[--keyCtr]; R0 ^= _expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib4(ref R0, ref R1, ref R2, ref R3); R3 ^= _expKey[--keyCtr]; R2 ^= _expKey[--keyCtr]; R1 ^= _expKey[--keyCtr]; R0 ^= _expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib3(ref R0, ref R1, ref R2, ref R3); R3 ^= _expKey[--keyCtr]; R2 ^= _expKey[--keyCtr]; R1 ^= _expKey[--keyCtr]; R0 ^= _expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib2(ref R0, ref R1, ref R2, ref R3); R3 ^= _expKey[--keyCtr]; R2 ^= _expKey[--keyCtr]; R1 ^= _expKey[--keyCtr]; R0 ^= _expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib1(ref R0, ref R1, ref R2, ref R3); R3 ^= _expKey[--keyCtr]; R2 ^= _expKey[--keyCtr]; R1 ^= _expKey[--keyCtr]; R0 ^= _expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib0(ref R0, ref R1, ref R2, ref R3); // skip on last block if (keyCtr != LRD) { R3 ^= _expKey[--keyCtr]; R2 ^= _expKey[--keyCtr]; R1 ^= _expKey[--keyCtr]; R0 ^= _expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); } }while (keyCtr != LRD); // last round IntUtils.Be32ToBytes(R3 ^ _expKey[--keyCtr], Output, OutOffset); IntUtils.Be32ToBytes(R2 ^ _expKey[--keyCtr], Output, OutOffset + 4); IntUtils.Be32ToBytes(R1 ^ _expKey[--keyCtr], Output, OutOffset + 8); IntUtils.Be32ToBytes(R0 ^ _expKey[--keyCtr], Output, OutOffset + 12); }