public void Set(BigNum bigNum) { m1MSBLocation = bigNum.m1MSBLocation; //mBinaryNumber = bigNum.mBinaryNumber; for (int i = 0; i < GlobalVariables.MAX_NUM; ++i) { mBinaryNumber[i] = bigNum.mBinaryNumber[i]; } }
/// <summary> /// I. /// Gets BigNum type and substract between the current value of the binary number with the given one. /// Let do substraction A = A-B. We know that A-B = A + (-B). /// Calculating -B: Doing complement and then add 1. /// </summary> /// <param name="numberToSubtract"></param> public void SubNum(BigNum numberToSubtract) { // numberToSubstract = B. BigNum modifiedNumberToSubtract = new BigNum(numberToSubtract); modifiedNumberToSubtract.Complement(); // numberToSubtract = -B - 1. modifiedNumberToSubtract.AddNum(GlobalVariables.one); // numberToSubtract = -B. AddNum(modifiedNumberToSubtract); // Allready updates <mMSB1Location>. UpdateMSB1Location(); }
public static void PrintNumberInPowersOfTwo(BigNum num) { List <int> positionsOf1s = num.WriteNum1sPosition(); for (int i = 0; i < positionsOf1s.Count - 1; ++i) { Console.Write($"2^{GlobalVariables.MAX_NUM - positionsOf1s[i] - 1} + "); } Console.WriteLine($"2^{GlobalVariables.MAX_NUM - positionsOf1s[positionsOf1s.Count - 1] - 1}"); }
public static void F() { Console.WriteLine("(F) Using ShiftLeft method."); Console.WriteLine("Multiply 25 by 2."); BigNum bigNumF = new BigNum(25L); bigNumF.ShiftLeft(); Console.WriteLine(bigNumF.WriteNum()); Console.WriteLine(); }
public BigNum(BigNum bigNum) { mBinaryNumber = new int[GlobalVariables.MAX_NUM]; for (int i = 0; i < GlobalVariables.MAX_NUM; ++i) { mBinaryNumber[i] = bigNum.mBinaryNumber[i]; } m1MSBLocation = bigNum.m1MSBLocation; }
public static void E() { Console.WriteLine("(E) Using AddNum method."); Console.WriteLine("8 + 13 = 21."); BigNum bigNumE1 = new BigNum(8L); BigNum bigNumE2 = new BigNum(13L); bigNumE1.AddNum(bigNumE2); Console.WriteLine(bigNumE1.WriteNum()); Console.WriteLine(); }
public static void MSB1LocationTest() { Console.WriteLine("Creating new BigNum type number."); BigNum bigNum = new BigNum(); for (int i = 0; i < GlobalVariables.MAX_NUM; ++i) { Console.Write(bigNum[i]); } Console.WriteLine($"The first 1' digit is in position: {bigNum.MSB1Location}"); Console.WriteLine(); }
public static void C() { Console.WriteLine("(C) Using LongToBig method."); Console.WriteLine("Creating number with long 35."); BigNum bigNumC1 = new BigNum(35L); Console.WriteLine(bigNumC1.WriteNum()); Console.WriteLine("Creating number with long 9223372036854775807 (max value of long)."); BigNum bigNumC2 = new BigNum(9223372036854775807L); Console.WriteLine(bigNumC2.WriteNum()); Console.WriteLine(); }
public static void IIA() { Console.WriteLine("I."); Console.WriteLine("Calculating 1233456897 ^ 8001 mod 1783369431"); BigNum num = new BigNum(1233456897); BigNum power = new BigNum(8001); BigNum mod = new BigNum(1783369431); BigNum result = new BigNum(); result = MathOps.Power(num, power, mod); Console.WriteLine(result.DecimalValue); Console.WriteLine(); }
public static void J() { Console.WriteLine("(I) Using DivNum method."); Console.WriteLine("257 / 13 ==> result = 19, reminder 10."); BigNum divided = new BigNum(257L); BigNum divider = new BigNum(13L); BigNum quitient = new BigNum(); BigNum reminder = new BigNum(); MathOps.DivNum(divided, divider, quitient, reminder); Console.WriteLine($"Quitient is: {quitient.WriteNum()}, Reminder is: {reminder.WriteNum()}."); Console.WriteLine(); }
/// <summary> /// L. /// Gets two BigNums, calculates the opposite number of a in mod m. ([a^-1][mod m]). /// Returns null if the a does not have an inverse mode m. (i.e: gcd(a, m) != 1). /// </summary> /// <param name="a"></param> /// <param name="m"></param> public static BigNum Inverse(BigNum a, BigNum m) { BigNum inverse = null; BigNum x = new BigNum(); BigNum y = new BigNum(); BigNum d = new BigNum(); // d will be gcd(a, m). ExtendedGCD(a, m, x, y, d); if (d.CompNumWithoutPrint(GlobalVariables.one)) { inverse = y; } return(inverse); }
private bool IsBigNumFitsIntoLongType(BigNum num) { bool isBigNumFitsIntoLongType; if (m1MSBLocation.HasValue) { isBigNumFitsIntoLongType = (GlobalVariables.MAX_NUM - num.m1MSBLocation.Value <= GlobalVariables.MaxNumberOfDigitsInLongType); } else // It means that num is zero. { isBigNumFitsIntoLongType = true; } return(isBigNumFitsIntoLongType); }
/// <summary> /// G. /// Every number can be represented as 2N or 2N+1, when N is even and natural number. /// Converts <numberToMult> into long and into representation of 2N or 2N+1. /// Then doing N times ShiftLeft() method, If the number is 2N+1, adding one time the initial value /// of this instance. /// Or /// Let the current value of this intance be <value>. /// If <numberToMult[i]> == 0 then mult by 2 (ShiftLeft() method). /// If <numberToMult[i]> == 1 then mult by 2 (ShiftLeft() method) and adds <value>. /// </summary> /// <param name="numberToMult"></param> public void MultNum(BigNum numberToMult) { BigNum valueToAdd = new BigNum(this); InitializeToZero(); for (int i = GlobalVariables.MAX_NUM - 1; i >= numberToMult.m1MSBLocation; --i) { if (numberToMult[i] == 1) { AddNum(valueToAdd); } valueToAdd.ShiftLeft(); } UpdateMSB1Location(); }
/// <summary> /// Gets a number m. /// Finds p >= 0 and k (k is odd), where m = 2^p * k. /// Return p and k by ref. /// /// p = 0; /// if (!IsEven(m)) /// { /// k = m; /// } /// else // m is even. /// { /// while(IsEven(m)) /// { /// m /= 2; /// p++; /// } /// k = m; /// } /// </summary> /// <param name=""></param> /// <param name=""></param> public static void FindExpressionOfGivenNumberByPowerOfTwoTimesOddNumber(BigNum m, BigNum p, BigNum k) { if (!m.IsEven()) { k.Set(m); } else { while (m.IsEven()) { DivNum(m, GlobalVariables.two, m, new BigNum()); p.AddNum(GlobalVariables.one); } k.Set(m); } }
public static void N() { Console.WriteLine("(N) Using IsPrime method."); Console.WriteLine("Checking if 7, 513, 9973, 2147483647. We should get: true, false, true, true."); BigNum n1 = new BigNum(7); BigNum n2 = new BigNum(513); BigNum n3 = new BigNum(9973); BigNum eightMarsenNumber = new BigNum(2147483647); int k = 20; Console.WriteLine(MathOps.IsPrime(n1, k).ToString()); Console.WriteLine(MathOps.IsPrime(n2, k).ToString()); Console.WriteLine(MathOps.IsPrime(n3, k).ToString()); Console.WriteLine(MathOps.IsPrime(eightMarsenNumber, k).ToString()); Console.WriteLine(); }
/// <summary> /// K. /// Gets two BigNum type numbers a and m and returns by reference (d, x, y), also BigNum type numbers. /// d represents GCD(m,a). (Greatest common divider). /// Note: If d = 1, it means that x is the opposite number of m(mod a) and /// y is the opposite number of a(mod m). /// Proofe for Note: 1 = [m*x + a*y](mod m) ==> 1 = a*y. /// </summary> /// <param name="a"></param> /// <param name="m"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="d"></param> public static void ExtendedGCD(BigNum a, BigNum m, BigNum x, BigNum y, BigNum d) { BigNum r0 = new BigNum(m); BigNum x0 = new BigNum(GlobalVariables.one); BigNum y0 = new BigNum(GlobalVariables.zero); BigNum r1 = new BigNum(a); BigNum x1 = new BigNum(GlobalVariables.zero); BigNum y1 = new BigNum(GlobalVariables.one); BigNum r = new BigNum(GlobalVariables.one); // Just to be able to enter the while loop. BigNum q = new BigNum(); DivNum(r0, r1, q, r); while (!r.CompNumWithoutPrint(GlobalVariables.zero)) { // x = x0 - qx1. BigNum qx1 = new BigNum(q); qx1.MultNum(x1); x.Set(x0); x.SubNum(qx1); // y = y0 - qy1. BigNum qy1 = new BigNum(q); qy1.MultNum(y1); y.Set(y0); y.SubNum(qy1); r0.Set(r1); x0.Set(x1); y0.Set(y1); r1.Set(r); x1.Set(x); y1.Set(y); DivNum(r0, r1, q, r); } d.Set(r1); x.Set(x1); y.Set(y1); }
/// <summary> /// E. /// Gets BigNum type and adds it into this instance. /// Uses <carry> of type BigNum to implement the binary adding. /// Let do summing B = A + B when a[i] is the i'th digit of A. C is the carry. /// If a[i] + c[i] == 0, b[i] does not changes. /// If a[i] + c[i] == 1, b[i] changes it's value and c[i-1] gets 1. /// If a[i] + c[i] == 2, b[i] does not changes and c[i-1] gets 1. /// </summary> /// <param name="numberToAdd"></param> public void AddNum(BigNum numberToAdd) { BigNum carry = new BigNum(); // <carry> = 00..0. for (int i = GlobalVariables.MAX_NUM - 1; i > 0; --i) { if (numberToAdd[i] + carry[i] == 1) { if (mBinaryNumber[i] == 0) { mBinaryNumber[i] = 1; } else { mBinaryNumber[i] = 0; carry[i - 1] = 1; } } else if (numberToAdd[i] + carry[i] == 2) { carry[i - 1] = 1; } } // Handles i == 0. if (numberToAdd[0] + carry[0] == 1) { if (mBinaryNumber[0] == 0) { mBinaryNumber[0] = 1; } else { mBinaryNumber[0] = 0; // Console.WriteLine("There is an overflow. Carry 1 is dropped."); } } else if (numberToAdd[0] + carry[0] == 2) { // Console.WriteLine("There is an overflow. Carry 1 is dropped."); } UpdateMSB1Location(); }
public static void G() { Console.WriteLine("(G) Using MultNum method."); Console.WriteLine("Multiply 7 by 3. Equals 21 (10101 in base 2)"); BigNum bigNumG1 = new BigNum(7L); BigNum bigNumG2 = new BigNum(3L); bigNumG1.MultNum(bigNumG2); Console.WriteLine(bigNumG1.WriteNum()); Console.WriteLine("Multiply 113 by 73. Equals 8249 (10000000111001 in base 2)"); BigNum bigNumG3 = new BigNum(113L); BigNum bigNumG4 = new BigNum(73L); bigNumG3.MultNum(bigNumG4); Console.WriteLine(bigNumG3.WriteNum()); Console.WriteLine(); }
/// <summary> /// Gets BigNum type number and an index. /// Returns the sub number if the number by the index. /// Example: number = 0..001101101 (length of 400 bits), index = 398. /// The returned number will be 0..000110110. /// </summary> /// <param name="divided"></param> /// <param name="indexPos"></param> /// <returns></returns> public static BigNum GetSubBigNumFromLeftToIndex(BigNum divided, int indexPos) { BigNum bigNumFromLeftToIndex = new BigNum(); List <int> positionsOf1s = new List <int>(); int initialIndexPos = indexPos; while (indexPos >= divided.MSB1Location) { if (divided[indexPos] == 1) { positionsOf1s.Add(GlobalVariables.MAX_NUM - (initialIndexPos - indexPos) - 1); } indexPos--; } bigNumFromLeftToIndex.ReadNum(positionsOf1s); return(bigNumFromLeftToIndex); }
public static void I() { Console.WriteLine("(I) Using SubNum method."); Console.WriteLine("18 - 5 = 13"); BigNum bigNumI1 = new BigNum(18L); BigNum bigNumI2 = new BigNum(5L); bigNumI1.SubNum(bigNumI2); Console.WriteLine(bigNumI1.WriteNum()); Console.WriteLine("375683 - 12345 = 363338 (1011000101101001010 in binary.)"); BigNum bigNumI3 = new BigNum(375683L); BigNum bigNumI4 = new BigNum(12345L); bigNumI3.SubNum(bigNumI4); Console.WriteLine(bigNumI3.WriteNum()); Console.WriteLine(); }
public static void M() { Console.WriteLine("(M) Using Power method."); Console.WriteLine("Calculating 30^14 mod 7 = 4."); BigNum x = new BigNum(30); BigNum power = new BigNum(14); BigNum mod = new BigNum(7); Console.WriteLine(MathOps.Power(x, power, mod).DecimalValue); Console.WriteLine("Calculating 130^27 mod 41 = 24."); BigNum x2 = new BigNum(130); BigNum power2 = new BigNum(27); BigNum mod2 = new BigNum(41); Console.WriteLine(MathOps.Power(x2, power2, mod2).DecimalValue); Console.WriteLine(); }
/// <summary> /// H. /// Gets another BigNum type number and compare between the two. /// </summary> /// <returns></returns> public bool CompNum(BigNum numberToCompare) { bool isEqual = true; bool isFinishCompare = false; if ((!m1MSBLocation.HasValue) && (!numberToCompare.m1MSBLocation.HasValue)) { // That means that they both equal to zero. isFinishCompare = true; } else if (((m1MSBLocation.HasValue) && (!numberToCompare.m1MSBLocation.HasValue)) || ((!m1MSBLocation.HasValue) && (numberToCompare.m1MSBLocation.HasValue))) { // That means that one is zero and other is not. isEqual = false; isFinishCompare = true; } if (!isFinishCompare) { for (int i = m1MSBLocation.Value; i < GlobalVariables.MAX_NUM; ++i) { if (mBinaryNumber[i] != numberToCompare.mBinaryNumber[i]) { isEqual = false; break; } } } if (isEqual) { Console.WriteLine("The numbers are equal."); } else { Console.WriteLine("The numbers are NOT equal."); } return(isEqual); }
/// <summary> /// N. /// Runs Miller-Rabin algorithm k times. /// </summary> /// <param name="n"></param> /// <param name="k"></param> /// <returns></returns> public static bool IsPrime(BigNum n, int k) { bool isPrimeNumber = true; BigNum t = new BigNum(); BigNum u = new BigNum(); BigNum nMinusOne = new BigNum(n); nMinusOne.SubNum(GlobalVariables.one); FindExpressionOfGivenNumberByPowerOfTwoTimesOddNumber(nMinusOne, t, u); for (int i = 0; i < k; ++i) { if (!MillerRabinAlgorithm(n, new BigNum(t), u)) { isPrimeNumber = false; break; } } return(isPrimeNumber); }
public static void A() { Console.WriteLine("(A) Using ReadNum methods."); Console.WriteLine("1. reading 0101"); BigNum bigNum1a = new BigNum(); bigNum1a.ReadNum("0101"); Console.WriteLine(bigNum1a.WriteNum()); Console.WriteLine($"The first 1' digit is in position: {bigNum1a.MSB1Location}"); Console.WriteLine("2. reading positions of 1s. Getting a the list {399, 385}."); BigNum bigNum2a = new BigNum(); bigNum2a.ReadNum(new List <int> { 399, 385 }); Console.WriteLine(bigNum2a.WriteNum()); Console.WriteLine($"The first 1' digit is in position: {bigNum2a.MSB1Location}"); Console.WriteLine(); }
public static void L() { Console.WriteLine("(L) Using Inverse method."); BigNum bigNum1 = new BigNum(26); BigNum bigNum2 = new BigNum(21); Console.WriteLine("Calculates the opposite number of 26 mod 21:"); Console.WriteLine(MathOps.Inverse(bigNum1, bigNum2).DecimalValue); Console.WriteLine("Calculates the opposite number of 21 mod 26:"); Console.WriteLine(MathOps.Inverse(bigNum2, bigNum1).DecimalValue); BigNum bigNum3 = new BigNum(15); BigNum bigNum4 = new BigNum(10); Console.WriteLine("Calculates the opposite number of 15 mod 10:"); if (MathOps.Inverse(bigNum3, bigNum4) == null) { Console.WriteLine("There is no opposite for 15"); } Console.WriteLine(); }
/// <summary> /// Gets BigNum number. /// Finds the index of the MSB 1 digit, run from it to the LSB. /// It has boolean variable <isSmaller> that set to true when the first 1's digits is cleared /// (set to 0). /// Unless <isSmaller> = true, this method cannot set any bit. /// Use random (IsGeneratedToSet() method) to set or clear that bit. /// </summary> /// <param name="top"></param> /// <returns></returns> private static BigNum GenerateNumberFromOneToGivenTop(BigNum top) { BigNum generatedNumber = new BigNum(); if (top.MSB1Location.HasValue) { do { bool isSmaller = false; List <int> PositionsOf1sList = new List <int>(); for (int i = top.MSB1Location.Value; i < GlobalVariables.MAX_NUM; ++i) { if (top[i] == 1) { if (GenerateOneOrZero() == 0) { isSmaller = true; } else { PositionsOf1sList.Add(i); } } else { if ((GenerateOneOrZero() == 1) && (isSmaller)) { PositionsOf1sList.Add(i); } } } generatedNumber.ReadNum(PositionsOf1sList); } while ((generatedNumber.CompNumWithoutPrint(GlobalVariables.zero)) || (generatedNumber.CompNumWithoutPrint(top))); } return(generatedNumber); }
public static void D() { Console.WriteLine("(D) Using BigToLong method."); BigNum bigNumC1 = new BigNum(35L); long? num1 = bigNumC1.BigToLong(); Console.WriteLine(num1); BigNum bigNumC2 = new BigNum(9223372036854775807L); long? num2 = bigNumC2.BigToLong(); Console.WriteLine(num2); BigNum bigNumD = new BigNum(); bigNumD.Complement(); long?num3 = bigNumD.BigToLong(); Console.WriteLine(num3); Console.WriteLine(); }
/// <summary> /// O. /// Generates random prime number in the length of MAX_NUN/4. /// </summary> public static BigNum GenPrime() { BigNum randomPrimeNumber = new BigNum(); BigNum top = new BigNum(); int k = 20; int tryNumber = 1; List <int> positionsOf1s = new List <int>(); for (int i = 392; i < GlobalVariables.MAX_NUM; ++i) // TODO change back. { positionsOf1s.Add(i); } top.ReadNum(positionsOf1s); Console.WriteLine("Generating random prime number..."); do { Console.WriteLine($"try number: {tryNumber++}"); randomPrimeNumber = GenerateNumberFromOneToGivenTop(top); } while (!IsPrime(randomPrimeNumber, k)); return(randomPrimeNumber); }
/// <summary> /// J. /// Gets two BigNum type numbers, divided and divider. /// Returns by reference the result - quotient and reminder. /// </summary> /// <param name="divider"></param> public static void DivNum(BigNum divided, BigNum divider, BigNum quotientRetrunByRef, BigNum reminderReturnByRef) { List <int> positionsOf1s = new List <int>(); if (divided.MSB1Location.HasValue) { int indexPos = divided.MSB1Location.Value + divider.Length - 1; BigNum subResult = new BigNum(divided); while (indexPos < GlobalVariables.MAX_NUM) { BigNum numberFromLeftToIndex = GetSubBigNumFromLeftToIndex(subResult, indexPos); if (numberFromLeftToIndex >= divider) { // Saving quotient's info. positionsOf1s.Add(indexPos); // Subtract. int numberOfShifts = GlobalVariables.MAX_NUM - indexPos - 1; BigNum numberToSubtract = new BigNum(divider); numberToSubtract.ShiftLeft(numberOfShifts); subResult.SubNum(numberToSubtract); } indexPos++; } quotientRetrunByRef.ReadNum(positionsOf1s); reminderReturnByRef.Set(subResult); } else { Console.WriteLine("Cannot divide by zero"); } }
public static void K() { Console.WriteLine("(K) Using ExtendedGCD method."); Console.WriteLine("Calculates GCD(26, 21). Should be = 1"); BigNum bigNum3 = new BigNum(26); BigNum bigNum4 = new BigNum(21); BigNum x = new BigNum(); BigNum y = new BigNum(); BigNum gcd = new BigNum(); MathOps.ExtendedGCD(bigNum4, bigNum3, x, y, gcd); Console.WriteLine($"GCD = {gcd.WriteNum()} = {bigNum3.DecimalValue}*{x.DecimalValue}" + $" + {bigNum4.DecimalValue}*{y.DecimalValue}"); Console.WriteLine("Calculates GCD(15, 10). Should be = 5"); BigNum bigNum1 = new BigNum(15); BigNum bigNum2 = new BigNum(10); MathOps.ExtendedGCD(bigNum2, bigNum1, x, y, gcd); Console.WriteLine($"GCD = {gcd.DecimalValue} = {bigNum1.DecimalValue}*{x.DecimalValue}" + $" + {bigNum2.DecimalValue}*{y.DecimalValue}"); Console.WriteLine(); }