public static BigInteger[] LucasSequence(BigInteger P, BigInteger Q,
BigInteger k, BigInteger n)
{
if(k.dataLength == 1 && k.data[0] == 0)
{
BigInteger[] result = new BigInteger[3];
result[0] = 0; result[1] = 2 % n; result[2] = 1 % n;
return result;
}
// calculate constant = b^(2k) / m
// for Barrett Reduction
BigInteger constant = new BigInteger();
int nLen = n.dataLength << 1;
constant.data[nLen] = 0x00000001;
constant.dataLength = nLen + 1;
constant = constant / n;
// calculate values of s and t
int s = 0;
for(int index = 0; index < k.dataLength; index++)
{
uint mask = 0x01;
for(int i = 0; i < 32; i++)
{
if((k.data[index] & mask) != 0)
{
index = k.dataLength; // to break the outer loop
break;
}
mask <<= 1;
s++;
}
}
BigInteger t = k >> s;
//Console.WriteLine("s = " + s + " t = " + t);
return LucasSequenceHelper(P, Q, t, n, constant, s);
}