示例#1
0
            static SRP()
            {
                // initialize N
                {
                    NHex =
                        //512bit
                        //"D4C7F8A2B32C11B8FBA9581EC4BA4F1B04215642EF7355E37C0FC0443EF756EA2C6B8EEB755A1C723027663CAA265EF785B8FF6A9B35227A52D86633DBDFCA43";
                        //256bit
                        "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3".ToLowerInvariant();
                    N = new BigInteger(NHex, 16);
                    _nbits = N.bitCount();
                    Nminus1 = N - 1;

                //                    if (!N.isProbablePrime(80))
                //                    {
                //                        throw new Exception("Warning: N is not prime");
                //                    }
                //
                //                    if (!(Nminus1 / 2).isProbablePrime(80))
                //                    {
                //                        throw new Exception("Warning: (N-1)/2 is not prime");
                //                    }
                }

                // initialize g
                {
                    gHex = "2";
                    g = new BigInteger(gHex, 16);
                }

                // initialize k = H(N || g)
                {
                    BigInteger ktmp = new BigInteger(HHex(
                        (((NHex.Length & 1) == 0) ? "" : "0") + NHex +
                        new string('0', NHex.Length - gHex.Length) + gHex
                        ), 16);

                    k = (ktmp < N) ? ktmp : (ktmp % N);
                    kHex = k.ToString(16).ToLowerInvariant().TrimStart('0');
                }

                // initialize a, A
                {
                    a = new BigInteger();
                    a.genRandomBits(36);
                    A = g.modPow(a, N);

                    while (A.modInverse(N) == 0)
                    {
                        a = new BigInteger();
                        a.genRandomBits(36);
                        A = g.modPow(a, N);
                    }
                    Ahex = A.ToString(16).ToLowerInvariant().TrimStart('0');
                }
            }
示例#2
0
            /// <summary>
            /// Generate a new SRP verifier. Password is the plaintext password.
            /// </summary>
            /// <returns>The verifier.</returns>
            /// <param name="password">Password.</param>
            //original: (didn't work with 3.5 .Net compiler and was annoying to keep switching to 4.0
            //public static Meteor.Verifier GenerateVerifier(string password, string identity = null, string salt = null)
            public static Meteor.Verifier GenerateVerifier(string password, string identity, string salt)
            {
                if (identity == null)
                {
                    BigInteger i = new BigInteger ();
                    i.genRandomBits (36);
                    identity = i.ToString(16).ToLowerInvariant().TrimStart('0');
                }

                if (salt == null)
                {
                    BigInteger s = new BigInteger ();
                    s.genRandomBits (36);
                    salt = s.ToString(16).ToLowerInvariant().TrimStart('0');
                }

                string x = Hash (salt + Hash (identity + ":" + password));

                BigInteger xi = new BigInteger (x, 16);
                BigInteger v = g.modPow (xi, N);

                return new Meteor.Verifier () {
                    identity = identity,
                    salt = salt,
                    verifier = v.ToString(16).ToLowerInvariant().TrimStart('0')
                };
            }
