public PedersenCommitmentScheme(
        int n,
        IInputChannel chanal,
        long fieldsize,
        long subgroupsize)

    {
        F_size = fieldsize;
        G_size = subgroupsize;
        Debug.Assert(n >= 1);

        // Initialize the parameters of the commitment scheme.
        p = chanal.Recieve();
        q = chanal.Recieve();
        k = chanal.Recieve();
        h = chanal.Recieve();

        System.Diagnostics.Debug.WriteLine("PedersenCommitmentScheme::PedersenCommitmentScheme p " + p.BitLength());
        System.Diagnostics.Debug.WriteLine("PedersenCommitmentScheme::PedersenCommitmentScheme q " + q.BitLength());
        System.Diagnostics.Debug.WriteLine("PedersenCommitmentScheme::PedersenCommitmentScheme k " + k.BitLength());
        System.Diagnostics.Debug.WriteLine("PedersenCommitmentScheme::PedersenCommitmentScheme h " + h.BitLength());

        g = new List <BigInteger>();
        for (int i = 0; i < n; i++)
        {
            g.Add(chanal.Recieve());
        }
    }
        bool VerifiableDecryptionProtocol_Verify_Update(
            BigInteger c_1,
            IInputChannel input_channel)
        {
            BigInteger d_j    = input_channel.Recieve();
            BigInteger h_j_fp = input_channel.Recieve();

            // public key stored?
            String str = h_j_fp.ToString();

            if (!h_j.ContainsKey(str))
            {
                return(false);
            }
            // verify the in-group property
            if (!CheckElement(d_j))
            {
                return(false);
            }

            // invoke CP(d_j, h_j, c_1, g; x_j) as verifier
            if (!CP_Verify(d_j, h_j[str], c_1, g, input_channel, false))
            {
                return(false);
            }
            // update the value of $d$
            d = d * d_j;
            d = d * p;

            // finish
            return(true);
        }
        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);
        }
        BarnettSmartVTMF_dlog(
            IInputChannel input_channel,
            long fieldsize,
            long subgroupsize)
        {
            F_size = fieldsize;
            G_size = subgroupsize;
            // Initialize the members for the finite abelian group $G$.
            p = input_channel.Recieve();
            q = input_channel.Recieve();
            g = input_channel.Recieve();
            k = input_channel.Recieve();

            // Initialize all members for the key.
            x_i    = 0;
            h_i    = 0;
            h      = 0;
            d      = 0;
            h_i_fp = 0;
        }
        bool KeyGenerationProtocol_RemoveKey(
            IInputChannel input_channel)
        {
            //  = input_channel.read_big_integer();foo >> bar >> bar;
            BigInteger foo = input_channel.Recieve();

            input_channel.Recieve(); // ???
            BigInteger bar = input_channel.Recieve();

            // compute the fingerprint
            bar = mpz_shash_tools.mpz_shash(foo);

            // public key with this fingerprint stored?
            if (h_j.ContainsKey(bar.ToString()))
            {
                // update the global key
                BigInteger temp = h_j[bar.ToString()];
                if (!ToolsMathBigInteger.AreCoprime(temp, p))
                {
                    return(false);
                }
                else
                {
                    foo = temp.ModInverse(p);
                }
                foo = temp.ModInverse(p);
                h   = h * foo;
                h   = h % p;

                // release the public key
                h_j.Remove(bar.ToString());

                // finish
                return(true);
            }
            else
            {
                return(false);
            }
        }
        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);
        }
Пример #8
0
    public GrothVSSHE(
        int n,
        IInputChannel input_channel,
        long ell_e,
        long fieldsize,
        long subgroupsize)
    {
        l_e = ell_e;

        p = input_channel.Recieve();
        q = input_channel.Recieve();
        g = input_channel.Recieve();
        h = input_channel.Recieve();

        com = new PedersenCommitmentScheme(n, input_channel, fieldsize, subgroupsize);

        IChannel lej = new ChannelOneWay();//TODO this is ugly as hell!!! constructors should not take streams they should take symbols

        com.PublishGroup(lej);
        skc = new GrothSKC(n, lej, ell_e, fieldsize, subgroupsize);

        // Compute $2^{\ell_e}$ for the input reduction.
        exp2l_e = new BigInteger(2).Pow(ell_e);
    }
