private static unsafe void BlockMix(uint[] b, uint[] x1, uint[] x2, uint[] y, int r) { fixed(uint *bPtr = &b[b.Length - 16], x1Ptr = x1) { PointerUtils.MemMove(x1Ptr, bPtr, 16 * sizeof(uint)); } var bOffset = 0; var yOffset = 0; var halfLen = b.Length / 2; var idx = 2 * r; fixed(uint *x1Ptr = x1) { while (idx > 0) { Xor(x1, b, bOffset, x2); SalsaCore(8, x2, x1); fixed(uint *yPtr = &y[yOffset]) { PointerUtils.MemMove(yPtr, x1Ptr, 16 * sizeof(uint)); } yOffset = halfLen + bOffset - yOffset; bOffset += 16; idx--; } } }
public unsafe void ChainingValue(uint *result) { var full = new uint[16]; fixed(uint *ptrFull = full) { Compress(ptrFull); PointerUtils.MemMove(&result[0], ptrFull, 8 * sizeof(uint)); } }
private static unsafe byte[] GetInitialHashLong(byte[] initialHash, byte[] appendix) { var result = new byte[ARGON2_PREHASH_SEED_LENGTH]; fixed(byte *initialHashPtr = initialHash, resultPtr = result, appendixPtr = appendix) { PointerUtils.MemMove(resultPtr, initialHashPtr, ARGON2_PREHASH_DIGEST_LENGTH); PointerUtils.MemMove(resultPtr + ARGON2_PREHASH_DIGEST_LENGTH, appendixPtr, 4); } return(result); }
static unsafe Grindahl256() { fixed(uint *ptrTable0 = Table0, ptrTable1 = Table1, ptrTable2 = Table2, ptrTable3 = Table3, ptrMasterTable = MasterTable) { PointerUtils.MemMove(ptrTable0, ptrMasterTable, MasterTable.Length * sizeof(uint)); CalcTable(1, ptrTable1); CalcTable(2, ptrTable2); CalcTable(3, ptrTable3); } }
public override unsafe void TransformBytes(byte[] data, int index, int length) { if (data == null) { throw new ArgumentNullException(nameof(data)); } Debug.Assert(index >= 0); Debug.Assert(length >= 0); Debug.Assert(index + length <= data.Length); var dataLength = (ulong)length; fixed(byte *dataPtr = data, bufferPtr = _buffer) { var dataPtr2 = dataPtr + index; var left = _bufferLength; var fill = (ulong)_buffer.Length - left; if (left > 0 && dataLength >= fill) { PointerUtils.MemMove(dataPtr2, bufferPtr + left, (int)fill); for (var idx = 0; idx < ParallelismDegree; idx++) { _leafHashes[idx].TransformBytes(_buffer, idx * BlockSizeInBytes, BlockSizeInBytes); } dataPtr2 += fill; dataLength -= fill; left = 0; } DoBlake2SParallel(dataPtr2, dataLength); dataPtr2 += dataLength - dataLength % (ParallelismDegree * BlockSizeInBytes); dataLength %= ParallelismDegree * BlockSizeInBytes; if (dataLength > 0) { PointerUtils.MemMove(bufferPtr + left, dataPtr2, (int)dataLength); } _bufferLength = left + dataLength; } }
static unsafe Grindahl512() { fixed(ulong *ptrTable0 = Table0, ptrTable1 = Table1, ptrTable2 = Table2, ptrTable3 = Table3, ptrTable4 = Table4, ptrTable5 = Table5, ptrTable6 = Table6, ptrTable7 = Table7, ptrMasterTable = MasterTable) { PointerUtils.MemMove(ptrTable0, ptrMasterTable, MasterTable.Length * sizeof(ulong)); CalcTable(1, ptrTable1); CalcTable(2, ptrTable2); CalcTable(3, ptrTable3); CalcTable(4, ptrTable4); CalcTable(5, ptrTable5); CalcTable(6, ptrTable6); CalcTable(7, ptrTable7); } }
private unsafe void Blake2SParallel(int idx, void *dataPtr, ulong counter) { var buffer = new byte[BlockSizeInBytes]; var dataPtr2 = (byte *)dataPtr; dataPtr2 += idx * BlockSizeInBytes; fixed(byte *bufferPtr = buffer) { while (counter >= ParallelismDegree * BlockSizeInBytes) { PointerUtils.MemMove(bufferPtr, dataPtr2, BlockSizeInBytes); _leafHashes[idx].TransformBytes(buffer, 0, BlockSizeInBytes); dataPtr2 += (ulong)(ParallelismDegree * BlockSizeInBytes); counter -= ParallelismDegree * BlockSizeInBytes; } } }
protected override unsafe void TransformBlock(void *data, int dataLength, int index) { uint t = 0; var temp = new byte[48]; fixed(byte *tempPtr = temp, statePtr = _state) { PointerUtils.MemMove(tempPtr, statePtr, dataLength); PointerUtils.MemMove(tempPtr + dataLength, (byte *)data + index, dataLength); for (var i = 0; i < 16; i++) { temp[i + 32] = (byte)(_state[i] ^ ((byte *)data)[i + index]); } for (var i = 0; i < 18; i++) { for (var j = 0; j < 48; j++) { temp[j] = (byte)(temp[j] ^ Pi[t]); t = temp[j]; } t = (byte)(t + i); } PointerUtils.MemMove(statePtr, tempPtr, 16); t = _checksum[15]; for (var i = 0; i < 16; i++) { _checksum[i] = (byte)(_checksum[i] ^ Pi[((byte *)data)[i + index] ^ t]); t = _checksum[i]; } ArrayUtils.ZeroFill(temp); } }
public unsafe void Read(byte[] dest, ulong destOffset, ulong outputLength) { var words = new uint[16]; if (Offset == MaxDigestLengthInBytes) { throw new ArgumentException(MaximumOutputLengthExceeded); } var remainder = MaxDigestLengthInBytes - Offset; outputLength = Math.Min(outputLength, remainder); fixed(uint *wordsPtr = words) { fixed(byte *blockPtr = _block, destPtr = dest) { while (outputLength > 0) { if ((Offset & (BlockSizeInBytes - 1)) == 0) { N.Counter = Offset / BlockSizeInBytes; N.Compress(wordsPtr); Converters.le32_copy(wordsPtr, 0, blockPtr, 0, BlockSizeInBytes); } var blockOffset = Offset & (BlockSizeInBytes - 1); var diff = (ulong)_block.Length - blockOffset; var count = (int)Math.Min(outputLength, diff); PointerUtils.MemMove(destPtr + destOffset, blockPtr + blockOffset, count); outputLength -= (ulong)count; destOffset += (ulong)count; Offset += (ulong)count; } } } }
protected override unsafe byte[] GetResult() { var buffer = new ulong[HashSize / sizeof(ulong)]; var result = new byte[HashSize]; fixed(ulong *bufferPtr = buffer, millPtr = _mill) { fixed(byte *resultPtr = result) { for (var i = 0; i < 2; i++) { RoundFunction(); PointerUtils.MemMove(bufferPtr + (i * 2), (millPtr + 1), 2 * sizeof(ulong)); } Converters.le64_copy(bufferPtr, 0, resultPtr, 0, result.Length); } } return(result); }
// update incorporates input into the chunkState. public unsafe void Update(byte *dataPtr, int dataLength) { var index = 0; fixed(byte *blockPtr = _block) { fixed(uint *blockPtr2 = _n.Block) { fixed(uint *cvPtr = _n.CV) { while (dataLength > 0) { // If the block buffer is full, compress it and clear it. More // input is coming, so this compression is not flagChunkEnd. if (_blockLen == BlockSizeInBytes) { // copy the chunk block (bytes) into the node block and chain it. Converters.le32_copy(blockPtr, 0, blockPtr2, 0, BlockSizeInBytes); _n.ChainingValue(cvPtr); // clear the start flag for all but the first block _n.Flags &= _n.Flags ^ flagChunkStart; _blockLen = 0; } // Copy input bytes into the chunk block. var count = Math.Min(BlockSizeInBytes - _blockLen, dataLength); PointerUtils.MemMove(blockPtr + _blockLen, dataPtr + index, count); _blockLen += count; BytesConsumed += count; index += count; dataLength -= count; } } } } }
public override unsafe byte[] GetBytes(int byteCount) { if (byteCount <= MIN_OUTLEN) { throw new ArgumentException( string.Format(InvalidOutputByteCount, MIN_OUTLEN)); } Initialize(_password, byteCount); DoFillMemoryBlocks(); Digest(byteCount); var result = new byte[byteCount]; fixed(byte *digestPtr = _digest, resultPtr = result) { PointerUtils.MemMove(resultPtr, digestPtr, byteCount); } Reset(); return(result); }
public override unsafe void TransformBytes(byte[] data, int index, int length) { if (data == null) { throw new ArgumentNullException(nameof(data)); } Debug.Assert(index >= 0); Debug.Assert(length >= 0); Debug.Assert(index + length <= data.Length); fixed(byte *dataPtr = data, memoryPtr = _state.Memory) { var dataPtr2 = dataPtr + index; _state.TotalLength += (ulong)length; byte *memoryPtr2; if (_state.MemorySize + (uint)length < 16) { memoryPtr2 = memoryPtr + _state.MemorySize; PointerUtils.MemMove(memoryPtr2, dataPtr2, length); _state.MemorySize += (uint)length; return; } var ptrEnd = dataPtr2 + (uint)length; if (_state.MemorySize > 0) { memoryPtr2 = memoryPtr + _state.MemorySize; PointerUtils.MemMove(memoryPtr2, dataPtr2, (int)(16 - _state.MemorySize)); _state.V1 = PRIME32_1 * Bits.RotateLeft32( _state.V1 + PRIME32_2 * Converters.ReadBytesAsUInt32LE(memoryPtr, 0), 13); _state.V2 = PRIME32_1 * Bits.RotateLeft32( _state.V2 + PRIME32_2 * Converters.ReadBytesAsUInt32LE(memoryPtr, 4), 13); _state.V3 = PRIME32_1 * Bits.RotateLeft32( _state.V3 + PRIME32_2 * Converters.ReadBytesAsUInt32LE(memoryPtr, 8), 13); _state.V4 = PRIME32_1 * Bits.RotateLeft32( _state.V4 + PRIME32_2 * Converters.ReadBytesAsUInt32LE(memoryPtr, 12), 13); dataPtr2 += 16 - _state.MemorySize; _state.MemorySize = 0; } if (dataPtr2 <= ptrEnd - 16) { var v1 = _state.V1; var v2 = _state.V2; var v3 = _state.V3; var v4 = _state.V4; var ptrLimit = ptrEnd - 16; do { var dataPtrStart2 = (uint *)dataPtr2; v1 = PRIME32_1 * Bits.RotateLeft32( v1 + PRIME32_2 * Converters.ReadPCardinalAsUInt32LE(dataPtrStart2), 13); v2 = PRIME32_1 * Bits.RotateLeft32( v2 + PRIME32_2 * Converters.ReadPCardinalAsUInt32LE(dataPtrStart2 + 1), 13); v3 = PRIME32_1 * Bits.RotateLeft32( v3 + PRIME32_2 * Converters.ReadPCardinalAsUInt32LE(dataPtrStart2 + 2), 13); v4 = PRIME32_1 * Bits.RotateLeft32( v4 + PRIME32_2 * Converters.ReadPCardinalAsUInt32LE(dataPtrStart2 + 3), 13); dataPtr2 += 16; } while (dataPtr2 <= ptrLimit); _state.V1 = v1; _state.V2 = v2; _state.V3 = v3; _state.V4 = v4; } if (dataPtr2 >= ptrEnd) { return; } PointerUtils.MemMove(memoryPtr, dataPtr2, (int)(ptrEnd - dataPtr2)); _state.MemorySize = (uint)(ptrEnd - dataPtr2); } }
/// <summary> /// Returns the pseudo-random bytes for this object. /// </summary> /// <param name="byteCount">The number of pseudo-random key bytes to generate.</param> /// <returns>A byte array filled with pseudo-random key bytes.</returns> /// <exception cref="ArgumentException">byteCount must be greater than zero.</exception> /// <exception cref="IndexOutOfRangeException">invalid start index or end index of internal buffer.</exception> public override unsafe byte[] GetBytes(int byteCount) { if (byteCount <= 0) { throw new ArgumentException(InvalidByteCount); } var key = new byte[byteCount]; var offset = 0; var size = _endIndex - _startIndex; if (size > 0) { fixed(byte *bufferPtr = &_buffer[_startIndex], keyPtr = key) { if (byteCount >= size) { PointerUtils.MemMove(keyPtr, bufferPtr, size); _startIndex = 0; _endIndex = 0; offset += size; } else { PointerUtils.MemMove(keyPtr, bufferPtr, byteCount); _startIndex += byteCount; Initialize(); return(key); } } } if (_startIndex != 0 && _endIndex != 0) { throw new IndexOutOfRangeException(InvalidIndex); } while (offset < byteCount) { var block = Func(); var remainder = byteCount - offset; if (remainder > _blockSize) { fixed(byte *blockPtr = block, keyPtr = &key[offset]) { PointerUtils.MemMove(keyPtr, blockPtr, _blockSize); } offset += _blockSize; } else { if (remainder > 0) { fixed(byte *blockPtr = block, keyPtr = &key[offset]) { PointerUtils.MemMove(keyPtr, blockPtr, remainder); } } var remCount = _blockSize - remainder; if (remCount > 0) { fixed(byte *blockPtr = &block[remainder], bufferPtr = &_buffer[_startIndex]) { PointerUtils.MemMove(bufferPtr, blockPtr, remCount); } } _endIndex += remCount; Initialize(); return(key); } } Initialize(); return(key); }
private static unsafe byte[] Hash(byte[] input, int outputLength) { Blake2B blake2B; const int blake2BLength = 64; var result = new byte[outputLength]; var outputLengthBytes = Converters.ReadUInt32AsBytesLE((uint)outputLength); if (outputLength <= blake2BLength) { blake2B = MakeBlake2BInstanceAndInitialize(outputLength); blake2B.TransformBytes(outputLengthBytes, 0, outputLengthBytes.Length); blake2B.TransformBytes(input, 0, input.Length); result = blake2B.TransformFinal().GetBytes(); } else { blake2B = MakeBlake2BInstanceAndInitialize(blake2BLength); blake2B.TransformBytes(outputLengthBytes, 0, outputLengthBytes.Length); blake2B.TransformBytes(input, 0, input.Length); var buffer = blake2B.TransformFinal().GetBytes(); fixed(byte *bufferPtr = buffer, resultPtr = result) { PointerUtils.MemMove(resultPtr, bufferPtr, blake2BLength / 2); } var count = (outputLength + 31) / 32 - 2; var position = blake2BLength / 2; var idx = 2; while (idx <= count) { blake2B.TransformBytes(buffer, 0, buffer.Length); buffer = blake2B.TransformFinal().GetBytes(); fixed(byte *bufferPtr = buffer, resultPtr = result) { PointerUtils.MemMove(resultPtr + position, bufferPtr, blake2BLength / 2); } idx++; position += blake2BLength / 2; } var lastLength = outputLength - 32 * count; blake2B = MakeBlake2BInstanceAndInitialize(lastLength); blake2B.TransformBytes(buffer, 0, buffer.Length); buffer = blake2B.TransformFinal().GetBytes(); fixed(byte *bufferPtr = buffer, resultPtr = result) { PointerUtils.MemMove(resultPtr + position, bufferPtr, lastLength); } } Debug.Assert(result.Length == outputLength); return(result); }
protected override unsafe void TransformBlock(void *data, int dataLength, int index) { var buffer = new ulong[8]; var k = new ulong[8]; var m = new ulong[8]; var temp = new ulong[8]; fixed(ulong *bufferPtr = buffer, kPtr = k, tempPtr = temp, mPtr = m) { Converters.be64_copy(data, index, bufferPtr, 0, dataLength); for (var i = 0; i < 8; i++) { k[i] = _state[i]; temp[i] = buffer[i] ^ k[i]; } for (var round = 1; round < Rounds + 1; round++) { for (var i = 0; i < 8; i++) { m[i] = 0; m[i] = m[i] ^ (C0[(byte)(k[(i - 0) & 7] >> 56)]); m[i] = m[i] ^ (C1[(byte)(k[(i - 1) & 7] >> 48)]); m[i] = m[i] ^ (C2[(byte)(k[(i - 2) & 7] >> 40)]); m[i] = m[i] ^ (C3[(byte)(k[(i - 3) & 7] >> 32)]); m[i] = m[i] ^ (C4[(byte)(k[(i - 4) & 7] >> 24)]); m[i] = m[i] ^ (C5[(byte)(k[(i - 5) & 7] >> 16)]); m[i] = m[i] ^ (C6[(byte)(k[(i - 6) & 7] >> 8)]); m[i] = m[i] ^ (C7[(byte)(k[(i - 7) & 7])]); } PointerUtils.MemMove(kPtr, mPtr, m.Length * sizeof(ulong)); k[0] = k[0] ^ Rc[round]; for (var i = 0; i < 8; i++) { m[i] = k[i]; m[i] = m[i] ^ (C0[(byte)(temp[(i - 0) & 7] >> 56)]); m[i] = m[i] ^ (C1[(byte)(temp[(i - 1) & 7] >> 48)]); m[i] = m[i] ^ (C2[(byte)(temp[(i - 2) & 7] >> 40)]); m[i] = m[i] ^ (C3[(byte)(temp[(i - 3) & 7] >> 32)]); m[i] = m[i] ^ (C4[(byte)(temp[(i - 4) & 7] >> 24)]); m[i] = m[i] ^ (C5[(byte)(temp[(i - 5) & 7] >> 16)]); m[i] = m[i] ^ (C6[(byte)(temp[(i - 6) & 7] >> 8)]); m[i] = m[i] ^ (C7[(byte)(temp[(i - 7) & 7])]); } PointerUtils.MemMove(tempPtr, mPtr, m.Length * sizeof(ulong)); } for (var i = 0; i < 8; i++) { _state[i] = _state[i] ^ (temp[i] ^ buffer[i]); } } ArrayUtils.ZeroFill(buffer); }
private static unsafe void SMix(uint[] block, int blockOffset, int cost, int blockSize) { var blockCount = blockSize * 32; var blockX1 = new uint[16]; var blockX2 = new uint[16]; var blockY = new uint[blockCount]; var x = new uint[blockCount]; var v = new uint[cost * blockCount]; try { int idx; fixed(uint *xPtr = x, blockPtr = &block[blockOffset]) { PointerUtils.MemMove(xPtr, blockPtr, blockCount * sizeof(uint)); var offset = 0; idx = 0; while (idx < cost) { fixed(uint *vPtr = &v[offset]) { PointerUtils.MemMove(vPtr, xPtr, blockCount * sizeof(uint)); } offset += blockCount; BlockMix(x, blockX1, blockX2, blockY, blockSize); fixed(uint *vPtr = &v[offset], blockYPtr = blockY) { PointerUtils.MemMove(vPtr, blockYPtr, blockCount * sizeof(uint)); } offset += blockCount; BlockMix(blockY, blockX1, blockX2, x, blockSize); idx += 2; } } var mask = (uint)cost - 1; idx = 0; while (idx < cost) { var jdx = (int)(x[blockCount - 16] & mask); fixed(uint *vPtr = &v[jdx *blockCount], blockYPtr = blockY) { PointerUtils.MemMove(blockYPtr, vPtr, blockCount * sizeof(uint)); } Xor(blockY, x, 0, blockY); BlockMix(blockY, blockX1, blockX2, x, blockSize); idx++; } fixed(uint *xPtr = x, bPtr = &block[blockOffset]) { PointerUtils.MemMove(bPtr, xPtr, blockCount * sizeof(uint)); } } finally { ClearArray(v); ClearAllArrays(new[] { x, blockX1, blockX2, blockY }); } }