//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Convertations //Format the polyValue to the classic polynom-looking string (x^a + x^b + ...) public static string ToPolyString(this BigInteger num) { StringBuilder bld = new StringBuilder(); //Go thru given num and check for the bit set, and format the string for each iteration for (int i = num.GetBitLength(); i >= 0; i--) { if (num.CheckBit(i)) { if (bld.Length > 0) { bld.Append(" + "); } bld.Append((i > 0) ? "x" : "1"); if (i > 1) { bld.Append("^"); bld.Append(i); } } } if (bld.Length == 0) { bld.Append("0"); } return(bld.ToString()); }
//Operator *. Represents multiplication of two finite field polynoms using modified AncientEgyptian/Russian peasant multiplication method. //It decomposes one of the multiplicands (preferably the smaller) into a sum of powers of two and creates a table of doublings //of the second multiplicand. This method may be called mediation and duplation, where mediation means halving one number, //and duplation means doubling the other number. public static FFPolynom operator *(FFPolynom left, FFPolynom right) { //Invariant is (b * a + p) is product. Continue to 2*a and taking b/2. //If b is odd number => calculate a + p BigInteger a = left._polynomCoefficients; BigInteger b = right._polynomCoefficients; BigInteger product = BigInteger.Zero; //p //Degree is a length of the entered phrase in bytes * 8 int degree = left.PrimePolynom.Degree; //Shift a BigInt value a specified number of bits to the left (preserves the sign) //"BigInteger.One << degree" means 1 * 2^degree //- BigInteger.One means to invert all bits // 2^degree -1 => length in bits w/o sign BigInteger mask = (BigInteger.One << degree) - BigInteger.One; for (int i = 0; i < degree; i++) { if ((a == BigInteger.Zero) || (b == BigInteger.Zero)) { break; } //Take lowest bit of b, and check if it set meaning b is odd if (b.CheckBit(0)) { //b odd, do a + product product = product ^ a; } //Check if the highest bit set for a bool isHighBitSet = a.CheckBit(degree - 1); a = a << 1; // a*2 a = a & mask; // remove the highest bit if (isHighBitSet) { a = a ^ left.PrimePolynom.PolynomValue; a = a & mask; } b = b >> 1; // b/2 } product = product & mask; return(new FFPolynom(left.PrimePolynom, product)); }