Пример #1
0
        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);
        }
Пример #2
0
        private static byte[] FinalHash(Argon2Ctx ctx, int cbOut, Blake2b h)
        {
            ulong[] pqBlockHash = new ulong[NbBlockSizeInQW];
            CopyBlock(pqBlockHash, 0, ctx.Mem, (ctx.LaneLength - 1UL) *
                      NbBlockSizeInQW);
            for (ulong l = 1; l < ctx.Lanes; ++l)
            {
                XorBlock(pqBlockHash, 0, ctx.Mem, (l * ctx.LaneLength +
                                                   ctx.LaneLength - 1UL) * NbBlockSizeInQW);
            }

            byte[] pbBlockHashBytes = new byte[NbBlockSize];
            StoreBlock(pbBlockHashBytes, pqBlockHash);

            byte[] pbOut = new byte[cbOut];
            Blake2bLong(pbOut, cbOut, pbBlockHashBytes, (int)NbBlockSize, h);

            MemUtil.ZeroArray <ulong>(pqBlockHash);
            MemUtil.ZeroByteArray(pbBlockHashBytes);
            return(pbOut);
        }
Пример #3
0
        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();
                    }
                }
            }
        }
Пример #4
0
        private static void FillFirstBlocks(Argon2Ctx ctx, byte[] pbBlockHash,
                                            Blake2b h)
        {
            byte[] pbBlock = new byte[NbBlockSize];

            for (ulong l = 0; l < ctx.Lanes; ++l)
            {
                MemUtil.UInt32ToBytesEx(0, pbBlockHash, NbPreHashDigestLength);
                MemUtil.UInt32ToBytesEx((uint)l, pbBlockHash, NbPreHashDigestLength + 4);

                Blake2bLong(pbBlock, (int)NbBlockSize, pbBlockHash,
                            NbPreHashSeedLength, h);
                LoadBlock(ctx.Mem, l * ctx.LaneLength * NbBlockSizeInQW, pbBlock);

                MemUtil.UInt32ToBytesEx(1, pbBlockHash, NbPreHashDigestLength);

                Blake2bLong(pbBlock, (int)NbBlockSize, pbBlockHash,
                            NbPreHashSeedLength, h);
                LoadBlock(ctx.Mem, (l * ctx.LaneLength + 1UL) * NbBlockSizeInQW, pbBlock);
            }

            MemUtil.ZeroByteArray(pbBlock);
        }
Пример #5
0
        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();
                    }
                }
            }
        }