Пример #9
0
    public bool Verify_interactive(
        List <Tuple <BigInteger, BigInteger> > e,
        List <Tuple <BigInteger, BigInteger> > E,
        IInputChannel input_channel,
        IOutputChannel output_channel)
    {
        Debug.Assert(com.g.Count >= e.Count);
        Debug.Assert(e.Count == E.Count);
        Debug.Assert(E.Count >= 2);

        // initialize
        BigInteger c, c_d, Z, lambda, foo, bar, foo2, bar2, foo3, bar3;

        Tuple <BigInteger, BigInteger> E_d = new Tuple <BigInteger, BigInteger>(1, 1);
        List <BigInteger> f = new List <BigInteger>();
        List <BigInteger> m = new List <BigInteger>();
        List <BigInteger> t = new List <BigInteger>();

        for (int i = 0; i < e.Count; i++)
        {
            f.Add(0);
            m.Add(0);
            t.Add(0);
        }
        // verifier: first move
        c   = input_channel.Recieve();
        c_d = input_channel.Recieve();
        E_d = new Tuple <BigInteger, BigInteger>(input_channel.Recieve(), input_channel.Recieve());

        // verifier: second move
        for (int i = 0; i < t.Count; i++)
        {
            t[i] = mpz_srandom.mpz_srandomb(l_e);
            output_channel.Send(t[i]);
        }

        // verifier: third move
        for (int i = 0; i < f.Count; i++)
        {
            f[i] = input_channel.Recieve();
        }
        Z = input_channel.Recieve();

        // verifier: fourth move
        lambda = mpz_srandom.mpz_srandomb(l_e);
        output_channel.Send(lambda);

        // verifier: fifth to seventh move (Shuffle of Known Content)

        /*
         * This part is not necessary: see personal communication with Jens Groth
         * // SKC commitment $c^{\lambda} c_d \mathrm{com}(f_1,\ldots,f_n;0) \bmod p$
         * mpz_set_ui(bar, 0L);
         * com.CommitBy(foo, bar, f, false);
         * mpz_mul(foo, foo, c_d);
         * mpz_mod(foo, foo, com.p);
         * mpz_powm(bar, c, lambda, com.p);
         * mpz_mul(foo, foo, bar);
         * mpz_mod(foo, foo, com.p);
         */
        // SKC (optimized homomorphic) commitment $c^{\lambda} c_d \bmod p$
        foo = c.ModPow(lambda, com.p);
        foo = foo * c_d;
        foo = foo % com.p;
        // SKC messages
        // $m_i := i \lambda + t_i \bmod q$ for all $i = 1,\ldots, n$
        for (int i = 0; i < m.Count; i++)
        {
            BigInteger value = i + 1;
            value *= lambda;
            value %= com.q;
            value  = value + t[i];
            value  = value % com.q;
            m[i]   = value;
        }

        // perform and verify SKC
        if (!skc.Verify_interactive(foo, f, m, input_channel, output_channel))
        {
            return(false);
        }

        // check whether $c, c_d \in\mathcal{C}_{ck}$
        if (!(com.TestMembership(c) && com.TestMembership(c_d)))
        {
            return(false);
        }

        // check whether $E_d\in\mathcal{C}_{pk}$
        foo = E_d.Item1.ModPow(q, p);
        bar = E_d.Item2.ModPow(q, p);
        if (foo != 1 || bar != 1)
        {
            return(false);
        }

        // check whether $2^{\ell_e} \le f_1,\ldots,f_n < q$
        for (int i = 0; i < f.Count; i++)
        {
            if ((f[i].BitLength() < l_e) || (f[i].CompareTo(com.q) >= 0))
            {
                return(false);
            }
        }

        // check whether $Z\in\mathcal{R}_{pk}$
        if ((Z.CompareTo(0) <= 0) || (Z.CompareTo(q) >= 0))
        {
            return(false);
        }

        // check whether
        // $\prod_{i=1}^n e_i^{-t_i} \prod_{i=1}^n E_i^{f_i} E_d = E(1;Z)$
        foo2 = 1;
        bar2 = 1;
        for (int i = 0; i < e.Count; i++)
        {
            t[i] = t[i].FlipSign();
            foo  = e[i].Item1.ModPow(t[i], p);
            foo2 = foo2 * foo;
            foo2 = foo2 % p;
            bar  = e[i].Item2.ModPow(t[i], p);
            bar2 = bar2 * bar;
            bar2 = bar2 % p;
        }
        foo3 = 1;
        bar3 = 1;
        for (int i = 0; i < E.Count; i++)
        {
            foo  = E[i].Item1.ModPow(f[i], p);
            foo3 = foo3 * foo;
            foo3 = foo3 % p;
            bar  = E[i].Item2.ModPow(f[i], p);
            bar3 = bar3 * bar;
            bar3 = bar3 % p;
        }
        foo3 = foo3 * E_d.Item1;
        foo3 = foo3 % p;
        bar3 = bar3 * E_d.Item2;
        bar3 = bar3 % p;
        foo3 = foo3 * foo2;
        foo3 = foo3 % p;
        bar3 = bar3 * bar2;
        bar3 = bar3 % p;
        foo  = g.ModPow(Z, p);
        bar  = h.ModPow(Z, p);

        if (foo3 == foo || bar3 != bar)
        {
            return(false);
        }
        return(true);
    }
