Esempio n. 1
0
	//***********************************************************************
	// Modulo Exponentiation
	//***********************************************************************

	public BigInteger modPow(BigInteger exp, BigInteger n)
	{
		if((exp.data[maxLength-1] & 0x80000000) != 0)
			throw (new ArithmeticException("Positive exponents only."));

		BigInteger resultNum = 1;
		BigInteger tempNum;
		bool thisNegative = false;

		if((this.data[maxLength-1] & 0x80000000) != 0)   // negative this
		{
			tempNum = -this % n;
			thisNegative = true;
		}
		else
			tempNum = this % n;  // ensures (tempNum * tempNum) < b^(2k)

		if((n.data[maxLength-1] & 0x80000000) != 0)   // negative n
			n = -n;

		// calculate constant = b^(2k) / m
		BigInteger constant = new BigInteger();

		int i = n.dataLength << 1;
		constant.data[i] = 0x00000001;
		constant.dataLength = i + 1;

		constant = constant / n;
		int totalBits = exp.bitCount();
		int count = 0;

		// perform squaring and multiply exponentiation
		for(int pos = 0; pos < exp.dataLength; pos++)
		{
			uint mask = 0x01;
			//Console.WriteLine("pos = " + pos);

			for(int index = 0; index < 32; index++)
			{
				if((exp.data[pos] & mask) != 0)
					resultNum = BarrettReduction(resultNum * tempNum, n, constant);

				mask <<= 1;

				tempNum = BarrettReduction(tempNum * tempNum, n, constant);


				if(tempNum.dataLength == 1 && tempNum.data[0] == 1)
				{
					if(thisNegative && (exp.data[0] & 0x1) != 0)    //odd exp
						return -resultNum;
					return resultNum;
				}
				count++;
				if(count == totalBits)
					break;
			}
		}

		if(thisNegative && (exp.data[0] & 0x1) != 0)    //odd exp
			return -resultNum;

		return resultNum;
	}
Esempio n. 2
0
	//***********************************************************************
	// Performs the calculation of the kth term in the Lucas Sequence.
	// For details of the algorithm, see reference [9].
	//
	// k must be odd.  i.e LSB == 1
	//***********************************************************************

	private static BigInteger[] LucasSequenceHelper(BigInteger P, BigInteger Q,
		BigInteger k, BigInteger n,
		BigInteger constant, int s)
	{
		BigInteger[] result = new BigInteger[3];

		if((k.data[0] & 0x00000001) == 0)
			throw (new ArgumentException("Argument k must be odd."));

		int numbits = k.bitCount();
		uint mask = (uint)0x1 << ((numbits & 0x1F) - 1);

		// v = v0, v1 = v1, u1 = u1, Q_k = Q^0

		BigInteger v = 2 % n, Q_k = 1 % n,
			v1 = P % n, u1 = Q_k;
		bool flag = true;

		for(int i = k.dataLength - 1; i >= 0 ; i--)     // iterate on the binary expansion of k
		{
			//Console.WriteLine("round");
			while(mask != 0)
			{
				if(i == 0 && mask == 0x00000001)        // last bit
					break;

				if((k.data[i] & mask) != 0)             // bit is set
				{
					// index doubling with addition

					u1 = (u1 * v1) % n;

					v = ((v * v1) - (P * Q_k)) % n;
					v1 = n.BarrettReduction(v1 * v1, n, constant);
					v1 = (v1 - ((Q_k * Q) << 1)) % n;

					if(flag)
						flag = false;
					else
						Q_k = n.BarrettReduction(Q_k * Q_k, n, constant);

					Q_k = (Q_k * Q) % n;
				}
				else
				{
					// index doubling
					u1 = ((u1 * v) - Q_k) % n;

					v1 = ((v * v1) - (P * Q_k)) % n;
					v = n.BarrettReduction(v * v, n, constant);
					v = (v - (Q_k << 1)) % n;

					if(flag)
					{
						Q_k = Q % n;
						flag = false;
					}
					else
						Q_k = n.BarrettReduction(Q_k * Q_k, n, constant);
				}

				mask >>= 1;
			}
			mask = 0x80000000;
		}

		// at this point u1 = u(n+1) and v = v(n)
		// since the last bit always 1, we need to transform u1 to u(2n+1) and v to v(2n+1)

		u1 = ((u1 * v) - Q_k) % n;
		v = ((v * v1) - (P * Q_k)) % n;
		if(flag)
			flag = false;
		else
			Q_k = n.BarrettReduction(Q_k * Q_k, n, constant);

		Q_k = (Q_k * Q) % n;


		for(int i = 0; i < s; i++)
		{
			// index doubling
			u1 = (u1 * v) % n;
			v = ((v * v) - (Q_k << 1)) % n;

			if(flag)
			{
				Q_k = Q % n;
				flag = false;
			}
			else
				Q_k = n.BarrettReduction(Q_k * Q_k, n, constant);
		}

		result[0] = u1;
		result[1] = v;
		result[2] = Q_k;

		return result;
	}
Esempio n. 3
0
 /**
  * <summary>
  * finde eine sichere große Primzahl p und eine primitive Wurzel g mit den
   	 * angegebenen Parametern
   	 * </summary>
  	 */
 private void generateParameters()
 {
     BigInteger g, p, q;
     int qLength = size - 1;
     // finde eine sichere große Primzahl p durch 2*q + 1, q ist ebenfalls eine Primzahl
     while(true)
     {
         q = new BigInteger();
         q.genRandomBits(qLength,random);
         if (q.bitCount() != qLength)
         {
             continue;
         }
         if (!q.isProbablePrime(certainty))
         {
             continue;
         }
         p = q*(TWO)+(ONE);
         if (p.isProbablePrime(certainty))
         {
             break;
         }
     }
     this.p=p;
     // berechne g durch 2q+1while(true)
     while(true)
     {
         g = new BigInteger();
         g.genRandomBits(qLength, random);
         if (g.modPow(TWO, p).Equals(ONE))
         {
             continue;
         }
         if (g.modPow(q, p).Equals(ONE))
         {
             continue;
         }
         break;
     }
     this.g=g;
 }