Beispiel #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);
        }
Beispiel #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);
        }