Пример #10
0
    public void Prove_interactive(
        List <int> pi,
        List <BigInteger> R,
        List <Tuple <BigInteger, BigInteger> > e,
        List <Tuple <BigInteger, BigInteger> > E,
        IInputChannel input_channel,
        IOutputChannel output_channel)
    {
        Debug.Assert(com.g.Count >= pi.Count);
        Debug.Assert(pi.Count == R.Count);
        Debug.Assert(R.Count == e.Count);
        Debug.Assert(e.Count == E.Count);
        Debug.Assert(E.Count >= 2);

        // initialize
        BigInteger r, R_d, r_d, c, c_d, Z, lambda, rho, foo, bar;
        Tuple <BigInteger, BigInteger> E_d;

        List <BigInteger> d = new List <BigInteger>();
        List <BigInteger> f = new List <BigInteger>();
        List <BigInteger> m = new List <BigInteger>();
        List <BigInteger> t = new List <BigInteger>();

        for (int i = 0; i < e.Count; i++)
        {
            d.Add(0);
            f.Add(0);
            m.Add(0);
            t.Add(0);
        }

        // prover: first move
        r   = mpz_srandom.mpz_srandomm(com.q);
        R_d = mpz_srandom.mpz_srandomm(q);
        for (int i = 0; i < d.Count; i++)
        {
            d[i] = mpz_srandom.mpz_srandomm(com.q).FlipSign();
        }
        r_d = mpz_srandom.mpz_srandomm(com.q);
        for (int i = 0; i < m.Count; i++)
        {
            m[i] = new BigInteger(pi[i] + 1);
        }
        c   = com.CommitBy(r, m);
        c_d = com.CommitBy(r_d, d);
        E_d = new Tuple <BigInteger, BigInteger>(1, 1);

        for (int i = 0; i < d.Count; i++)
        {
            // Compute and multiply $E_i^{-d_i}$

            foo = E[i].Item1.ModPow(d[i], p);
            BigInteger E_d1 = E_d.Item1;
            E_d1 = E_d1 * foo;
            E_d1 = E_d1 % p;

            bar = E[i].Item2.ModPow(d[i], p);
            BigInteger E_d2 = E_d.Item2;
            E_d2 = E_d2 * bar;
            E_d2 = E_d2 % p;
            E_d  = new Tuple <BigInteger, BigInteger>(E_d1, E_d2);
        }
        // Compute and multiply $E(1;R_d)$
        foo = g.ModPow(R_d, p);
        bar = h.ModPow(R_d, p);
        E_d = new Tuple <BigInteger, BigInteger>((E_d.Item1 * foo) % p, (E_d.Item2 * bar) % p);

        output_channel.Send(c);
        output_channel.Send(c_d);
        output_channel.Send(E_d.Item1);
        output_channel.Send(E_d.Item2);

        // prover: second move
        for (int i = 0; i < f.Count; i++)
        {
            t[i] = input_channel.Recieve();
            // check whether the $t_i$'s are from $\{0, 1\}^{\ell_e}$
            if (t[i].BitLength() > l_e)
            {
                t[i] = t[i] % exp2l_e;
            }
        }

        // prover: third move
        for (int i = 0; i < f.Count; i++)
        {
            f[i] = (d[i].FlipSign() + t[pi[i]]) % com.q;
        }
        Z = 0;

        for (int i = 0; i < t.Count; i++)
        {
            foo = t[pi[i]] * R[i];
            foo = foo % q;
            Z   = Z + foo;
            Z   = Z % q;
        }
        Z = Z + R_d;
        Z = Z % q;

        for (int i = 0; i < f.Count; i++)
        {
            output_channel.Send(f[i]);
        }
        output_channel.Send(Z);
        // prover: fourth move
        lambda = input_channel.Recieve();
        // check whether $\lambda$ is from $\{0, 1\}^{\ell_e}$, otherwise reduce
        if (lambda.BitLength() > l_e)
        {
            lambda = lambda % exp2l_e;
        }
        // prover: fifth to seventh move (Shuffle of Known Content)
        // $\rho := \lambda r + r_d \bmod q$
        rho = lambda * r;
        rho = rho % com.q;
        rho = rho * r_d;
        rho = rho % com.q;

        /*
         * This part is not necessary: see personal communication with Jens Groth
         * // SKC commitment $c^{\lambda} c_d \mathrm{com}(f_1,\ldots,f_n;0) \bmod p$
         * mpz_set_ui(bar, 0L);
         * com.CommitBy(foo, bar, f, false);
         * mpz_mul(foo, foo, c_d);
         * mpz_mod(foo, foo, com.p);
         * mpz_powm(bar, c, lambda, com.p);
         * mpz_mul(foo, foo, bar);
         * mpz_mod(foo, foo, com.p);
         */
        // SKC messages $m_i := i \lambda + t_i \bmod q$ for all $i = 1,\ldots, n$
        for (int i = 0; i < m.Count; i++)
        {
            BigInteger value = i + 1;
            value = value + lambda;
            value = value % com.q;
            value = value + t[i];
            value = value % com.q;
            m[i]  = value;
        }
        skc.Prove_interactive(pi, rho, m, input_channel, output_channel);
    }
