protected void processBlock(byte[] in, int inOff)
    {
        System.arraycopy(in, inOff, M, 0, 32);

        //key step 1
 
        // H = h3 || h2 || h1 || h0
        // S = s3 || s2 || s1 || s0
        System.arraycopy(H, 0, U, 0, 32);
        System.arraycopy(M, 0, V, 0, 32);
        for (int j=0; j<32; j++)
        {
            W[j] = (byte)(U[j]^V[j]);
        }
        // Encrypt gost28147-ECB
        E(P(W), S, 0, H, 0); // s0 = EK0 [h0]

        //keys step 2,3,4
        for (int i=1; i<4; i++)
        {
            byte[] tmpA = A(U);
            for (int j=0; j<32; j++)
            {
                U[j] = (byte)(tmpA[j] ^ C[i][j]);
            }
            V = A(A(V));
            for (int j=0; j<32; j++)
            {
                W[j] = (byte)(U[j]^V[j]);
            }
            // Encrypt gost28147-ECB
            E(P(W), S, i * 8, H, i * 8); // si = EKi [hi]
        }

        // x(M, H) = y61(H^y(M^y12(S)))
        for(int n = 0; n < 12; n++)
        {
            fw(S);
        }
        for(int n = 0; n < 32; n++)
        {
            S[n] = (byte)(S[n] ^ M[n]);
        }

        fw(S);

        for(int n = 0; n < 32; n++)
        {
            S[n] = (byte)(H[n] ^ S[n]);
        }
        for(int n = 0; n < 61; n++)
        {
            fw(S);
        }
        System.arraycopy(S, 0, H, 0, H.length);
    }