Beispiel #1
0
 protected override BigInteger GenerateSearchBase(int bits, object Context)
 {
     if (Context == null) throw new ArgumentNullException("Context");
     var ret = new BigInteger((BigInteger) Context);
     ret.SetBit(0);
     return ret;
 }
Beispiel #2
0
        /// <summary>
        /// Генерация ключа авторизации
        /// </summary>
        /// <returns></returns>
        private bool GenerateAuthKey(string address, int port)
        {
            using (var connection = new TcpConnection(address, port, _formatter))
            {
                connection.Connect(true);

                var pns = new PlainMtProtoSession(connection);

                _nonce = BigInteger.GenerateRandom(128);
                var reqpq = new Combinator("req_pq", _nonce);
                RpcAnswer result = pns.RpcCall(reqpq,
                    "resPQ nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector long = ResPQ");
                if (!result.Success) throw new Exception(result.Error.ToString());

                Combinator reqDhParams = ProcessPqAnswer(result.Combinator);

                result = pns.RpcCall(reqDhParams,
                    "server_DH_params_ok nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params",
                    "server_DH_params_fail nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params");

                if (result.Combinator.Name == "server_DH_params_ok")
                {
                    Combinator serverDhInnerData = ProcessDhParams(result.Combinator);
                    Combinator setClientDhParams = SetClientDhParams(serverDhInnerData);

                    result = pns.RpcCall(setClientDhParams,
                        "dh_gen_ok nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer",
                        "dh_gen_retry nonce:int128 server_nonce:int128 new_nonce_hash2:int128 = Set_client_DH_params_answer",
                        "dh_gen_fail nonce:int128 server_nonce:int128 new_nonce_hash3:int128 = Set_client_DH_params_answer");

                    Thread.Sleep(100);

                    switch (result.Combinator.Name)
                    {
                        case "dh_gen_ok":
                            InitialSalt = CalculateInitialSalt(_newNonce, _serverNonce);

                            // Проверим new_nonce_hash1
                            bool res = CheckNewNonceHash(result.Combinator.Get<BigInteger>("new_nonce_hash1"), 1);

                            return res;
                        case "dh_gen_retry": // HACK: ретри не реализован
                        case "dh_gen_fail":
                            return false;
                        default:
                            return false;
                    }
                }
                return false;

            }
        }
Beispiel #3
0
        /// <summary>
        ///     Конструктор по умолчанию
        /// </summary>
        /// <param name="authKey"></param>
        /// <param name="data"></param>
        public EncryptedMessage(byte[] authKey, EncryptedData data, int x)
        {
            SHA1 sha1 = SHA1.Create();
            _authKey = authKey;
            byte[] hash = sha1.ComputeHash(authKey);
            AuthKeyId = BitConverter.ToInt64(hash, hash.Length - 8);

            hash = sha1.ComputeHash(data.SerializeNoPadding());
            var buf = new byte[16];
            Array.Copy(hash, hash.Length - 16, buf, 0, 16);
            MsgKey = new BigInteger(buf);
            _x = x;

            Data = data;
        }
Beispiel #4
0
        public EncryptedMessage(byte[] authKey, byte[] plainData)
        {
            _authKey = authKey;
            using (var ms = new MemoryStream(plainData))
            {
                using (var br = new BinaryReader(ms))
                {
                    AuthKeyId = br.ReadInt64();
                    MsgKey = new BigInteger(br.ReadBytes(16));

                    // дешифруем эту дату
                    byte[] aesKey = CalculateAesKey(8, MsgKey.GetBytes());
                    byte[] aesIv = CalculateIV(8, MsgKey.GetBytes());

                    var aesIge = new Aes256IgeManaged(aesKey, aesIv);
                    Data = new EncryptedData(aesIge.Decrypt(br.ReadBytes(plainData.Length - 8 - 16)));
                }
            }
        }
Beispiel #5
0
        private static int GetSPPRounds(BigInteger bi, ConfidenceFactor confidence)
        {
            int bc = bi.BitCount();

            int Rounds;

            // Data from HAC, 4.49
            if (bc <= 100) Rounds = 27;
            else if (bc <= 150) Rounds = 18;
            else if (bc <= 200) Rounds = 15;
            else if (bc <= 250) Rounds = 12;
            else if (bc <= 300) Rounds = 9;
            else if (bc <= 350) Rounds = 8;
            else if (bc <= 400) Rounds = 7;
            else if (bc <= 500) Rounds = 6;
            else if (bc <= 600) Rounds = 5;
            else if (bc <= 800) Rounds = 4;
            else if (bc <= 1250) Rounds = 3;
            else Rounds = 2;

            switch (confidence)
            {
                case ConfidenceFactor.ExtraLow:
                    Rounds >>= 2;
                    return Rounds != 0 ? Rounds : 1;
                case ConfidenceFactor.Low:
                    Rounds >>= 1;
                    return Rounds != 0 ? Rounds : 1;
                case ConfidenceFactor.Medium:
                    return Rounds;
                case ConfidenceFactor.High:
                    return Rounds << 1;
                case ConfidenceFactor.ExtraHigh:
                    return Rounds << 2;
                case ConfidenceFactor.Provable:
                    throw new Exception(
                        "The Rabin-Miller test can not be executed in a way such that its results are provable");
                default:
                    throw new ArgumentOutOfRangeException("confidence");
            }
        }
