⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 biginteger.java

📁 J2ME加密算法的代码!里面包括常用的算法
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        if (useMonty)        {            mQ = m.getMQuote();            // tmp = this * R mod m            BigInteger tmp = this.shiftLeft(32 * m.magnitude.length).mod(m);            zVal = tmp.magnitude;            useMonty = (zVal.length <= m.magnitude.length);            if (useMonty)            {                yAccum = new int[m.magnitude.length + 1];                if (zVal.length < m.magnitude.length)                {                    int[] longZ = new int[m.magnitude.length];                    System.arraycopy(zVal, 0, longZ, longZ.length - zVal.length, zVal.length);                    zVal = longZ;                  }            }        }        if (!useMonty)        {            if (magnitude.length <= m.magnitude.length)            {                //zAccum = new int[m.magnitude.length * 2];                zVal = new int[m.magnitude.length];                System.arraycopy(magnitude, 0, zVal, zVal.length - magnitude.length,                        magnitude.length);            }            else            {                //                // in normal practice we'll never see this...                //                BigInteger tmp = this.remainder(m);                //zAccum = new int[m.magnitude.length * 2];                zVal = new int[m.magnitude.length];                System.arraycopy(tmp.magnitude, 0, zVal, zVal.length - tmp.magnitude.length,                        tmp.magnitude.length);            }            yAccum = new int[m.magnitude.length * 2];        }        yVal = new int[m.magnitude.length];        //        // from LSW to MSW        //        for (int i = 0; i < exponent.magnitude.length; i++)        {            int v = exponent.magnitude[i];            int bits = 0;            if (i == 0)            {                while (v > 0)                {                    v <<= 1;                    bits++;                }                //                // first time in initialise y                //                System.arraycopy(zVal, 0, yVal, 0, zVal.length);                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.magnitude, mQ);                }                else                {                    square(yAccum, yVal);                    remainder(yAccum, m.magnitude);                    System.arraycopy(yAccum, yAccum.length - yVal.length, yVal, 0, yVal.length);                    zero(yAccum);                }                bits++;                if (v < 0)                {                    if (useMonty)                    {                        multiplyMonty(yAccum, yVal, zVal, m.magnitude, mQ);                    }                    else                    {                        multiply(yAccum, yVal, zVal);                        remainder(yAccum, m.magnitude);                        System.arraycopy(yAccum, yAccum.length - yVal.length, yVal, 0,                                yVal.length);                        zero(yAccum);                    }                }                v <<= 1;            }            while (bits < 32)            {                if (useMonty)                {                    multiplyMonty(yAccum, yVal, yVal, m.magnitude, mQ);                }                else                {                    square(yAccum, yVal);                    remainder(yAccum, m.magnitude);                    System.arraycopy(yAccum, yAccum.length - yVal.length, yVal, 0, yVal.length);                    zero(yAccum);                }                bits++;            }        }        if (useMonty)        {            // Return y * R^(-1) mod m by doing y * 1 * R^(-1) mod m            zero(zVal);            zVal[zVal.length - 1] = 1;            multiplyMonty(yAccum, yVal, zVal, m.magnitude, mQ);        }        return new BigInteger(1, yVal);    }    /**     * return w with w = x * x - w is assumed to have enough space.     */    private int[] square(int[] w, int[] x)    {        long u1,         u2,         c;        if (w.length != 2 * x.length)        {            throw new IllegalArgumentException("no I don't think so...");        }        for (int i = x.length - 1; i != 0; i--)        {            long v = (x[i] & IMASK);            u1 = v * v;            u2 = u1 >>> 32;            u1 = u1 & IMASK;            u1 += (w[2 * i + 1] & IMASK);            w[2 * i + 1] = (int)u1;            c = u2 + (u1 >> 32);            for (int j = i - 1; j >= 0; j--)            {                u1 = (x[j] & IMASK) * v;                u2 = u1 >>> 31; // multiply by 2!                u1 = (u1 & 0x7fffffff) << 1; // multiply by 2!                u1 += (w[i + j + 1] & IMASK) + c;                w[i + j + 1] = (int)u1;                c = u2 + (u1 >>> 32);            }            c += w[i] & IMASK;            w[i] = (int)c;            w[i - 1] = (int)(c >> 32);        }        u1 = (x[0] & IMASK);        u1 = u1 * u1;        u2 = u1 >>> 32;        u1 = u1 & IMASK;        u1 += (w[1] & IMASK);        w[1] = (int)u1;        w[0] = (int)(u2 + (u1 >> 32) + w[0]);        return w;    }    /**     * return x with x = y * z - x is assumed to have enough space.     */    private int[] multiply(int[] x, int[] y, int[] z)    {        for (int i = z.length - 1; i >= 0; i--)        {            long a = z[i] & IMASK;            long value = 0;            for (int j = y.length - 1; j >= 0; j--)            {                value += a * (y[j] & IMASK) + (x[i + j + 1] & IMASK);                x[i + j + 1] = (int)value;                value >>>= 32;            }            x[i] = (int)value;        }        return x;    }    private long _extEuclid(long a, long b, long[] uOut)    {        long res;        long u1 = 1;        long u3 = a;        long v1 = 0;        long v3 = b;        while (v3 > 0)        {            long q, tn;            q = u3 / v3;            tn = u1 - (v1 * q);            u1 = v1;            v1 = tn;            tn = u3 - (v3 * q);            u3 = v3;            v3 = tn;        }        uOut[0] = u1;        res = (u3 - (u1 * a)) / b;        uOut[1] = res;        return u3;    }    private long _modInverse(long v, long m)        throws ArithmeticException    {        if (m < 0)        {            throw new ArithmeticException("Modulus must be positive");        }        long[]  x = new long[2];        long gcd = _extEuclid(v, m, x);        if (gcd != 1)        {            throw new ArithmeticException("Numbers not relatively prime.");        }        if (x[0] < 0)        {            x[0] = x[0] + m;        }        return x[0];    }    /**     * Calculate mQuote = -m^(-1) mod b with b = 2^32 (32 = word size)     */    private long getMQuote()    {        if (mQuote != -1L)        { // allready calculated            return mQuote;        }        if ((magnitude[magnitude.length - 1] & 1) == 0)        {            return -1L; // not for even numbers        }/*        byte[] bytes = {1, 0, 0, 0, 0};        BigInteger b = new BigInteger(1, bytes); // 2^32        mQuote = this.negate().mod(b).modInverse(b).longValue();*/        long v = (((~this.magnitude[this.magnitude.length - 1]) | 1) & 0xffffffffL);        mQuote = _modInverse(v, 0x100000000L);        return mQuote;    }    /**     * Montgomery multiplication: a = x * y * R^(-1) mod m     * <br>     * Based algorithm 14.36 of Handbook of Applied Cryptography.     * <br>     * <li> m, x, y should have length n </li>     * <li> a should have length (n + 1) </li>     * <li> b = 2^32, R = b^n </li>     * <br>     * The result is put in x     * <br>     * NOTE: the indices of x, y, m, a different in HAC and in Java     */    private void multiplyMonty(int[] a, int[] x, int[] y, int[] m, long mQuote)    // mQuote = -m^(-1) mod b    {        int n = m.length;        int nMinus1 = n - 1;        long y_0 = y[n - 1] & IMASK;        // 1. a = 0 (Notation: a = (a_{n} a_{n-1} ... a_{0})_{b} )        for (int i = 0; i <= n; i++)        {            a[i] = 0;        }        // 2. for i from 0 to (n - 1) do the following:        for (int i = n; i > 0; i--)        {            long x_i = x[i - 1] & IMASK;            // 2.1 u = ((a[0] + (x[i] * y[0]) * mQuote) mod b            long u = ((((a[n] & IMASK) + ((x_i * y_0) & IMASK)) & IMASK) * mQuote) & IMASK;            // 2.2 a = (a + x_i * y + u * m) / b            long prod1 = x_i * y_0;            long prod2 = u * (m[n - 1] & IMASK);            long tmp = (a[n] & IMASK) + (prod1 & IMASK) + (prod2 & IMASK);            long carry = (prod1 >>> 32) + (prod2 >>> 32) + (tmp >>> 32);            for (int j = nMinus1; j > 0; j--)            {                prod1 = x_i * (y[j - 1] & IMASK);                prod2 = u * (m[j - 1] & IMASK);                tmp = (a[j] & IMASK) + (prod1 & IMASK) + (prod2 & IMASK) + (carry & IMASK);                carry = (carry >>> 32) + (prod1 >>> 32) + (prod2 >>> 32) + (tmp >>> 32);                a[j + 1] = (int)tmp; // division by b            }            carry += (a[0] & IMASK);            a[1] = (int)carry;            a[0] = (int)(carry >>> 32);        }        // 3. if x >= m the x = x - m        if (compareTo(0, a, 0, m) >= 0)        {            subtract(0, a, 0, m);        }        // put the result in x        System.arraycopy(a, 1, x, 0, n);    }    public BigInteger multiply(BigInteger val)    {        if (sign == 0 || val.sign == 0)            return BigInteger.ZERO;        int[] res = new int[magnitude.length + val.magnitude.length];        return new BigInteger(sign * val.sign, multiply(res, magnitude, val.magnitude));    }    public BigInteger negate()    {        return new BigInteger( -sign, magnitude);    }    public BigInteger not()    {        return add(ONE).negate();    }    public BigInteger pow(int exp) throws ArithmeticException    {        if (exp < 0)            throw new ArithmeticException("Negative exponent");        if (sign == 0)            return (exp == 0 ? BigInteger.ONE : this);        BigInteger y,         z;        y = BigInteger.ONE;        z = this;        while (exp != 0)        {            if ((exp & 0x1) == 1)            {                y = y.multiply(z);            }            exp >>= 1;            if (exp != 0)            {                z = z.multiply(z);            }        }        return y;    }    private int remainder(int m)    {        long acc = 0;        for (int pos = 0; pos < magnitude.length; ++pos)        {            acc = (acc << 32 | ((long)magnitude[pos] & 0xffffffffL)) % m;        }        return (int) acc;    }        /**     * return x = x % y - done in place (y value preserved)     */    private int[] remainder(int[] x, int[] y)    {        int xyCmp = compareTo(0, x, 0, y);        if (xyCmp > 0)        {            int[] c;            int shift = bitLength(0, x) - bitLength(0, y);            if (shift > 1)            {                c = shiftLeft(y, shift - 1);            }            else            {                c = new int[x.length];                System.arraycopy(y, 0, c, c.length - y.length, y.length);            }            subtract(0, x, 0, c);            int xStart = 0;            int cStart = 0;            for (; ; )            {                int cmp = compareTo(xStart, x, cStart, c);                while (cmp >= 0)                {                    subtract(xStart, x, cStart, c);                    cmp = compareTo(xStart, x, cStart, c);                }                xyCmp = compareTo(xStart, x, 0, y);                if (xyCmp > 0)                {                    if (x[xStart] == 0)                    {                        xStart++;                    }                    shift = bitLength(cStart, c) - bitLength(xStart, x);                    if (shift == 0)                    {                        c = shiftRightOne(cStart, c);                    }                    else                    {                        c = shiftRight(cStart, c, shift);                    }                    if (c[cStart] == 0)                    {                        cStart++;                    }                }                else if (xyCmp == 0)                {                    for (int i = xStart; i != x.length; i++)                    {                        x[i] = 0;                    }                    break;                }                else                {                    break;                }            }        }        else if (xyCmp == 0)        {            for (int i = 0; i != x.length; i++)            {                x[i] = 0;            }        }        return x;    }    public BigInteger remainder(BigInteger val) throws ArithmeticException    {        if (val.sign == 0)        {            throw new ArithmeticException("BigInteger: Divide by zero");        }        if (sign == 0)        {            return BigInteger.ZERO;        }        int[] res = new int[this.magnitude.length];        System.arraycopy(this.magnitude, 0, res, 0, res.length);        return new BigInteger(sign, remainder(res, val.magnitude));    }    /**     * do a left shift - this returns a new array.     */    private int[] shiftLeft(int[] mag, int n)    {        int nInts = n >>> 5;        int nBits = n & 0x1f;        int magLen = mag.length;        int newMag[] = null;        if (nBits == 0)        {            newMag = new int[magLen + nInts];            System.arraycopy(mag, 0, newMag, 0, magLen);        }        else        {            int i = 0;            int nBits2 = 32 - nBits;            int highBits = mag[0] >>> nBits2;            if (highBits != 0)            {                newMag = new int[magLen + nInts + 1];                newMag[i++] = highBits;            }            else            {                newMag = new int[magLen + nInts];            }            int m = mag[0];            for (int j = 0; j < magLen - 1; j++)            {                int next = mag[j + 1];                newMag[i++] = (m << nBits) | (next >>> nBits2);                m = next;            }            newMag[i] = mag[magLen - 1] << nBits;        }        return newMag;    }    public BigInteger shiftLeft(int n)    {        if (sign == 0 || magnitude.length == 0)        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -