Beispiel #1
0
        /// <summary>
        /// Calculates B.
        /// </summary>
        /// <param name="N"></param>
        /// <param name="g"></param>
        /// <param name="b"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        public static NetBigInteger CalcB(NetBigInteger N, NetBigInteger g, NetBigInteger b, NetBigInteger v)
        {
            //B = k*v + g^b % N
            NetBigInteger k = Calck(N, g);

            return((k.Multiply(v).Add(g.ModPow(b, N))).Mod(N));
        }
Beispiel #2
0
        //public byte[] GenerateObfuscationCallback()
        //{
        //    var _loc5_ = 0;
        //    var _loc6_ = "";
        //    var _loc1_ = "";
        //    var _loc2_ = 0;
        //    while (_loc2_ < 128)
        //    {
        //        _loc5_ = (int)(MathF.random() * 256);
        //        _loc6_ = Convert.ToString(_loc5_, 16);
        //        if (_loc6_.Length == 1)
        //        {
        //            _loc6_ = "0" + _loc6_;
        //        }
        //        _loc1_ = _loc1_ + _loc6_;
        //        _loc2_++;
        //    }
        //    this.privateKey = new NetBigInteger(_loc1_, 16);
        //    var _loc3_ = ENC_BASE_GENERATOR.ModPow(privateKey, ENC_PRIME_MODULUS);
        //    var loc3Bytes = _loc3_.ToByteArray();
        //    Console.WriteLine("Generated key, L:" + loc3Bytes.Length);
        //    return loc3Bytes;
        //}

        public byte[] GenerateObfuscationCallback()
        {
            var finalizedString = "";

            for (int i = 0; i < 128; i++)
            {
                var randomNum        = Convert.ToInt32(MathF.random() * 256);
                var randomizedString = Convert.ToString(randomNum, 16);
                if (randomizedString.Length == 1)
                {
                    randomizedString = "0" + randomizedString;
                }
                finalizedString = finalizedString + randomizedString;
            }
            Console.WriteLine(finalizedString);
            // Output 0: a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1
            // Output 1: b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7
            // Output 2: dededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededede3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
            privateKey = new NetBigInteger(finalizedString, 16);
            var generatedKey = ENC_BASE_GENERATOR.ModPow(privateKey, ENC_PRIME_MODULUS);
            var bytes        = generatedKey.ToByteArray();

            Console.WriteLine("Generated key, L:" + bytes.Length);
            return(bytes);
        }
        /// <summary>
        /// Generates Salt and Verifier for username and password
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="keysize"></param>
        /// <param name="salt"></param>
        /// <returns></returns>
        public static NetBigInteger PasswordVerifier(String username, String password, Int32 keysize, out Byte[] salt)
        {
            salt = NetSRP.GenerateSalt();
            NetBigInteger g, N = NetSRP.GetNandG(keysize, out g);

            return(NetSRP.PasswordVerifier(username, password, salt, N, g));
        }
Beispiel #4
0
        /// <summary>
        /// Calculates server's S.
        /// </summary>
        /// <param name="N"></param>
        /// <param name="A"></param>
        /// <param name="v"></param>
        /// <param name="u"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static NetBigInteger CalcSServer(NetBigInteger N, NetBigInteger A, NetBigInteger v, NetBigInteger u, NetBigInteger b)
        {
            // Host:  S = (Av^u) ^ b   (computes session key)
            NetBigInteger S = (A.Multiply(v.ModPow(u, N))).ModPow(b, N);

            return(S);
        }
Beispiel #5
0
        /// <summary>
        /// Returns 32 byte array using SHA256 one-way hash of value S.
        /// RijndaelManaged, for example can use max key of 32 bytes directly,
        /// so this is convienent.  If you need more or less entropy, add or subtract
        /// bytes as required.  Naturally, both sides need to be able to generate the same
        /// key bytes.  It is recommended to just use the 32 bytes as returned from this
        /// method.
        /// </summary>
        /// <param name="S"></param>
        /// <returns></returns>
        public static Byte[] CalcK(NetBigInteger S)
        {
            SHA256 sha256 = SHA256.Create();

            Byte[] ba = sha256.ComputeHash(S.ToByteArray());
            return(ba);
        }
Beispiel #6
0
        /// <summary>
        /// Returns N and g as an out parameter based on given keySize.
        /// </summary>
        /// <param name="keySize"></param>
        /// <param name="g"></param>
        /// <returns></returns>
        public static NetBigInteger GetNandG(Int32 keySize, out NetBigInteger g)
        {
            switch (keySize)
            {
            case 1024:
                g = g1024Bit;
                return(N1024Bit);

            case 1536:
                g = g1536Bit;
                return(N1536Bit);

            case 2048:
                g = g2048Bit;
                return(N2048Bit);

            case 3072:
                g = g3072Bit;
                return(N3072Bit);

            case 4096:
                g = g4096Bit;
                return(N4096Bit);

            case 6144:
                g = g6144Bit;
                return(N6144Bit);

            case 8192:
                g = g8192Bit;
                return(N8192Bit);
            }
            throw new ArgumentOutOfRangeException("Invalid key size.");
        }