Beispiel #6
0
 public BigInteger ModPow(BigInteger exp, BigInteger n)
 {
     var mr = new ModulusRing(n);
     return mr.Pow(this, exp);
 }
Beispiel #7
0
 public BigInteger GCD(BigInteger bi)
 {
     return Kernel.gcd(this, bi);
 }
Beispiel #8
0
 public Sign Compare(BigInteger bi)
 {
     return Kernel.Compare(this, bi);
 }
Beispiel #9
0
 public static BigInteger Multiply(BigInteger bi, int i)
 {
     return (bi * i);
 }
Beispiel #10
0
 public static BigInteger Divid(BigInteger bi1, BigInteger bi2)
 {
     return (bi1 / bi2);
 }
Beispiel #11
0
 public static BigInteger Modulus(BigInteger bi1, BigInteger bi2)
 {
     return (bi1 % bi2);
 }
Beispiel #12
0
            public static unsafe void SquarePositive(BigInteger bi, ref uint[] wkSpace)
            {
                uint[] t = wkSpace;
                wkSpace = bi.data;
                uint[] d = bi.data;
                uint dl = bi.length;
                bi.data = t;

                fixed (uint* dd = d, tt = t)
                {
                    uint* ttE = tt + t.Length;
                    // Clear the dest
                    for (uint* ttt = tt; ttt < ttE; ttt++)
                        *ttt = 0;

                    uint* dP = dd, tP = tt;

                    for (uint i = 0; i < dl; i++, dP++)
                    {
                        if (*dP == 0)
                            continue;

                        ulong mcarry = 0;
                        uint bi1val = *dP;

                        uint* dP2 = dP + 1, tP2 = tP + 2 * i + 1;

                        for (uint j = i + 1; j < dl; j++, tP2++, dP2++)
                        {
                            // k = i + j
                            mcarry += (bi1val * (ulong)*dP2) + *tP2;

                            *tP2 = (uint)mcarry;
                            mcarry >>= 32;
                        }

                        if (mcarry != 0)
                            *tP2 = (uint)mcarry;
                    }

                    // Double t. Inlined for speed.

                    tP = tt;

                    uint x, carry = 0;
                    while (tP < ttE)
                    {
                        x = *tP;
                        *tP = (x << 1) | carry;
                        carry = x >> (32 - 1);
                        tP++;
                    }
                    if (carry != 0) *tP = carry;

                    // Add in the diagnals

                    dP = dd;
                    tP = tt;
                    for (uint* dE = dP + dl; (dP < dE); dP++, tP++)
                    {
                        ulong val = *dP * (ulong)*dP + *tP;
                        *tP = (uint)val;
                        val >>= 32;
                        *(++tP) += (uint)val;
                        if (*tP < (uint)val)
                        {
                            uint* tP3 = tP;
                            // Account for the first carry
                            (*++tP3)++;

                            // Keep adding until no carry
                            while ((*tP3++) == 0)
                                (*tP3)++;
                        }
                    }

                    bi.length <<= 1;

                    // Normalize length
                    while (tt[bi.length - 1] == 0 && bi.length > 1) bi.length--;
                }
            }
Beispiel #13
0
            public static BigInteger MultiplyByDword(BigInteger n, uint f)
            {
                var ret = new BigInteger(Sign.Positive, n.length + 1);

                uint i = 0;
                ulong c = 0;

                do
                {
                    c += n.data[i] * (ulong)f;
                    ret.data[i] = (uint)c;
                    c >>= 32;
                } while (++i < n.length);
                ret.data[i] = (uint)c;
                ret.Normalize();
                return ret;
            }
