|
@@ -332,7 +332,7 @@ std::vector<Proof> PrsonaBase::generate_reputation_proof(
|
|
|
for (size_t i = 0; i < proofBits; i++)
|
|
|
{
|
|
|
Proof currProof;
|
|
|
- Curvepoint g, h, c, c_a, c_b;
|
|
|
+ Curvepoint g, h, C, C_a, C_b;
|
|
|
g = commitment.mask;
|
|
|
h = elGamalBlindGenerator;
|
|
|
|
|
@@ -344,14 +344,14 @@ std::vector<Proof> PrsonaBase::generate_reputation_proof(
|
|
|
m = Scalar(currBit);
|
|
|
r = masksPerBit[i];
|
|
|
|
|
|
- c = g * r + h * m;
|
|
|
- currProof.curvepointUniversals.push_back(c);
|
|
|
+ C = g * r + h * m;
|
|
|
+ currProof.curvepointUniversals.push_back(C);
|
|
|
|
|
|
- c_a = g * s + h * a;
|
|
|
- c_b = g * t + h * a * m;
|
|
|
+ C_a = g * s + h * a;
|
|
|
+ C_b = g * t + h * a * m;
|
|
|
|
|
|
std::stringstream oracleInput;
|
|
|
- oracleInput << g << h << c << c_a << c_b;
|
|
|
+ oracleInput << g << h << C << C_a << C_b;
|
|
|
|
|
|
Scalar x = oracle(oracleInput.str());
|
|
|
currProof.challengeParts.push_back(x);
|
|
@@ -697,7 +697,6 @@ bool PrsonaBase::verify_proof_of_added_user(
|
|
|
const std::vector<Proof>& pi,
|
|
|
const Curvepoint& currentFreshGenerator,
|
|
|
const Curvepoint& shortTermPublicKey,
|
|
|
- const Curvepoint& elGamalBlindGenerator,
|
|
|
const CurveBipoint& curveG,
|
|
|
const CurveBipoint& curveH,
|
|
|
const TwistBipoint& twistG,
|
|
@@ -787,55 +786,547 @@ bool PrsonaBase::verify_proof_of_added_user(
|
|
|
* EPOCH PROOFS
|
|
|
*/
|
|
|
|
|
|
-Proof PrsonaBase::generate_proof_of_correct_tally() const
|
|
|
+std::vector<Proof> PrsonaBase::generate_valid_permutation_proof(
|
|
|
+ const std::vector<std::vector<Scalar>>& permutations,
|
|
|
+ const std::vector<std::vector<Scalar>>& seeds,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& commits) const
|
|
|
{
|
|
|
- Proof retval;
|
|
|
+ std::vector<Proof> retval;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.hbc = "PROOF";
|
|
|
+ retval.push_back(Proof("PROOF"));
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.hbc = "PROOF";
|
|
|
+ // Taken from Fig. 1 in https://eprint.iacr.org/2014/764.pdf
|
|
|
+ for (size_t i = 0; i < permutations.size(); i++)
|
|
|
+ {
|
|
|
+ for (size_t j = 0; j < permutations[i].size(); j++)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+ Curvepoint g, h, C, C_a, C_b;
|
|
|
+ g = EL_GAMAL_GENERATOR;
|
|
|
+ h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ Scalar a, s, t, p, r;
|
|
|
+ a.set_random();
|
|
|
+ s.set_random();
|
|
|
+ t.set_random();
|
|
|
+ p = permutations[i][j];
|
|
|
+ r = seeds[i][j];
|
|
|
+
|
|
|
+ C = commits[i][j];
|
|
|
+
|
|
|
+ C_a = g * a + h * s;
|
|
|
+ C_b = g * a * p + h * t;
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h << C << C_a << C_b;
|
|
|
+
|
|
|
+ Scalar x = oracle(oracleInput.str());
|
|
|
+ currProof.challengeParts.push_back(x);
|
|
|
+
|
|
|
+ Scalar f, z_a, z_b;
|
|
|
+ f = p * x + a;
|
|
|
+ z_a = r * x + s;
|
|
|
+ z_b = r * (x - f) + t;
|
|
|
+
|
|
|
+ currProof.responseParts.push_back(f);
|
|
|
+ currProof.responseParts.push_back(z_a);
|
|
|
+ currProof.responseParts.push_back(z_b);
|
|
|
+
|
|
|
+ retval.push_back(currProof);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaBase::generate_proof_of_correct_sum() const
|
|
|
+bool PrsonaBase::verify_valid_permutation_proof(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& commits) const
|
|
|
{
|
|
|
- Proof retval;
|
|
|
+ // Reject outright if there's no proof to check
|
|
|
+ if (pi.empty())
|
|
|
+ {
|
|
|
+ std::cerr << "Proof was empty, aborting." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
+ return pi[0].hbc == "PROOF";
|
|
|
+
|
|
|
+ Curvepoint g, h;
|
|
|
+ g = EL_GAMAL_GENERATOR;
|
|
|
+ h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < commits.size(); i++)
|
|
|
{
|
|
|
- retval.hbc = "PROOF";
|
|
|
+ for (size_t j = 0; j < commits[i].size(); j++)
|
|
|
+ {
|
|
|
+ size_t piIndex = i * commits.size() + j;
|
|
|
+
|
|
|
+ Curvepoint C, C_a, C_b;
|
|
|
+
|
|
|
+ C = commits[i][j];
|
|
|
+
|
|
|
+ Scalar x, f, z_a, z_b;
|
|
|
+ x = pi[piIndex].challengeParts[0];
|
|
|
+ f = pi[piIndex].responseParts[0];
|
|
|
+ z_a = pi[piIndex].responseParts[1];
|
|
|
+ z_b = pi[piIndex].responseParts[2];
|
|
|
+
|
|
|
+ // Taken from Fig. 1 in https://eprint.iacr.org/2014/764.pdf
|
|
|
+ C_a = g * f + h * z_a - C * x;
|
|
|
+ C_b = h * z_b - C * (x - f);
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h << C << C_a << C_b;
|
|
|
+
|
|
|
+ if (oracle(oracleInput.str()) != x)
|
|
|
+ {
|
|
|
+ std::cerr << "0 or 1 proof failed at index " << i << " of " << pi.size() - 1 << ", aborting." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (size_t i = 0; i < commits.size(); i++)
|
|
|
+ {
|
|
|
+ Curvepoint sum = commits[i][0];
|
|
|
+
|
|
|
+ for (size_t j = 1; j < commits[i].size(); j++)
|
|
|
+ sum = sum + commits[i][j];
|
|
|
+
|
|
|
+ if (sum != g)
|
|
|
+ {
|
|
|
+ std::cerr << "Commits did not sum to g, aborting." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+std::vector<Proof> PrsonaBase::generate_proof_of_reordering_plus_power(
|
|
|
+ const std::vector<std::vector<Scalar>>& permutations,
|
|
|
+ const Scalar& power,
|
|
|
+ const std::vector<std::vector<Scalar>>& permutationSeeds,
|
|
|
+ const std::vector<std::vector<Scalar>>& productSeeds,
|
|
|
+ const std::vector<Curvepoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& productCommits,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& seedCommits) const
|
|
|
+{
|
|
|
+ std::vector<Proof> retval;
|
|
|
+
|
|
|
+ if (!SERVER_IS_MALICIOUS)
|
|
|
+ {
|
|
|
+ retval.push_back(Proof("PROOF"));
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.hbc = "PROOF";
|
|
|
+ Proof first;
|
|
|
+ retval.push_back(first);
|
|
|
+
|
|
|
+ Curvepoint g = EL_GAMAL_GENERATOR;
|
|
|
+ Curvepoint h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ oracleInput << permutationCommits[i][j];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < productCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < productCommits[i].size(); j++)
|
|
|
+ oracleInput << productCommits[i][j];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < seedCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < seedCommits[i].size(); j++)
|
|
|
+ oracleInput << seedCommits[i][j];
|
|
|
+
|
|
|
+ std::cout << "Pre: " << oracle(oracleInput.str()) << std::endl;
|
|
|
+
|
|
|
+ Scalar b1;
|
|
|
+ b1.set_random();
|
|
|
+ std::vector<std::vector<Scalar>> b2;
|
|
|
+ std::vector<std::vector<Scalar>> t1;
|
|
|
+ std::vector<std::vector<Scalar>> t2;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ {
|
|
|
+ std::vector<Scalar> currb2Row;
|
|
|
+ std::vector<Scalar> currt1Row;
|
|
|
+ std::vector<Scalar> currt2Row;
|
|
|
+
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+
|
|
|
+ Scalar currb2;
|
|
|
+ Scalar currt1;
|
|
|
+ Scalar currt2;
|
|
|
+
|
|
|
+ Curvepoint U1, U2, U3, U4;
|
|
|
+
|
|
|
+ currb2.set_random();
|
|
|
+ currt1.set_random();
|
|
|
+ currt2.set_random();
|
|
|
+
|
|
|
+ // Permutations go in weird order because of
|
|
|
+ // matrix multiplication stuff
|
|
|
+ U1 = g * currb2 + h * currt1;
|
|
|
+ U2 = oldValues[i] *
|
|
|
+ (b1 * permutations[j][i] + currb2 * power);
|
|
|
+ U3 = oldValues[i] * b1 * currb2 + h * currt2;
|
|
|
+ U4 = g * currt2;
|
|
|
+
|
|
|
+ currProof.curvepointUniversals.push_back(U2);
|
|
|
+
|
|
|
+ oracleInput << U1 << U2 << U3 << U4;
|
|
|
+ std::cout << i * permutationCommits.size() + j + 1 << ": " << oracle(oracleInput.str()) << std::endl;
|
|
|
+ std::stringstream out1, out2, out3, out4;
|
|
|
+ out1 << U1;
|
|
|
+ out2 << U2;
|
|
|
+ out3 << U3;
|
|
|
+ out4 << U4;
|
|
|
+ std::cout << "U1: " << oracle(out1.str()) << std::endl;
|
|
|
+ std::cout << "U2: " << oracle(out2.str()) << std::endl;
|
|
|
+ std::cout << "U3: " << oracle(out3.str()) << std::endl;
|
|
|
+ std::cout << "U4: " << oracle(out4.str()) << std::endl;
|
|
|
+
|
|
|
+ currb2Row.push_back(currb2);
|
|
|
+ currt1Row.push_back(currt1);
|
|
|
+ currt2Row.push_back(currt2);
|
|
|
+
|
|
|
+ retval.push_back(currProof);
|
|
|
+ }
|
|
|
+
|
|
|
+ b2.push_back(currb2Row);
|
|
|
+ t1.push_back(currt1Row);
|
|
|
+ t2.push_back(currt2Row);
|
|
|
+ }
|
|
|
+
|
|
|
+ Scalar x = oracle(oracleInput.str());
|
|
|
+ retval[0].challengeParts.push_back(x);
|
|
|
+
|
|
|
+ Scalar f1 = power * x + b1;
|
|
|
+ retval[0].responseParts.push_back(f1);
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ {
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ size_t piIndex = i * permutationCommits.size() + j + 1;
|
|
|
+
|
|
|
+ // Permutations go in weird order because of
|
|
|
+ // matrix multiplication stuff
|
|
|
+ Scalar f2 = permutations[j][i] * x + b2[i][j];
|
|
|
+ Scalar z1 = permutationSeeds[j][i] * x + t1[i][j];
|
|
|
+ Scalar z2 = productSeeds[i][j] * x * x + t2[i][j];
|
|
|
+
|
|
|
+ retval[piIndex].responseParts.push_back(f2);
|
|
|
+ retval[piIndex].responseParts.push_back(z1);
|
|
|
+ retval[piIndex].responseParts.push_back(z2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaBase::generate_proof_of_shuffle() const
|
|
|
+bool PrsonaBase::verify_proof_of_reordering_plus_power(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const std::vector<Curvepoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& productCommits,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& seedCommits) const
|
|
|
{
|
|
|
- Proof retval;
|
|
|
+ if (pi.empty())
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (!SERVER_IS_MALICIOUS)
|
|
|
+ return pi[0].hbc == "PROOF";
|
|
|
+
|
|
|
+ Curvepoint g = EL_GAMAL_GENERATOR;
|
|
|
+ Curvepoint h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ oracleInput << permutationCommits[i][j];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < productCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < productCommits[i].size(); j++)
|
|
|
+ oracleInput << productCommits[i][j];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < seedCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < seedCommits[i].size(); j++)
|
|
|
+ oracleInput << seedCommits[i][j];
|
|
|
+
|
|
|
+ std::cout << "Pre: " << oracle(oracleInput.str()) << std::endl;
|
|
|
+
|
|
|
+ Scalar x = pi[0].challengeParts[0];
|
|
|
+ Scalar f1 = pi[0].responseParts[0];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ {
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ size_t piIndex = i * permutationCommits.size() + j + 1;
|
|
|
+
|
|
|
+ Curvepoint U1, U2, U3, U4;
|
|
|
+ U2 = pi[piIndex].curvepointUniversals[0];
|
|
|
+
|
|
|
+ Scalar f2 = pi[piIndex].responseParts[0];
|
|
|
+ Scalar z1 = pi[piIndex].responseParts[1];
|
|
|
+ Scalar z2 = pi[piIndex].responseParts[2];
|
|
|
+
|
|
|
+ // Permutations go in weird order because of
|
|
|
+ // matrix multiplication stuff
|
|
|
+ U1 = g * f2 + h * z1 - permutationCommits[j][i] * x;
|
|
|
+
|
|
|
+ U3 = oldValues[i] * f1 * f2 +
|
|
|
+ h * z2 -
|
|
|
+ productCommits[i][j] * x * x -
|
|
|
+ U2 * x;
|
|
|
+
|
|
|
+ U4 = g * z2 - seedCommits[i][j] * x * x;
|
|
|
+
|
|
|
+ oracleInput << U1 << U2 << U3 << U4;
|
|
|
+
|
|
|
+ std::cout << i * permutationCommits.size() + j + 1 << ": " << oracle(oracleInput.str()) << std::endl;
|
|
|
+ std::stringstream out1, out2, out3, out4;
|
|
|
+ out1 << U1;
|
|
|
+ out2 << U2;
|
|
|
+ out3 << U3;
|
|
|
+ out4 << U4;
|
|
|
+ std::cout << "U1: " << oracle(out1.str()) << std::endl;
|
|
|
+ std::cout << "U2: " << oracle(out2.str()) << std::endl;
|
|
|
+ std::cout << "U3: " << oracle(out3.str()) << std::endl;
|
|
|
+ std::cout << "U4: " << oracle(out4.str()) << std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (x != oracle(oracleInput.str()))
|
|
|
+ {
|
|
|
+ std::cerr << "Fresh pseudonyms not generated by permutation matrix." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (size_t i = 0; i < seedCommits.size(); i++)
|
|
|
+ {
|
|
|
+ Curvepoint sum = seedCommits[i][0];
|
|
|
+
|
|
|
+ for (size_t j = 1; j < seedCommits[i].size(); j++)
|
|
|
+ sum = sum + seedCommits[i][j];
|
|
|
+
|
|
|
+ if (sum != Curvepoint())
|
|
|
+ {
|
|
|
+ std::cerr << "seed commits did not sum to 0, aborting." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+std::vector<Proof> PrsonaBase::generate_proof_of_reordering(
|
|
|
+ const std::vector<std::vector<Scalar>>& permutations,
|
|
|
+ const std::vector<std::vector<Scalar>>& permutationSeeds,
|
|
|
+ const std::vector<std::vector<Scalar>>& productSeeds,
|
|
|
+ const std::vector<T>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<T>>& productCommits,
|
|
|
+ const T& otherG,
|
|
|
+ const T& otherH,
|
|
|
+ bool inverted) const
|
|
|
+{
|
|
|
+ std::vector<Proof> retval;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.hbc = "PROOF";
|
|
|
+ retval.push_back(Proof("PROOF"));
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.hbc = "PROOF";
|
|
|
+ Proof first;
|
|
|
+ retval.push_back(first);
|
|
|
+
|
|
|
+ Curvepoint g = EL_GAMAL_GENERATOR;
|
|
|
+ Curvepoint h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h << otherG << otherH;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ oracleInput << permutationCommits[i][j];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < productCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < productCommits[i].size(); j++)
|
|
|
+ oracleInput << productCommits[i][j];
|
|
|
+
|
|
|
+ std::vector<std::vector<Scalar>> a;
|
|
|
+ std::vector<std::vector<Scalar>> t1;
|
|
|
+ std::vector<std::vector<Scalar>> t2;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ {
|
|
|
+ std::vector<Scalar> curraRow;
|
|
|
+ std::vector<Scalar> currt1Row;
|
|
|
+ std::vector<Scalar> currt2Row;
|
|
|
+
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+
|
|
|
+ Scalar curra;
|
|
|
+ Scalar currt1;
|
|
|
+ Scalar currt2;
|
|
|
+
|
|
|
+ Curvepoint U1;
|
|
|
+ T U2;
|
|
|
+
|
|
|
+ curra.set_random();
|
|
|
+ currt1.set_random();
|
|
|
+ currt2.set_random();
|
|
|
+
|
|
|
+ U1 = g * curra + h * currt1;
|
|
|
+ U2 = oldValues[i] * curra + otherH * currt2;
|
|
|
+
|
|
|
+ oracleInput << U1 << U2;
|
|
|
+
|
|
|
+ curraRow.push_back(curra);
|
|
|
+ currt1Row.push_back(currt1);
|
|
|
+ currt2Row.push_back(currt2);
|
|
|
+
|
|
|
+ retval.push_back(currProof);
|
|
|
+ }
|
|
|
+
|
|
|
+ a.push_back(curraRow);
|
|
|
+ t1.push_back(currt1Row);
|
|
|
+ t2.push_back(currt2Row);
|
|
|
+ }
|
|
|
+
|
|
|
+ Scalar x = oracle(oracleInput.str());
|
|
|
+ retval[0].challengeParts.push_back(x);
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ {
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ size_t piIndex = i * permutationCommits.size() + j + 1;
|
|
|
+ size_t permI, permJ;
|
|
|
+
|
|
|
+ // Permutations normally go in weird order because of
|
|
|
+ // matrix multiplication stuff
|
|
|
+ if (inverted)
|
|
|
+ {
|
|
|
+ permI = i;
|
|
|
+ permJ = j;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ permI = j;
|
|
|
+ permJ = i;
|
|
|
+ }
|
|
|
+
|
|
|
+ Scalar f = permutations[permI][permJ] * x + a[i][j];
|
|
|
+ Scalar z1 = permutationSeeds[permI][permJ] * x + t1[i][j];
|
|
|
+ Scalar z2 = productSeeds[i][j] * x + t2[i][j];
|
|
|
+
|
|
|
+ retval[piIndex].responseParts.push_back(f);
|
|
|
+ retval[piIndex].responseParts.push_back(z1);
|
|
|
+ retval[piIndex].responseParts.push_back(z2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-bool PrsonaBase::verify_update_proof(
|
|
|
- const Proof& pi) const
|
|
|
+template <typename T>
|
|
|
+bool PrsonaBase::verify_proof_of_reordering(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const std::vector<T>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<T>>& productCommits,
|
|
|
+ const T& otherG,
|
|
|
+ const T& otherH,
|
|
|
+ bool inverted) const
|
|
|
{
|
|
|
+ if (pi.empty())
|
|
|
+ return false;
|
|
|
+
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
- return pi.hbc == "PROOF";
|
|
|
+ return pi[0].hbc == "PROOF";
|
|
|
+
|
|
|
+ Curvepoint g = EL_GAMAL_GENERATOR;
|
|
|
+ Curvepoint h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h << otherG << otherH;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ oracleInput << permutationCommits[i][j];
|
|
|
|
|
|
- return pi.hbc == "PROOF";
|
|
|
+ for (size_t i = 0; i < productCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < productCommits[i].size(); j++)
|
|
|
+ oracleInput << productCommits[i][j];
|
|
|
+
|
|
|
+ Scalar x = pi[0].challengeParts[0];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ {
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ size_t piIndex = i * permutationCommits.size() + j + 1;
|
|
|
+
|
|
|
+ Curvepoint U1;
|
|
|
+ T U2;
|
|
|
+
|
|
|
+ Scalar f = pi[piIndex].responseParts[0];
|
|
|
+ Scalar z1 = pi[piIndex].responseParts[1];
|
|
|
+ Scalar z2 = pi[piIndex].responseParts[2];
|
|
|
+
|
|
|
+ size_t permI, permJ;
|
|
|
+
|
|
|
+ // Permutations normally go in weird order because of
|
|
|
+ // matrix multiplication stuff
|
|
|
+ if (inverted)
|
|
|
+ {
|
|
|
+ permI = i;
|
|
|
+ permJ = j;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ permI = j;
|
|
|
+ permJ = i;
|
|
|
+ }
|
|
|
+
|
|
|
+ U1 = g * f + h * z1 -
|
|
|
+ permutationCommits[permI][permJ] * x;
|
|
|
+
|
|
|
+ U2 = oldValues[i] * f + otherH * z2 -
|
|
|
+ productCommits[i][j] * x;
|
|
|
+
|
|
|
+ oracleInput << U1 << U2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (x != oracle(oracleInput.str()))
|
|
|
+ {
|
|
|
+ std::cerr << "Fresh pseudonyms not generated by permutation matrix." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1094,3 +1585,63 @@ bool PrsonaBase::verify_valid_pseudonyms_proof(
|
|
|
|
|
|
return agreement * 2 > pi.size();
|
|
|
}
|
|
|
+
|
|
|
+template std::vector<Proof> PrsonaBase::generate_proof_of_reordering<Curvepoint>(
|
|
|
+ const std::vector<std::vector<Scalar>>& permutations,
|
|
|
+ const std::vector<std::vector<Scalar>>& permutationSeeds,
|
|
|
+ const std::vector<std::vector<Scalar>>& productSeeds,
|
|
|
+ const std::vector<Curvepoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& productCommits,
|
|
|
+ const Curvepoint& otherG,
|
|
|
+ const Curvepoint& otherH,
|
|
|
+ bool inverted) const;
|
|
|
+
|
|
|
+template std::vector<Proof> PrsonaBase::generate_proof_of_reordering<CurveBipoint>(
|
|
|
+ const std::vector<std::vector<Scalar>>& permutations,
|
|
|
+ const std::vector<std::vector<Scalar>>& permutationSeeds,
|
|
|
+ const std::vector<std::vector<Scalar>>& productSeeds,
|
|
|
+ const std::vector<CurveBipoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<CurveBipoint>>& productCommits,
|
|
|
+ const CurveBipoint& otherG,
|
|
|
+ const CurveBipoint& otherH,
|
|
|
+ bool inverted) const;
|
|
|
+
|
|
|
+template std::vector<Proof> PrsonaBase::generate_proof_of_reordering<TwistBipoint>(
|
|
|
+ const std::vector<std::vector<Scalar>>& permutations,
|
|
|
+ const std::vector<std::vector<Scalar>>& permutationSeeds,
|
|
|
+ const std::vector<std::vector<Scalar>>& productSeeds,
|
|
|
+ const std::vector<TwistBipoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<TwistBipoint>>& productCommits,
|
|
|
+ const TwistBipoint& otherG,
|
|
|
+ const TwistBipoint& otherH,
|
|
|
+ bool inverted) const;
|
|
|
+
|
|
|
+template bool PrsonaBase::verify_proof_of_reordering<Curvepoint>(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const std::vector<Curvepoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& productCommits,
|
|
|
+ const Curvepoint& otherG,
|
|
|
+ const Curvepoint& otherH,
|
|
|
+ bool inverted) const;
|
|
|
+
|
|
|
+template bool PrsonaBase::verify_proof_of_reordering<CurveBipoint>(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const std::vector<CurveBipoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<CurveBipoint>>& productCommits,
|
|
|
+ const CurveBipoint& otherG,
|
|
|
+ const CurveBipoint& otherH,
|
|
|
+ bool inverted) const;
|
|
|
+
|
|
|
+template bool PrsonaBase::verify_proof_of_reordering<TwistBipoint>(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const std::vector<TwistBipoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Curvepoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<TwistBipoint>>& productCommits,
|
|
|
+ const TwistBipoint& otherG,
|
|
|
+ const TwistBipoint& otherH,
|
|
|
+ bool inverted) const;
|