//*********************************************************************** // 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 var constant = new BigInteger(0); int i = n.Length << 1; constant.Data[i] = 0x00000001; constant.Length = i + 1; constant.Divide(n); //constant /= n; int totalBits = exp.bitCount(); int count = 0; var temp = new BigInteger(0); // perform squaring and multiply exponentiation for (var pos = 0; pos < exp.Length; pos++) { uint mask = 0x01; //Console.WriteLine("pos = " + pos); for (var index = 0; index < 32; index++) { if ((exp.Data[pos] & mask) != 0) { BarrettReduction(ref resultNum, tempNum, n, constant, ref temp); } mask <<= 1; BarrettReduction(ref tempNum, tempNum, n, constant, ref temp); if (tempNum.Length == 1 && tempNum.Data[0] == 1) { if (thisNegative && (exp.Data[0] & 0x1) != 0) //odd exp { resultNum.Negative(); } return(resultNum); } count++; if (count == totalBits) { break; } } } constant.Recycle(); temp.Recycle(); if (thisNegative && (exp.Data[0] & 0x1) != 0) //odd exp { resultNum.Negative(); } return(resultNum); }
//*********************************************************************** // 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 var constant = new BigInteger(0); int i = n.Length << 1; constant.Data[i] = 0x00000001; constant.Length = i + 1; constant.Divide(n); //constant /= n; int totalBits = exp.bitCount(); int count = 0; var temp = new BigInteger(0); // perform squaring and multiply exponentiation for(var pos = 0; pos < exp.Length; pos++) { uint mask = 0x01; //Console.WriteLine("pos = " + pos); for(var index = 0; index < 32; index++) { if ((exp.Data[pos] & mask) != 0) { BarrettReduction(ref resultNum, tempNum, n, constant, ref temp); } mask <<= 1; BarrettReduction(ref tempNum, tempNum, n, constant, ref temp); if(tempNum.Length == 1 && tempNum.Data[0] == 1) { if(thisNegative && (exp.Data[0] & 0x1) != 0) //odd exp resultNum.Negative(); return resultNum; } count++; if(count == totalBits) break; } } constant.Recycle(); temp.Recycle(); if(thisNegative && (exp.Data[0] & 0x1) != 0) //odd exp resultNum.Negative(); return resultNum; }