/// <summary> /// Writes a bigint value to the stream, truncating the value to the given size in bytes. /// </summary> public void WriteBigInt(BigInt Value, int Size) { for (int t = 0; t < Value.Digits.Length; t++) { uint dig = Value.Digits[t]; if (Size >= 4) { this.Write((byte)(dig)); this.Write((byte)(dig >> 8)); this.Write((byte)(dig >> 16)); this.Write((byte)(dig >> 24)); Size -= 4; continue; } if (Size == 3) { this.Write((byte)(dig)); this.Write((byte)(dig >> 8)); this.Write((byte)(dig >> 16)); break; } if (Size == 2) { this.Write((byte)(dig)); this.Write((byte)(dig >> 8)); break; } if (Size == 1) { this.Write((byte)(dig)); break; } break; } }
/// <summary> /// Writes a bigint value to the stream. /// </summary> public void WriteBigInt(BigInt Value) { int bs = Value.ByteSize; this.WriteInt(bs); this.WriteBigInt(Value, bs); }
/// <summary> /// Subtracts a BigInt in-place from this value. Any carried values will be ignored. /// </summary> public void Subtract(BigInt Int) { this.Subtract(Int, 0); }
private static BigInt _PowMod(BigInt Base, BigInt TempExponent, BigInt Modulus) { if (TempExponent == 0) { return 1; } if (TempExponent == 1) { return Base % Modulus; } if (TempExponent[0]) { TempExponent[0] = false; return Multiply(_PowMod(Base, TempExponent, Modulus), Base) % Modulus; } else { TempExponent.Shift(-1); BigInt hp = _PowMod(Base, TempExponent, Modulus); return Multiply(hp, hp) % Modulus; } }
/// <summary> /// Copies a BigInt in-place to this value. /// </summary> public void Copy(BigInt Int) { this.Copy(Int, 0); }
/// <summary> /// Subtracts a BigInt in-place from this value. Any carried values will be ignored. /// </summary> /// <param name="Offset">The offset in this BigInt's digits to start adding to. The given Int will, in effect, be multipled /// by (base ^ Offset) before subtracting.</param> public void Subtract(BigInt Int, int Offset) { int cur = 0; uint carry = 0; while (Offset < this.Size) { if (cur < Int.Size) { uint ncarry; Subtract(this.Digits[Offset], carry, out this.Digits[Offset], out ncarry); Subtract(this.Digits[Offset], Int.Digits[cur], out this.Digits[Offset], out carry); carry += ncarry; cur++; Offset++; } else { Subtract(this.Digits[Offset], carry, out this.Digits[Offset], out carry); if (carry == 0) { return; } Offset++; } } }
/// <summary> /// Adds a BigInt in-place to this value. Any carried values will be ignored. /// </summary> public void Add(BigInt Int) { this.Add(Int, 0); }
/// <summary> /// Copies a BigInt in-place to this value, starting at the given offset in this value's digits. Note that if this integer has a larger /// size than the given integer, the higher digits of this integer will remain unchanged. /// </summary> public void Copy(BigInt Int, int Offset) { int cur = 0; while (Offset < this.Size && cur < Int.Size) { this.Digits[Offset] = Int.Digits[cur]; cur++; Offset++; } }
/// <summary> /// Subtracts B from A. If B is greater than A, the result will be the 2's complement form /// of the negative integer result. /// </summary> public static BigInt Subtract(BigInt A, BigInt B) { BigInt res = BigInt.Empty(Math.Max(A.Size, B.Size) + 1); res.Copy(A); res.Subtract(B); return res; }
/// <summary> /// Performs (Base ^ Exponent) % Modulus in an efficent way. /// </summary> public static BigInt PowMod(BigInt Base, BigInt Exponent, BigInt Modulus) { BigInt tempexp = BigInt.Empty(Exponent.Size); tempexp.Copy(Exponent); return _PowMod(Base, tempexp, Modulus); }
/// <summary> /// Multiplies two integers together. /// </summary> public static BigInt Multiply(BigInt A, BigInt B) { BigInt res = BigInt.Empty(A.Size + B.Size); BigInt temp = BigInt.Empty(A.Size + 1); for (int t = 0; t < B.Size; t++) { temp.ZeroFill(); temp.Copy(A); temp.Multiply(B.Digits[t]); res.Add(temp, t); } return res; }
/// <summary> /// Gets wether A has a lesser value than B. /// </summary> public static bool Lesser(BigInt A, BigInt B) { int c = Math.Max(A.Digits.Length, B.Digits.Length); while (c >= 0) { uint a = c < A.Digits.Length ? A.Digits[c] : 0; uint b = c < B.Digits.Length ? B.Digits[c] : 0; if (a < b) { return true; } if (a > b) { return false; } c--; } return false; }
/// <summary> /// Finds the quotient and remainder for the division of A by B. /// </summary> public static void Divide(BigInt A, BigInt B, out BigInt Quotient, out BigInt Remainder) { if (B > A) { Remainder = A; Quotient = Zero; } Remainder = BigInt.Empty(A.Size); Remainder.Copy(A); BigInt btemp = BigInt.Empty(A.Size); btemp.Copy(B); int bitoff = A.Magnitude - B.Magnitude; btemp.Shift(bitoff); Quotient = BigInt.Empty(bitoff/ 32 + 1); while (bitoff >= 0) { if (btemp <= Remainder) { Remainder.Subtract(btemp); Quotient[bitoff] = true; } btemp.Shift(-1); bitoff--; } }