Beispiel #7
0
        /// <summary>
        /// Calculates client's S.
        /// </summary>
        /// <param name="N"></param>
        /// <param name="g"></param>
        /// <param name="B"></param>
        /// <param name="k"></param>
        /// <param name="x"></param>
        /// <param name="a"></param>
        /// <param name="u"></param>
        /// <returns></returns>
        public static NetBigInteger CalcSClient(NetBigInteger N, NetBigInteger g, NetBigInteger B, NetBigInteger k, NetBigInteger x, NetBigInteger a, NetBigInteger u)
        {
            // <premaster secret> = (B - (k * g^x)) ^ (a + (u * x)) % N
            // (B + (N - ((k*g.ModExp(x,N))%N))) - Do it this way.  Thanks Valery.
            NetBigInteger S = (B.Add(N.Subtract((k.Multiply(g.ModPow(x, N))).Mod(N)))).ModPow(a.Add(u.Multiply(x)), N);

            return(S);
        }
            /// <summary>
            /// Gets data from message
            /// </summary>
            /// <param name="message">source</param>
            protected override void Gets(NetIncomingMessage message)
            {
                this.Username = message.ReadString();
                Int32 bytes = message.ReadInt32();

                this.OtherData = bytes > 0 ? message.ReadBytes(bytes) : new Byte[0];
                this.A         = new NetBigInteger(message.ReadBytes(message.ReadInt32()));
            }
Beispiel #9
0
        /// <summary>
        /// Compute client public ephemeral value (A)
        /// </summary>
        public static byte[] ComputeClientEphemeral(byte[] clientPrivateEphemeral)         // a
        {
            // A= g^a (mod N)
            NetBigInteger a      = new NetBigInteger(NetUtility.ToHexString(clientPrivateEphemeral), 16);
            NetBigInteger retval = g.ModPow(a, N);

            return(retval.ToByteArrayUnsigned());
        }
Beispiel #10
0
 /// <summary>
 /// Calculates k.
 /// </summary>
 /// <param name="N"></param>
 /// <param name="g"></param>
 /// <returns></returns>
 public static NetBigInteger Calck(NetBigInteger N, NetBigInteger g)
 {
     // k = SHA1(N | PAD(g)) SRP-6a
     Byte[] gBytes = g.ToByteArray();
     Byte[] NBytes = N.ToByteArray();
     Byte[] both   = NetUtility.JoinArrays(NBytes, gBytes);
     Byte[] hash   = hashAlgo.ComputeHash(both);
     return(new NetBigInteger(hash));
 }
        /// <summary>
        /// Generates key from request
        /// </summary>
        /// <param name="A">Generated A from request</param>
        /// <param name="v">Verifier v</param>
        private void KeyFromRequest(NetBigInteger A, NetBigInteger v)
        {
            // Shared random scrambler
            Lidgren.Network.NetBigInteger u = NetSRP.Calcu(A, _cache.B);

            // Sessionkey
            _cache.S = NetSRP.CalcSServer(N, A, v, u, _cache.b);
            _cache.K = NetSRP.CalcK(_cache.S);
        }
Beispiel #12
0
        /// <summary>
        /// Creates a verifier that the server can later use to authenticate users later on (v)
        /// </summary>
        public static byte[] ComputeServerVerifier(byte[] privateKey)
        {
            NetBigInteger x = new NetBigInteger(NetUtility.ToHexString(privateKey), 16);

            // Verifier (v) = g^x (mod N)
            var serverVerifier = g.ModPow(x, N);

            return(serverVerifier.ToByteArrayUnsigned());
        }
Beispiel #13
0
 /// <summary>
 /// Calculates u.
 /// </summary>
 /// <param name="A"></param>
 /// <param name="B"></param>
 /// <returns></returns>
 public static NetBigInteger Calcu(NetBigInteger A, NetBigInteger B)
 {
     // Both:  u = SHA1(PAD(A) | PAD(B))
     Byte[] aBytes = A.ToByteArray();
     Byte[] bBytes = B.ToByteArray();
     Byte[] both   = NetUtility.JoinArrays(aBytes, bBytes);
     Byte[] hash   = hashAlgo.ComputeHash(both);
     return(new NetBigInteger(hash));
 }
Beispiel #14
0
        /// <summary>
        /// Generates key from request
        /// </summary>
        /// <param name="A">Generated A from request</param>
        /// <param name="v">Verifier v</param>
        private void KeyFromRequest(NetBigInteger A, NetBigInteger v)
        {
            // Shared random scrambler
            Lidgren.Network.NetBigInteger u = NetSRP.Calcu(A, _cache.B);

            // Sessionkey
            _cache.S = NetSRP.CalcSServer(N, A, v, u, _cache.b);
            _cache.K = NetSRP.CalcK(_cache.S);
        }
Beispiel #15
0
        /// <summary>
        /// Calculates x.
        /// </summary>
        /// <param name="salt"></param>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static NetBigInteger Calcx(Byte[] salt, String userName, String password)
        {
            // x = SHA(s + SHA(userName + ":" + password))
            Byte[]        saltBytes  = salt;
            Byte[]        innerBytes = Encoding.UTF8.GetBytes(userName + ":" + password);
            Byte[]        bytes      = NetUtility.JoinArrays(saltBytes, innerBytes);
            Byte[]        hash       = hashAlgo.ComputeHash(bytes);
            NetBigInteger x          = new NetBigInteger(hash);

            return(x);
        }
Beispiel #16
0
        /// <summary>
        /// M2 is Server's proof of K.
        /// </summary>
        /// <returns></returns>
        public static Byte[] CalcM2(NetBigInteger A, Byte[] M, Byte[] K)
        {
            // Host -> User:  H(A, M, K)
            Byte[]    ABytes = A.ToByteArray();
            ArrayList al     = new ArrayList();

            al.Add(ABytes);
            al.Add(M);
            al.Add(K);
            Byte[] all = NetUtility.JoinArrays(al);
            return(hashAlgo.ComputeHash(all));
        }
