Пример #1
0
        public RemoteGroup(string primeString, string generatorString)
        {
            SHA1Managed sha1 = new SHA1Managed();

            generator = new BigInteger(2);
            byte[] primeBytes = RemotePassword.getBytes(primeString);
            prime = new BigInteger(1, primeBytes);

            byte[] generatorBytes = generator.ToByteArray();
            int pad = primeBytes.Length - generatorBytes.Length;
            byte[] buffer = new byte[primeBytes.Length + Math.Max(0, pad) + generatorBytes.Length];
            Array.Copy(primeBytes, 0, buffer, 0, primeBytes.Length);
            Array.Copy(generatorBytes, 0, buffer, primeBytes.Length + Math.Max(0, pad), generatorBytes.Length);
            byte[] kBytes = sha1.ComputeHash(buffer);
            k = new BigInteger(1, kBytes);
        }
Пример #2
0
        //***********************************************************************
        // Constructor (Default value provided by BigInteger)
        //***********************************************************************

        public BigInteger(BigInteger bi)
        {
            data = new uint[maxLength];

            dataLength = bi.dataLength;

            for (int i = 0; i < dataLength; i++)
                data[i] = bi.data[i];
        }
Пример #3
0
 public static string getHex(BigInteger number)
 {
     return getHex(number.ToByteArray());
 }
