public bool KeyGenerationProtocol_UpdateKey(
            IInputChannel input_channel)
        {
            BigInteger foo = input_channel.Recieve();
            BigInteger c   = input_channel.Recieve();
            BigInteger r   = input_channel.Recieve();

            // verify the in-group property
            if (!CheckElement(foo))
            {
                System.Diagnostics.Debug.WriteLine("CheckElement incorrect");
                return(false);
            }

            // check the size of $r$
            if (ToolsMathBigInteger.CompareAbs(r, q) >= 0)
            {
                System.Diagnostics.Debug.WriteLine("compare_absolutes incorrect");
                return(false);
            }
            // verify the proof of knowledge [CaS97]
            BigInteger t = g.ModPow(r, p);

            r = foo.ModPow(c, p);
            t = t * r;
            t = t % p;
            r = mpz_shash_tools.mpz_shash(new BigInteger [] { g, foo, t });
            // c = mpz_shash_tools.mpz_shash(new BigInteger [] {g, h_i, t});

            if (c != r)
            {
                System.Diagnostics.Debug.WriteLine("c != r " + c.BitLength() + " " + r.BitLength());
                System.Diagnostics.Debug.WriteLine("g " + g.BitLength() + " foo " + foo.BitLength() + " t " + t.BitLength());
                return(false);
            }

            // update the global key h
            h *= foo;
            h  = h % p;

            // store the public key
            BigInteger tmp = foo;

            t = mpz_shash_tools.mpz_shash(foo);
            h_j.Add(t.ToString(), tmp);

            // finish
            return(true);
        }
        bool OR_Verify(
            BigInteger y_1,
            BigInteger y_2,
            BigInteger g_1,
            BigInteger g_2,
            IInputChannel input_channel)
        {
            BigInteger c_1 = input_channel.Recieve();
            BigInteger c_2 = input_channel.Recieve();
            BigInteger r_1 = input_channel.Recieve();
            BigInteger r_2 = input_channel.Recieve();
            BigInteger c;

            // check the size of $r_1$ and $r_2$
            if ((ToolsMathBigInteger.CompareAbs(r_1, q) >= 0L) || (ToolsMathBigInteger.CompareAbs(r_2, q) >= 0L))
            {
                return(false);
            }

            // verify (S)PK ($y_1 = g_1^\alpha \vee y_2 = g_2^\beta$) [CaS97]
            BigInteger t_1 = y_1.ModPow(c_1, p);
            BigInteger tmp = g_1.ModPow(r_1, p);

            t_1 = t_1 * tmp;
            t_1 = t_1 % p;

            BigInteger t_2 = y_2.ModPow(c_2, p);

            tmp = g_2.ModPow(r_2, p);
            t_2 = t_2 * tmp;
            t_2 = t_2 % p;

            // check the equation
            // $c_1 + c_2 \stackrel{?}{=} \mathcal{H}(g_1, y_1, g_2, y_2, t_1, t_2)$
            tmp = c_1 + c_2;
            // c = c % q; ERROR this does nothing
            c = mpz_shash_tools.mpz_shash(new BigInteger [] { g_1, y_1, g_2, y_2, t_1, t_2 });
            c = c % q;

            if (tmp != c)
            {
                return(false);
            }
            // finish
            return(true);
        }
        bool CP_Verify(
            BigInteger x,
            BigInteger y,
            BigInteger gg,
            BigInteger hh,
            IInputChannel input_channel,
            bool fpowm_usage)
        {
            BigInteger a;
            BigInteger b;
            BigInteger c = input_channel.Recieve();
            BigInteger r = input_channel.Recieve();

            // check the size of $r$
            if (ToolsMathBigInteger.CompareAbs(r, q) >= 0)
            {
                return(false);
            }

            // verify proof of knowledge (equality of discrete logarithms) [CaS97]
            a = gg.ModPow(r, p);
            b = x.ModPow(c, p);
            a = a * b;
            a = a % p;

            b = hh.ModPow(r, p);
            r = y.ModPow(c, p);
            b = b * r;
            b = b % p;
            r = mpz_shash_tools.mpz_shash(new BigInteger [] { a, b, x, y, gg, hh });
            if (r != c)
            {
                return(false);
            }
            // finish
            return(true);
        }