示例#3
0
            public static void AuthStep1(
                string vHex,
                string AHex,
                out string bHex,
                out string BHex,
                out string uHex)
            {
                BigInteger v = new BigInteger(vHex, 16);
                //BigInteger A = new BigInteger(AHex, 16); REMOVED WARNING

                BigInteger b;
                // b - ephemeral private key
                // b = random between 2 and N-1
                {
                    b = new BigInteger();
                    //[TODO] perhaps here use a better random generator
                    b.genRandomBits(_nbits);

                    if (b >= N)
                    {
                        b = b % Nminus1;
                    }
                    if (b < 2)
                    {
                        b = 2;
                    }
                }
                bHex = b.ToHexString();

                // B = public key
                // B = kv + g^b (mod N)
                BigInteger B = (v * k + g.modPow(b, N)) % N;
                BHex = B.ToHexString();

                BigInteger u;
                // u - scrambling parameter
                // u = H (A || B)
                {
                    int nlen = 2 * ((_nbits + 7) >> 3);

                    BigInteger utmp = new BigInteger(HHex(
                        new string('0', nlen - AHex.Length) + AHex +
                        new string('0', nlen - BHex.Length) + BHex
                        ), 16);

                    u = (utmp < N) ? utmp : (utmp % Nminus1);
                }

                uHex = u.ToHexString();
            }
        //***********************************************************************
        // Generates a random number with the specified number of bits such
        // that gcd(number, this) = 1
        //***********************************************************************

        public BigInteger genCoPrime(int bits)
        {
            bool done = false;
            BigInteger result = new BigInteger();

            while (!done)
            {
                result.genRandomBits(bits);
                //Console.WriteLine(result.ToString(16));

                // gcd test
                BigInteger g = result.gcd(this);
                if (g.dataLength == 1 && g.data[0] == 1)
                    done = true;
            }

            return result;
        }
        //***********************************************************************
        // Generates a positive BigInteger that is probably prime.
        //***********************************************************************

        public static BigInteger genPseudoPrime(int bits, int confidence)
        {
            BigInteger result = new BigInteger();
            bool done = false;

            while (!done)
            {
                result.genRandomBits(bits);
                result.data[0] |= 0x01;		// make it odd

                // prime test
                done = result.isProbablePrime(confidence);
            }
            return result;
        }
        //***********************************************************************
        // Probabilistic prime test based on Solovay-Strassen (Euler Criterion)
        //
        // p is probably prime if for any a < p (a is not multiple of p),
        // a^((p-1)/2) mod p = J(a, p)
        //
        // where J is the Jacobi symbol.
        //
        // Otherwise, p is composite.
        //
        // Returns
        // -------
        // True if "this" is a Euler pseudoprime to randomly chosen
        // bases.  The number of chosen bases is given by the "confidence"
        // parameter.
        //
        // False if "this" is definitely NOT prime.
        //
        //***********************************************************************

        public bool SolovayStrassenTest(int confidence)
        {
            BigInteger thisVal;
            if ((this.data[maxLength - 1] & 0x80000000) != 0)        // negative
                thisVal = -this;
            else
                thisVal = this;

            if (thisVal.dataLength == 1)
            {
                // test small numbers
                if (thisVal.data[0] == 0 || thisVal.data[0] == 1)
                    return false;
                else if (thisVal.data[0] == 2 || thisVal.data[0] == 3)
                    return true;
            }

            if ((thisVal.data[0] & 0x1) == 0)     // even numbers
                return false;


            int bits = thisVal.bitCount();
            BigInteger a = new BigInteger();
            BigInteger p_sub1 = thisVal - 1;
            BigInteger p_sub1_shift = p_sub1 >> 1;

            for (int round = 0; round < confidence; round++)
            {
                bool done = false;

                while (!done)		// generate a < n
                {
                    int testBits = 0;

                    // make sure "a" has at least 2 bits
                    while (testBits < 2)
						testBits = (int)(UnityEngine.Random.value * bits);

                    a.genRandomBits(testBits);

                    int byteLen = a.dataLength;

                    // make sure "a" is not 0
                    if (byteLen > 1 || (byteLen == 1 && a.data[0] != 1))
                        done = true;
                }

                // check whether a factor exists (fix for version 1.03)
                BigInteger gcdTest = a.gcd(thisVal);
                if (gcdTest.dataLength == 1 && gcdTest.data[0] != 1)
                    return false;

                // calculate a^((p-1)/2) mod p

                BigInteger expResult = a.modPow(p_sub1_shift, thisVal);
                if (expResult == p_sub1)
                    expResult = -1;

                // calculate Jacobi symbol
                BigInteger jacob = Jacobi(a, thisVal);

                //Console.WriteLine("a = " + a.ToString(10) + " b = " + thisVal.ToString(10));
                //Console.WriteLine("expResult = " + expResult.ToString(10) + " Jacob = " + jacob.ToString(10));

                // if they are different then it is not prime
                if (expResult != jacob)
                    return false;
            }

            return true;
        }
        //***********************************************************************
        // Probabilistic prime test based on Rabin-Miller's
        //
        // for any p > 0 with p - 1 = 2^s * t
        //
        // p is probably prime (strong pseudoprime) if for any a < p,
        // 1) a^t mod p = 1 or
        // 2) a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1
        //
        // Otherwise, p is composite.
        //
        // Returns
        // -------
        // True if "this" is a strong pseudoprime to randomly chosen
        // bases.  The number of chosen bases is given by the "confidence"
        // parameter.
        //
        // False if "this" is definitely NOT prime.
        //
        //***********************************************************************

        public bool RabinMillerTest(int confidence)
        {
            BigInteger thisVal;
            if ((this.data[maxLength - 1] & 0x80000000) != 0)        // negative
                thisVal = -this;
            else
                thisVal = this;

            if (thisVal.dataLength == 1)
            {
                // test small numbers
                if (thisVal.data[0] == 0 || thisVal.data[0] == 1)
                    return false;
                else if (thisVal.data[0] == 2 || thisVal.data[0] == 3)
                    return true;
            }

            if ((thisVal.data[0] & 0x1) == 0)     // even numbers
                return false;


            // calculate values of s and t
            BigInteger p_sub1 = thisVal - (new BigInteger(1));
            int s = 0;

            for (int index = 0; index < p_sub1.dataLength; index++)
            {
                uint mask = 0x01;

                for (int i = 0; i < 32; i++)
                {
                    if ((p_sub1.data[index] & mask) != 0)
                    {
                        index = p_sub1.dataLength;      // to break the outer loop
                        break;
                    }
                    mask <<= 1;
                    s++;
                }
            }

            BigInteger t = p_sub1 >> s;

            int bits = thisVal.bitCount();
            BigInteger a = new BigInteger();

			System.Random r = new System.Random ();

            for (int round = 0; round < confidence; round++)
            {
                bool done = false;

                while (!done)		// generate a < n
                {
                    int testBits = 0;

                    // make sure "a" has at least 2 bits
                    while (testBits < 2)
						testBits = (int)(r.NextDouble() * bits);

                    a.genRandomBits(testBits);

                    int byteLen = a.dataLength;

                    // make sure "a" is not 0
                    if (byteLen > 1 || (byteLen == 1 && a.data[0] != 1))
                        done = true;
                }

                // check whether a factor exists (fix for version 1.03)
                BigInteger gcdTest = a.gcd(thisVal);
                if (gcdTest.dataLength == 1 && gcdTest.data[0] != 1)
                    return false;

                BigInteger b = a.modPow(t, thisVal);

                /*
                Console.WriteLine("a = " + a.ToString(10));
                Console.WriteLine("b = " + b.ToString(10));
                Console.WriteLine("t = " + t.ToString(10));
                Console.WriteLine("s = " + s);
                */

                bool result = false;

                if (b.dataLength == 1 && b.data[0] == 1)         // a^t mod p = 1
                    result = true;

                for (int j = 0; result == false && j < s; j++)
                {
                    if (b == p_sub1)         // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1
                    {
                        result = true;
                        break;
                    }

                    b = (b * b) % thisVal;
                }

                if (result == false)
                    return false;
            }
            return true;
        }