public bool VerifiableMaskingProtocol_Verify(
            BigInteger m,
            BigInteger c_1,
            BigInteger c_2,
            IInputChannel input_channel)
        {
            // verify the in-group properties
            if (!CheckElement(c_1) || !CheckElement(c_2))
            {
                return(false);
            }

            // invoke CP(c_1, c_2/m, g, h; r) as verifier
            if (ToolsMathBigInteger.AreCoprime(m, p))
            {
                return(false);
            }
            BigInteger foo = m.ModInverse(p);

            foo = foo * c_2;
            foo = foo % p;
            if (!CP_Verify(c_1, foo, g, h, input_channel, true))
            {
                return(false);
            }

            // finish
            return(true);
        }
Esempio n. 2
0
        public BigIntegerPrimeFactorial(BigInteger to_factor)
        {
            d_factorized_number = to_factor;
            d_factor_counts     = new DictionaryCount <BigInteger>();
            List <BigInteger> factors = ToolsMathBigInteger.factorize(to_factor);

            foreach (BigInteger factor in factors)
            {
                d_factor_counts.Increment(factor);
            }
        }
        BigInteger VerifiableDecryptionProtocol_Verify_Finalize(
            BigInteger c_2)
        {
            Debug.Assert(ToolsMathBigInteger.AreCoprime(d, p));

            // finalize the decryption
            BigInteger m = d.ModInverse(p);

            m = m * c_2;
            m = m % p;
            return(m);
        }
        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);
        }
        void VerifiableMaskingProtocol_Prove(
            BigInteger m,
            BigInteger c_1,
            BigInteger c_2,
            BigInteger r,
            IOutputChannel output_channel)
        {
            BigInteger foo;

            // invoke CP(c_1, c_2/m, g, h; r) as prover
            Debug.Assert(ToolsMathBigInteger.AreCoprime(m, p));
            foo = m.ModInverse(p);
            foo = m.ModInverse(p);
            foo = foo * c_2;
            foo = foo % p;
            CP_Prove(c_1, foo, g, h, r, output_channel, 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 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);
            }
        }
        public bool CheckGroup()
        {
            // Check whether $p$ and $q$ have appropriate sizes.
            if ((p.BitLength() < F_size) || (q.BitLength() < G_size))
            {
                //return false;
                throw new Exception("Bitlenght mismatch");
            }
            // Check whether $p$ has the correct form, i.e. $p = qk + 1$.
            if ((q * k) + 1 != p)
            {
                throw new Exception("p of incorrect form: (q * k) + 1 != p");
            }
            // Check whether $p$ and $q$ are both (probable) prime with
            // a soundness error probability ${} \le 4^{-TMCG_MR_ITERATIONS}$.
            if (!p.IsProbablePrime(Constants.TMCG_MR_ITERATIONS) || !q.IsProbablePrime(Constants.TMCG_MR_ITERATIONS))
            {
                //return false;
                throw new Exception("p or q not prime");
            }

            // Check whether $k$ is not divisible by $q$, i.e. $q$ and $k$ are
            // coprime.
            if (!ToolsMathBigInteger.AreCoprime(q, k))
            {
                //return false;
                throw new Exception("p or q not coprime"); //TODO this seems redundant given the former test
            }
            // Check whether $g$ is a generator for the subgroup $G$ of prime
            // order $q$. We have to assert that $g^q \equiv 1 \pmod{p}$,
            // which means that the order of $g$ is $q$. Of course, we must
            // ensure that $g$ is not trivial, i.e., $1 < g < p-1$.
            if (g <= 1 || p - 1 <= g || g.ModPow(q, p) != 1)
            {
                //return false;
                throw new Exception("g not a subgroup generator of G:  $1 < g < p-1 && g.ModPow(q, p) == 1 fails");
            }
            // finish
            return(true);
        }
        void VerifiableRemaskingProtocol_Prove(
            BigInteger c_1,
            BigInteger c_2,
            BigInteger c__1,
            BigInteger c__2,
            BigInteger r,
            IOutputChannel output_channel)
        {
            BigInteger foo, bar;

            // invoke CP(c'_1/c_1, c'_2/c_2, g, h; r) as prover
            Debug.Assert(ToolsMathBigInteger.AreCoprime(c_1, p));
            foo = c_1.ModInverse(p);
            foo = foo * c__1;
            foo = foo % p;

            Debug.Assert(ToolsMathBigInteger.AreCoprime(c_2, p));
            bar = c_2.ModInverse(p);
            bar = bar * c__2;
            bar = bar % p;
            CP_Prove(foo, bar, g, h, r, output_channel, true);
        }
        bool VerifiableRemaskingProtocol_Verify(
            BigInteger c_1,
            BigInteger c_2,
            BigInteger c__1,
            BigInteger c__2,
            IInputChannel input_channel)
        {
            BigInteger foo = 0;
            BigInteger bar = 1;

            // verify the in-group properties
            if (!CheckElement(c__1) || !CheckElement(c__2))
            {
                return(false);
            }

            // invoke CP(c'_1/c_1, c'_2/c_2, g, h; r) as verifier
            if (!ToolsMathBigInteger.AreCoprime(c_1, p))
            {
                return(false);
            }
            foo = c_1.ModInverse(p);
            foo = foo * c__1;
            foo = foo % p;
            if (!ToolsMathBigInteger.AreCoprime(c_2, p))
            {
                return(false);
            }
            bar = c_2.ModInverse(p);
            bar = bar * c__2;
            bar = bar % p;
            if (!CP_Verify(foo, bar, g, h, input_channel, true))
            {
                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);
        }
