// 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; } }
private static void XorLanes(Argon2Lane[] lanes) { Argon2Memory data = lanes[0][lanes[0].BlockCount - 1]; foreach (Argon2Lane lane in lanes.Skip(1)) { Argon2Memory block = lane[lane.BlockCount - 1]; for (int b = 0; b < 128; ++b) { if (!BitConverter.IsLittleEndian) { block[b] = (block[b] >> 56) ^ ((block[b] >> 40) & 0xff00UL) ^ ((block[b] >> 24) & 0xff0000UL) ^ ((block[b] >> 8) & 0xff000000UL) ^ ((block[b] << 8) & 0xff00000000UL) ^ ((block[b] << 24) & 0xff0000000000UL) ^ ((block[b] << 40) & 0xff000000000000UL) ^ ((block[b] << 56) & 0xff00000000000000UL); } data[b] ^= block[b]; } } }
public void Expose(Argon2Memory memory) { if (memory != null) { byte[] buff = new byte[0x80 * 8]; memory.GetBuffer(buff); Expose(buff); } }
private byte[] Finalize(Argon2Lane[] lanes) { XorLanes(lanes); LittleEndianActiveStream ds = new LittleEndianActiveStream(); ds.Expose(lanes[0][lanes[0].BlockCount - 1]); ModifiedBlake2.Blake2Prime(lanes[0][1], ds, TagLine); byte[] result = new byte[TagLine]; Argon2Memory memory = lanes[0][1]; memory.GetBuffer(result); return(result); }
internal static void Compress(Argon2Memory dest, Argon2Memory refb, Argon2Memory prev) { ulong[] tmpblock = new ulong[dest.Length]; for (int n = 0; n < 128; ++n) { tmpblock[n] = refb[n] ^ prev[n]; dest[n] ^= tmpblock[n]; } for (int i = 0; i < 8; ++i) { ModifiedBlake2.DoRoundColumns(tmpblock, i); } for (int i = 0; i < 8; ++i) { ModifiedBlake2.DoRoundRows(tmpblock, i); } for (int n = 0; n < 128; ++n) { dest[n] ^= tmpblock[n]; } }