private static ulong IndexAlpha(Argon2Ctx ctx, Argon2ThreadInfo ti, uint uPseudoRand, bool bSameLane) { ulong uRefAreaSize; if (ti.Pass == 0) { if (ti.Slice == 0) { Debug.Assert(ti.Index > 0); uRefAreaSize = ti.Index - 1UL; } else { if (bSameLane) { uRefAreaSize = ti.Slice * ctx.SegmentLength + ti.Index - 1UL; } else { uRefAreaSize = ti.Slice * ctx.SegmentLength - ((ti.Index == 0UL) ? 1UL : 0UL); } } } else { if (bSameLane) { uRefAreaSize = ctx.LaneLength - ctx.SegmentLength + ti.Index - 1UL; } else { uRefAreaSize = ctx.LaneLength - ctx.SegmentLength - ((ti.Index == 0) ? 1UL : 0UL); } } Debug.Assert(uRefAreaSize <= (ulong)uint.MaxValue); ulong uRelPos = uPseudoRand; uRelPos = (uRelPos * uRelPos) >> 32; uRelPos = uRefAreaSize - 1UL - ((uRefAreaSize * uRelPos) >> 32); ulong uStart = 0; if (ti.Pass != 0) { uStart = (((ti.Slice + 1UL) == NbSyncPoints) ? 0UL : ((ti.Slice + 1UL) * ctx.SegmentLength)); } Debug.Assert(uStart <= (ulong)uint.MaxValue); Debug.Assert(ctx.LaneLength <= (ulong)uint.MaxValue); return((uStart + uRelPos) % ctx.LaneLength); }
private static void FillMemoryBlocks(Argon2Ctx ctx) { int np = (int)ctx.Lanes; Argon2ThreadInfo[] v = new Argon2ThreadInfo[np]; for (ulong r = 0; r < ctx.TCost; ++r) { for (ulong s = 0; s < NbSyncPoints; ++s) { for (int l = 0; l < np; ++l) { Argon2ThreadInfo ti = new Argon2ThreadInfo(); ti.Context = ctx; ti.Pass = r; ti.Lane = (ulong)l; ti.Slice = s; #if ModernKeePassLib Task.Factory.StartNew(FillSegmentThr, ti); //ThreadPool.RunAsync(a => FillSegmentThr(ti)); #else if (!ThreadPool.QueueUserWorkItem(FillSegmentThr, ti)) { Debug.Assert(false); throw new OutOfMemoryException(); } #endif v[l] = ti; } for (int l = 0; l < np; ++l) { v[l].Finished.WaitOne(); v[l].Release(); } } } }
private static void FillMemoryBlocks(Argon2Ctx ctx) { int np = (int)ctx.Lanes; Argon2ThreadInfo[] v = new Argon2ThreadInfo[np]; for (ulong r = 0; r < ctx.TCost; ++r) { for (ulong s = 0; s < NbSyncPoints; ++s) { for (int l = 0; l < np; ++l) { Argon2ThreadInfo ti = new Argon2ThreadInfo(); ti.Context = ctx; ti.Pass = r; ti.Lane = (ulong)l; ti.Slice = s; if (!ThreadUtil.Schedule(FillSegmentThr, ti)) { Debug.Assert(false); throw new OutOfMemoryException(); } v[l] = ti; } for (int l = 0; l < np; ++l) { v[l].Finished.WaitOne(); v[l].Release(); } } } }
private static void FillSegmentThr(object o) { Argon2ThreadInfo ti = (o as Argon2ThreadInfo); if (ti == null) { Debug.Assert(false); return; } try { Argon2Ctx ctx = ti.Context; if (ctx == null) { Debug.Assert(false); return; } Debug.Assert(ctx.Version >= MinVersion); bool bCanXor = (ctx.Version >= 0x13U); ulong uStart = 0; if ((ti.Pass == 0) && (ti.Slice == 0)) { uStart = 2; } ulong uCur = (ti.Lane * ctx.LaneLength) + (ti.Slice * ctx.SegmentLength) + uStart; ulong uPrev = (((uCur % ctx.LaneLength) == 0) ? (uCur + ctx.LaneLength - 1UL) : (uCur - 1UL)); ulong[] pbR = new ulong[NbBlockSizeInQW]; ulong[] pbTmp = new ulong[NbBlockSizeInQW]; for (ulong i = uStart; i < ctx.SegmentLength; ++i) { if ((uCur % ctx.LaneLength) == 1) { uPrev = uCur - 1UL; } ulong uPseudoRand = ctx.Mem[uPrev * NbBlockSizeInQW]; ulong uRefLane = (uPseudoRand >> 32) % ctx.Lanes; if ((ti.Pass == 0) && (ti.Slice == 0)) { uRefLane = ti.Lane; } ti.Index = i; ulong uRefIndex = IndexAlpha(ctx, ti, (uint)uPseudoRand, (uRefLane == ti.Lane)); ulong uRefBlockIndex = (ctx.LaneLength * uRefLane + uRefIndex) * NbBlockSizeInQW; ulong uCurBlockIndex = uCur * NbBlockSizeInQW; FillBlock(ctx.Mem, uPrev * NbBlockSizeInQW, uRefBlockIndex, uCurBlockIndex, ((ti.Pass != 0) && bCanXor), pbR, pbTmp); ++uCur; ++uPrev; } MemUtil.ZeroArray <ulong>(pbR); MemUtil.ZeroArray <ulong>(pbTmp); } catch (Exception) { Debug.Assert(false); } try { ti.Finished.Set(); } catch (Exception) { Debug.Assert(false); } }
private static void FillSegmentThr(object o) { Argon2ThreadInfo ti = (o as Argon2ThreadInfo); if (ti == null) { Debug.Assert(false); return; } try { Argon2Ctx ctx = ti.Context; if (ctx == null) { Debug.Assert(false); return; } Debug.Assert(ctx.Version >= MinVersion); bool bCanXor = (ctx.Version >= 0x13U); ulong[] pbR = new ulong[NbBlockSizeInQW]; ulong[] pbTmp = new ulong[NbBlockSizeInQW]; ulong[] pbAddrInputZero = null; bool bDataIndependentAddr = ((ctx.Type == Argon2Type.ID) && (ti.Pass == 0) && (ti.Slice < (NbSyncPoints / 2))); if (bDataIndependentAddr) { pbAddrInputZero = new ulong[NbBlockSizeInQW * 3]; const int iInput = (int)NbBlockSizeInQW; pbAddrInputZero[iInput] = ti.Pass; pbAddrInputZero[iInput + 1] = ti.Lane; pbAddrInputZero[iInput + 2] = ti.Slice; pbAddrInputZero[iInput + 3] = ctx.MemoryBlocks; pbAddrInputZero[iInput + 4] = ctx.TCost; pbAddrInputZero[iInput + 5] = (ulong)ctx.Type; } ulong uStart = 0; if ((ti.Pass == 0) && (ti.Slice == 0)) { uStart = 2; if (bDataIndependentAddr) { NextAddresses(pbAddrInputZero, pbR, pbTmp); } } ulong uCur = (ti.Lane * ctx.LaneLength) + (ti.Slice * ctx.SegmentLength) + uStart; ulong uPrev = (((uCur % ctx.LaneLength) == 0) ? (uCur + ctx.LaneLength - 1UL) : (uCur - 1UL)); for (ulong i = uStart; i < ctx.SegmentLength; ++i) { if ((uCur % ctx.LaneLength) == 1) { uPrev = uCur - 1UL; } ulong uPseudoRand; if (bDataIndependentAddr) { ulong iMod = i % NbAddressesInBlock; if (iMod == 0) { NextAddresses(pbAddrInputZero, pbR, pbTmp); } uPseudoRand = pbAddrInputZero[iMod]; } else { uPseudoRand = ctx.Mem[uPrev * NbBlockSizeInQW]; } ulong uRefLane = (uPseudoRand >> 32) % ctx.Lanes; if ((ti.Pass == 0) && (ti.Slice == 0)) { uRefLane = ti.Lane; } ti.Index = i; ulong uRefIndex = IndexAlpha(ctx, ti, (uint)uPseudoRand, (uRefLane == ti.Lane)); ulong uRefBlockIndex = (ctx.LaneLength * uRefLane + uRefIndex) * NbBlockSizeInQW; ulong uCurBlockIndex = uCur * NbBlockSizeInQW; FillBlock(ctx.Mem, uPrev * NbBlockSizeInQW, uRefBlockIndex, uCurBlockIndex, ((ti.Pass != 0) && bCanXor), pbR, pbTmp); ++uCur; ++uPrev; } MemUtil.ZeroArray <ulong>(pbR); MemUtil.ZeroArray <ulong>(pbTmp); if (pbAddrInputZero != null) { MemUtil.ZeroArray <ulong>(pbAddrInputZero); } } catch (Exception) { Debug.Assert(false); } try { ti.Finished.Set(); } catch (Exception) { Debug.Assert(false); } }
private static void FillMemoryBlocks(Argon2Ctx ctx) { int np = (int)ctx.Lanes; Argon2ThreadInfo[] v = new Argon2ThreadInfo[np]; for(ulong r = 0; r < ctx.TCost; ++r) { for(ulong s = 0; s < NbSyncPoints; ++s) { for(int l = 0; l < np; ++l) { Argon2ThreadInfo ti = new Argon2ThreadInfo(); ti.Context = ctx; ti.Pass = r; ti.Lane = (ulong)l; ti.Slice = s; if(!ThreadPool.QueueUserWorkItem(FillSegmentThr, ti)) { Debug.Assert(false); throw new OutOfMemoryException(); } v[l] = ti; } for(int l = 0; l < np; ++l) { v[l].Finished.WaitOne(); v[l].Release(); } } } }
private static ulong IndexAlpha(Argon2Ctx ctx, Argon2ThreadInfo ti, uint uPseudoRand, bool bSameLane) { ulong uRefAreaSize; if(ti.Pass == 0) { if(ti.Slice == 0) { Debug.Assert(ti.Index > 0); uRefAreaSize = ti.Index - 1UL; } else { if(bSameLane) uRefAreaSize = ti.Slice * ctx.SegmentLength + ti.Index - 1UL; else uRefAreaSize = ti.Slice * ctx.SegmentLength - ((ti.Index == 0UL) ? 1UL : 0UL); } } else { if(bSameLane) uRefAreaSize = ctx.LaneLength - ctx.SegmentLength + ti.Index - 1UL; else uRefAreaSize = ctx.LaneLength - ctx.SegmentLength - ((ti.Index == 0) ? 1UL : 0UL); } Debug.Assert(uRefAreaSize <= (ulong)uint.MaxValue); ulong uRelPos = uPseudoRand; uRelPos = (uRelPos * uRelPos) >> 32; uRelPos = uRefAreaSize - 1UL - ((uRefAreaSize * uRelPos) >> 32); ulong uStart = 0; if(ti.Pass != 0) uStart = (((ti.Slice + 1UL) == NbSyncPoints) ? 0UL : ((ti.Slice + 1UL) * ctx.SegmentLength)); Debug.Assert(uStart <= (ulong)uint.MaxValue); Debug.Assert(ctx.LaneLength <= (ulong)uint.MaxValue); return ((uStart + uRelPos) % ctx.LaneLength); }