Пример #4
0
        public virtual int decode(byte[] source, int sourceOffset)
        {
            int offset = sourceOffset;
            int code = source[offset++] & 0xff;
            int l;
            int count;

            switch (code)
            {
                case edsNull:
                    type = edsTypeNull;
                    break;

                case edsTrue:
                    type = edsTypeBoolean;
                    @bool = true;
                    break;

                case edsFalse:
                    type = edsTypeBoolean;
                    @bool = false;
                    break;

                case edsIntMinus10:
                case edsIntMinus9:
                case edsIntMinus8:
                case edsIntMinus7:
                case edsIntMinus6:
                case edsIntMinus5:
                case edsIntMinus4:
                case edsIntMinus3:
                case edsIntMinus2:
                case edsIntMinus1:
                case edsInt0:
                case edsInt1:
                case edsInt2:
                case edsInt3:
                case edsInt4:
                case edsInt5:
                case edsInt6:
                case edsInt7:
                case edsInt8:
                case edsInt9:
                case edsInt10:
                case edsInt11:
                case edsInt12:
                case edsInt13:
                case edsInt14:
                case edsInt15:
                case edsInt16:
                case edsInt17:
                case edsInt18:
                case edsInt19:
                case edsInt20:
                case edsInt21:
                case edsInt22:
                case edsInt23:
                case edsInt24:
                case edsInt25:
                case edsInt26:
                case edsInt27:
                case edsInt28:
                case edsInt29:
                case edsInt30:
                case edsInt31:
                    integer32 = code - edsInt0;
                    scale = 0;
                    type = edsTypeInt32;
                    break;

                case edsIntLen1:
                    type = edsTypeInt32;
                    scale = 0;
                    integer32 = (sbyte)source[offset++];
                    break;

                case edsIntLen2:
                    type = edsTypeInt32;
                    scale = 0;
                    integer32 = ((sbyte)source[offset] << 8) | (source[offset + 1] & 0xff);
                    offset += 2;
                    break;

                case edsIntLen3:
                    type = edsTypeInt32;
                    scale = 0;
                    integer32 = ((sbyte)source[offset]) << 16 | (source[offset + 1] & 0xff) << 8 | (source[offset + 2] & 0xff);
                    offset += 3;
                    break;

                case edsIntLen4:
                    type = edsTypeInt32;
                    scale = 0;
                    integer32 = ((sbyte)source[offset]) << 24 | (source[offset + 1] & 0xff) << 16 | (source[offset + 2] & 0xff) << 8 | (source[offset + 3] & 0xff);
                    offset += 4;
                    break;

                case edsIntLen5:
                case edsIntLen6:
                case edsIntLen7:
                case edsIntLen8:
                    l = code - edsIntLen1;
                    integer64 = (sbyte)source[offset++];

                    for (int n = 0; n < l; ++n)
                    {
                        integer64 = (integer64 << 8) | (source[offset++] & 0xff);
                    }

                    scale = 0;
                    type = edsTypeInt64;
                    break;

                case edsScaledLen0:
                    scale = (sbyte)source[offset++];
                    integer64 = 0;
                    type = edsTypeScaled;
                    break;

                case edsScaledLen1:
                case edsScaledLen2:
                case edsScaledLen3:
                case edsScaledLen4:
                case edsScaledLen5:
                case edsScaledLen6:
                case edsScaledLen7:
                case edsScaledLen8:
                    scale = (sbyte)source[offset++];
                    l = code - edsScaledLen1;
                    integer64 = (sbyte)source[offset++];

                    for (int n = 0; n < l; ++n)
                    {
                        integer64 = (integer64 << 8) | (source[offset++] & 0xff);
                    }

                    type = edsTypeScaled;
                    break;

                case edsUtf8Len0:
                case edsUtf8Len1:
                case edsUtf8Len2:
                case edsUtf8Len3:
                case edsUtf8Len4:
                case edsUtf8Len5:
                case edsUtf8Len6:
                case edsUtf8Len7:
                case edsUtf8Len8:
                case edsUtf8Len9:
                case edsUtf8Len10:
                case edsUtf8Len11:
                case edsUtf8Len12:
                case edsUtf8Len13:
                case edsUtf8Len14:
                case edsUtf8Len15:
                case edsUtf8Len16:
                case edsUtf8Len17:
                case edsUtf8Len18:
                case edsUtf8Len19:
                case edsUtf8Len20:
                case edsUtf8Len21:
                case edsUtf8Len22:
                case edsUtf8Len23:
                case edsUtf8Len24:
                case edsUtf8Len25:
                case edsUtf8Len26:
                case edsUtf8Len27:
                case edsUtf8Len28:
                case edsUtf8Len29:
                case edsUtf8Len30:
                case edsUtf8Len31:
                case edsUtf8Len32:
                case edsUtf8Len33:
                case edsUtf8Len34:
                case edsUtf8Len35:
                case edsUtf8Len36:
                case edsUtf8Len37:
                case edsUtf8Len38:
                case edsUtf8Len39:
                    l = code - edsUtf8Len0;
                    @string = getString(source, offset, l);
                    offset += l;
                    type = edsTypeUtf8;
                    break;

                case edsUtf8Count1:
                case edsUtf8Count2:
                case edsUtf8Count3:
                case edsUtf8Count4:
                    count = code - edsUtf8Count1;
                    int length = source[offset++] & 0xff;

                    for (int n = 0; n < count; ++n)
                    {
                        length = length << 8 | (source[offset++] & 0xff);
                    }

                    @string = getString(source, offset, length);
                    offset += length;
                    type = edsTypeUtf8;
                    break;

                case edsOpaqueLen0:
                case edsOpaqueLen1:
                case edsOpaqueLen2:
                case edsOpaqueLen3:
                case edsOpaqueLen4:
                case edsOpaqueLen5:
                case edsOpaqueLen6:
                case edsOpaqueLen7:
                case edsOpaqueLen8:
                case edsOpaqueLen9:
                case edsOpaqueLen10:
                case edsOpaqueLen11:
                case edsOpaqueLen12:
                case edsOpaqueLen13:
                case edsOpaqueLen14:
                case edsOpaqueLen15:
                case edsOpaqueLen16:
                case edsOpaqueLen17:
                case edsOpaqueLen18:
                case edsOpaqueLen19:
                case edsOpaqueLen20:
                case edsOpaqueLen21:
                case edsOpaqueLen22:
                case edsOpaqueLen23:
                case edsOpaqueLen24:
                case edsOpaqueLen25:
                case edsOpaqueLen26:
                case edsOpaqueLen27:
                case edsOpaqueLen28:
                case edsOpaqueLen29:
                case edsOpaqueLen30:
                case edsOpaqueLen31:
                case edsOpaqueLen32:
                case edsOpaqueLen33:
                case edsOpaqueLen34:
                case edsOpaqueLen35:
                case edsOpaqueLen36:
                case edsOpaqueLen37:
                case edsOpaqueLen38:
                case edsOpaqueLen39:
                    l = code - edsOpaqueLen0;
                    bytes = new byte[l];
                    Array.Copy(source, offset, bytes, 0, l);
                    offset += l;
                    type = edsTypeOpaque;
                    break;

                case edsOpaqueCount1:
                case edsOpaqueCount2:
                case edsOpaqueCount3:
                case edsOpaqueCount4:
                    count = code - edsOpaqueCount1 + 1;
                    l = source[offset++] & 0xff;

                    for (int n = 1; n < count; ++n)
                    {
                        l = l << 8 | (source[offset++] & 0xff);
                    }

                    bytes = new byte[l];
                    Array.Copy(source, offset, bytes, 0, l);
                    offset += l;
                    type = edsTypeOpaque;
                    break;

                case edsDoubleLen0:
                case edsDoubleLen1:
                case edsDoubleLen2:
                case edsDoubleLen3:
                case edsDoubleLen4:
                case edsDoubleLen5:
                case edsDoubleLen6:
                case edsDoubleLen7:
                case edsDoubleLen8:
                    count = code - edsDoubleLen0;
                    long lvalue = 0;

                    for (int n = 0; n < count; ++n)
                    {
                        lvalue = (lvalue << 8) | (source[offset++] & 0xff);
                    }

                    lvalue <<= (8 - count) * 8;
                    dbl = BitConverter.Int64BitsToDouble(lvalue);
                    type = edsTypeDouble;
                    break;

                case edsTimeLen0:
                    integer64 = 0;
                    scale = 0;
                    type = edsTypeTime;
                    break;

                case edsTimeLen1:
                case edsTimeLen2:
                case edsTimeLen3:
                case edsTimeLen4:
                    l = code - edsTimeLen1;
                    integer64 = (sbyte)source[offset++];

                    for (int n = 0; n < l; ++n)
                    {
                        integer64 = (integer64 << 8) | (source[offset++] & 0xff);
                    }

                    scale = 0;
                    type = edsTypeTime;
                    break;

                case edsMilliSecLen0:
                    integer64 = 0;
                    scale = 0;
                    type = edsTypeMilliseconds;
                    break;

                case edsMilliSecLen1:
                case edsMilliSecLen2:
                case edsMilliSecLen3:
                case edsMilliSecLen4:
                case edsMilliSecLen5:
                case edsMilliSecLen6:
                case edsMilliSecLen7:
                case edsMilliSecLen8:
                    l = code - edsMilliSecLen1;
                    integer64 = (sbyte)source[offset++];

                    for (int n = 0; n < l; ++n)
                    {
                        integer64 = (integer64 << 8) | (source[offset++] & 0xff);
                    }

                    scale = 0;
                    type = edsTypeMilliseconds;
                    break;

                case edsNanoSecLen0:
                    integer64 = 0;
                    scale = 0;
                    type = edsTypeNanoseconds;
                    break;

                case edsNanoSecLen1:
                case edsNanoSecLen2:
                case edsNanoSecLen3:
                case edsNanoSecLen4:
                case edsNanoSecLen5:
                case edsNanoSecLen6:
                case edsNanoSecLen7:
                case edsNanoSecLen8:
                    l = code - edsNanoSecLen1;
                    integer64 = (sbyte)source[offset++];

                    for (int n = 0; n < l; ++n)
                    {
                        integer64 = (integer64 << 8) | (source[offset++] & 0xff);
                    }

                    scale = 0;
                    type = edsTypeNanoseconds;
                    break;

                //
                // 09/2012 Added support for new scaled date/times encoding. These replace the old encoding
                // edsTimeLen, edsMilliSecLen and edsNanoSecLen.
                //

                case edsScaledTimeLen1:
                case edsScaledTimeLen2:
                case edsScaledTimeLen3:
                case edsScaledTimeLen4:
                case edsScaledTimeLen5:
                case edsScaledTimeLen6:
                case edsScaledTimeLen7:
                case edsScaledTimeLen8:
                    scale = (sbyte)source[offset++];
                    l = code - edsScaledTimeLen1 + 1;
                    integer64 = (sbyte)source[offset++];

                    for (int n = 1; n < l; ++n)
                    {
                        integer64 = (integer64 << 8) | (source[offset++] & 0xff);
                    }

                    type = edsTypeScaledTime;
                    break;

                case edsScaledDateLen1:
                case edsScaledDateLen2:
                case edsScaledDateLen3:
                case edsScaledDateLen4:
                case edsScaledDateLen5:
                case edsScaledDateLen6:
                case edsScaledDateLen7:
                case edsScaledDateLen8:
                    scale = (sbyte)source[offset++];
                    l = code - edsScaledDateLen1 + 1;
                    integer64 = (sbyte)source[offset++];

                    for (int n = 1; n < l; ++n)
                    {
                        integer64 = (integer64 << 8) | (source[offset++] & 0xff);
                    }

                    type = edsTypeScaledDate;
                    break;

                case edsScaledTimestampLen1:
                case edsScaledTimestampLen2:
                case edsScaledTimestampLen3:
                case edsScaledTimestampLen4:
                case edsScaledTimestampLen5:
                case edsScaledTimestampLen6:
                case edsScaledTimestampLen7:
                case edsScaledTimestampLen8:
                    scale = (sbyte)source[offset++];
                    l = code - edsScaledTimestampLen1 + 1;
                    integer64 = (sbyte)source[offset++];

                    for (int n = 1; n < l; ++n)
                    {
                        integer64 = (integer64 << 8) | (source[offset++] & 0xff);
                    }

                    type = edsTypeScaledTimestamp;
                    break;

                case edsClobLen0:
                    blobId = 0;
                    type = edsTypeClob;
                    break;

                case edsClobLen1:
                case edsClobLen2:
                case edsClobLen3:
                case edsClobLen4:
                    l = code - edsClobLen1;
                    blobId = (sbyte)source[offset++];

                    for (int n = 0; n < l; ++n)
                    {
                        blobId = (blobId << 8) | (source[offset++] & 0xff);
                    }

                    type = edsTypeClob;
                    break;

                case edsBlobLen0:
                    blobId = 0;
                    type = edsTypeBlob;
                    break;

                case edsBlobLen1:
                case edsBlobLen2:
                case edsBlobLen3:
                case edsBlobLen4:
                    l = code - edsBlobLen1;
                    blobId = (sbyte)source[offset++];

                    for (int n = 0; n < l; ++n)
                    {
                        blobId = (blobId << 8) | (source[offset++] & 0xff);
                    }

                    type = edsTypeBlob;
                    break;

                case edsScaledCount1:
                    {
                        // For some reason C++ EncodedStream expects the encoded
                        // length to be length+1.

                        length = (source[offset++] & 0xff) - 1;
                        scale = (sbyte)source[offset++];
                        type = edsTypeBigInt;
                        bytes = new byte[length];
                        Array.Copy(source, offset, bytes, 0, length);
                        offset += length;
                        int sign = ((bytes[0] & 0x80) > 0) ? -1 : 1;

                        if (sign == -1)
                        {
                            bytes[0] &= 0x7f;
                        }

                        BigInteger bi = new BigInteger(bytes);
                        bigDecimal = Decimal.Parse(bi.ToString());
                    }
                    break;

                case edsScaledCount2:
                    {
                        // For some reason C++ EncodedStream expects the encoded
                        // length to be length+1.

                        scale = (sbyte)source[offset++];
                        sbyte sign = (sbyte)source[offset++];
                        length = (source[offset++] & 0xff); // in bytes
                        type = edsTypeBigInt;
                        bytes = new byte[length];
                        Array.Copy(source, offset, bytes, 0, length);
                        offset += length;

                        if (sign == -1)
                            bytes[0] &= 0x7f;
                        else
                            sign = 1;

                        BigInteger bi = new BigInteger(bytes);
                        if (sign == -1)
                            bi = -bi;
                        bigDecimal = ScaleDecimal(Decimal.Parse(bi.ToString()), scale);
                    }
                    break;

                case edsUUID:
                    {
                        byte[] buff = new byte[16];

                        for (int n = 0; n < 16; ++n)
                        {
                            buff[n] = (byte)(source[offset++] & 0xff);
                        }

                        uuid = new Guid(buff);
                        type = edsTypeUUID;
                    }
                    break;

                default:
                    type = edsTypeUnknown;
                    break;
            }

            priorCode = code;

            return offset;
        }