Beispiel #14
0
            public static BigInteger RightShift(BigInteger bi, int n)
            {
                if (n == 0) return new BigInteger(bi);

                int w = n >> 5;
                int s = n & ((1 << 5) - 1);

                var ret = new BigInteger(Sign.Positive, bi.length - (uint)w + 1);
                uint l = (uint)ret.data.Length - 1;

                if (s != 0)
                {
                    uint x, carry = 0;

                    while (l-- > 0)
                    {
                        x = bi.data[l + w];
                        ret.data[l] = (x >> n) | carry;
                        carry = x << (32 - n);
                    }
                }
                else
                {
                    while (l-- > 0)
                        ret.data[l] = bi.data[l + w];
                }
                ret.Normalize();
                return ret;
            }
Beispiel #15
0
            public static BigInteger LeftShift(BigInteger bi, int n)
            {
                if (n == 0) return new BigInteger(bi, bi.length + 1);

                int w = n >> 5;
                n &= ((1 << 5) - 1);

                var ret = new BigInteger(Sign.Positive, bi.length + 1 + (uint)w);

                uint i = 0, l = bi.length;
                if (n != 0)
                {
                    uint x, carry = 0;
                    while (i < l)
                    {
                        x = bi.data[i];
                        ret.data[i + w] = (x << n) | carry;
                        carry = x >> (32 - n);
                        i++;
                    }
                    ret.data[i + w] = carry;
                }
                else
                {
                    while (i < l)
                    {
                        ret.data[i + w] = bi.data[i];
                        i++;
                    }
                }

                ret.Normalize();
                return ret;
            }
Beispiel #16
0
 public static int Modulus(BigInteger bi, int i)
 {
     return (bi % i);
 }
Beispiel #17
0
 public static uint Modulus(BigInteger bi, uint ui)
 {
     return (bi % ui);
 }
Beispiel #18
0
            /* 
			 * Never called in BigInteger (and part of a private class)
			 * 			public static bool Double (uint [] u, int l)
						{
							uint x, carry = 0;
							uint i = 0;
							while (i < l) {
								x = u [i];
								u [i] = (x << 1) | carry;
								carry = x >> (32 - 1);
								i++;
							}
							if (carry != 0) u [l] = carry;
							return carry != 0;
						}*/

            #endregion

            #region Number Theory

            public static BigInteger gcd(BigInteger a, BigInteger b)
            {
                BigInteger x = a;
                BigInteger y = b;

                BigInteger g = y;

                while (x.length > 1)
                {
                    g = x;
                    x = y % x;
                    y = g;
                }
                if (x == 0) return g;

                // TODO: should we have something here if we can convert to long?

                //
                // Now we can just do it with single precision. I am using the binary gcd method,
                // as it should be faster.
                //

                uint yy = x.data[0];
                uint xx = y % yy;

                int t = 0;

                while (((xx | yy) & 1) == 0)
                {
                    xx >>= 1;
                    yy >>= 1;
                    t++;
                }
                while (xx != 0)
                {
                    while ((xx & 1) == 0) xx >>= 1;
                    while ((yy & 1) == 0) yy >>= 1;
                    if (xx >= yy)
                        xx = (xx - yy) >> 1;
                    else
                        yy = (yy - xx) >> 1;
                }

                return yy << t;
            }
Beispiel #19
0
 public static BigInteger Divid(BigInteger bi, int i)
 {
     return (bi / i);
 }
Beispiel #20
0
            public static uint modInverse(BigInteger bi, uint modulus)
            {
                uint a = modulus, b = bi % modulus;
                uint p0 = 0, p1 = 1;

                while (b != 0)
                {
                    if (b == 1)
                        return p1;
                    p0 += (a / b) * p1;
                    a %= b;

                    if (a == 0)
                        break;
                    if (a == 1)
                        return modulus - p0;

                    p1 += (b / a) * p0;
                    b %= a;
                }
                return 0;
            }
Beispiel #21
0
 public static BigInteger Multiply(BigInteger bi1, BigInteger bi2)
 {
     return (bi1 * bi2);
 }
Beispiel #22
0
            public static BigInteger modInverse(BigInteger bi, BigInteger modulus)
            {
                if (modulus.length == 1) return modInverse(bi, modulus.data[0]);

                BigInteger[] p = { 0, 1 };
                var q = new BigInteger[2]; // quotients
                BigInteger[] r = { 0, 0 }; // remainders

                int step = 0;

                BigInteger a = modulus;
                BigInteger b = bi;

                var mr = new ModulusRing(modulus);

                while (b != 0)
                {
                    if (step > 1)
                    {
                        BigInteger pval = mr.Difference(p[0], p[1] * q[0]);
                        p[0] = p[1];
                        p[1] = pval;
                    }

                    BigInteger[] divret = multiByteDivide(a, b);

                    q[0] = q[1];
                    q[1] = divret[0];
                    r[0] = r[1];
                    r[1] = divret[1];
                    a = b;
                    b = divret[1];

                    step++;
                }

                if (r[0] != 1)
                    throw (new ArithmeticException("No inverse!"));

                return mr.Difference(p[0], p[1] * q[0]);
            }
