Org.BouncyCastle.Math.BigInteger.MultiplyMonty C# (CSharp) Method

MultiplyMonty() private static method

private static MultiplyMonty ( int a, int x, int y, int m, long mQuote ) : void
a int
x int
y int
m int
mQuote long
return void
		private static void MultiplyMonty(
			int[]	a,
			int[]	x,
			int[]	y,
			int[]	m,
			long	mQuote)
			// mQuote = -m^(-1) mod b
		{
			if (m.Length == 1)
			{
				x[0] = (int)MultiplyMontyNIsOne((uint)x[0], (uint)y[0], (uint)m[0], (ulong)mQuote);
				return;
			}

			int n = m.Length;
			int nMinus1 = n - 1;
			long y_0 = y[nMinus1] & IMASK;

			// 1. a = 0 (Notation: a = (a_{n} a_{n-1} ... a_{0})_{b} )
			Array.Clear(a, 0, n + 1);

			// 2. for i from 0 to (n - 1) do the following:
			for (int i = n; i > 0; i--)
			{
				long x_i = x[i - 1] & IMASK;

				// 2.1 u = ((a[0] + (x[i] * y[0]) * mQuote) mod b
				long u = ((((a[n] & IMASK) + ((x_i * y_0) & IMASK)) & IMASK) * mQuote) & IMASK;

				// 2.2 a = (a + x_i * y + u * m) / b
				long prod1 = x_i * y_0;
				long prod2 = u * (m[nMinus1] & IMASK);
				long tmp = (a[n] & IMASK) + (prod1 & IMASK) + (prod2 & IMASK);
				long carry = (long)((ulong)prod1 >> 32) + (long)((ulong)prod2 >> 32) + (long)((ulong)tmp >> 32);
				for (int j = nMinus1; j > 0; j--)
				{
					prod1 = x_i * (y[j - 1] & IMASK);
					prod2 = u * (m[j - 1] & IMASK);
					tmp = (a[j] & IMASK) + (prod1 & IMASK) + (prod2 & IMASK) + (carry & IMASK);
					carry = (long)((ulong)carry >> 32) + (long)((ulong)prod1 >> 32) +
						(long)((ulong)prod2 >> 32) + (long)((ulong)tmp >> 32);
					a[j + 1] = (int)tmp; // division by b
				}
				carry += (a[0] & IMASK);
				a[1] = (int)carry;
				a[0] = (int)((ulong)carry >> 32); // OJO!!!!!
			}

			// 3. if x >= m the x = x - m
			if (CompareTo(0, a, 0, m) >= 0)
			{
				Subtract(0, a, 0, m);
			}

			// put the result in x
			Array.Copy(a, 1, x, 0, n);
		}