Пример #5
0
        //***********************************************************************
        // Overloading of the NEGATE operator (2's complement)
        //***********************************************************************

        public static BigInteger operator -(BigInteger bi1)
        {
            // handle neg of zero separately since it'll cause an overflow
            // if we proceed.

            if (bi1.dataLength == 1 && bi1.data[0] == 0)
                return (new BigInteger());

            BigInteger result = new BigInteger(bi1);

            // 1's complement
            for (int i = 0; i < maxLength; i++)
                result.data[i] = (uint)(~(bi1.data[i]));

            // add one to result of 1's complement
            long val, carry = 1;
            int index = 0;

            while (carry != 0 && index < maxLength)
            {
                val = (long)(result.data[index]);
                val++;

                result.data[index] = (uint)(val & 0xFFFFFFFF);
                carry = val >> 32;

                index++;
            }

            if ((bi1.data[maxLength - 1] & 0x80000000) == (result.data[maxLength - 1] & 0x80000000))
                throw (new ArithmeticException("Overflow in negation.\n"));

            result.dataLength = maxLength;

            while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)
                result.dataLength--;
            return result;
        }
Пример #6
0
        //***********************************************************************
        // Overloading of subtraction operator
        //***********************************************************************

        public static BigInteger operator -(BigInteger bi1, BigInteger bi2)
        {
            BigInteger result = new BigInteger();

            result.dataLength = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;

            long carryIn = 0;
            for (int i = 0; i < result.dataLength; i++)
            {
                long diff;

                diff = (long)bi1.data[i] - (long)bi2.data[i] - carryIn;
                result.data[i] = (uint)(diff & 0xFFFFFFFF);

                if (diff < 0)
                    carryIn = 1;
                else
                    carryIn = 0;
            }

            // roll over to negative
            if (carryIn != 0)
            {
                for (int i = result.dataLength; i < maxLength; i++)
                    result.data[i] = 0xFFFFFFFF;
                result.dataLength = maxLength;
            }

            // fixed in v1.03 to give correct datalength for a - (-b)
            while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)
                result.dataLength--;

            // overflow check

            int lastPos = maxLength - 1;
            if ((bi1.data[lastPos] & 0x80000000) != (bi2.data[lastPos] & 0x80000000) &&
               (result.data[lastPos] & 0x80000000) != (bi1.data[lastPos] & 0x80000000))
            {
                throw (new ArithmeticException());
            }

            return result;
        }
