// 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; } }
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); }