Esempio n. 12
0
        public static Tuple <BigInteger, BigInteger, BigInteger> MPZLPrime(
            long psize,
            long qsize,
            int mr_iterations)
        {
            System.Diagnostics.Debug.WriteLine("mpz_lprime:" + psize + " " + qsize + " " + mr_iterations);
            BigInteger p, q, k;

            p = 0;
            Debug.Assert(psize > qsize);

            /*
             * Choose randomly a prime number $q$ of appropriate size.
             * Primes of this type are only for public usage, because
             * we use weak random numbers here!
             */
            do
            {
                q = mpz_srandom.mpz_wrandomb(qsize);
            }while ((q.BitLength() < qsize) || !q.IsProbablePrime(mr_iterations));

            do
            {
                /* Choose randomly an even number $k$ and compute $p:= qk + 1$. */
                do
                {
                    k = mpz_srandom.mpz_wrandomb(psize - qsize);
                }while (k.BitLength() < (psize - qsize));

                if (!k.IsEven)
                {
                    k = k + 1;
                }
                p = (q * k) + 1;


                if (p.BitLength() < psize)
                {
                    System.Diagnostics.Debug.WriteLine("p is to small");
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("size of p: " + p.BitLength());
                }

                if (!ToolsMathBigInteger.AreCoprime(k, q))
                {
                    System.Diagnostics.Debug.WriteLine("p and q not are coprime");
                }

                if (!p.IsProbablePrime(mr_iterations))
                {
                    System.Diagnostics.Debug.WriteLine("p is not prime");
                }
                /* Check wether $k$ and $q$ are coprime, i.e. $gcd(k, q) = 1$. */
            }while (!ToolsMathBigInteger.AreCoprime(k, q) || (p.BitLength() < psize) || !p.IsProbablePrime(mr_iterations));
            // System.Diagnostics.Debug.WriteLine("mpz_lprime done");
            Debug.Assert(p.IsProbablePrime(mr_iterations));
            Debug.Assert(q.IsProbablePrime(mr_iterations));
            return(new Tuple <BigInteger, BigInteger, BigInteger>(p, q, k));
        }
Esempio n. 13
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);
        }
    public bool CheckGroup()
    {
        // Check whether $p$ and $q$ have appropriate sizes.
        if ((p.BitLength() < F_size) || (q.BitLength() < G_size))
        {
            throw new Exception("$p$ and $q$ do not have appropriate sizes.");
        }

        // Check whether $p$ has the correct form, i.e. $p = kq + 1$.
        if (p != (k * q) + 1)
        {
            throw new Exception("$p$ does not have the correct form.");
        }
        // Check whether $p$ and $q$ are both (probable) prime with
        // a soundness error probability ${} \le 4^{-TMCG_MR_ITERATIONS}$.
        if (!p.IsProbablePrime(Constants.TMCG_MR_ITERATIONS) || !q.IsProbablePrime(Constants.TMCG_MR_ITERATIONS))
        {
            throw new Exception("$p$ and $q$ are not both (probable) prime with a large soundness error probability.");
        }

        // Check whether $k$ is not divisible by $q$, i.e. $q, k$ are coprime.

        if (!ToolsMathBigInteger.AreCoprime(q, k))
        {
            throw new Exception("$q, k$ are not coprime.");
        }
        // Check whether the elements $h, g_1, \ldots, g_n$ are of order $q$.
        BigInteger foo = h.ModPow(q, p);

        if (foo != 1)
        {
            throw new Exception("the elements $h, g_1, ldots, g_n$ are not of order $q$.");
        }

        for (int i = 0; i < g.Count; i++)
        {
            foo = g[i].ModPow(q, p);
            if (foo != 1)
            {
                throw new Exception("the elements $h, g_1, ldots, g_n$ are not of order $q$.");
            }
        }

        // Check whether the elements $h, g_1, \ldots, g_n$ are different
        // and non-trivial, i.e., $1 < h, g_1, \ldots, g_n < p-1$.
        foo = p - 1; // compute $p-1$
        if ((h.CompareTo(new BigInteger(1)) <= 0) || (h.CompareTo(foo) >= 0))
        {
            return(false);
        }
        for (int i = 0; i < g.Count; i++)
        {
            if ((g[i].CompareTo(1) <= 0) || (g[i].CompareTo(foo) >= 0) || g[i] == h)
            {
                return(false);
            }
            for (int j = (i + 1); j < g.Count; j++)
            {
                if (g[i] == g[j])
                {
                    return(false);
                }
            }
        }
        return(true);
    }