Пример #7
0
        //***********************************************************************
        // Overloading of unary << operators
        //***********************************************************************

        public static BigInteger operator <<(BigInteger bi1, int shiftVal)
        {
            BigInteger result = new BigInteger(bi1);
            result.dataLength = shiftLeft(result.data, shiftVal);

            return result;
        }
Пример #8
0
        public virtual string genServerKey(BigInteger privateKey, string verifier)
        {
            serverPrivateKey = privateKey; // b
            BigInteger gb = generator.modPow(serverPrivateKey, prime); // g^b
            BigInteger v = new BigInteger(getBytes(verifier)); // v
            BigInteger kv = k * v;
            kv = kv % prime;
            serverPublicKey = kv + gb;
            serverPublicKey = serverPublicKey % prime;

            return getHex(serverPublicKey);
        }
Пример #9
0
        public virtual string setClientPrivateKey(string key)
        {
            clientPrivateKey = new BigInteger(getBytes(key));
            clientPublicKey = generator.modPow(clientPrivateKey, prime);

            return getHex(clientPublicKey);
        }
Пример #10
0
        public virtual string genClientKey()
        {
            clientPrivateKey = new BigInteger(256, random);
            clientPublicKey = generator.modPow(clientPrivateKey, prime);

            return getHex(clientPublicKey);
        }
Пример #11
0
        public virtual string genSalt()
        {
            BigInteger n = new BigInteger(256, random);

            return getHex(n);
        }
Пример #12
0
        // Server session key
        public virtual byte[] computeSessionKey(string clientPubKey, string verifier)
        {
            clientPublicKey = getBigInteger(clientPubKey);
            computeScramble();
            BigInteger v = getBigInteger(verifier);
            BigInteger vu = v.modPow(scramble, prime); // v^u
            BigInteger Avu = (clientPublicKey * vu) % prime; // Av^u
            BigInteger sessionSecret = Avu.modPow(serverPrivateKey, prime); // (Av^u) ^ b
            byte[] secret = sessionSecret.ToByteArray();
            int n = (secret[0] == 0) ? 1 : 0;

            return sha1.ComputeHash(secret, n, secret.Length - n);
        }
Пример #13
0
        public virtual byte[] computeSessionKey(string account, string password, string salt, string serverPubKey)
        {
            serverPublicKey = getBigInteger(serverPubKey);
            computeScramble();
            BigInteger x = getUserHash(account, password, salt); // x
            BigInteger gx = generator.modPow(x, prime); // g^x
            BigInteger kgx = (k * gx) % prime; // kg^x
            BigInteger diff = (serverPublicKey - kgx) % prime; // B - kg^x
            BigInteger ux = (scramble * x) % prime; // ux
            BigInteger aux = (clientPrivateKey + ux) % prime; // A + ux
            BigInteger sessionSecret = diff.modPow(aux, prime); // (B - kg^x) ^ (a + ux)
            byte[] secret = sessionSecret.ToByteArray();
            int n = (secret[0] == 0) ? 1 : 0;

            return sha1.ComputeHash(secret, n, secret.Length - n);
        }
Пример #14
0
        public virtual void computeScramble()
        {
            byte[] client = clientPublicKey.ToByteArray();
            byte[] server = serverPublicKey.ToByteArray();

            int n1 = (client[0] == 0) ? 1 : 0;
            int n2 = (server[0] == 0) ? 1 : 0;
            byte[] buffer = new byte[client.Length - n1 + server.Length - n2];
            Array.Copy(client, n1, buffer, 0, client.Length - n1);
            Array.Copy(server, n2, buffer, client.Length - n1, server.Length - n2);
            byte[] hash = sha1.ComputeHash(buffer);
            scramble = new BigInteger(hash);
        }