Пример #11
0
        public void Prove_interactive(
            List <int> pi,
            BigInteger r,
            List <BigInteger> m,
            IInputChannel input_channel,
            IOutputChannel output_channel)
        {
            Debug.Assert(com.g.Count >= pi.Count);
            Debug.Assert(pi.Count == m.Count);
            Debug.Assert(m.Count >= 2);

            BigInteger        x, r_d, r_Delta, r_a, c_d, c_Delta, c_a, e, z, z_Delta, foo, bar;
            List <BigInteger> d       = new List <BigInteger>();
            List <BigInteger> Delta   = new List <BigInteger>();
            List <BigInteger> a       = new List <BigInteger>();
            List <BigInteger> f       = new List <BigInteger>();
            List <BigInteger> f_Delta = new List <BigInteger>();
            List <BigInteger> lej     = new List <BigInteger>();

            // initialize
            for (int i = 0; i < m.Count; i++)
            {
                d.Add(0);
                Delta.Add(0);
                a.Add(0);
                f.Add(0);
                f_Delta.Add(0);
                lej.Add(0);
            }

            // prover: first move
            x = input_channel.Recieve(); // get $x$ from the verifier

            // check whether $x$ is from $\{0, 1\}^{\ell_e}$, otherwise reduce
            if (x.BitLength() > l_e)
            {
                x = x % exp2l_e;
            }

            // prover: second move
            r_d     = mpz_srandom.mpz_srandomm(com.q); // $r_d \gets \mathbb{Z}_q$
            r_Delta = mpz_srandom.mpz_srandomm(com.q); // $r_{\Delta} \gets \mathbb{Z}_q$
            for (int index = 0; index < d.Count; index++)
            {
                d[index] = mpz_srandom.mpz_srandomm(com.q); // $d_1,\ldots,d_n \gets \mathbb{Z}_q$
            }

            Delta[0] = d[0]; // $\Delta_1 := d_1$
            for (int index = 1; index < (Delta.Count - 1); index++)
            {
                Delta[index] = mpz_srandom.mpz_srandomm(com.q); // $\Delta_2,\ldots,\Delta_{n-1}
            } // \gets \mathbb{Z}_q$

            Delta[Delta.Count - 1] = 0; // $\Delta_n := 0$

            for (int i = 0; i < a.Count; i++)
            {
                a[i] = 1;
                // compute a_i = \prod_{j=1}^i (m_{\pi(j)} - x)
                for (int j = 0; j <= i; j++)
                {
                    foo  = m[pi[j]] - x;
                    foo  = foo % com.q;
                    a[i] = a[i] * foo;
                    a[i] = a[i] * com.q; //TODO CHECK!!!
                }
            }
            r_a = mpz_srandom.mpz_srandomm(com.q); // $r_a \gets \mathbb{Z}_q$
            // $c_d = \mathrm{com}_{ck}(d_1,\ldots,d_n;r_d)$
            c_d = com.CommitBy(r_d, d);
            for (int i = 0; i < lej.Count; i++)
            {
                if (i < (lej.Count - 1))
                {
                    foo    = Delta[i];
                    foo    = foo.FlipSign();
                    lej[i] = foo * d[i + 1];
                    lej[i] = lej[i] % com.q;
                }
                else
                {
                    lej[i] = 0;
                }
            }
            // $c_{\Delta} = \mathrm{com}_{ck}(-\Delta_1 d_2,\ldots,
            // -\Delta_{n-1} d_n;r_{\Delta})$
            c_Delta = com.CommitBy(r_Delta, lej);
            for (int i = 0; i < lej.Count; i++)
            {
                if (i < (lej.Count - 1))
                {
                    foo    = Delta[i + 1];
                    bar    = m[pi[i + 1]] - x;
                    bar    = bar % com.q;
                    bar    = bar * Delta[i];
                    bar    = bar % com.q;
                    foo    = foo - bar;
                    foo    = foo % com.q;
                    bar    = a[i] * d[i + 1];
                    bar    = bar % com.q;
                    foo    = foo - bar;
                    foo    = foo % com.q;
                    lej[i] = foo;
                }
                else
                {
                    lej[i] = 0;
                }
            }
            // $c_a = \mathrm{com}_{ck}(\Delta_2 - (m_{\pi(2)} - x)\Delta_1 - a_1 d_2,
            // \ldots,\Delta_n - (m_{\pi(n)} - x)\Delta_{n-1}
            // - a_{n-1} d_n;r_a)$
            c_a = com.CommitBy(r_a, lej);
            // send $c_d$, $c_\Delta$, and $c_a$ to the verifier
            output_channel.Send(c_d);
            output_channel.Send(c_Delta);
            output_channel.Send(c_a);

            // prover: third move
            e = input_channel.Recieve(); // get $e$ from the verifier

            // check whether $x$ is from $\{0, 1\}^{\ell_e}$, otherwise reduce
            if (e.BitLength() > l_e)
            {
                e = e.ModInverse(exp2l_e);
            }

            // prover: fourth move
            // compute $f_i = e m_{\pi(i)} + d_i$
            for (int i = 0; i < f.Count; i++)
            {
                f[i] = e * m[pi[i]];
                f[i] = f[i] % com.q;
                f[i] = f[i] + d[i];
                f[i] = f[i] % com.q;
            }
            // compute $z = e r + r_d$
            z = e * r;
            z = z % com.q;
            z = z + r_d;
            z = z % com.q;

            // compute $f_{\Delta_i} = e (\Delta_{i+1} - (m_{\pi(i+1)} - x)\Delta_i
            // - a_i d_{i+1}) - \Delta_i d_{i+1}$
            for (int i = 0; i < (f_Delta.Count - 1); i++)
            {
                foo        = Delta[i + 1];
                bar        = m[pi[i + 1]] - x;
                bar        = bar % com.q;
                bar        = bar * Delta[i];
                bar        = bar % com.q;
                foo        = foo - bar;
                foo        = foo % com.q;
                bar        = a[i] * d[i + 1];
                bar        = bar % com.q;
                foo        = foo - bar;
                foo        = foo % com.q;
                foo        = foo * e;
                foo        = foo % com.q;
                bar        = Delta[i] * d[i + 1];
                bar        = bar % com.q;
                foo        = foo - bar;
                foo        = foo % com.q;
                f_Delta[i] = foo;
            }
            // compute $z_{\Delta} = e r_a + r_{\Delta}$
            z_Delta = e * r_a;
            z_Delta = z_Delta % com.q;
            z_Delta = z_Delta + r_Delta;
            z_Delta = z_Delta % com.q;

            for (int i = 0; i < f.Count; i++)
            {
                output_channel.Send(f[i]); // send $f_1,\ldots,f_n$ to the verifier
            }
            output_channel.Send(z);        // send $z$ to the verifier

            for (int i = 0; i < (f_Delta.Count - 1); i++)
            {
                output_channel.Send(f_Delta[i]); // send $f_{\Delta_1},\ldots,
            }
            output_channel.Send(z_Delta);        // f_{\Delta_{n-1}}$ to verifier
        }
