Esempio n. 1
0
        internal async Task <Argon2Lane[]> InitializeLanes(byte[] password)
        {
            var blockHash = Initialize(password);

            var lanes = new Argon2Lane[DegreeOfParallelism];

            // adjust memory size if needed so that each segment has
            // an even size
            var segmentLength = MemorySize / (lanes.Length * 4);

            MemorySize = segmentLength * 4 * lanes.Length;
            var blocksPerLane = MemorySize / lanes.Length;

            if (blocksPerLane < 4)
            {
                throw new InvalidOperationException($"Memory should be enough to provide at least 4 blocks per {nameof(DegreeOfParallelism)}");
            }

            Task[] init = new Task[lanes.Length * 2];
            for (var i = 0; i < lanes.Length; ++i)
            {
                lanes[i] = new Argon2Lane(blocksPerLane);

                int taskIndex = i * 2;
                int iClosure  = i;
                init[taskIndex] = Task.Run(() =>
                {
                    var stream = new LittleEndianActiveStream();
                    stream.Expose(blockHash);
                    stream.Expose(0);
                    stream.Expose(iClosure);

                    ModifiedBlake2.Blake2Prime(lanes[iClosure][0], stream);
                });

                init[taskIndex + 1] = Task.Run(() =>
                {
                    var stream = new LittleEndianActiveStream();
                    stream.Expose(blockHash);
                    stream.Expose(1);
                    stream.Expose(iClosure);

                    ModifiedBlake2.Blake2Prime(lanes[iClosure][1], stream);
                });
            }

            await Task.WhenAll(init).ConfigureAwait(false);

            Array.Clear(blockHash, 0, blockHash.Length);
            return(lanes);
        }
Esempio n. 2
0
        private byte[] Finalize(Argon2Lane[] lanes)
        {
            XorLanes(lanes);

            var ds = new LittleEndianActiveStream();

            ds.Expose(lanes[0][lanes[0].BlockCount - 1]);

            ModifiedBlake2.Blake2Prime(lanes[0][1], ds, _tagLine);
            var result = new byte[_tagLine];
            var tmp    = MemoryMarshal.Cast <ulong, byte>(lanes[0][1].Span).Slice(0, result.Length);

            tmp.CopyTo(result);
            return(result);
        }
        private byte[] Finalize(Argon2Lane[] lanes)
        {
            XorLanes(lanes);

            var ds = new LittleEndianActiveStream();

            ds.Expose(lanes[0][lanes[0].BlockCount - 1]);

            ModifiedBlake2.Blake2Prime(lanes[0][1], ds, _tagLine);
            var result = new byte[_tagLine];

            var stream = new Argon2Memory.Stream(lanes[0][1]);

            stream.Read(result, 0, _tagLine);

            return(result);
        }
        internal unsafe static void Compress(Argon2Memory dest, Argon2Memory refb, Argon2Memory prev)
        {
            var tmpblock = stackalloc ulong[dest.Length];

            for (var n = 0; n < 128; ++n)
            {
                tmpblock[n] = refb[n] ^ prev[n];
                dest[n]    ^= tmpblock[n];
            }

            for (var i = 0; i < 8; ++i)
            {
                ModifiedBlake2.DoRoundColumns(tmpblock, i);
            }
            for (var i = 0; i < 8; ++i)
            {
                ModifiedBlake2.DoRoundRows(tmpblock, i);
            }

            for (var n = 0; n < 128; ++n)
            {
                dest[n] ^= tmpblock[n];
            }
        }