public static int CryptoOnetimeauth(byte[] Outv, int Outvoffset, byte[] Inv, int Invoffset, long Inlen, byte[] K)
        {
            int j;

            int[] r = new int[17];
            int[] h = new int[17];
            int[] c = new int[17];

            r[0]  = K[0] & 0xFF;
            r[1]  = K[1] & 0xFF;
            r[2]  = K[2] & 0xFF;
            r[3]  = K[3] & 15;
            r[4]  = K[4] & 252;
            r[5]  = K[5] & 0xFF;
            r[6]  = K[6] & 0xFF;
            r[7]  = K[7] & 15;
            r[8]  = K[8] & 252;
            r[9]  = K[9] & 0xFF;
            r[10] = K[10] & 0xFF;
            r[11] = K[11] & 15;
            r[12] = K[12] & 252;
            r[13] = K[13] & 0xFF;
            r[14] = K[14] & 0xFF;
            r[15] = K[15] & 15;
            r[16] = 0;

            for (j = 0; j < 17; ++j)
            {
                h[j] = 0;
            }

            while (Inlen > 0)
            {
                for (j = 0; j < 17; ++j)
                {
                    c[j] = 0;
                }

                for (j = 0; j < 16 && j < Inlen; ++j)
                {
                    c[j] = Inv[Invoffset + j] & 0xff;
                }

                c[j]       = 1;
                Invoffset += j;
                Inlen     -= j;
                Poly1305.Add(h, c);
                Poly1305.Mulmod(h, r);
            }

            Poly1305.Freeze(h);

            for (j = 0; j < 16; ++j)
            {
                c[j] = K[j + 16] & 0xFF;
            }

            c[16] = 0;
            Poly1305.Add(h, c);

            for (j = 0; j < 16; ++j)
            {
                Outv[j + Outvoffset] = (byte)h[j];
            }

            return(0);
        }