Пример #1
0
        // Private stuff starts here
        internal void InitializeLanesTask(int l, int s, int i, Argon2Lane[] lanes, int start)
        {
            Argon2Lane lane          = lanes[l];
            int        segmentLength = lane.BlockCount / 4;
            int        curOffset     = s * segmentLength + start;

            int prevLane   = l;
            int prevOffset = curOffset - 1;

            if (curOffset == 0)
            {
                prevOffset = lane.BlockCount - 1;
            }

            IArgon2PseudoRands state = GenerateState(lanes, segmentLength, i, l, s);

            for (int c = start; c < segmentLength; ++c, curOffset++)
            {
                ulong pseudoRand = state.PseudoRand(c, prevLane, prevOffset);
                int   refLane    = (int)((uint)(pseudoRand >> 32) % lanes.Length);

                if (i == 0 && s == 0)
                {
                    refLane = l;
                }

                int          refIndex = IndexAlpha(l == refLane, (uint)pseudoRand, lane.BlockCount, segmentLength, i, s, c);
                Argon2Memory refBlock = lanes[refLane][refIndex];
                Argon2Memory curBlock = lane[curOffset];

                Compress(curBlock, refBlock, lanes[prevLane][prevOffset]);
                prevOffset = curOffset;
            }
        }
Пример #2
0
        internal Argon2Lane[] InitializeLanes(byte[] password)
        {
            byte[] blockHash = Initialize(password);

            Argon2Lane[] lanes = new Argon2Lane[1];

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

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

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

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

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

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

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

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

            foreach (Action t in init)
            {
                t();
            }

            Array.Clear(blockHash, 0, blockHash.Length);
            return(lanes);
        }