Beispiel #23
0
        /// <summary>
        ///     Generates a new, random BigInteger of the specified length.
        /// </summary>
        /// <param name="bits">The number of bits for the new number.</param>
        /// <param name="rng">A random number generator to use to obtain the bits.</param>
        /// <returns>A random number of the specified length.</returns>
        public static BigInteger GenerateRandom(int bits, RandomNumberGenerator rng)
        {
            int dwords = bits >> 5;
            int remBits = bits & 0x1F;

            if (remBits != 0)
                dwords++;

            var ret = new BigInteger(Sign.Positive, (uint)dwords + 1);
            var random = new byte[dwords << 2];

            rng.GetBytes(random);
            Buffer.BlockCopy(random, 0, ret.data, 0, dwords << 2);

            if (remBits != 0)
            {
                var mask = (uint)(0x01 << (remBits - 1));
                ret.data[dwords - 1] |= mask;

                mask = 0xFFFFFFFF >> (32 - remBits);
                ret.data[dwords - 1] &= mask;
            }
            else
                ret.data[dwords - 1] |= 0x80000000;

            ret.Normalize();
            return ret;
        }
Beispiel #24
0
        /* This is the BigInteger.Parse method I use. This method works
		because BigInteger.ToString returns the input I gave to Parse. */

        public static BigInteger Parse(string number)
        {
            if (number == null)
                throw new ArgumentNullException("number");

            int i = 0, len = number.Length;
            char c;
            bool digits_seen = false;
            var val = new BigInteger(0);
            if (number[i] == '+')
            {
                i++;
            }
            else if (number[i] == '-')
            {
                throw new FormatException(WouldReturnNegVal);
            }

            for (; i < len; i++)
            {
                c = number[i];
                if (c == '\0')
                {
                    i = len;
                    continue;
                }
                if (c >= '0' && c <= '9')
                {
                    val = val * 10 + (c - '0');
                    digits_seen = true;
                }
                else
                {
                    if (Char.IsWhiteSpace(c))
                    {
                        for (i++; i < len; i++)
                        {
                            if (!Char.IsWhiteSpace(number[i]))
                                throw new FormatException();
                        }
                        break;
                    }
                    throw new FormatException();
                }
            }
            if (!digits_seen)
                throw new FormatException();
            return val;
        }
Beispiel #25
0
        public string ToString(uint radix, string characterSet)
        {
            if (characterSet.Length < radix)
                throw new ArgumentException("charSet length less than radix", "characterSet");
            if (radix == 1)
                throw new ArgumentException("There is no such thing as radix one notation", "radix");

            if (this == 0) return "0";
            if (this == 1) return "1";

            string result = "";

            var a = new BigInteger(this);

            while (a != 0)
            {
                uint rem = Kernel.SingleByteDivideInPlace(a, radix);
                result = characterSet[(int)rem] + result;
            }

            return result;
        }
Beispiel #26
0
        public static BigInteger operator *(BigInteger bi1, BigInteger bi2)
        {
            if (bi1 == 0 || bi2 == 0) return 0;

            //
            // Validate pointers
            //
            if (bi1.data.Length < bi1.length) throw new IndexOutOfRangeException("bi1 out of range");
            if (bi2.data.Length < bi2.length) throw new IndexOutOfRangeException("bi2 out of range");

            var ret = new BigInteger(Sign.Positive, bi1.length + bi2.length);

            Kernel.Multiply(bi1.data, 0, bi1.length, bi2.data, 0, bi2.length, ret.data, 0);

            ret.Normalize();
            return ret;
        }
Beispiel #27
0
 public BigInteger ModInverse(BigInteger modulus)
 {
     return Kernel.modInverse(this, modulus);
 }
Beispiel #28
0
        // with names suggested by FxCop 1.30

        public static BigInteger Add(BigInteger bi1, BigInteger bi2)
        {
            return (bi1 + bi2);
        }
Beispiel #29
0
 /// <summary>
 ///     Generates the smallest prime >= bi
 /// </summary>
 /// <param name="bi">A BigInteger</param>
 /// <returns>The smallest prime >= bi. More mathematically, if bi is prime: bi, else Prime [PrimePi [bi] + 1].</returns>
 public static BigInteger NextHighestPrime(BigInteger bi)
 {
     var npf = new NextPrimeFinder();
     return npf.GenerateNewPrime(0, bi);
 }
Beispiel #30
0
 public static BigInteger Subtract(BigInteger bi1, BigInteger bi2)
 {
     return (bi1 - bi2);
 }