Ejemplo n.º 1
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();
		}
Ejemplo n.º 2
0
        public NetBigInteger Max(
			NetBigInteger value)
        {
            return CompareTo(value) > 0 ? this : value;
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
		/// <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();
		}
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        public NetBigInteger Modulus(
			NetBigInteger val)
        {
            return Mod(val);
        }
Ejemplo n.º 8
0
        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;
        }
Ejemplo n.º 9
0
        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;
        }
Ejemplo n.º 10
0
        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;
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
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();
		}
Ejemplo n.º 13
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();
		}
Ejemplo n.º 14
0
        public NetBigInteger Min(
			NetBigInteger value)
        {
            return CompareTo(value) < 0 ? this : value;
        }
Ejemplo n.º 15
0
        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);
        }
Ejemplo n.º 16
0
        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));
        }
Ejemplo n.º 17
0
        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;
        }
Ejemplo n.º 18
0
        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);
        }
Ejemplo n.º 19
0
        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);
        }
Ejemplo n.º 20
0
        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);
        }
Ejemplo n.º 21
0
        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);
        }
Ejemplo n.º 22
0
        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;
        }
Ejemplo n.º 23
0
		/// <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();
		}