Org.BouncyCastle.Math.EC.FpFieldElement.fastLucasSequence C# (CSharp) Method

fastLucasSequence() private static method

private static fastLucasSequence ( BigInteger p, BigInteger P, BigInteger Q, BigInteger k ) : BigInteger[]
p BigInteger
P BigInteger
Q BigInteger
k BigInteger
return BigInteger[]
		private static BigInteger[] fastLucasSequence(
			BigInteger	p,
			BigInteger	P,
			BigInteger	Q,
			BigInteger	k)
		{
			// TODO Research and apply "common-multiplicand multiplication here"

			int n = k.BitLength;
			int s = k.GetLowestSetBit();

			Debug.Assert(k.TestBit(s));

			BigInteger Uh = BigInteger.One;
			BigInteger Vl = BigInteger.Two;
			BigInteger Vh = P;
			BigInteger Ql = BigInteger.One;
			BigInteger Qh = BigInteger.One;

			for (int j = n - 1; j >= s + 1; --j)
			{
				Ql = Ql.Multiply(Qh).Mod(p);

				if (k.TestBit(j))
				{
					Qh = Ql.Multiply(Q).Mod(p);
					Uh = Uh.Multiply(Vh).Mod(p);
					Vl = Vh.Multiply(Vl).Subtract(P.Multiply(Ql)).Mod(p);
					Vh = Vh.Multiply(Vh).Subtract(Qh.ShiftLeft(1)).Mod(p);
				}
				else
				{
					Qh = Ql;
					Uh = Uh.Multiply(Vl).Subtract(Ql).Mod(p);
					Vh = Vh.Multiply(Vl).Subtract(P.Multiply(Ql)).Mod(p);
					Vl = Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)).Mod(p);
				}
			}

			Ql = Ql.Multiply(Qh).Mod(p);
			Qh = Ql.Multiply(Q).Mod(p);
			Uh = Uh.Multiply(Vl).Subtract(Ql).Mod(p);
			Vl = Vh.Multiply(Vl).Subtract(P.Multiply(Ql)).Mod(p);
			Ql = Ql.Multiply(Qh).Mod(p);

			for (int j = 1; j <= s; ++j)
			{
				Uh = Uh.Multiply(Vl).Mod(p);
				Vl = Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)).Mod(p);
				Ql = Ql.Multiply(Ql).Mod(p);
			}

			return new BigInteger[]{ Uh, Vl };
		}