Пример #12
0
        public bool Verify_interactive(
            BigInteger c,
            List <BigInteger> f_prime,
            List <BigInteger> m,
            IInputChannel input_channel,
            IOutputChannel output_channel,
            bool optimizations)
        {
            Debug.Assert(com.g.Count >= m.Count);
            Debug.Assert(m.Count == f_prime.Count);
            Debug.Assert(m.Count >= 2);

            // initialize
            BigInteger x, c_d, c_Delta, c_a, e, z, z_Delta, foo, bar, foo2;

            BigInteger [] f       = new BigInteger [m.Count];
            BigInteger [] f_Delta = new BigInteger [m.Count];
            BigInteger [] lej     = new BigInteger [m.Count];
            for (int i = 0; i < m.Count; i++)
            {
                f[i]       = 0;
                f_Delta[i] = 0;
                lej[i]     = 0;
            }

            // verifier: first move
            x = mpz_srandom.mpz_srandomb(l_e);
            output_channel.Send(x);

            // verifier: second move
            c_d     = input_channel.Recieve();
            c_Delta = input_channel.Recieve();
            c_a     = input_channel.Recieve();

            // verifier: third move
            e = mpz_srandom.mpz_srandomb(l_e);
            output_channel.Send(e);

            // verifier: fourth move
            for (int i = 0; i < f.Length; i++)
            {
                f[i] = input_channel.Recieve();
            }

            z = input_channel.Recieve();
            for (int i = 0; i < (f_Delta.Length - 1); i++)
            {
                f_Delta[i] = input_channel.Recieve();
            }
            z_Delta = input_channel.Recieve();

            // check whether $c_d, c_a, c_{\Delta} \in\mathcal{C}_{ck}$
            if (!(com.TestMembership(c_d) && com.TestMembership(c_a) && com.TestMembership(c_Delta)))
            {
                return(false);
            }

            // check whether $f_1, \ldots, f_n, z \in\mathbb{Z}_q$
            if (!(z.CompareTo(com.q) < 0))
            {
                return(false);
            }
            for (int i = 0; i < f.Length; i++)
            {
                if (!(f[i].CompareTo(com.q) < 0))
                {
                    return(false);
                }
            }

            // check whether $f_{\Delta_1}, \ldots, f_{\Delta_{n-1}}$
            // and $z_{\Delta}$ are from $\mathbb{Z}_q$
            if (!(z_Delta.CompareTo(com.q) < 0))
            {
                return(false);
            }
            for (int i = 0; i < (f_Delta.Length - 1); i++)
            {
                if (!(f_Delta[i].CompareTo(com.q) < 0))
                {
                    return(false);
                }
            }

            if (optimizations)
            {
                // randomization technique from section 6,
                // paragraph 'Batch verification'
                // pick $\alpha\in_R\{0, 1\}^{\ell_e}$ at random
                BigInteger alpha = mpz_srandom.mpz_srandomb(l_e);
                // compute $(c^e c_d)^{\alpha}$
                foo = c.ModPow(e, com.p);
                foo = foo * c_d;
                foo = foo % com.p;
                foo = foo.ModPow(alpha, com.p);
                // compute $c_a^e c_{\Delta}$
                bar = c_a.ModPow(e, com.p);
                bar = bar * c_Delta;
                bar = bar % com.p;
                // compute the product
                foo = foo * bar;
                foo = foo % com.p;
                // compute the messages for the commitment
                for (int i = 0; i < f.Length; i++)
                {
                    BigInteger tmp2 = alpha * f[i];
                    tmp2 = tmp2 % com.q;
                    tmp2 = tmp2 + f_Delta[i];
                    tmp2 = tmp2 % com.q;

                    // compute $f'_i e \alpha$ (optimized commitment)
                    bar = alpha * f_prime[i];
                    bar = bar % com.q;
                    bar = bar * e;
                    bar = bar % com.q;
                    bar = bar.FlipSign();

                    tmp2   = tmp2 + bar;
                    tmp2   = tmp2 % com.q;
                    lej[i] = tmp2;
                }
                bar = alpha * z;
                bar = bar % com.q;
                bar = bar + z_Delta;
                bar = bar % com.q;
                // check the randomized commitments
                if (!com.Verify(foo, bar, lej))
                {
                    return(false);
                }
            }
            else
            {
                // check whether $c^e c_d = \mathrm{com}(f''_1, \ldots, f''_n; z)$
                foo = c.ModPow(e, com.p);
                foo = foo * c_d;
                foo = foo % com.q;
                // compute $f''_i = f_i - f'_i e$
                for (int i = 0; i < f.Length; i++)
                {
                    BigInteger tmp2 = f_prime[i] * e;
                    tmp2   = tmp2 % com.q;
                    tmp2   = tmp2.FlipSign();
                    tmp2   = tmp2 + f[i];
                    tmp2   = tmp2 % com.q;
                    lej[i] = tmp2;
                }

                if (!com.Verify(foo, z, lej))
                {
                    return(false);
                }

                // check whether $c_a^e c_{\Delta} = \mathrm{com}(f_{\Delta_1},
                // \ldots, f_{\Delta_{n-1}}; z_{\Delta})$
                foo = c_a.ModPow(e, com.p);
                foo = foo * c_Delta;
                foo = foo % com.p;
                if (!com.Verify(foo, z_Delta, f_Delta))
                {
                    return(false);
                }
            }

            // check $F_n = e \prod_{i=1}^n (m_i - x)$
            foo = e * x;
            foo = foo % com.q;
            Debug.Assert(ToolsMathBigInteger.AreCoprime(e, com.q));
            bar  = e.ModInverse(com.q);
            foo2 = 1;
            BigInteger bar2 = 0;

            for (int i = 0; i < f.Length; i++)
            {
                bar2 = f[i] - foo;
                bar2 = bar2 % com.q;
                bar2 = bar2 * foo2;
                bar2 = bar2 % com.q;
                if (i > 0)
                {
                    bar2 = bar2 + f_Delta[i - 1];
                    bar2 = bar2 % com.q;
                    bar2 = bar2 * bar;
                    bar2 = bar2 % com.q;
                }
                foo2 = bar2;
            }
            foo2 = 1;
            for (int i = 0; i < m.Count; i++)
            {
                foo  = m[i] - x;
                foo  = foo % com.q;
                foo2 = foo2 * foo;
                foo2 = foo2 % com.q;
            }
            foo2 = foo2 * e;
            foo2 = foo2 % com.q;
            return(foo2 == bar2);
        }