internal void SetFromString(Integer Result, string InString) { if (InString == null) { throw(new Exception("InString was null in SetFromString().")); } if (InString.Length < 1) { Result.SetToZero(); return; } Base10Number Base10N = new Base10Number(); Integer Tens = new Integer(); Integer OnePart = new Integer(); // This might throw an exception if the string is bad. Base10N.SetFromString(InString); Result.SetFromULong(Base10N.GetD(0)); Tens.SetFromULong(10); for (int Count = 1; Count <= Base10N.GetIndex(); Count++) { OnePart.SetFromULong(Base10N.GetD(Count)); Multiplier.Multiply(OnePart, Tens); Result.Add(OnePart); Multiplier.MultiplyULong(Tens, 10); } }
// Copyright Eric Chauvin 2015 - 2018. internal int Reduce(Integer Result, Integer ToReduce) { try { if (ToReduce.ParamIsGreater(CurrentModReductionBase)) { Result.Copy(ToReduce); return(Result.GetIndex()); } if (GeneralBaseArray == null) { throw(new Exception("SetupGeneralBaseArray() should have already been called.")); } Result.SetToZero(); int TopOfToReduce = ToReduce.GetIndex() + 1; if (TopOfToReduce > GeneralBaseArray.Length) { throw(new Exception("The Input number should have been reduced first. HowManyToAdd > GeneralBaseArray.Length")); } // If it gets this far then ToReduce is at // least this big. int HighestCopyIndex = CurrentModReductionBase.GetIndex(); Result.CopyUpTo(ToReduce, HighestCopyIndex - 1); int BiggestIndex = 0; for (int Count = HighestCopyIndex; Count < TopOfToReduce; Count++) { // The size of the numbers in GeneralBaseArray // are all less than the size of GeneralBase. // This multiplication by a uint is with a // number that is not bigger than GeneralBase. // Compare this with the two full Muliply() // calls done on each digit of the quotient // in LongDivide3(). // AccumulateBase is set to a new value here. int CheckIndex = IntMath.MultiplyUIntFromCopy(AccumulateBase, GeneralBaseArray[Count], ToReduce.GetD(Count)); if (CheckIndex > BiggestIndex) { BiggestIndex = CheckIndex; } Result.Add(AccumulateBase); } return(Result.GetIndex()); } catch (Exception Except) { throw(new Exception("Exception in ModularReduction(): " + Except.Message)); } }
internal void Subtract(Integer Result, Integer ToSub) { // This checks that the sign is equal too. if (Result.IsEqual(ToSub)) { Result.SetToZero(); return; } // ParamIsGreater() handles positive and negative values, so if the // parameter is more toward the positive side then it's true. It's greater. // The most common form. They are both positive. if (!Result.IsNegative && !ToSub.IsNegative) { if (ToSub.ParamIsGreater(Result)) { SubtractPositive(Result, ToSub); return; } // ToSub is bigger. TempSub1.Copy(Result); TempSub2.Copy(ToSub); SubtractPositive(TempSub2, TempSub1); Result.Copy(TempSub2); Result.IsNegative = true; return; } if (Result.IsNegative && !ToSub.IsNegative) { TempSub1.Copy(Result); TempSub1.IsNegative = false; TempSub1.Add(ToSub); Result.Copy(TempSub1); Result.IsNegative = true; return; } if (!Result.IsNegative && ToSub.IsNegative) { TempSub1.Copy(ToSub); TempSub1.IsNegative = false; Result.Add(TempSub1); return; } if (Result.IsNegative && ToSub.IsNegative) { TempSub1.Copy(Result); TempSub1.IsNegative = false; TempSub2.Copy(ToSub); TempSub2.IsNegative = false; // -12 - -7 = -12 + 7 = -5 // Comparing the positive numbers here. if (TempSub2.ParamIsGreater(TempSub1)) { SubtractPositive(TempSub1, TempSub2); Result.Copy(TempSub1); Result.IsNegative = true; return; } // -7 - -12 = -7 + 12 = 5 SubtractPositive(TempSub2, TempSub1); Result.Copy(TempSub2); Result.IsNegative = false; return; } }
internal void Add(Integer Result, Integer ToAdd) { if (ToAdd.IsZero()) { return; } // The most common form. They are both positive. if (!Result.IsNegative && !ToAdd.IsNegative) { Result.Add(ToAdd); return; } if (!Result.IsNegative && ToAdd.IsNegative) { TempAdd1.Copy(ToAdd); TempAdd1.IsNegative = false; if (TempAdd1.ParamIsGreater(Result)) { Subtract(Result, TempAdd1); return; } else { Subtract(TempAdd1, Result); Result.Copy(TempAdd1); Result.IsNegative = true; return; } } if (Result.IsNegative && !ToAdd.IsNegative) { TempAdd1.Copy(Result); TempAdd1.IsNegative = false; TempAdd2.Copy(ToAdd); if (TempAdd1.ParamIsGreater(TempAdd2)) { Subtract(TempAdd2, TempAdd1); Result.Copy(TempAdd2); return; } else { Subtract(TempAdd1, TempAdd2); Result.Copy(TempAdd2); Result.IsNegative = true; return; } } if (Result.IsNegative && ToAdd.IsNegative) { TempAdd1.Copy(Result); TempAdd1.IsNegative = false; TempAdd2.Copy(ToAdd); TempAdd2.IsNegative = false; TempAdd1.Add(TempAdd2); Result.Copy(TempAdd1); Result.IsNegative = true; return; } }
internal bool DecryptWithQInverse(Integer EncryptedNumber, Integer DecryptedNumber, Integer TestDecryptedNumber, Integer PubKeyN, Integer PrivKInverseExponentDP, Integer PrivKInverseExponentDQ, Integer PrimeP, Integer PrimeQ, BackgroundWorker Worker) { Worker.ReportProgress(0, " "); Worker.ReportProgress(0, "Top of DecryptWithQInverse()."); // QInv and the dP and dQ numbers are normally already set up before // you start your listening socket. ECTime DecryptTime = new ECTime(); DecryptTime.SetToNow(); // See section 5.1.2 of RFC 2437 for these steps: // http://tools.ietf.org/html/rfc2437 // 2.2 Let m_1 = c^dP mod p. // 2.3 Let m_2 = c^dQ mod q. // 2.4 Let h = qInv ( m_1 - m_2 ) mod p. // 2.5 Let m = m_2 + hq. Worker.ReportProgress(0, "EncryptedNumber: " + IntMath.ToString10(EncryptedNumber)); // 2.2 Let m_1 = c^dP mod p. TestForDecrypt.Copy(EncryptedNumber); IntMathForP.ModReduction.ModularPower(TestForDecrypt, PrivKInverseExponentDP, PrimeP, true); if (Worker.CancellationPending) { return(false); } M1ForInverse.Copy(TestForDecrypt); // 2.3 Let m_2 = c^dQ mod q. TestForDecrypt.Copy(EncryptedNumber); IntMathForQ.ModReduction.ModularPower(TestForDecrypt, PrivKInverseExponentDQ, PrimeQ, true); if (Worker.CancellationPending) { return(false); } M2ForInverse.Copy(TestForDecrypt); // 2.4 Let h = qInv ( m_1 - m_2 ) mod p. // How many is optimal to avoid the division? int HowManyIsOptimal = (PrimeP.GetIndex() * 3); for (int Count = 0; Count < HowManyIsOptimal; Count++) { if (M1ForInverse.ParamIsGreater(M2ForInverse)) { M1ForInverse.Add(PrimeP); } else { break; } } if (M1ForInverse.ParamIsGreater(M2ForInverse)) { M1M2SizeDiff.Copy(M2ForInverse); IntMath.Subtract(M1M2SizeDiff, M1ForInverse); // Unfortunately this long Divide() has to be done. IntMath.Divider.Divide(M1M2SizeDiff, PrimeP, Quotient, Remainder); Quotient.AddULong(1); Worker.ReportProgress(0, "The Quotient for M1M2SizeDiff is: " + IntMath.ToString10(Quotient)); IntMath.Multiply(Quotient, PrimeP); M1ForInverse.Add(Quotient); } M1MinusM2.Copy(M1ForInverse); IntMath.Subtract(M1MinusM2, M2ForInverse); if (M1MinusM2.IsNegative) { throw(new Exception("M1MinusM2.IsNegative is true.")); } if (QInv.IsNegative) { throw(new Exception("QInv.IsNegative is true.")); } HForQInv.Copy(M1MinusM2); IntMath.Multiply(HForQInv, QInv); if (HForQInv.IsNegative) { throw(new Exception("HForQInv.IsNegative is true.")); } if (PrimeP.ParamIsGreater(HForQInv)) { IntMath.Divider.Divide(HForQInv, PrimeP, Quotient, Remainder); HForQInv.Copy(Remainder); } // 2.5 Let m = m_2 + hq. DecryptedNumber.Copy(HForQInv); IntMath.Multiply(DecryptedNumber, PrimeQ); DecryptedNumber.Add(M2ForInverse); if (!TestDecryptedNumber.IsEqual(DecryptedNumber)) { throw(new Exception("!TestDecryptedNumber.IsEqual( DecryptedNumber ).")); } Worker.ReportProgress(0, " "); Worker.ReportProgress(0, "DecryptedNumber: " + IntMath.ToString10(DecryptedNumber)); Worker.ReportProgress(0, " "); Worker.ReportProgress(0, "TestDecryptedNumber: " + IntMath.ToString10(TestDecryptedNumber)); Worker.ReportProgress(0, " "); Worker.ReportProgress(0, "Decrypt with QInv time seconds: " + DecryptTime.GetSecondsToNow().ToString("N2")); Worker.ReportProgress(0, " "); return(true); }