Beispiel #17
0
        /// <summary>
        /// Compute server ephemeral value (B)
        /// </summary>
        public static byte[] ComputeServerEphemeral(byte[] serverPrivateEphemeral, byte[] verifier)         // b
        {
            var b = new NetBigInteger(NetUtility.ToHexString(serverPrivateEphemeral), 16);
            var v = new NetBigInteger(NetUtility.ToHexString(verifier), 16);

            // B = kv + g^b (mod N)
            var bb = g.ModPow(b, N);
            var kv = v.Multiply(k);
            var B  = (kv.Add(bb)).Mod(N);

            return(B.ToByteArrayUnsigned());
        }
Beispiel #18
0
        public static byte[] ComputeServerSessionValue(byte[] clientPublicEphemeral, byte[] verifier, byte[] udata, byte[] serverPrivateEphemeral)
        {
            // S = (Av^u) ^ b (mod N)
            var A = new NetBigInteger(NetUtility.ToHexString(clientPublicEphemeral), 16);
            var v = new NetBigInteger(NetUtility.ToHexString(verifier), 16);
            var u = new NetBigInteger(NetUtility.ToHexString(udata), 16);
            var b = new NetBigInteger(NetUtility.ToHexString(serverPrivateEphemeral), 16);

            NetBigInteger retval = v.ModPow(u, N).Multiply(A).Mod(N).ModPow(b, N).Mod(N);

            return(retval.ToByteArrayUnsigned());
        }
Beispiel #19
0
        public static byte[] ComputeClientSessionValue(byte[] serverPublicEphemeral, byte[] xdata, byte[] udata, byte[] clientPrivateEphemeral)
        {
            // (B - kg^x) ^ (a + ux)   (mod N)
            var B = new NetBigInteger(NetUtility.ToHexString(serverPublicEphemeral), 16);
            var x = new NetBigInteger(NetUtility.ToHexString(xdata), 16);
            var u = new NetBigInteger(NetUtility.ToHexString(udata), 16);
            var a = new NetBigInteger(NetUtility.ToHexString(clientPrivateEphemeral), 16);

            var bx   = g.ModPow(x, N);
            var btmp = B.Add(N.Multiply(k)).Subtract(bx.Multiply(k)).Mod(N);

            return(btmp.ModPow(x.Multiply(u).Add(a), N).ToByteArrayUnsigned());
        }
Beispiel #20
0
        /// <summary>
        /// Returns A.
        /// </summary>
        /// <param name="N"></param>
        /// <param name="g"></param>
        /// <param name="a"></param>
        /// <returns></returns>
        public static NetBigInteger CalcA(NetBigInteger N, NetBigInteger g, NetBigInteger a)
        {
            // A = g^a % N
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (N == null)
            {
                throw new ArgumentNullException("N");
            }

            return(g.ModPow(a, N));
        }
Beispiel #21
0
        public static NetBigInteger Create(string value)
        {
            int res;

            PexAssume.IsTrue(int.TryParse(value, out res));

            NetBigInteger netBigInteger = new NetBigInteger(value);

            return(netBigInteger);

            // TODO: Edit factory method of NetBigInteger
            // This method should be able to configure the object in all possible ways.
            // Add as many parameters as needed,
            // and assign their values to each field by using the API.
        }
        /// <summary>
        /// This functions generates a database entry for the given username and password. It
        /// is key that this function can only be called from a safe environment and that the
        /// password is sent safely to this function. Think about SSL encryption or one time
        /// one way keys and so forth. Do your best! We actually generate these on the client
        /// so the password is NEVER sent over the network, and then sent it over an encrypted
        /// channel.
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="keysize"></param>
        /// <returns></returns>
        public static PlayerDatabaseEntry Generate(String username, String password, Int32 keysize)
        {
            Byte[] salt;

            // Calculates the verifier with a random salt
            // And we make sure the username is no longer case sensitive
            NetBigInteger verifier = Handshake.PasswordVerifier(username.ToLower().Trim(), password, keysize, out salt);

            // Returns the new entry
            return(new PlayerDatabaseEntry()
            {
                Username = username,
                Salt = salt,
                Verifier = verifier.ToByteArray()
            });
        }
Beispiel #23
0
        /// <summary>
        /// Generates Session key from response
        /// </summary>
        /// <param name="response"></param>
        /// <response></response>
        private NetSRP.Verification KeyFromResponse(NetSRP.Response response)
        {
            if ((Handshake.State.AllowVerificating & this.HandshakeState) != this.HandshakeState)
            {
                return(_verification); // Double Request
            }
            // When we get the response, get their public key B
            if (response.B.Mod(N).IntValue == 0)
            {
                this.HandshakeState = Handshake.State.Failed;
                throw new NetSRP.HandShakeException("Response contains invalid data", new ArgumentException("B mod N is zero."));
            }

            // Shared random scrambler
            NetBigInteger u = NetSRP.Calcu(_cache.A, response.B);

            if (u.IntValue == 0)
            {
                this.HandshakeState = Handshake.State.Failed;
                throw new NetSRP.HandShakeException("Response contains invalid data", new ArgumentException("u is zero."));
            }

            // Private key x
            NetBigInteger x = NetSRP.Calcx(response.Salt, _request.Username, _cache.UserData);

            // Cache Response;
            _response = response;

            // Session key
            _cache.S = NetSRP.CalcSClient(N, g, response.B, k, x, _cache.a, u);
            _cache.K = NetSRP.CalcK(_cache.S);


            // Create the verification
            _verification = new NetSRP.Verification(NetSRP.CalcM(N, g, _request.Username, response.Salt, _cache.A, response.B, _cache.K));

            // Set State
            this.HandshakeState = Handshake.State.Verificating;
            return(_verification);
        }
