Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
 private static int CompareSize(MyBigInteger a, MyBigInteger b)
 {
     if (a.Size < b.Size)
     {
         return(-1);
     }
     return(a.Size > b.Size ? 1 : CompareDigits(a, b));
 }
Пример #4
0
        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);
        }
Пример #5
0
        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));
        }
Пример #6
0
        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));
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
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);
        }
Пример #11
0
        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);
        }
Пример #12
0
        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));
        }
Пример #13
0
        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));
        }
Пример #14
0
        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);
        }
Пример #15
0
 private static int Comparison(MyBigInteger a, MyBigInteger b, bool ignoreSign = false) => CompareSign(a, b, ignoreSign);
Пример #16
0
 public static MyBigInteger Decrypt(MyBigInteger data, Tuple <MyBigInteger, MyBigInteger> key)
 {
     return(MyBigInteger.ModPow(data, key.Item1, key.Item2));
 }