Пример #6
0
        private static byte[] Argon2d(byte[] pbMsg, byte[] pbSalt, uint uParallel,
                                      ulong uMem, ulong uIt, int cbOut, uint uVersion, byte[] pbSecretKey,
                                      byte[] pbAssocData)
        {
            pbSecretKey = (pbSecretKey ?? MemUtil.EmptyByteArray);
            pbAssocData = (pbAssocData ?? MemUtil.EmptyByteArray);

#if ARGON2_B2ROUND_ARRAYS
            InitB2RoundIndexArrays();
#endif

            Argon2Ctx ctx = new Argon2Ctx();
            ctx.Version = uVersion;

            ctx.Lanes        = uParallel;
            ctx.TCost        = uIt;
            ctx.MCost        = uMem / NbBlockSize;
            ctx.MemoryBlocks = Math.Max(ctx.MCost, 2UL * NbSyncPoints * ctx.Lanes);

            ctx.SegmentLength = ctx.MemoryBlocks / (ctx.Lanes * NbSyncPoints);
            ctx.MemoryBlocks  = ctx.SegmentLength * ctx.Lanes * NbSyncPoints;

            ctx.LaneLength = ctx.SegmentLength * NbSyncPoints;

            Debug.Assert(NbBlockSize == (NbBlockSizeInQW *
#if KeePassUAP
                                         (ulong)Marshal.SizeOf <ulong>()
#else
                                         (ulong)Marshal.SizeOf(typeof(ulong))
#endif
                                         ));
            ctx.Mem = new ulong[ctx.MemoryBlocks * NbBlockSizeInQW];

            Blake2b h = new Blake2b();

            // Initial hash
            Debug.Assert(h.HashSize == (NbPreHashDigestLength * 8));
            byte[] pbBuf = new byte[4];
            MemUtil.UInt32ToBytesEx(uParallel, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx((uint)cbOut, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx((uint)ctx.MCost, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx((uint)uIt, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx(uVersion, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx(0, pbBuf, 0);             // Argon2d type = 0
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            MemUtil.UInt32ToBytesEx((uint)pbMsg.Length, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0);
            MemUtil.UInt32ToBytesEx((uint)pbSalt.Length, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            h.TransformBlock(pbSalt, 0, pbSalt.Length, pbSalt, 0);
            MemUtil.UInt32ToBytesEx((uint)pbSecretKey.Length, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            h.TransformBlock(pbSecretKey, 0, pbSecretKey.Length, pbSecretKey, 0);
            MemUtil.UInt32ToBytesEx((uint)pbAssocData.Length, pbBuf, 0);
            h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
            h.TransformBlock(pbAssocData, 0, pbAssocData.Length, pbAssocData, 0);
            h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
            byte[] pbH0 = h.Hash;
            Debug.Assert(pbH0.Length == 64);

            byte[] pbBlockHash = new byte[NbPreHashSeedLength];
            Array.Copy(pbH0, pbBlockHash, pbH0.Length);
            MemUtil.ZeroByteArray(pbH0);

            FillFirstBlocks(ctx, pbBlockHash, h);
            MemUtil.ZeroByteArray(pbBlockHash);

            FillMemoryBlocks(ctx);

            byte[] pbOut = FinalHash(ctx, cbOut, h);

            h.Clear();
            MemUtil.ZeroArray <ulong>(ctx.Mem);
            return(pbOut);
        }
Пример #7
0
        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); }
        }
Пример #8
0
        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); }
        }
Пример #9
0
		private static byte[] Argon2d(byte[] pbMsg, byte[] pbSalt, uint uParallel,
			ulong uMem, ulong uIt, int cbOut, uint uVersion, byte[] pbSecretKey,
			byte[] pbAssocData)
		{
			pbSecretKey = (pbSecretKey ?? MemUtil.EmptyByteArray);
			pbAssocData = (pbAssocData ?? MemUtil.EmptyByteArray);

#if ARGON2_B2ROUND_ARRAYS
			InitB2RoundIndexArrays();
#endif

			Argon2Ctx ctx = new Argon2Ctx();
			ctx.Version = uVersion;

			ctx.Lanes = uParallel;
			ctx.TCost = uIt;
			ctx.MCost = uMem / NbBlockSize;
			ctx.MemoryBlocks = Math.Max(ctx.MCost, 2UL * NbSyncPoints * ctx.Lanes);

			ctx.SegmentLength = ctx.MemoryBlocks / (ctx.Lanes * NbSyncPoints);
			ctx.MemoryBlocks = ctx.SegmentLength * ctx.Lanes * NbSyncPoints;

			ctx.LaneLength = ctx.SegmentLength * NbSyncPoints;

			Debug.Assert(NbBlockSize == (NbBlockSizeInQW *
#if KeePassUAP
				(ulong)Marshal.SizeOf<ulong>()
#else
				(ulong)Marshal.SizeOf(typeof(ulong))
#endif
				));
			ctx.Mem = new ulong[ctx.MemoryBlocks * NbBlockSizeInQW];

			Blake2b h = new Blake2b();

			// Initial hash
			Debug.Assert(h.HashSize == (NbPreHashDigestLength * 8));
			byte[] pbBuf = new byte[4];
			MemUtil.UInt32ToBytesEx(uParallel, pbBuf, 0);
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			MemUtil.UInt32ToBytesEx((uint)cbOut, pbBuf, 0);
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			MemUtil.UInt32ToBytesEx((uint)ctx.MCost, pbBuf, 0);
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			MemUtil.UInt32ToBytesEx((uint)uIt, pbBuf, 0);
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			MemUtil.UInt32ToBytesEx(uVersion, pbBuf, 0);
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			MemUtil.UInt32ToBytesEx(0, pbBuf, 0); // Argon2d type = 0
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			MemUtil.UInt32ToBytesEx((uint)pbMsg.Length, pbBuf, 0);
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0);
			MemUtil.UInt32ToBytesEx((uint)pbSalt.Length, pbBuf, 0);
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			h.TransformBlock(pbSalt, 0, pbSalt.Length, pbSalt, 0);
			MemUtil.UInt32ToBytesEx((uint)pbSecretKey.Length, pbBuf, 0);
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			h.TransformBlock(pbSecretKey, 0, pbSecretKey.Length, pbSecretKey, 0);
			MemUtil.UInt32ToBytesEx((uint)pbAssocData.Length, pbBuf, 0);
			h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
			h.TransformBlock(pbAssocData, 0, pbAssocData.Length, pbAssocData, 0);
			h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
			byte[] pbH0 = h.Hash;
			Debug.Assert(pbH0.Length == 64);

			byte[] pbBlockHash = new byte[NbPreHashSeedLength];
			Array.Copy(pbH0, pbBlockHash, pbH0.Length);
			MemUtil.ZeroByteArray(pbH0);

			FillFirstBlocks(ctx, pbBlockHash, h);
			MemUtil.ZeroByteArray(pbBlockHash);

			FillMemoryBlocks(ctx);

			byte[] pbOut = FinalHash(ctx, cbOut, h);

			h.Clear();
			MemUtil.ZeroArray<ulong>(ctx.Mem);
			return pbOut;
		}
