public void multiplyMonty(int[] a, int[] x, int[] y, int[] m, long mQuote)
private void multiplyMonty(int[] a, int[] x, int[] y, int[] m, long mQuote)
    public 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        for (int i = 0; i < n; i++)        {            x[i] = a[i + 1];        }    }