Beispiel #24
0
        /// <summary>
        /// M is client's proof of K.
        /// </summary>
        /// <returns></returns>
        public static Byte[] CalcM(NetBigInteger N, NetBigInteger g, String userName, Byte[] salt, NetBigInteger A, NetBigInteger B, Byte[] K)
        {
            // User -> Host:  M = H(H(N) xor H(g), H(I), s, A, B, K)
            Byte[]    gBytes         = g.ToByteArray();
            Byte[]    NBytes         = N.ToByteArray();
            Byte[]    hg             = hashAlgo.ComputeHash(gBytes);
            Byte[]    hN             = hashAlgo.ComputeHash(NBytes);
            Byte[]    gNXorBytes     = XorArrays(hN, hg);
            Byte[]    userNameBytes  = Encoding.UTF8.GetBytes(userName);
            Byte[]    hUserNameBytes = hashAlgo.ComputeHash(userNameBytes);
            Byte[]    ABytes         = A.ToByteArray();
            Byte[]    BBytes         = B.ToByteArray();
            ArrayList al             = new ArrayList();

            al.Add(gNXorBytes);
            al.Add(hUserNameBytes);
            al.Add(salt);
            al.Add(ABytes);
            al.Add(BBytes);
            al.Add(K);
            Byte[] all = NetUtility.JoinArrays(al);
            return(hashAlgo.ComputeHash(all));
        }
Beispiel #25
0
        /// <summary>
        /// Creates a new Handshake
        /// </summary>
        /// <param name="active">Is active party</param>
        /// <param name="keySize">keysize</param>
        /// <param name="logonManager">logonManager (only needed if passive)</param>
        internal Handshake(Boolean active, Int32 keySize, ILogonManager logonManager)
        {
            // Local Data setup
            _cache        = new NetSRP.State();
            _keySize      = keySize;
            _logonManager = logonManager ?? _defaultLogonManager;

            if (!active && _defaultLogonManager == null)
            {
                _defaultLogonManager = logonManager;
            }

            // We calculate N and G for this insance. I choose to do so, so you can
            // have different keysizes throughout your program and are not stuck with one
            N = NetSRP.GetNandG(_keySize, out g);
            k = NetSRP.Calck(N, g);

            // Set as NotInitialized
            this.HandshakeState = Handshake.State.NotInitialized;

            if (!active && _logonManager == null)
            {
                throw new InvalidOperationException("Receiving handshakes need a logonManager");
            }

            if (keySize == 0 || N == null || g == null || k == null)
            {
                throw new InvalidOperationException("Handshake not intialized");
            }

            // NOTE: this is caused by the length of the hailmessage - larger then 4096 goes over the MTU
            if (keySize < 1024 || keySize > 4096)
            {
                throw new NetException("SRP6Keysize is not supported by Lidgren.Network",
                                       new ArgumentOutOfRangeException("keySize"));
            }
        }
            public NetBigInteger Mod(
                NetBigInteger m)
            {
                if (m.m_sign < 1)
                    throw new ArithmeticException("Modulus must be positive");

                NetBigInteger biggie = Remainder(m);

                return (biggie.m_sign >= 0 ? biggie : biggie.Add(m));
            }
            /// <summary>
            /// Compute server ephemeral value (B)
            /// </summary>
            public static byte[] ComputeServerEphemeral(byte[] serverPrivateEphemeral, byte[] verifier) // b
            {
                var b = new NetBigInteger(NetUtility.ToHexString(serverPrivateEphemeral), 16);
                var v = new NetBigInteger(NetUtility.ToHexString(verifier), 16);

                // B = kv + g^b (mod N) 
                var bb = g.ModPow(b, N);
                var kv = v.Multiply(k);
                var B = (kv.Add(bb)).Mod(N);

                return B.ToByteArrayUnsigned();
            }
            public NetBigInteger[] DivideAndRemainder(
                NetBigInteger val)
            {
                if (val.m_sign == 0)
                    throw new ArithmeticException("Division by zero error");

                NetBigInteger[] biggies = new NetBigInteger[2];

                if (m_sign == 0)
                {
                    biggies[0] = Zero;
                    biggies[1] = Zero;
                }
                else if (val.QuickPow2Check()) // val is power of two
                {
                    int e = val.Abs().BitLength - 1;
                    NetBigInteger quotient = Abs().ShiftRight(e);
                    int[] remainder = LastNBits(e);

                    biggies[0] = val.m_sign == m_sign ? quotient : quotient.Negate();
                    biggies[1] = new NetBigInteger(m_sign, remainder, true);
                }
                else
                {
                    int[] remainder = (int[])m_magnitude.Clone();
                    int[] quotient = Divide(remainder, val.m_magnitude);

                    biggies[0] = new NetBigInteger(m_sign * val.m_sign, quotient, true);
                    biggies[1] = new NetBigInteger(m_sign, remainder, true);
                }

                return biggies;
            }
 public NetBigInteger Max(
     NetBigInteger value)
 {
     return CompareTo(value) > 0 ? this : value;
 }
            public NetBigInteger Add(
                NetBigInteger value)
            {
                if (m_sign == 0)
                    return value;

                if (m_sign != value.m_sign)
                {
                    if (value.m_sign == 0)
                        return this;

                    if (value.m_sign < 0)
                        return Subtract(value.Negate());

                    return value.Subtract(Negate());
                }

                return AddToMagnitude(value.m_magnitude);
            }
 public int CompareTo(
     NetBigInteger value)
 {
     return m_sign < value.m_sign ? -1
         : m_sign > value.m_sign ? 1
         : m_sign == 0 ? 0
         : m_sign * CompareNoLeadingZeroes(0, m_magnitude, 0, value.m_magnitude);
 }
Beispiel #32
0
 /// <summary>
 /// Calculates V.  The password verifier.
 /// </summary>
 /// <param name="N"></param>
 /// <param name="g"></param>
 /// <param name="x"></param>
 /// <returns></returns>
 public static NetBigInteger CalcV(NetBigInteger N, NetBigInteger g, NetBigInteger x)
 {
     // v = g^x % N
     return(g.ModPow(x, N));
 }
 /// <summary>
 /// Returns N and g as an out parameter based on given keySize.
 /// </summary>
 /// <param name="keySize"></param>
 /// <param name="g"></param>
 /// <returns></returns>
 public static NetBigInteger GetNandG(Int32 keySize, out NetBigInteger g)
 {
     switch (keySize)
     {
         case 1024:
             g = g1024Bit;
             return N1024Bit;
         case 1536:
             g = g1536Bit;
             return N1536Bit;
         case 2048:
             g = g2048Bit;
             return N2048Bit;
         case 3072:
             g = g3072Bit;
             return N3072Bit;
         case 4096:
             g = g4096Bit;
             return N4096Bit;
         case 6144:
             g = g6144Bit;
             return N6144Bit;
         case 8192:
             g = g8192Bit;
             return N8192Bit;
     }
     throw new ArgumentOutOfRangeException("Invalid key size.");
 }
 /// <summary>
 /// Creates a new SRPRequest
 /// </summary>
 /// <param name="username">username</param>
 /// <param name="A">Public value</param>
 /// <param name="otherData">Other login data</param>
 public Request(String username, NetBigInteger A, Byte[] otherData)
 {
     this.Username  = username;
     this.A         = A;
     this.OtherData = otherData;
 }
            /// <summary>
            /// Creates a verifier that the server can later use to authenticate users later on (v)
            /// </summary>
            public static byte[] ComputeServerVerifier(byte[] privateKey)
            {
                NetBigInteger x = new NetBigInteger(NetUtility.ToHexString(privateKey), 16);

                // Verifier (v) = g^x (mod N)
                var serverVerifier = g.ModPow(x, N);

                return serverVerifier.ToByteArrayUnsigned();
            }
 /// <summary>
 /// Creates a new SRPResponse
 /// </summary>
 /// <param name="salt">Salt</param>
 /// <param name="B">Public value</param>
 public Response(Byte[] salt, NetBigInteger B)
 {
     this.Salt = salt;
     this.B    = B;
 }
 /// <summary>
 /// Calculates x.
 /// </summary>
 /// <param name="salt"></param>
 /// <param name="userName"></param>
 /// <param name="password"></param>
 /// <returns></returns>
 public static NetBigInteger Calcx(Byte[] salt, String userName, String password)
 {
     // x = SHA(s + SHA(userName + ":" + password))
     Byte[] saltBytes = salt;
     Byte[] innerBytes = Encoding.UTF8.GetBytes(userName + ":" + password);
     Byte[] bytes = NetUtility.JoinArrays(saltBytes, innerBytes);
     Byte[] hash = hashAlgo.ComputeHash(bytes);
     NetBigInteger x = new NetBigInteger(hash);
     return x;
 }
 /// <summary>
 /// Gets data from message
 /// </summary>
 /// <param name="message">source</param>
 protected override void Gets(NetIncomingMessage message)
 {
     this.B    = new NetBigInteger(message.ReadBytes(message.ReadInt32()));
     this.Salt = message.ReadBytes(message.ReadInt32());
 }
 /// <summary>
 /// Creates a new SRPRequest
 /// </summary>
 /// <param name="username">username</param>
 /// <param name="A">Public value</param>
 /// <param name="otherData">Other login data</param>
 public Request(String username, NetBigInteger A, Byte[] otherData)
 {
     this.Username = username;
     this.A = A;
     this.OtherData = otherData;
 }
 /// <summary>
 /// Creates a new SRPRequest
 /// </summary>
 /// <param name="username">username</param>
 /// <param name="A">Public value</param>
 public Request(String username, NetBigInteger A)
 {
     this.Username = username;
     this.A        = A;
 }
 /// <summary>
 /// Gets data from message
 /// </summary>
 /// <param name="message">source</param>
 protected override void Gets(NetIncomingMessage message)
 {
     this.Username = message.ReadString();
     Int32 bytes = message.ReadInt32();
     this.OtherData = bytes > 0 ? message.ReadBytes(bytes) : new Byte[0];
     this.A = new NetBigInteger(message.ReadBytes(message.ReadInt32()));
 }
            /// <summary>
            /// Computes the client session value
            /// </summary>
            public static byte[] ComputeClientSessionValue(byte[] serverPublicEphemeral, byte[] xdata, byte[] udata, byte[] clientPrivateEphemeral)
            {
                // (B - kg^x) ^ (a + ux)   (mod N)
                var B = new NetBigInteger(NetUtility.ToHexString(serverPublicEphemeral), 16);
                var x = new NetBigInteger(NetUtility.ToHexString(xdata), 16);
                var u = new NetBigInteger(NetUtility.ToHexString(udata), 16);
                var a = new NetBigInteger(NetUtility.ToHexString(clientPrivateEphemeral), 16);

                var bx = g.ModPow(x, N);
                var btmp = B.Add(N.Multiply(k)).Subtract(bx.Multiply(k)).Mod(N);
                return btmp.ModPow(x.Multiply(u).Add(a), N).ToByteArrayUnsigned();
            }
            private static NetBigInteger createUValueOf(
                ulong value)
            {
                int msw = (int)(value >> 32);
                int lsw = (int)value;

                if (msw != 0)
                    return new NetBigInteger(1, new int[] { msw, lsw }, false);

                if (lsw != 0)
                {
                    NetBigInteger n = new NetBigInteger(1, new int[] { lsw }, false);
                    // Check for a power of two
                    if ((lsw & -lsw) == lsw)
                    {
                        n.m_numBits = 1;
                    }
                    return n;
                }

                return Zero;
            }
            /// <summary>
            /// Computes the server session value
            /// </summary>
            public static byte[] ComputeServerSessionValue(byte[] clientPublicEphemeral, byte[] verifier, byte[] udata, byte[] serverPrivateEphemeral)
            {
                // S = (Av^u) ^ b (mod N)
                var A = new NetBigInteger(NetUtility.ToHexString(clientPublicEphemeral), 16);
                var v = new NetBigInteger(NetUtility.ToHexString(verifier), 16);
                var u = new NetBigInteger(NetUtility.ToHexString(udata), 16);
                var b = new NetBigInteger(NetUtility.ToHexString(serverPrivateEphemeral), 16);

                NetBigInteger retval = v.ModPow(u, N).Multiply(A).Mod(N).ModPow(b, N).Mod(N);

                return retval.ToByteArrayUnsigned();
            }
            public NetBigInteger And(
                NetBigInteger value)
            {
                if (m_sign == 0 || value.m_sign == 0)
                {
                    return Zero;
                }

                int[] aMag = m_sign > 0
                    ? m_magnitude
                    : Add(One).m_magnitude;

                int[] bMag = value.m_sign > 0
                    ? value.m_magnitude
                    : value.Add(One).m_magnitude;

                bool resultNeg = m_sign < 0 && value.m_sign < 0;
                int resultLength = System.Math.Max(aMag.Length, bMag.Length);
                int[] resultMag = new int[resultLength];

                int aStart = resultMag.Length - aMag.Length;
                int bStart = resultMag.Length - bMag.Length;

                for (int i = 0; i < resultMag.Length; ++i)
                {
                    int aWord = i >= aStart ? aMag[i - aStart] : 0;
                    int bWord = i >= bStart ? bMag[i - bStart] : 0;

                    if (m_sign < 0)
                    {
                        aWord = ~aWord;
                    }

                    if (value.m_sign < 0)
                    {
                        bWord = ~bWord;
                    }

                    resultMag[i] = aWord & bWord;

                    if (resultNeg)
                    {
                        resultMag[i] = ~resultMag[i];
                    }
                }

                NetBigInteger result = new NetBigInteger(1, resultMag, true);

                if (resultNeg)
                {
                    result = result.Not();
                }

                return result;
            }
            private static NetBigInteger ExtEuclid(
                NetBigInteger a,
                NetBigInteger b,
                NetBigInteger u1Out,
                NetBigInteger u2Out)
            {
                NetBigInteger u1 = One;
                NetBigInteger u3 = a;
                NetBigInteger v1 = Zero;
                NetBigInteger v3 = b;

                while (v3.m_sign > 0)
                {
                    NetBigInteger[] q = u3.DivideAndRemainder(v3);

                    NetBigInteger tmp = v1.Multiply(q[0]);
                    NetBigInteger tn = u1.Subtract(tmp);
                    u1 = v1;
                    v1 = tn;

                    u3 = v3;
                    v3 = q[1];
                }

                if (u1Out != null)
                {
                    u1Out.m_sign = u1.m_sign;
                    u1Out.m_magnitude = u1.m_magnitude;
                }

                if (u2Out != null)
                {
                    NetBigInteger tmp = u1.Multiply(a);
                    tmp = u3.Subtract(tmp);
                    NetBigInteger res = tmp.Divide(b);
                    u2Out.m_sign = res.m_sign;
                    u2Out.m_magnitude = res.m_magnitude;
                }

                return u3;
            }
            public NetBigInteger Divide(
                NetBigInteger val)
            {
                if (val.m_sign == 0)
                    throw new ArithmeticException("Division by zero error");

                if (m_sign == 0)
                    return Zero;

                if (val.QuickPow2Check()) // val is power of two
                {
                    NetBigInteger result = Abs().ShiftRight(val.Abs().BitLength - 1);
                    return val.m_sign == m_sign ? result : result.Negate();
                }

                int[] mag = (int[])m_magnitude.Clone();

                return new NetBigInteger(m_sign * val.m_sign, Divide(mag, val.m_magnitude), true);
            }
            public NetBigInteger ModPow(
                NetBigInteger exponent,
                NetBigInteger m)
            {
                if (m.m_sign < 1)
                    throw new ArithmeticException("Modulus must be positive");

                if (m.Equals(One))
                    return Zero;

                if (exponent.m_sign == 0)
                    return One;

                if (m_sign == 0)
                    return Zero;

                int[] zVal = null;
                int[] yAccum = null;
                int[] yVal;

                // Montgomery exponentiation is only possible if the modulus is odd,
                // but AFAIK, this is always the case for crypto algo's
                bool useMonty = ((m.m_magnitude[m.m_magnitude.Length - 1] & 1) == 1);
                long mQ = 0;
                if (useMonty)
                {
                    mQ = m.GetMQuote();

                    // tmp = this * R mod m
                    NetBigInteger tmp = ShiftLeft(32 * m.m_magnitude.Length).Mod(m);
                    zVal = tmp.m_magnitude;

                    useMonty = (zVal.Length <= m.m_magnitude.Length);

                    if (useMonty)
                    {
                        yAccum = new int[m.m_magnitude.Length + 1];
                        if (zVal.Length < m.m_magnitude.Length)
                        {
                            int[] longZ = new int[m.m_magnitude.Length];
                            zVal.CopyTo(longZ, longZ.Length - zVal.Length);
                            zVal = longZ;
                        }
                    }
                }

                if (!useMonty)
                {
                    if (m_magnitude.Length <= m.m_magnitude.Length)
                    {
                        //zAccum = new int[m.magnitude.Length * 2];
                        zVal = new int[m.m_magnitude.Length];
                        m_magnitude.CopyTo(zVal, zVal.Length - m_magnitude.Length);
                    }
                    else
                    {
                        //
                        // in normal practice we'll never see ..
                        //
                        NetBigInteger tmp = Remainder(m);

                        //zAccum = new int[m.magnitude.Length * 2];
                        zVal = new int[m.m_magnitude.Length];
                        tmp.m_magnitude.CopyTo(zVal, zVal.Length - tmp.m_magnitude.Length);
                    }

                    yAccum = new int[m.m_magnitude.Length * 2];
                }

                yVal = new int[m.m_magnitude.Length];

                //
                // from LSW to MSW
                //
                for (int i = 0; i < exponent.m_magnitude.Length; i++)
                {
                    int v = exponent.m_magnitude[i];
                    int bits = 0;

                    if (i == 0)
                    {
                        while (v > 0)
                        {
                            v <<= 1;
                            bits++;
                        }

                        //
                        // first time in initialise y
                        //
                        zVal.CopyTo(yVal, 0);

                        v <<= 1;
                        bits++;
                    }

                    while (v != 0)
                    {
                        if (useMonty)
                        {
                            // Montgomery square algo doesn't exist, and a normal
                            // square followed by a Montgomery reduction proved to
                            // be almost as heavy as a Montgomery mulitply.
                            MultiplyMonty(yAccum, yVal, yVal, m.m_magnitude, mQ);
                        }
                        else
                        {
                            Square(yAccum, yVal);
                            Remainder(yAccum, m.m_magnitude);
                            Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length);
                            ZeroOut(yAccum);
                        }
                        bits++;

                        if (v < 0)
                        {
                            if (useMonty)
                            {
                                MultiplyMonty(yAccum, yVal, zVal, m.m_magnitude, mQ);
                            }
                            else
                            {
                                Multiply(yAccum, yVal, zVal);
                                Remainder(yAccum, m.m_magnitude);
                                Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0,
                                    yVal.Length);
                                ZeroOut(yAccum);
                            }
                        }

                        v <<= 1;
                    }

                    while (bits < 32)
                    {
                        if (useMonty)
                        {
                            MultiplyMonty(yAccum, yVal, yVal, m.m_magnitude, mQ);
                        }
                        else
                        {
                            Square(yAccum, yVal);
                            Remainder(yAccum, m.m_magnitude);
                            Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length);
                            ZeroOut(yAccum);
                        }
                        bits++;
                    }
                }

                if (useMonty)
                {
                    // Return y * R^(-1) mod m by doing y * 1 * R^(-1) mod m
                    ZeroOut(zVal);
                    zVal[zVal.Length - 1] = 1;
                    MultiplyMonty(yAccum, yVal, zVal, m.m_magnitude, mQ);
                }

                NetBigInteger result = new NetBigInteger(1, yVal, true);

                return exponent.m_sign > 0
                    ? result
                    : result.ModInverse(m);
            }
            public NetBigInteger Gcd(
                NetBigInteger value)
            {
                if (value.m_sign == 0)
                    return Abs();

                if (m_sign == 0)
                    return value.Abs();

                NetBigInteger r;
                NetBigInteger u = this;
                NetBigInteger v = value;

                while (v.m_sign != 0)
                {
                    r = u.Mod(v);
                    u = v;
                    v = r;
                }

                return u;
            }
 public NetBigInteger Modulus(
     NetBigInteger val)
 {
     return Mod(val);
 }
 public NetBigInteger Min(
     NetBigInteger value)
 {
     return CompareTo(value) < 0 ? this : value;
 }
            public NetBigInteger Multiply(
                NetBigInteger val)
            {
                if (m_sign == 0 || val.m_sign == 0)
                    return Zero;

                if (val.QuickPow2Check()) // val is power of two
                {
                    NetBigInteger result = ShiftLeft(val.Abs().BitLength - 1);
                    return val.m_sign > 0 ? result : result.Negate();
                }

                if (QuickPow2Check()) // this is power of two
                {
                    NetBigInteger result = val.ShiftLeft(Abs().BitLength - 1);
                    return m_sign > 0 ? result : result.Negate();
                }

                int maxBitLength = BitLength + val.BitLength;
                int resLength = (maxBitLength + BitsPerInt - 1) / BitsPerInt;

                int[] res = new int[resLength];

                if (val == this)
                {
                    Square(res, m_magnitude);
                }
                else
                {
                    Multiply(res, m_magnitude, val.m_magnitude);
                }

                return new NetBigInteger(m_sign * val.m_sign, res, true);
            }
            public NetBigInteger ModInverse(
                NetBigInteger m)
            {
                if (m.m_sign < 1)
                    throw new ArithmeticException("Modulus must be positive");

                NetBigInteger x = new NetBigInteger();
                NetBigInteger gcd = ExtEuclid(this, m, x, null);

                if (!gcd.Equals(One))
                    throw new ArithmeticException("Numbers not relatively prime.");

                if (x.m_sign < 0)
                {
                    x.m_sign = 1;
                    //x = m.Subtract(x);
                    x.m_magnitude = doSubBigLil(m.m_magnitude, x.m_magnitude);
                }

                return x;
            }
            public NetBigInteger Remainder(
                NetBigInteger n)
            {
                if (n.m_sign == 0)
                    throw new ArithmeticException("Division by zero error");

                if (m_sign == 0)
                    return Zero;

                // For small values, use fast remainder method
                if (n.m_magnitude.Length == 1)
                {
                    int val = n.m_magnitude[0];

                    if (val > 0)
                    {
                        if (val == 1)
                            return Zero;

                        int rem = Remainder(val);

                        return rem == 0
                            ? Zero
                            : new NetBigInteger(m_sign, new int[] { rem }, false);
                    }
                }

                if (CompareNoLeadingZeroes(0, m_magnitude, 0, n.m_magnitude) < 0)
                    return this;

                int[] result;
                if (n.QuickPow2Check())  // n is power of two
                {
                    result = LastNBits(n.Abs().BitLength - 1);
                }
                else
                {
                    result = (int[])m_magnitude.Clone();
                    result = Remainder(result, n.m_magnitude);
                }

                return new NetBigInteger(m_sign, result, true);
            }
            /// <summary>
            /// Compute client public ephemeral value (A)
            /// </summary>
            public static byte[] ComputeClientEphemeral(byte[] clientPrivateEphemeral) // a
            {
                // A= g^a (mod N) 
                NetBigInteger a = new NetBigInteger(NetUtility.ToHexString(clientPrivateEphemeral), 16);
                NetBigInteger retval = g.ModPow(a, N);

                return retval.ToByteArrayUnsigned();
            }
            public NetBigInteger ShiftLeft(
                int n)
            {
                if (m_sign == 0 || m_magnitude.Length == 0)
                    return Zero;

                if (n == 0)
                    return this;

                if (n < 0)
                    return ShiftRight(-n);

                NetBigInteger result = new NetBigInteger(m_sign, ShiftLeft(m_magnitude, n), true);

                if (m_numBits != -1)
                {
                    result.m_numBits = m_sign > 0
                        ? m_numBits
                        : m_numBits + n;
                }

                if (m_numBitLength != -1)
                {
                    result.m_numBitLength = m_numBitLength + n;
                }

                return result;
            }
 /// <summary>
 /// Creates a new SRPRequest
 /// </summary>
 /// <param name="username">username</param>
 /// <param name="A">Public value</param>
 public Request(String username, NetBigInteger A)
 {
     this.Username = username;
     this.A = A;
 }
            public NetBigInteger Subtract(
                NetBigInteger n)
            {
                if (n.m_sign == 0)
                    return this;

                if (m_sign == 0)
                    return n.Negate();

                if (m_sign != n.m_sign)
                    return Add(n.Negate());

                int compare = CompareNoLeadingZeroes(0, m_magnitude, 0, n.m_magnitude);
                if (compare == 0)
                    return Zero;

                NetBigInteger bigun, lilun;
                if (compare < 0)
                {
                    bigun = n;
                    lilun = this;
                }
                else
                {
                    bigun = this;
                    lilun = n;
                }

                return new NetBigInteger(m_sign * compare, doSubBigLil(bigun.m_magnitude, lilun.m_magnitude), true);
            }
 /// <summary>
 /// Host stores v (password verifier) in database.
 /// </summary>
 /// <param name="userName"></param>
 /// <param name="password"></param>
 /// <param name="salt"></param>
 /// <param name="N"></param>
 /// <param name="g"></param>
 /// <returns></returns>
 public static NetBigInteger PasswordVerifier(String userName, String password, Byte[] salt, NetBigInteger N, NetBigInteger g)
 {
     NetBigInteger x = NetSRP.Calcx(salt, userName, password);
     return NetSRP.CalcV(N, g, x);
 }
Beispiel #60
0
        /// <summary>
        /// Host stores v (password verifier) in database.
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="salt"></param>
        /// <param name="N"></param>
        /// <param name="g"></param>
        /// <returns></returns>
        public static NetBigInteger PasswordVerifier(String userName, String password, Byte[] salt, NetBigInteger N, NetBigInteger g)
        {
            NetBigInteger x = NetSRP.Calcx(salt, userName, password);

            return(NetSRP.CalcV(N, g, x));
        }