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); }
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); }
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); }
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); }
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 }
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); }