private static MyBigInteger Mod(MyBigInteger a, MyBigInteger b) { var result = Zero; for (var i = a.Size - 1; i >= 0; i--) { result += Exp(a.GetByte(i), i); var x = 0; var left = 0; var right = 10; while (left <= right) { var middle = (left + right) >> 1; var current = b * Exp((byte)middle, i); if (current <= result) { x = middle; left = middle + 1; } else { right = middle - 1; } } result -= b * Exp((byte)x, i); } result.RemoveNulls(); result.Sign = a.Sign == b.Sign ? Sign.Plus : Sign.Minus; return(result); }
public static MyBigInteger ModPow(MyBigInteger value, MyBigInteger power, MyBigInteger module) { var binaryValue = ConvertToBinary(power); var arr = new MyBigInteger [binaryValue.Count]; arr[0] = value; for (var i = 1; i < binaryValue.Count; i++) { arr[i] = arr[i - 1] * arr[i - 1] % module; } var multiplication = One; var zero = Zero; for (var j = 0; j < binaryValue.Count; j++) { if (binaryValue[j] > zero) { multiplication *= binaryValue[j] * arr[j]; } } return(multiplication % module); }
private static int CompareSize(MyBigInteger a, MyBigInteger b) { if (a.Size < b.Size) { return(-1); } return(a.Size > b.Size ? 1 : CompareDigits(a, b)); }
public static MyBigInteger GetModInverse(MyBigInteger a, MyBigInteger n) { var gcd = Gcc(a, n, out var x, out var _); if (gcd != One) { return(Zero); } return((x % n + n) % n); }
public static Tuple <Tuple <MyBigInteger, MyBigInteger>, Tuple <MyBigInteger, MyBigInteger> > CreateKeys( MyBigInteger p, MyBigInteger q, MyBigInteger e) { var n = p * q; var fi = (p - MyBigInteger.One) * (q - MyBigInteger.One); var publicKey = Tuple.Create(e, n); var d = MyBigInteger.GetModInverse(e, fi) + fi; var privateKey = Tuple.Create(d, n); return(Tuple.Create(publicKey, privateKey)); }
private static int CompareSign(MyBigInteger a, MyBigInteger b, bool ignoreSign = false) { if (ignoreSign) { return(CompareSize(a, b)); } if (a.Sign < b.Sign) { return(-1); } return(a.Sign > b.Sign ? 1 : CompareSize(a, b)); }
private static List <MyBigInteger> ConvertToBinary(MyBigInteger value) { var copy = new MyBigInteger(value.Sign, value._digits.ToList()); var two = new MyBigInteger(2); var result = new List <MyBigInteger>(); while (!copy.IsZero) { result.Add(copy % two); copy /= two; } return(result); }
public static MyBigInteger Gcc(MyBigInteger number, MyBigInteger modul, out MyBigInteger x, out MyBigInteger y) { if (number.IsZero) { x = Zero; y = One; return(modul); } var d = Gcc(modul % number, number, out var x1, out var y1); x = y1 - (modul / number) * x1; y = x1; return(d); }
private static int CompareDigits(MyBigInteger a, MyBigInteger b) { var maxLength = Math.Max(a.Size, b.Size); for (var i = maxLength; i >= 0; i--) { if (a.GetByte(i) < b.GetByte(i)) { return(-1); } if (a.GetByte(i) > b.GetByte(i)) { return(1); } } return(0); }
private static MyBigInteger Multiply(MyBigInteger a, MyBigInteger b) { var result = Zero; for (var i = 0; i < a.Size; i++) { for (int j = 0, reduce = 0; (j < b.Size) || (reduce > 0); j++) { var sum = result.GetByte(i + j) + a.GetByte(i) * b.GetByte(j) + reduce; result.SetByte(i + j, (byte)(sum % 10)); reduce = sum / 10; } } result.Sign = a.Sign == b.Sign ? Sign.Plus : Sign.Minus; return(result); }
public static List <MyBigInteger> EncryptFile(string path) { var p = new MyBigInteger(5037569); var q = new MyBigInteger(5810011); var e = new MyBigInteger(65537); var keys = RSA.CreateKeys(p, q, e); var encrypted = new List <MyBigInteger>(); var text = System.IO.File.ReadAllText(@path).Split(' '); foreach (var s in text) { var chars = s.ToCharArray(); encrypted.AddRange(chars.Select(c => RSA.Encrypt(new MyBigInteger(Convert.ToInt32(c)), keys.Item1))); } return(encrypted); }
private static MyBigInteger Subtract(MyBigInteger a, MyBigInteger b) { var digits = new List <byte>(); var max = Zero; var min = Zero; var compare = Comparison(a, b, ignoreSign: true); switch (compare) { case -1: min = a; max = b; break; case 0: return(Zero); case 1: min = b; max = a; break; } var maxLength = Math.Max(a.Size, b.Size); var reduce = 0; for (var i = 0; i < maxLength; i++) { var sub = max.GetByte(i) - min.GetByte(i) - reduce; if (sub < 0) { sub += 10; reduce = 1; } else { reduce = 0; } digits.Add((byte)sub); } return(new MyBigInteger(max.Sign, digits)); }
private static MyBigInteger Add(MyBigInteger a, MyBigInteger b) { var digits = new List <byte>(); var maxLength = Math.Max(a.Size, b.Size); var reduce = 0; for (var i = 0; i < maxLength; i++) { var sum = (byte)(a.GetByte(i) + b.GetByte(i) + reduce); reduce = sum / 10; digits.Add((byte)(sum % 10)); } if (reduce > 0) { digits.Add((byte)reduce); } return(new MyBigInteger(a.Sign, digits)); }
private static MyBigInteger Div(MyBigInteger a, MyBigInteger b) { var result = Zero; var current = Zero; for (var i = a.Size - 1; i >= 0; i--) { current += Exp(a.GetByte(i), i); var x = 0; var left = 0; var right = 10; while (left <= right) { var middle = (left + right) / 2; var cur = b * Exp((byte)middle, i); if (cur <= current) { x = middle; left = middle + 1; } else { right = middle - 1; } } result.SetByte(i, (byte)(x % 10)); var reduce = b * Exp((byte)x, i); current = current - reduce; } result.RemoveNulls(); result.Sign = a.Sign == b.Sign ? Sign.Plus : Sign.Minus; return(result); }
private static int Comparison(MyBigInteger a, MyBigInteger b, bool ignoreSign = false) => CompareSign(a, b, ignoreSign);
public static MyBigInteger Decrypt(MyBigInteger data, Tuple <MyBigInteger, MyBigInteger> key) { return(MyBigInteger.ModPow(data, key.Item1, key.Item2)); }