Пример #10
0
		private static byte[] FinalHash(Argon2Ctx ctx, int cbOut, Blake2b h)
		{
			ulong[] pqBlockHash = new ulong[NbBlockSizeInQW];
			CopyBlock(pqBlockHash, 0, ctx.Mem, (ctx.LaneLength - 1UL) *
				NbBlockSizeInQW);
			for(ulong l = 1; l < ctx.Lanes; ++l)
				XorBlock(pqBlockHash, 0, ctx.Mem, (l * ctx.LaneLength +
					ctx.LaneLength - 1UL) * NbBlockSizeInQW);

			byte[] pbBlockHashBytes = new byte[NbBlockSize];
			StoreBlock(pbBlockHashBytes, pqBlockHash);

			byte[] pbOut = new byte[cbOut];
			Blake2bLong(pbOut, cbOut, pbBlockHashBytes, (int)NbBlockSize, h);

			MemUtil.ZeroArray<ulong>(pqBlockHash);
			MemUtil.ZeroByteArray(pbBlockHashBytes);
			return pbOut;
		}
Пример #11
0
		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();
					}
				}
			}
		}
Пример #12
0
		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);
		}
Пример #13
0
		private static void FillFirstBlocks(Argon2Ctx ctx, byte[] pbBlockHash,
			Blake2b h)
		{
			byte[] pbBlock = new byte[NbBlockSize];

			for(ulong l = 0; l < ctx.Lanes; ++l)
			{
				MemUtil.UInt32ToBytesEx(0, pbBlockHash, NbPreHashDigestLength);
				MemUtil.UInt32ToBytesEx((uint)l, pbBlockHash, NbPreHashDigestLength + 4);

				Blake2bLong(pbBlock, (int)NbBlockSize, pbBlockHash,
					NbPreHashSeedLength, h);
				LoadBlock(ctx.Mem, l * ctx.LaneLength * NbBlockSizeInQW, pbBlock);

				MemUtil.UInt32ToBytesEx(1, pbBlockHash, NbPreHashDigestLength);

				Blake2bLong(pbBlock, (int)NbBlockSize, pbBlockHash,
					NbPreHashSeedLength, h);
				LoadBlock(ctx.Mem, (l * ctx.LaneLength + 1UL) * NbBlockSizeInQW, pbBlock);
			}

			MemUtil.ZeroByteArray(pbBlock);
		}