Пример #15
0
        //***********************************************************************
        // Constructor (Default value provided by a string of digits of the
        //              specified base)
        //
        // Example (base 10)
        // -----------------
        // To initialize "a" with the default value of 1234 in base 10
        //      BigInteger a = new BigInteger("1234", 10)
        //
        // To initialize "a" with the default value of -1234
        //      BigInteger a = new BigInteger("-1234", 10)
        //
        // Example (base 16)
        // -----------------
        // To initialize "a" with the default value of 0x1D4F in base 16
        //      BigInteger a = new BigInteger("1D4F", 16)
        //
        // To initialize "a" with the default value of -0x1D4F
        //      BigInteger a = new BigInteger("-1D4F", 16)
        //
        // Note that string values are specified in the <sign><magnitude>
        // format.
        //
        //***********************************************************************

        public BigInteger(string value, int radix)
        {
            BigInteger multiplier = new BigInteger(1);
            BigInteger result = new BigInteger();
            value = (value.ToUpper()).Trim();
            int limit = 0;

            if (value[0] == '-')
                limit = 1;

            for (int i = value.Length - 1; i >= limit; i--)
            {
                int posVal = (int)value[i];

                if (posVal >= '0' && posVal <= '9')
                    posVal -= '0';
                else if (posVal >= 'A' && posVal <= 'Z')
                    posVal = (posVal - 'A') + 10;
                else
                    posVal = 9999999;       // arbitrary large


                if (posVal >= radix)
                    throw (new ArithmeticException("Invalid string in constructor."));
                else
                {
                    if (value[0] == '-')
                        posVal = -posVal;

                    result = result + (multiplier * posVal);

                    if ((i - 1) >= limit)
                        multiplier = multiplier * radix;
                }
            }

            if (value[0] == '-')     // negative values
            {
                if ((result.data[maxLength - 1] & 0x80000000) == 0)
                    throw (new ArithmeticException("Negative underflow in constructor."));
            }
            else    // positive values
            {
                if ((result.data[maxLength - 1] & 0x80000000) != 0)
                    throw (new ArithmeticException("Positive overflow in constructor."));
            }

            data = new uint[maxLength];
            for (int i = 0; i < result.dataLength; i++)
                data[i] = result.data[i];

            dataLength = result.dataLength;
        }
Пример #16
0
        //***********************************************************************
        // Private function that supports the division of two numbers with
        // a divisor that has only 1 digit.
        //***********************************************************************

        private static void singleByteDivide(BigInteger bi1, BigInteger bi2,
                                             BigInteger outQuotient, BigInteger outRemainder)
        {
            uint[] result = new uint[maxLength];
            int resultPos = 0;

            // copy dividend to reminder
            for (int i = 0; i < maxLength; i++)
                outRemainder.data[i] = bi1.data[i];
            outRemainder.dataLength = bi1.dataLength;

            while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0)
                outRemainder.dataLength--;

            ulong divisor = (ulong)bi2.data[0];
            int pos = outRemainder.dataLength - 1;
            ulong dividend = (ulong)outRemainder.data[pos];

            //Console.WriteLine("divisor = " + divisor + " dividend = " + dividend);
            //Console.WriteLine("divisor = " + bi2 + "\ndividend = " + bi1);

            if (dividend >= divisor)
            {
                ulong quotient = dividend / divisor;
                result[resultPos++] = (uint)quotient;

                outRemainder.data[pos] = (uint)(dividend % divisor);
            }
            pos--;

            while (pos >= 0)
            {
                //Console.WriteLine(pos);

                dividend = ((ulong)outRemainder.data[pos + 1] << 32) + (ulong)outRemainder.data[pos];
                ulong quotient = dividend / divisor;
                result[resultPos++] = (uint)quotient;

                outRemainder.data[pos + 1] = 0;
                outRemainder.data[pos--] = (uint)(dividend % divisor);
                //Console.WriteLine(">>>> " + bi1);
            }

            outQuotient.dataLength = resultPos;
            int j = 0;
            for (int i = outQuotient.dataLength - 1; i >= 0; i--, j++)
                outQuotient.data[j] = result[i];
            for (; j < maxLength; j++)
                outQuotient.data[j] = 0;

            while (outQuotient.dataLength > 1 && outQuotient.data[outQuotient.dataLength - 1] == 0)
                outQuotient.dataLength--;

            if (outQuotient.dataLength == 0)
                outQuotient.dataLength = 1;

            while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0)
                outRemainder.dataLength--;
        }
Пример #17
0
        //***********************************************************************
        // Overloading of addition operator
        //***********************************************************************

        public static BigInteger operator +(BigInteger bi1, BigInteger bi2)
        {
            BigInteger result = new BigInteger();

            result.dataLength = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;

            long carry = 0;
            for (int i = 0; i < result.dataLength; i++)
            {
                long sum = (long)bi1.data[i] + (long)bi2.data[i] + carry;
                carry = sum >> 32;
                result.data[i] = (uint)(sum & 0xFFFFFFFF);
            }

            if (carry != 0 && result.dataLength < maxLength)
            {
                result.data[result.dataLength] = (uint)(carry);
                result.dataLength++;
            }

            while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)
                result.dataLength--;


            // overflow check
            int lastPos = maxLength - 1;
            if ((bi1.data[lastPos] & 0x80000000) == (bi2.data[lastPos] & 0x80000000) &&
               (result.data[lastPos] & 0x80000000) != (bi1.data[lastPos] & 0x80000000))
            {
                throw (new ArithmeticException());
            }

            return result;
        }
