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--;
                }
            }
        }
Пример #2
0
            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));
                }
            }
Пример #3
0
        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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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;
            }
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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;
                }
            }
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
            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;
                        }
                    }
                }
            }
Пример #10
0
        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);
        }
Пример #11
0
            // 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;
                            }
                        }
                    }
                }
            }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #15
0
        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);
        }
Пример #16
0
        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 });
            }
        }