Пример #18
0
        //***********************************************************************
        // Overloading of division operator
        //***********************************************************************

        public static BigInteger operator /(BigInteger bi1, BigInteger bi2)
        {
            BigInteger quotient = new BigInteger();
            BigInteger remainder = new BigInteger();

            int lastPos = maxLength - 1;
            bool divisorNeg = false, dividendNeg = false;

            if ((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative
            {
                bi1 = -bi1;
                dividendNeg = true;
            }
            if ((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative
            {
                bi2 = -bi2;
                divisorNeg = true;
            }

            if (bi1 < bi2)
            {
                return quotient;
            }

            else
            {
                if (bi2.dataLength == 1)
                    singleByteDivide(bi1, bi2, quotient, remainder);
                else
                    multiByteDivide(bi1, bi2, quotient, remainder);

                if (dividendNeg != divisorNeg)
                    return -quotient;

                return quotient;
            }
        }
Пример #19
0
        //***********************************************************************
        // Overloading of multiplication operator
        //***********************************************************************

        public static BigInteger operator *(BigInteger bi1, BigInteger bi2)
        {
            int lastPos = maxLength - 1;
            bool bi1Neg = false, bi2Neg = false;

            // take the absolute value of the inputs
            try
            {
                if ((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative
                {
                    bi1Neg = true; bi1 = -bi1;
                }
                if ((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative
                {
                    bi2Neg = true; bi2 = -bi2;
                }
            }
            catch (Exception) { }

            BigInteger result = new BigInteger();

            // multiply the absolute values
            try
            {
                for (int i = 0; i < bi1.dataLength; i++)
                {
                    if (bi1.data[i] == 0) continue;

                    ulong mcarry = 0;
                    for (int j = 0, k = i; j < bi2.dataLength; j++, k++)
                    {
                        // k = i + j
                        ulong val = ((ulong)bi1.data[i] * (ulong)bi2.data[j]) +
                                     (ulong)result.data[k] + mcarry;

                        result.data[k] = (uint)(val & 0xFFFFFFFF);
                        mcarry = (val >> 32);
                    }

                    if (mcarry != 0)
                        result.data[i + bi2.dataLength] = (uint)mcarry;
                }
            }
            catch (Exception)
            {
                throw (new ArithmeticException("Multiplication overflow."));
            }


            result.dataLength = bi1.dataLength + bi2.dataLength;
            if (result.dataLength > maxLength)
                result.dataLength = maxLength;

            while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)
                result.dataLength--;

            // overflow check (result is -ve)
            if ((result.data[lastPos] & 0x80000000) != 0)
            {
                if (bi1Neg != bi2Neg && result.data[lastPos] == 0x80000000)    // different sign
                {
                    // handle the special case where multiplication produces
                    // a max negative number in 2's complement.

                    if (result.dataLength == 1)
                        return result;
                    else
                    {
                        bool isMaxNeg = true;
                        for (int i = 0; i < result.dataLength - 1 && isMaxNeg; i++)
                        {
                            if (result.data[i] != 0)
                                isMaxNeg = false;
                        }

                        if (isMaxNeg)
                            return result;
                    }
                }

                throw (new ArithmeticException("Multiplication overflow."));
            }

            // if input has different signs, then result is -ve
            if (bi1Neg != bi2Neg)
                return -result;

            return result;
        }
Пример #20
0
        //***********************************************************************
        // Overloading of modulus operator
        //***********************************************************************

        public static BigInteger operator %(BigInteger bi1, BigInteger bi2)
        {
            BigInteger quotient = new BigInteger();
            BigInteger remainder = new BigInteger(bi1);

            int lastPos = maxLength - 1;
            bool dividendNeg = false;

            if ((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative
            {
                bi1 = -bi1;
                dividendNeg = true;
            }
            if ((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative
                bi2 = -bi2;

            if (bi1 >= bi2)
            {
                if (bi2.dataLength == 1)
                    singleByteDivide(bi1, bi2, quotient, remainder);
                else
                    multiByteDivide(bi1, bi2, quotient, remainder);

                if (dividendNeg)
                    remainder = -remainder;
            }
            // NuoDB CHANGED!!! The original code was returning -remainder, but the Java BigInteger adds the negative remainder to the modulus instead
            if ((remainder.data[lastPos] & 0x80000000) != 0)
                return bi2 + remainder;
            return remainder;
        }
Пример #21
0
        //***********************************************************************
        // Overloading of unary >> operators
        //***********************************************************************

        public static BigInteger operator >>(BigInteger bi1, int shiftVal)
        {
            BigInteger result = new BigInteger(bi1);
            result.dataLength = shiftRight(result.data, shiftVal);


            if ((bi1.data[maxLength - 1] & 0x80000000) != 0) // negative
            {
                for (int i = maxLength - 1; i >= result.dataLength; i--)
                    result.data[i] = 0xFFFFFFFF;

                uint mask = 0x80000000;
                for (int i = 0; i < 32; i++)
                {
                    if ((result.data[result.dataLength - 1] & mask) != 0)
                        break;

                    result.data[result.dataLength - 1] |= mask;
                    mask >>= 1;
                }
                result.dataLength = maxLength;
            }

            return result;
        }
Пример #22
0
        //***********************************************************************
        // Returns a string representing the BigInteger in sign-and-magnitude
        // format in the specified radix.
        //
        // Example
        // -------
        // If the value of BigInteger is -255 in base 10, then
        // ToString(16) returns "-FF"
        //
        //***********************************************************************

        public string ToString(int radix)
        {
            if (radix < 2 || radix > 36)
                throw (new ArgumentException("Radix must be >= 2 and <= 36"));

            string charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string result = "";

            BigInteger a = this;

            bool negative = false;
            if ((a.data[maxLength - 1] & 0x80000000) != 0)
            {
                negative = true;
                try
                {
                    a = -a;
                }
                catch (Exception) { }
            }

            BigInteger quotient = new BigInteger();
            BigInteger remainder = new BigInteger();
            BigInteger biRadix = new BigInteger(radix);

            if (a.dataLength == 1 && a.data[0] == 0)
                result = "0";
            else
            {
                while (a.dataLength > 1 || (a.dataLength == 1 && a.data[0] != 0))
                {
                    singleByteDivide(a, biRadix, quotient, remainder);

                    if (remainder.data[0] < 10)
                        result = remainder.data[0] + result;
                    else
                        result = charSet[(int)remainder.data[0] - 10] + result;

                    a = quotient;
                }
                if (negative)
                    result = "-" + result;
            }

            return result;
        }
Пример #23
0
        //***********************************************************************
        // Private function that supports the division of two numbers with
        // a divisor that has more than 1 digit.
        //
        // Algorithm taken from [1]
        //***********************************************************************

        private static void multiByteDivide(BigInteger bi1, BigInteger bi2,
                                            BigInteger outQuotient, BigInteger outRemainder)
        {
            uint[] result = new uint[maxLength];

            int remainderLen = bi1.dataLength + 1;
            uint[] remainder = new uint[remainderLen];

            uint mask = 0x80000000;
            uint val = bi2.data[bi2.dataLength - 1];
            int shift = 0, resultPos = 0;

            while (mask != 0 && (val & mask) == 0)
            {
                shift++; mask >>= 1;
            }

            //Console.WriteLine("shift = {0}", shift);
            //Console.WriteLine("Before bi1 Len = {0}, bi2 Len = {1}", bi1.dataLength, bi2.dataLength);

            for (int i = 0; i < bi1.dataLength; i++)
                remainder[i] = bi1.data[i];
            shiftLeft(remainder, shift);
            bi2 = bi2 << shift;

            /*
            Console.WriteLine("bi1 Len = {0}, bi2 Len = {1}", bi1.dataLength, bi2.dataLength);
            Console.WriteLine("dividend = " + bi1 + "\ndivisor = " + bi2);
            for(int q = remainderLen - 1; q >= 0; q--)
                    Console.Write("{0:x2}", remainder[q]);
            Console.WriteLine();
            */

            int j = remainderLen - bi2.dataLength;
            int pos = remainderLen - 1;

            ulong firstDivisorByte = bi2.data[bi2.dataLength - 1];
            ulong secondDivisorByte = bi2.data[bi2.dataLength - 2];

            int divisorLen = bi2.dataLength + 1;
            uint[] dividendPart = new uint[divisorLen];

            while (j > 0)
            {
                ulong dividend = ((ulong)remainder[pos] << 32) + (ulong)remainder[pos - 1];
                //Console.WriteLine("dividend = {0}", dividend);

                ulong q_hat = dividend / firstDivisorByte;
                ulong r_hat = dividend % firstDivisorByte;

                //Console.WriteLine("q_hat = {0:X}, r_hat = {1:X}", q_hat, r_hat);

                bool done = false;
                while (!done)
                {
                    done = true;

                    if (q_hat == 0x100000000 ||
                       (q_hat * secondDivisorByte) > ((r_hat << 32) + remainder[pos - 2]))
                    {
                        q_hat--;
                        r_hat += firstDivisorByte;

                        if (r_hat < 0x100000000)
                            done = false;
                    }
                }

                for (int h = 0; h < divisorLen; h++)
                    dividendPart[h] = remainder[pos - h];

                BigInteger kk = new BigInteger(dividendPart);
                BigInteger ss = bi2 * (long)q_hat;

                //Console.WriteLine("ss before = " + ss);
                while (ss > kk)
                {
                    q_hat--;
                    ss -= bi2;
                    //Console.WriteLine(ss);
                }
                BigInteger yy = kk - ss;

                //Console.WriteLine("ss = " + ss);
                //Console.WriteLine("kk = " + kk);
                //Console.WriteLine("yy = " + yy);

                for (int h = 0; h < divisorLen; h++)
                    remainder[pos - h] = yy.data[bi2.dataLength - h];

                /*
                Console.WriteLine("dividend = ");
                for(int q = remainderLen - 1; q >= 0; q--)
                        Console.Write("{0:x2}", remainder[q]);
                Console.WriteLine("\n************ q_hat = {0:X}\n", q_hat);
                */

                result[resultPos++] = (uint)q_hat;

                pos--;
                j--;
            }

            outQuotient.dataLength = resultPos;
            int y = 0;
            for (int x = outQuotient.dataLength - 1; x >= 0; x--, y++)
                outQuotient.data[y] = result[x];
            for (; y < maxLength; y++)
                outQuotient.data[y] = 0;

            while (outQuotient.dataLength > 1 && outQuotient.data[outQuotient.dataLength - 1] == 0)
                outQuotient.dataLength--;

            if (outQuotient.dataLength == 0)
                outQuotient.dataLength = 1;

            outRemainder.dataLength = shiftRight(remainder, shift);

            for (y = 0; y < outRemainder.dataLength; y++)
                outRemainder.data[y] = remainder[y];
            for (; y < maxLength; y++)
                outRemainder.data[y] = 0;
        }
Пример #24
0
        //***********************************************************************
        // Modulo Exponentiation
        //***********************************************************************

        public BigInteger modPow(BigInteger exp, BigInteger n)
        {
            if ((exp.data[maxLength - 1] & 0x80000000) != 0)
                throw (new ArithmeticException("Positive exponents only."));

            BigInteger resultNum = 1;
            BigInteger tempNum;
            bool thisNegative = false;

            if ((this.data[maxLength - 1] & 0x80000000) != 0)   // negative this
            {
                tempNum = -this % n;
                thisNegative = true;
            }
            else
                tempNum = this % n;  // ensures (tempNum * tempNum) < b^(2k)

            if ((n.data[maxLength - 1] & 0x80000000) != 0)   // negative n
                n = -n;

            // calculate constant = b^(2k) / m
            BigInteger constant = new BigInteger();

            int i = n.dataLength << 1;
            constant.data[i] = 0x00000001;
            constant.dataLength = i + 1;

            constant = constant / n;
            int totalBits = exp.bitCount();
            int count = 0;

            // perform squaring and multiply exponentiation
            for (int pos = 0; pos < exp.dataLength; pos++)
            {
                uint mask = 0x01;
                //Console.WriteLine("pos = " + pos);

                for (int index = 0; index < 32; index++)
                {
                    if ((exp.data[pos] & mask) != 0)
                        resultNum = BarrettReduction(resultNum * tempNum, n, constant);

                    mask <<= 1;

                    tempNum = BarrettReduction(tempNum * tempNum, n, constant);


                    if (tempNum.dataLength == 1 && tempNum.data[0] == 1)
                    {
                        // NuoDB CHANGED!!! The original code was returning -resultNum, but the Java BigInteger adds the negative remainder to the modulus instead
                        if (thisNegative && (exp.data[0] & 0x1) != 0)    //odd exp
                            return n+resultNum;
                        return resultNum;
                    }
                    count++;
                    if (count == totalBits)
                        break;
                }
            }

            // NuoDB CHANGED!!! The original code was returning -resultNum, but the Java BigInteger adds the negative remainder to the modulus instead
            if (thisNegative && (exp.data[0] & 0x1) != 0)    //odd exp
                return n+resultNum;

            return resultNum;
        }
Пример #25
0
        public virtual void encodeOldBigDecimal(decimal bd)
        {
            int scale;
            Decimal temp;
            ConvertToScaledDecimal(bd, out scale, out temp);
            int neg = bd.CompareTo(decimal.Zero) == -1 ? 1 : 0;

            // The server expects a byte array with a signed first byte.
            // BigInteger.toByteArray() creates an array of the value in two's compliment.
            // So get the unsigned value and set the sign bit manually.

            BigInteger bi = new BigInteger(Decimal.Truncate(Math.Abs(temp)).ToString(), 10);
            byte[] byteArray = bi.ToByteArray();

            if (neg == 1)
            {
                byteArray[0] |= 0x80;
            }

            write(edsScaledCount1);
            write(byteArray.Length + 1);
            write(scale);
            write(byteArray);
        }
Пример #26
0
        //***********************************************************************
        // Fast calculation of modular reduction using Barrett's reduction.
        // Requires x < b^(2k), where b is the base.  In this case, base is
        // 2^32 (uint).
        //
        // Reference [4]
        //***********************************************************************

        private BigInteger BarrettReduction(BigInteger x, BigInteger n, BigInteger constant)
        {
            int k = n.dataLength,
                kPlusOne = k + 1,
                kMinusOne = k - 1;

            BigInteger q1 = new BigInteger();

            // q1 = x / b^(k-1)
            for (int i = kMinusOne, j = 0; i < x.dataLength; i++, j++)
                q1.data[j] = x.data[i];
            q1.dataLength = x.dataLength - kMinusOne;
            if (q1.dataLength <= 0)
                q1.dataLength = 1;


            BigInteger q2 = q1 * constant;
            BigInteger q3 = new BigInteger();

            // q3 = q2 / b^(k+1)
            for (int i = kPlusOne, j = 0; i < q2.dataLength; i++, j++)
                q3.data[j] = q2.data[i];
            q3.dataLength = q2.dataLength - kPlusOne;
            if (q3.dataLength <= 0)
                q3.dataLength = 1;


            // r1 = x mod b^(k+1)
            // i.e. keep the lowest (k+1) words
            BigInteger r1 = new BigInteger();
            int lengthToCopy = (x.dataLength > kPlusOne) ? kPlusOne : x.dataLength;
            for (int i = 0; i < lengthToCopy; i++)
                r1.data[i] = x.data[i];
            r1.dataLength = lengthToCopy;


            // r2 = (q3 * n) mod b^(k+1)
            // partial multiplication of q3 and n

            BigInteger r2 = new BigInteger();
            for (int i = 0; i < q3.dataLength; i++)
            {
                if (q3.data[i] == 0) continue;

                ulong mcarry = 0;
                int t = i;
                for (int j = 0; j < n.dataLength && t < kPlusOne; j++, t++)
                {
                    // t = i + j
                    ulong val = ((ulong)q3.data[i] * (ulong)n.data[j]) +
                                 (ulong)r2.data[t] + mcarry;

                    r2.data[t] = (uint)(val & 0xFFFFFFFF);
                    mcarry = (val >> 32);
                }

                if (t < kPlusOne)
                    r2.data[t] = (uint)mcarry;
            }
            r2.dataLength = kPlusOne;
            while (r2.dataLength > 1 && r2.data[r2.dataLength - 1] == 0)
                r2.dataLength--;

            r1 -= r2;
            if ((r1.data[maxLength - 1] & 0x80000000) != 0)        // negative
            {
                BigInteger val = new BigInteger();
                val.data[kPlusOne] = 0x00000001;
                val.dataLength = kPlusOne + 1;
                r1 += val;
            }

            while (r1 >= n)
                r1 -= n;

            return r1;
        }
Пример #27
0
        public virtual void encodeBigDecimal(Decimal bd)
        {
            int scale;
            Decimal temp;
            ConvertToScaledDecimal(bd, out scale, out temp);
            if (temp.CompareTo(long.MinValue) > 0 && temp.CompareTo(long.MaxValue) < 0)
                encodeLong((long)temp, scale);
            else
            {
                BigInteger bi = new BigInteger(Decimal.Truncate(Math.Abs(temp)).ToString(), 10);
                byte[] byteArray = bi.ToByteArray();

                write(edsScaledCount2);
                write(scale);
                write(bd.CompareTo(Decimal.Zero));
                write(byteArray.Length);
                write(byteArray);
            }
        }
Пример #28
0
 public RemotePassword()
 {
     RemoteGroup group = RemoteGroup.getGroup(1024);
     prime = group.prime;
     generator = group.generator;
     k = group.k;
     random = RemoteGroup.random;
     sha1 = new SHA1Managed();
 }