|
@@ -10,14 +10,16 @@ extern const twistpoint_fp2_t bn_twistgen;
|
|
|
* but in C++ putting code here doesn't actually execute
|
|
|
* (or at least, with g++, whenever it would execute is not at a useful time)
|
|
|
* so we have an init() function to actually put the correct values in them. */
|
|
|
+size_t PrsonaBase::MAX_ALLOWED_VOTE = 2;
|
|
|
Twistpoint PrsonaBase::EL_GAMAL_GENERATOR = Twistpoint();
|
|
|
+
|
|
|
Scalar PrsonaBase::SCALAR_N = Scalar();
|
|
|
Scalar PrsonaBase::DEFAULT_TALLY = Scalar();
|
|
|
Scalar PrsonaBase::DEFAULT_VOTE = Scalar();
|
|
|
|
|
|
bool PrsonaBase::SERVER_IS_MALICIOUS = false;
|
|
|
bool PrsonaBase::CLIENT_IS_MALICIOUS = false;
|
|
|
-size_t PrsonaBase::MAX_ALLOWED_VOTE = 2;
|
|
|
+size_t PrsonaBase::LAMBDA = 0;
|
|
|
|
|
|
|
|
|
mpz_class log2(mpz_class x)
|
|
@@ -66,6 +68,12 @@ void PrsonaBase::set_client_malicious()
|
|
|
CLIENT_IS_MALICIOUS = true;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+void PrsonaBase::set_lambda(size_t lambda)
|
|
|
+{
|
|
|
+ LAMBDA = lambda;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* CONST GETTERS
|
|
|
*/
|
|
@@ -941,15 +949,48 @@ bool PrsonaBase::verify_valid_permutation_proof(
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-std::vector<Proof> PrsonaBase::generate_proof_of_reordering_plus_power(
|
|
|
+template <typename T>
|
|
|
+std::vector<Proof> PrsonaBase::generate_proof_of_reordering(
|
|
|
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<Twistpoint>& oldValues,
|
|
|
+ const std::vector<T>& oldValues,
|
|
|
const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& productCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& seedCommits) const
|
|
|
+ const std::vector<std::vector<T>>& productCommits,
|
|
|
+ const T& otherG,
|
|
|
+ const T& otherH) const
|
|
|
+{
|
|
|
+ if (LAMBDA > 0)
|
|
|
+ return generate_batched_proof_of_reordering<T>(permutations, permutationSeeds, productSeeds, oldValues, permutationCommits, productCommits, otherG, otherH);
|
|
|
+ else
|
|
|
+ return generate_unbatched_proof_of_reordering<T>(permutations, permutationSeeds, productSeeds, oldValues, permutationCommits, productCommits, otherG, otherH);
|
|
|
+}
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+bool PrsonaBase::verify_proof_of_reordering(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const std::vector<T>& oldValues,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<T>>& productCommits,
|
|
|
+ const T& otherG,
|
|
|
+ const T& otherH) const
|
|
|
+{
|
|
|
+ if (LAMBDA > 0)
|
|
|
+ return verify_batched_proof_of_reordering<T>(pi, oldValues, permutationCommits, productCommits, otherG, otherH);
|
|
|
+ else
|
|
|
+ return verify_unbatched_proof_of_reordering<T>(pi, oldValues, permutationCommits, productCommits, otherG, otherH);
|
|
|
+}
|
|
|
+
|
|
|
+template <typename T>
|
|
|
+std::vector<Proof> PrsonaBase::generate_unbatched_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<Twistpoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<T>>& productCommits,
|
|
|
+ const T& otherG,
|
|
|
+ const T& otherH) const
|
|
|
{
|
|
|
std::vector<Proof> retval;
|
|
|
|
|
@@ -961,12 +1002,12 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering_plus_power(
|
|
|
|
|
|
Proof first;
|
|
|
retval.push_back(first);
|
|
|
-
|
|
|
+
|
|
|
Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
Twistpoint h = elGamalBlindGenerator;
|
|
|
|
|
|
std::stringstream oracleInput;
|
|
|
- oracleInput << g << h;
|
|
|
+ oracleInput << g << h << otherG << otherH;
|
|
|
|
|
|
for (size_t i = 0; i < oldValues.size(); i++)
|
|
|
oracleInput << oldValues[i];
|
|
@@ -979,19 +1020,13 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering_plus_power(
|
|
|
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];
|
|
|
-
|
|
|
- Scalar b1;
|
|
|
- b1.set_random();
|
|
|
- std::vector<std::vector<Scalar>> b2;
|
|
|
+ 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> currb2Row;
|
|
|
+ std::vector<Scalar> curraRow;
|
|
|
std::vector<Scalar> currt1Row;
|
|
|
std::vector<Scalar> currt2Row;
|
|
|
|
|
@@ -999,34 +1034,30 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering_plus_power(
|
|
|
{
|
|
|
Proof currProof;
|
|
|
|
|
|
- Scalar currb2;
|
|
|
+ Scalar curra;
|
|
|
Scalar currt1;
|
|
|
Scalar currt2;
|
|
|
|
|
|
- Twistpoint U1, U2, U3, U4;
|
|
|
+ Twistpoint U1;
|
|
|
+ T U2;
|
|
|
|
|
|
- currb2.set_random();
|
|
|
+ curra.set_random();
|
|
|
currt1.set_random();
|
|
|
currt2.set_random();
|
|
|
|
|
|
- U1 = g * currb2 + h * currt1;
|
|
|
- U2 = oldValues[j] *
|
|
|
- (b1 * permutations[j][i] + currb2 * power);
|
|
|
- U3 = oldValues[j] * b1 * currb2 + h * currt2;
|
|
|
- U4 = g * currt2;
|
|
|
-
|
|
|
- currProof.curvepointUniversals.push_back(U2);
|
|
|
+ U1 = g * curra + h * currt1;
|
|
|
+ U2 = oldValues[j] * curra + otherH * currt2;
|
|
|
|
|
|
- oracleInput << U1 << U2 << U3 << U4;
|
|
|
+ oracleInput << U1 << U2;
|
|
|
|
|
|
- currb2Row.push_back(currb2);
|
|
|
+ curraRow.push_back(curra);
|
|
|
currt1Row.push_back(currt1);
|
|
|
currt2Row.push_back(currt2);
|
|
|
|
|
|
retval.push_back(currProof);
|
|
|
}
|
|
|
|
|
|
- b2.push_back(currb2Row);
|
|
|
+ a.push_back(curraRow);
|
|
|
t1.push_back(currt1Row);
|
|
|
t2.push_back(currt2Row);
|
|
|
}
|
|
@@ -1034,20 +1065,17 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering_plus_power(
|
|
|
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;
|
|
|
|
|
|
- Scalar f2 = permutations[j][i] * x + b2[i][j];
|
|
|
+ Scalar f = permutations[j][i] * x + a[i][j];
|
|
|
Scalar z1 = permutationSeeds[j][i] * x + t1[i][j];
|
|
|
- Scalar z2 = productSeeds[i][j] * x * x + t2[i][j];
|
|
|
+ Scalar z2 = productSeeds[i][j] * x + t2[i][j];
|
|
|
|
|
|
- retval[piIndex].responseParts.push_back(f2);
|
|
|
+ retval[piIndex].responseParts.push_back(f);
|
|
|
retval[piIndex].responseParts.push_back(z1);
|
|
|
retval[piIndex].responseParts.push_back(z2);
|
|
|
}
|
|
@@ -1056,24 +1084,26 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering_plus_power(
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-bool PrsonaBase::verify_proof_of_reordering_plus_power(
|
|
|
+template <typename T>
|
|
|
+bool PrsonaBase::verify_unbatched_proof_of_reordering(
|
|
|
const std::vector<Proof>& pi,
|
|
|
- const std::vector<Twistpoint>& oldValues,
|
|
|
+ const std::vector<T>& oldValues,
|
|
|
const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& productCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& seedCommits) const
|
|
|
+ const std::vector<std::vector<T>>& productCommits,
|
|
|
+ const T& otherG,
|
|
|
+ const T& otherH) const
|
|
|
{
|
|
|
if (pi.empty())
|
|
|
return false;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
return pi[0].hbc == "PROOF";
|
|
|
-
|
|
|
+
|
|
|
Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
Twistpoint h = elGamalBlindGenerator;
|
|
|
|
|
|
std::stringstream oracleInput;
|
|
|
- oracleInput << g << h;
|
|
|
+ oracleInput << g << h << otherG << otherH;
|
|
|
|
|
|
for (size_t i = 0; i < oldValues.size(); i++)
|
|
|
oracleInput << oldValues[i];
|
|
@@ -1086,12 +1116,7 @@ bool PrsonaBase::verify_proof_of_reordering_plus_power(
|
|
|
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];
|
|
|
-
|
|
|
Scalar x = pi[0].challengeParts[0];
|
|
|
- Scalar f1 = pi[0].responseParts[0];
|
|
|
|
|
|
for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
{
|
|
@@ -1099,62 +1124,44 @@ bool PrsonaBase::verify_proof_of_reordering_plus_power(
|
|
|
{
|
|
|
size_t piIndex = i * permutationCommits.size() + j + 1;
|
|
|
|
|
|
- Twistpoint U1, U2, U3, U4;
|
|
|
- U2 = pi[piIndex].curvepointUniversals[0];
|
|
|
+ Twistpoint U1;
|
|
|
+ T U2;
|
|
|
|
|
|
- Scalar f2 = pi[piIndex].responseParts[0];
|
|
|
+ Scalar f = pi[piIndex].responseParts[0];
|
|
|
Scalar z1 = pi[piIndex].responseParts[1];
|
|
|
Scalar z2 = pi[piIndex].responseParts[2];
|
|
|
|
|
|
- U1 = g * f2 + h * z1 - permutationCommits[j][i] * x;
|
|
|
+ U1 = g * f +
|
|
|
+ h * z1 -
|
|
|
+ permutationCommits[j][i] * x;
|
|
|
|
|
|
- U3 = oldValues[j] * f1 * f2 +
|
|
|
- h * z2 -
|
|
|
- productCommits[i][j] * x * x -
|
|
|
- U2 * x;
|
|
|
-
|
|
|
- U4 = g * z2 - seedCommits[i][j] * x * x;
|
|
|
+ U2 = oldValues[j] * f +
|
|
|
+ otherH * z2 -
|
|
|
+ productCommits[i][j] * x;
|
|
|
|
|
|
- oracleInput << U1 << U2 << U3 << U4;
|
|
|
+ oracleInput << U1 << U2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (x != oracle(oracleInput.str()))
|
|
|
{
|
|
|
- std::cerr << "Reordered + power things not generated by permutation matrix." << std::endl;
|
|
|
+ std::cerr << "Reordered things not generated by permutation matrix." << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- for (size_t i = 0; i < seedCommits.size(); i++)
|
|
|
- {
|
|
|
- Twistpoint sum = seedCommits[i][0];
|
|
|
-
|
|
|
- for (size_t j = 1; j < seedCommits[i].size(); j++)
|
|
|
- sum = sum + seedCommits[i][j];
|
|
|
-
|
|
|
- if (sum != Twistpoint())
|
|
|
- {
|
|
|
- std::cerr << "seed commits did not sum to 0, aborting." << std::endl;
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-std::vector<Proof> PrsonaBase::generate_user_tally_proofs(
|
|
|
+template <typename T>
|
|
|
+std::vector<Proof> PrsonaBase::generate_batched_proof_of_reordering(
|
|
|
const std::vector<std::vector<Scalar>>& permutations,
|
|
|
- const Scalar& power,
|
|
|
- const Twistpoint& nextGenerator,
|
|
|
const std::vector<std::vector<Scalar>>& permutationSeeds,
|
|
|
- const std::vector<std::vector<Scalar>>& userTallySeeds,
|
|
|
- const std::vector<Twistpoint>& currPseudonyms,
|
|
|
- const std::vector<Twistpoint>& userTallyMasks,
|
|
|
- const std::vector<Twistpoint>& userTallyMessages,
|
|
|
+ const std::vector<std::vector<Scalar>>& productSeeds,
|
|
|
+ const std::vector<T>& oldValues,
|
|
|
const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& userTallyMaskCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& userTallyMessageCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& userTallySeedCommits) const
|
|
|
+ const std::vector<std::vector<T>>& productCommits,
|
|
|
+ const T& otherG,
|
|
|
+ const T& otherH) const
|
|
|
{
|
|
|
std::vector<Proof> retval;
|
|
|
|
|
@@ -1166,240 +1173,190 @@ std::vector<Proof> PrsonaBase::generate_user_tally_proofs(
|
|
|
|
|
|
Proof first;
|
|
|
retval.push_back(first);
|
|
|
-
|
|
|
+
|
|
|
Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
Twistpoint h = elGamalBlindGenerator;
|
|
|
|
|
|
std::stringstream oracleInput;
|
|
|
- oracleInput << g << h << nextGenerator;
|
|
|
-
|
|
|
- for (size_t i = 0; i < currPseudonyms.size(); i++)
|
|
|
- oracleInput << currPseudonyms[i];
|
|
|
-
|
|
|
- for (size_t i = 0; i < userTallyMasks.size(); i++)
|
|
|
- oracleInput << userTallyMasks[i];
|
|
|
+ oracleInput << g << h << otherG << otherH;
|
|
|
|
|
|
- for (size_t i = 0; i < userTallyMessages.size(); i++)
|
|
|
- oracleInput << userTallyMessages[i];
|
|
|
+ for (size_t i = 0; i < oldValues.size(); i++)
|
|
|
+ oracleInput << oldValues[i];
|
|
|
|
|
|
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 < userTallyMaskCommits.size(); i++)
|
|
|
- for (size_t j = 0; j < userTallyMaskCommits[i].size(); j++)
|
|
|
- oracleInput << userTallyMaskCommits[i][j];
|
|
|
-
|
|
|
- for (size_t i = 0; i < userTallyMessageCommits.size(); i++)
|
|
|
- for (size_t j = 0; j < userTallyMessageCommits[i].size(); j++)
|
|
|
- oracleInput << userTallyMessageCommits[i][j];
|
|
|
-
|
|
|
- for (size_t i = 0; i < userTallySeedCommits.size(); i++)
|
|
|
- for (size_t j = 0; j < userTallySeedCommits[i].size(); j++)
|
|
|
- oracleInput << userTallySeedCommits[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];
|
|
|
|
|
|
- Scalar b1;
|
|
|
- b1.set_random();
|
|
|
- std::vector<std::vector<Scalar>> b2;
|
|
|
- std::vector<std::vector<Scalar>> t1;
|
|
|
- std::vector<std::vector<Scalar>> t2;
|
|
|
+ std::vector<Scalar> a;
|
|
|
+ std::vector<Scalar> t1;
|
|
|
+ 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;
|
|
|
-
|
|
|
- Twistpoint U1, U2, U3, U4, U5, U6, U7;
|
|
|
+ Proof currProof;
|
|
|
|
|
|
- currb2.set_random();
|
|
|
- currt1.set_random();
|
|
|
- currt2.set_random();
|
|
|
+ Scalar curra;
|
|
|
+ Scalar currt1;
|
|
|
+ Scalar currt2;
|
|
|
|
|
|
- U1 = g * currb2 + h * currt1;
|
|
|
- U2 = userTallyMasks[j] * (b1 * permutations[j][i] + currb2 * power) +
|
|
|
- currPseudonyms[j] * (permutations[j][i] * b1 * userTallySeeds[i][j] + power * currb2 * userTallySeeds[i][j] + permutations[j][i] * power * currt2) +
|
|
|
- h * currt2;
|
|
|
- U3 = userTallyMasks[j] * (b1 * currb2) +
|
|
|
- currPseudonyms[j] * (b1 * currb2 * userTallySeeds[i][j] + permutations[j][i] * b1 * currt2 + power * currb2 * currt2);
|
|
|
- U4 = currPseudonyms[j] * (b1 * currb2 * currt2);
|
|
|
- U5 = userTallyMessages[j] * currb2 +
|
|
|
- nextGenerator * (permutations[j][i] * currt2 + userTallySeeds[i][j] * currb2) +
|
|
|
- h * currt2;
|
|
|
- U6 = nextGenerator * (currb2 * currt2);
|
|
|
- U7 = g * currt2;
|
|
|
+ Twistpoint U1;
|
|
|
+ T U2;
|
|
|
|
|
|
- currProof.curvepointUniversals.push_back(U2);
|
|
|
- currProof.curvepointUniversals.push_back(U3);
|
|
|
- currProof.curvepointUniversals.push_back(U5);
|
|
|
+ curra.set_random();
|
|
|
+ currt1.set_random();
|
|
|
+ currt2.set_random();
|
|
|
|
|
|
- oracleInput << U1 << U2 << U3 << U4 << U5 << U6 << U7;
|
|
|
+ U1 = g * curra + h * currt1;
|
|
|
+ U2 = oldValues[i] * curra + otherH * currt2;
|
|
|
|
|
|
- currb2Row.push_back(currb2);
|
|
|
- currt1Row.push_back(currt1);
|
|
|
- currt2Row.push_back(currt2);
|
|
|
+ oracleInput << U1 << U2;
|
|
|
|
|
|
- retval.push_back(currProof);
|
|
|
- }
|
|
|
+ a.push_back(curra);
|
|
|
+ t1.push_back(currt1);
|
|
|
+ t2.push_back(currt2);
|
|
|
|
|
|
- b2.push_back(currb2Row);
|
|
|
- t1.push_back(currt1Row);
|
|
|
- t2.push_back(currt2Row);
|
|
|
+ retval.push_back(currProof);
|
|
|
}
|
|
|
|
|
|
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++)
|
|
|
{
|
|
|
+ size_t piIndex = i + 1;
|
|
|
+
|
|
|
+ Scalar f = a[i];
|
|
|
+ Scalar z1 = t1[i];
|
|
|
+ Scalar z2 = t2[i];
|
|
|
+
|
|
|
for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
{
|
|
|
- size_t piIndex = i * permutationCommits.size() + j + 1;
|
|
|
-
|
|
|
- Scalar f2 = permutations[j][i] * x + b2[i][j];
|
|
|
- Scalar z1 = permutationSeeds[j][i] * x + t1[i][j];
|
|
|
- Scalar z2 = userTallySeeds[i][j] * x + t2[i][j];
|
|
|
+ std::stringstream currOracle;
|
|
|
+ currOracle << permutationCommits[i][j] << productCommits[j][i];
|
|
|
+ Scalar currx = oracle(currOracle.str(), LAMBDA);
|
|
|
|
|
|
- retval[piIndex].responseParts.push_back(f2);
|
|
|
- retval[piIndex].responseParts.push_back(z1);
|
|
|
- retval[piIndex].responseParts.push_back(z2);
|
|
|
+ f = f + permutations[i][j] * currx;
|
|
|
+ z1 = z1 + permutationSeeds[i][j] * currx;
|
|
|
+ z2 = z2 + productSeeds[j][i] * currx;
|
|
|
}
|
|
|
+
|
|
|
+ retval[piIndex].responseParts.push_back(f);
|
|
|
+ retval[piIndex].responseParts.push_back(z1);
|
|
|
+ retval[piIndex].responseParts.push_back(z2);
|
|
|
}
|
|
|
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-bool PrsonaBase::verify_user_tally_proofs(
|
|
|
+template <typename T>
|
|
|
+bool PrsonaBase::verify_batched_proof_of_reordering(
|
|
|
const std::vector<Proof>& pi,
|
|
|
- const Twistpoint& nextGenerator,
|
|
|
- const std::vector<Twistpoint>& currPseudonyms,
|
|
|
- const std::vector<Twistpoint>& userTallyMasks,
|
|
|
- const std::vector<Twistpoint>& userTallyMessages,
|
|
|
+ const std::vector<T>& oldValues,
|
|
|
const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& userTallyMaskCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& userTallyMessageCommits,
|
|
|
- const std::vector<std::vector<Twistpoint>>& userTallySeedCommits) const
|
|
|
-{
|
|
|
+ const std::vector<std::vector<T>>& productCommits,
|
|
|
+ const T& otherG,
|
|
|
+ const T& otherH) const
|
|
|
+{
|
|
|
if (pi.empty())
|
|
|
return false;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
return pi[0].hbc == "PROOF";
|
|
|
-
|
|
|
+
|
|
|
Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
Twistpoint h = elGamalBlindGenerator;
|
|
|
|
|
|
std::stringstream oracleInput;
|
|
|
- oracleInput << g << h << nextGenerator;
|
|
|
-
|
|
|
- for (size_t i = 0; i < currPseudonyms.size(); i++)
|
|
|
- oracleInput << currPseudonyms[i];
|
|
|
-
|
|
|
- for (size_t i = 0; i < userTallyMasks.size(); i++)
|
|
|
- oracleInput << userTallyMasks[i];
|
|
|
+ oracleInput << g << h << otherG << otherH;
|
|
|
|
|
|
- for (size_t i = 0; i < userTallyMessages.size(); i++)
|
|
|
- oracleInput << userTallyMessages[i];
|
|
|
+ for (size_t i = 0; i < oldValues.size(); i++)
|
|
|
+ oracleInput << oldValues[i];
|
|
|
|
|
|
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 < userTallyMaskCommits.size(); i++)
|
|
|
- for (size_t j = 0; j < userTallyMaskCommits[i].size(); j++)
|
|
|
- oracleInput << userTallyMaskCommits[i][j];
|
|
|
-
|
|
|
- for (size_t i = 0; i < userTallyMessageCommits.size(); i++)
|
|
|
- for (size_t j = 0; j < userTallyMessageCommits[i].size(); j++)
|
|
|
- oracleInput << userTallyMessageCommits[i][j];
|
|
|
-
|
|
|
- for (size_t i = 0; i < userTallySeedCommits.size(); i++)
|
|
|
- for (size_t j = 0; j < userTallySeedCommits[i].size(); j++)
|
|
|
- oracleInput << userTallySeedCommits[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];
|
|
|
|
|
|
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;
|
|
|
+ size_t piIndex = i + 1;
|
|
|
|
|
|
- Twistpoint U1, U2, U3, U4, U5, U6, U7;
|
|
|
- U2 = pi[piIndex].curvepointUniversals[0];
|
|
|
- U3 = pi[piIndex].curvepointUniversals[1];
|
|
|
- U5 = pi[piIndex].curvepointUniversals[2];
|
|
|
+ Scalar f = pi[piIndex].responseParts[0];
|
|
|
+ Scalar z1 = pi[piIndex].responseParts[1];
|
|
|
+ Scalar z2 = pi[piIndex].responseParts[2];
|
|
|
|
|
|
- Scalar f2 = pi[piIndex].responseParts[0];
|
|
|
- Scalar z1 = pi[piIndex].responseParts[1];
|
|
|
- Scalar z2 = pi[piIndex].responseParts[2];
|
|
|
+ Twistpoint U1 = g * f + h * z1;
|
|
|
+ T U2 = oldValues[i] * f + otherH * z2;
|
|
|
|
|
|
- U1 = g * f2 + h * z1 - permutationCommits[j][i] * x;
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ std::stringstream currOracle;
|
|
|
+ currOracle << permutationCommits[i][j] << productCommits[j][i];
|
|
|
+ Scalar currx = oracle(currOracle.str(), LAMBDA);
|
|
|
|
|
|
- U4 = userTallyMasks[j] * (f1 * f2 * x) +
|
|
|
- currPseudonyms[j] * (f1 * f2 * z2) +
|
|
|
- h * (z2 * x * x) -
|
|
|
- userTallyMaskCommits[i][j] * (x * x * x) -
|
|
|
- U2 * (x * x) -
|
|
|
- U3 * x;
|
|
|
-
|
|
|
- U6 = userTallyMessages[j] * (f2 * x) +
|
|
|
- nextGenerator * (f2 * z2) +
|
|
|
- h * (z2 * x) -
|
|
|
- userTallyMessageCommits[i][j] * (x * x) -
|
|
|
- U5 * x;
|
|
|
-
|
|
|
- U7 = g * z2 - userTallySeedCommits[i][j] * x;
|
|
|
-
|
|
|
- oracleInput << U1 << U2 << U3 << U4 << U5 << U6 << U7;
|
|
|
+ U1 = U1 - permutationCommits[i][j] * currx;
|
|
|
+ U2 = U2 - productCommits[j][i] * currx;
|
|
|
}
|
|
|
+
|
|
|
+ oracleInput << U1 << U2;
|
|
|
}
|
|
|
|
|
|
if (x != oracle(oracleInput.str()))
|
|
|
{
|
|
|
- std::cerr << "User tallies not generated by permutation matrix." << std::endl;
|
|
|
+ std::cerr << "Reordered things not generated by permutation matrix." << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- for (size_t i = 0; i < userTallySeedCommits.size(); i++)
|
|
|
- {
|
|
|
- Twistpoint sum = userTallySeedCommits[i][0];
|
|
|
-
|
|
|
- for (size_t j = 1; j < userTallySeedCommits[i].size(); j++)
|
|
|
- sum = sum + userTallySeedCommits[i][j];
|
|
|
+ return true;
|
|
|
+}
|
|
|
|
|
|
- if (sum != Twistpoint())
|
|
|
- {
|
|
|
- std::cerr << "seed commits did not sum to 0, aborting." << std::endl;
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
+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<Twistpoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& productCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& seedCommits) const
|
|
|
+{
|
|
|
+ if (LAMBDA > 0)
|
|
|
+ return generate_batched_proof_of_reordering_plus_power(permutations, power, permutationSeeds, productSeeds, oldValues, permutationCommits, productCommits, seedCommits);
|
|
|
+ else
|
|
|
+ return generate_unbatched_proof_of_reordering_plus_power(permutations, power, permutationSeeds, productSeeds, oldValues, permutationCommits, productCommits, seedCommits);
|
|
|
+}
|
|
|
|
|
|
- return true;
|
|
|
+bool PrsonaBase::verify_proof_of_reordering_plus_power(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const std::vector<Twistpoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& productCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& seedCommits) const
|
|
|
+{
|
|
|
+ if (LAMBDA > 0)
|
|
|
+ return verify_batched_proof_of_reordering_plus_power(pi, oldValues, permutationCommits, productCommits, seedCommits);
|
|
|
+ else
|
|
|
+ return verify_unbatched_proof_of_reordering_plus_power(pi, oldValues, permutationCommits, productCommits, seedCommits);
|
|
|
}
|
|
|
|
|
|
-template <typename T>
|
|
|
-std::vector<Proof> PrsonaBase::generate_proof_of_reordering(
|
|
|
+std::vector<Proof> PrsonaBase::generate_unbatched_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<T>& oldValues,
|
|
|
+ const std::vector<Twistpoint>& oldValues,
|
|
|
const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
- const std::vector<std::vector<T>>& productCommits,
|
|
|
- const T& otherG,
|
|
|
- const T& otherH) const
|
|
|
+ const std::vector<std::vector<Twistpoint>>& productCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& seedCommits) const
|
|
|
{
|
|
|
std::vector<Proof> retval;
|
|
|
|
|
@@ -1411,12 +1368,12 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering(
|
|
|
|
|
|
Proof first;
|
|
|
retval.push_back(first);
|
|
|
-
|
|
|
+
|
|
|
Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
Twistpoint h = elGamalBlindGenerator;
|
|
|
|
|
|
std::stringstream oracleInput;
|
|
|
- oracleInput << g << h << otherG << otherH;
|
|
|
+ oracleInput << g << h;
|
|
|
|
|
|
for (size_t i = 0; i < oldValues.size(); i++)
|
|
|
oracleInput << oldValues[i];
|
|
@@ -1429,13 +1386,19 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering(
|
|
|
for (size_t j = 0; j < productCommits[i].size(); j++)
|
|
|
oracleInput << productCommits[i][j];
|
|
|
|
|
|
- std::vector<std::vector<Scalar>> a;
|
|
|
+ for (size_t i = 0; i < seedCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < seedCommits[i].size(); j++)
|
|
|
+ oracleInput << seedCommits[i][j];
|
|
|
+
|
|
|
+ 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> curraRow;
|
|
|
+ std::vector<Scalar> currb2Row;
|
|
|
std::vector<Scalar> currt1Row;
|
|
|
std::vector<Scalar> currt2Row;
|
|
|
|
|
@@ -1443,30 +1406,34 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering(
|
|
|
{
|
|
|
Proof currProof;
|
|
|
|
|
|
- Scalar curra;
|
|
|
+ Scalar currb2;
|
|
|
Scalar currt1;
|
|
|
Scalar currt2;
|
|
|
|
|
|
- Twistpoint U1;
|
|
|
- T U2;
|
|
|
+ Twistpoint U1, U2, U3, U4;
|
|
|
|
|
|
- curra.set_random();
|
|
|
+ currb2.set_random();
|
|
|
currt1.set_random();
|
|
|
currt2.set_random();
|
|
|
|
|
|
- U1 = g * curra + h * currt1;
|
|
|
- U2 = oldValues[j] * curra + otherH * currt2;
|
|
|
+ U1 = g * currb2 + h * currt1;
|
|
|
+ U2 = oldValues[j] *
|
|
|
+ (b1 * permutations[j][i] + currb2 * power);
|
|
|
+ U3 = oldValues[j] * b1 * currb2 + h * currt2;
|
|
|
+ U4 = g * currt2;
|
|
|
|
|
|
- oracleInput << U1 << U2;
|
|
|
+ currProof.curvepointUniversals.push_back(U2);
|
|
|
|
|
|
- curraRow.push_back(curra);
|
|
|
+ oracleInput << U1 << U2 << U3 << U4;
|
|
|
+
|
|
|
+ currb2Row.push_back(currb2);
|
|
|
currt1Row.push_back(currt1);
|
|
|
currt2Row.push_back(currt2);
|
|
|
|
|
|
retval.push_back(currProof);
|
|
|
}
|
|
|
|
|
|
- a.push_back(curraRow);
|
|
|
+ b2.push_back(currb2Row);
|
|
|
t1.push_back(currt1Row);
|
|
|
t2.push_back(currt2Row);
|
|
|
}
|
|
@@ -1474,17 +1441,20 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering(
|
|
|
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;
|
|
|
|
|
|
- Scalar f = permutations[j][i] * x + a[i][j];
|
|
|
+ Scalar f2 = permutations[j][i] * x + b2[i][j];
|
|
|
Scalar z1 = permutationSeeds[j][i] * x + t1[i][j];
|
|
|
- Scalar z2 = productSeeds[i][j] * x + t2[i][j];
|
|
|
+ Scalar z2 = productSeeds[i][j] * x * x + t2[i][j];
|
|
|
|
|
|
- retval[piIndex].responseParts.push_back(f);
|
|
|
+ retval[piIndex].responseParts.push_back(f2);
|
|
|
retval[piIndex].responseParts.push_back(z1);
|
|
|
retval[piIndex].responseParts.push_back(z2);
|
|
|
}
|
|
@@ -1493,26 +1463,24 @@ std::vector<Proof> PrsonaBase::generate_proof_of_reordering(
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-template <typename T>
|
|
|
-bool PrsonaBase::verify_proof_of_reordering(
|
|
|
+bool PrsonaBase::verify_unbatched_proof_of_reordering_plus_power(
|
|
|
const std::vector<Proof>& pi,
|
|
|
- const std::vector<T>& oldValues,
|
|
|
+ const std::vector<Twistpoint>& oldValues,
|
|
|
const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
- const std::vector<std::vector<T>>& productCommits,
|
|
|
- const T& otherG,
|
|
|
- const T& otherH) const
|
|
|
+ const std::vector<std::vector<Twistpoint>>& productCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& seedCommits) const
|
|
|
{
|
|
|
if (pi.empty())
|
|
|
return false;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
return pi[0].hbc == "PROOF";
|
|
|
-
|
|
|
+
|
|
|
Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
Twistpoint h = elGamalBlindGenerator;
|
|
|
|
|
|
std::stringstream oracleInput;
|
|
|
- oracleInput << g << h << otherG << otherH;
|
|
|
+ oracleInput << g << h;
|
|
|
|
|
|
for (size_t i = 0; i < oldValues.size(); i++)
|
|
|
oracleInput << oldValues[i];
|
|
@@ -1525,7 +1493,12 @@ bool PrsonaBase::verify_proof_of_reordering(
|
|
|
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];
|
|
|
+
|
|
|
Scalar x = pi[0].challengeParts[0];
|
|
|
+ Scalar f1 = pi[0].responseParts[0];
|
|
|
|
|
|
for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
{
|
|
@@ -1533,31 +1506,535 @@ bool PrsonaBase::verify_proof_of_reordering(
|
|
|
{
|
|
|
size_t piIndex = i * permutationCommits.size() + j + 1;
|
|
|
|
|
|
- Twistpoint U1;
|
|
|
- T U2;
|
|
|
+ Twistpoint U1, U2, U3, U4;
|
|
|
+ U2 = pi[piIndex].curvepointUniversals[0];
|
|
|
|
|
|
- Scalar f = pi[piIndex].responseParts[0];
|
|
|
+ Scalar f2 = pi[piIndex].responseParts[0];
|
|
|
Scalar z1 = pi[piIndex].responseParts[1];
|
|
|
Scalar z2 = pi[piIndex].responseParts[2];
|
|
|
|
|
|
- U1 = g * f +
|
|
|
- h * z1 -
|
|
|
- permutationCommits[j][i] * x;
|
|
|
+ U1 = g * f2 + h * z1 - permutationCommits[j][i] * x;
|
|
|
|
|
|
- U2 = oldValues[j] * f +
|
|
|
- otherH * z2 -
|
|
|
- productCommits[i][j] * x;
|
|
|
+ U3 = oldValues[j] * f1 * f2 +
|
|
|
+ h * z2 -
|
|
|
+ productCommits[i][j] * x * x -
|
|
|
+ U2 * x;
|
|
|
|
|
|
- oracleInput << U1 << U2;
|
|
|
+ U4 = g * z2 - seedCommits[i][j] * x * x;
|
|
|
+
|
|
|
+ oracleInput << U1 << U2 << U3 << U4;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (x != oracle(oracleInput.str()))
|
|
|
{
|
|
|
- std::cerr << "Reordered things not generated by permutation matrix." << std::endl;
|
|
|
+ std::cerr << "Reordered + power things not generated by permutation matrix." << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ for (size_t i = 0; i < seedCommits.size(); i++)
|
|
|
+ {
|
|
|
+ Twistpoint sum = seedCommits[i][0];
|
|
|
+
|
|
|
+ for (size_t j = 1; j < seedCommits[i].size(); j++)
|
|
|
+ sum = sum + seedCommits[i][j];
|
|
|
+
|
|
|
+ if (sum != Twistpoint())
|
|
|
+ {
|
|
|
+ std::cerr << "seed commits did not sum to 0, aborting." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+std::vector<Proof> PrsonaBase::generate_batched_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<Twistpoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& productCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& seedCommits) const
|
|
|
+{
|
|
|
+ std::vector<Proof> retval;
|
|
|
+
|
|
|
+ if (!SERVER_IS_MALICIOUS)
|
|
|
+ {
|
|
|
+ retval.push_back(Proof("PROOF"));
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+
|
|
|
+ Proof first;
|
|
|
+ retval.push_back(first);
|
|
|
+
|
|
|
+ Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
+ Twistpoint h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < oldValues.size(); i++)
|
|
|
+ oracleInput << oldValues[i];
|
|
|
+
|
|
|
+ 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::vector<Scalar> b1;
|
|
|
+ std::vector<Scalar> b2;
|
|
|
+ std::vector<std::vector<Scalar>> b3;
|
|
|
+ std::vector<Scalar> t1;
|
|
|
+ std::vector<Scalar> t2;
|
|
|
+ std::vector<Scalar> t3;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+
|
|
|
+ Scalar currb1;
|
|
|
+ Scalar currb2;
|
|
|
+ std::vector<Scalar> currb3Row;
|
|
|
+ Scalar currt1;
|
|
|
+ Scalar currt2;
|
|
|
+ Scalar currt3;
|
|
|
+
|
|
|
+ Twistpoint U1, U3, U4;
|
|
|
+ std::vector<Twistpoint> U2;
|
|
|
+
|
|
|
+ currb1.set_random();
|
|
|
+ currb2.set_random();
|
|
|
+ currt1.set_random();
|
|
|
+ currt2.set_random();
|
|
|
+ currt3.set_random();
|
|
|
+
|
|
|
+ U1 = g * currb2 + h * currt1;
|
|
|
+ U3 = oldValues[i] * (currb1 * currb2 + currt3) + h * currt2;
|
|
|
+ U4 = g * currt2;
|
|
|
+
|
|
|
+ oracleInput << U1;
|
|
|
+
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ Twistpoint U2;
|
|
|
+ Scalar currb3;
|
|
|
+ currb3.set_random();
|
|
|
+
|
|
|
+ Scalar U2mult = (currb1 * permutations[i][j] + currb2 * power + currb3);
|
|
|
+ for (size_t k = 0; k < permutationCommits[i].size(); k++)
|
|
|
+ {
|
|
|
+ if (k == j)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ std::stringstream currOracle;
|
|
|
+ currOracle << permutationCommits[i][k] << productCommits[k][i] << seedCommits[k][i];
|
|
|
+ Scalar currx = oracle(currOracle.str(), LAMBDA);
|
|
|
+
|
|
|
+ U2mult = U2mult + power * permutations[i][j] * currx;
|
|
|
+ }
|
|
|
+ U2 = oldValues[i] * U2mult;
|
|
|
+ currProof.curvepointUniversals.push_back(U2);
|
|
|
+
|
|
|
+ oracleInput << U2;
|
|
|
+
|
|
|
+ currb3Row.push_back(currb3);
|
|
|
+ }
|
|
|
+ oracleInput << U3 << U4;
|
|
|
+
|
|
|
+ b1.push_back(currb1);
|
|
|
+ b2.push_back(currb2);
|
|
|
+ b3.push_back(currb3Row);
|
|
|
+ t1.push_back(currt1);
|
|
|
+ t2.push_back(currt2);
|
|
|
+ t3.push_back(currt3);
|
|
|
+
|
|
|
+ retval.push_back(currProof);
|
|
|
+ }
|
|
|
+
|
|
|
+ Scalar x = oracle(oracleInput.str());
|
|
|
+ retval[0].challengeParts.push_back(x);
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ {
|
|
|
+ size_t piIndex = i + 1;
|
|
|
+
|
|
|
+ Scalar f1 = b1[i];
|
|
|
+ Scalar f2 = b2[i];
|
|
|
+ Scalar z1 = t1[i];
|
|
|
+ Scalar z2 = t2[i];
|
|
|
+ Scalar z3 = t3[i];
|
|
|
+
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ std::stringstream currOracle;
|
|
|
+ currOracle << permutationCommits[i][j] << productCommits[j][i] << seedCommits[j][i];
|
|
|
+ Scalar currx = oracle(currOracle.str(), LAMBDA);
|
|
|
+
|
|
|
+ f1 = f1 + power * currx;
|
|
|
+ f2 = f2 + permutations[i][j] * currx;
|
|
|
+ z1 = z1 + permutationSeeds[i][j] * currx;
|
|
|
+ z2 = z2 + productSeeds[j][i] * currx * currx;
|
|
|
+ z3 = z3 + b3[i][j] * currx;
|
|
|
+ }
|
|
|
+
|
|
|
+ retval[piIndex].responseParts.push_back(f1);
|
|
|
+ retval[piIndex].responseParts.push_back(f2);
|
|
|
+ retval[piIndex].responseParts.push_back(z1);
|
|
|
+ retval[piIndex].responseParts.push_back(z2);
|
|
|
+ retval[piIndex].responseParts.push_back(z3);
|
|
|
+ }
|
|
|
+
|
|
|
+ return retval;
|
|
|
+}
|
|
|
+
|
|
|
+bool PrsonaBase::verify_batched_proof_of_reordering_plus_power(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const std::vector<Twistpoint>& oldValues,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& productCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& seedCommits) const
|
|
|
+{
|
|
|
+ if (pi.empty())
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (!SERVER_IS_MALICIOUS)
|
|
|
+ return pi[0].hbc == "PROOF";
|
|
|
+
|
|
|
+ Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
+ Twistpoint h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < oldValues.size(); i++)
|
|
|
+ oracleInput << oldValues[i];
|
|
|
+
|
|
|
+ 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];
|
|
|
+
|
|
|
+ Scalar x = pi[0].challengeParts[0];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ {
|
|
|
+ size_t piIndex = i + 1;
|
|
|
+
|
|
|
+ Scalar f1 = pi[piIndex].responseParts[0];
|
|
|
+ Scalar f2 = pi[piIndex].responseParts[1];
|
|
|
+ Scalar z1 = pi[piIndex].responseParts[2];
|
|
|
+ Scalar z2 = pi[piIndex].responseParts[3];
|
|
|
+ Scalar z3 = pi[piIndex].responseParts[4];
|
|
|
+
|
|
|
+ Twistpoint U1 = g * f2 + h * z1;
|
|
|
+ std::vector<Twistpoint> U2 = pi[piIndex].curvepointUniversals;
|
|
|
+ Twistpoint U3 = oldValues[i] * (f1 * f2 + z3) + h * z2;
|
|
|
+ Twistpoint U4 = g * z2;
|
|
|
+
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ {
|
|
|
+ std::stringstream currOracle;
|
|
|
+ currOracle << permutationCommits[i][j] << productCommits[j][i] << seedCommits[j][i];
|
|
|
+ Scalar currx = oracle(currOracle.str(), LAMBDA);
|
|
|
+
|
|
|
+ U1 = U1 - permutationCommits[i][j] * currx;
|
|
|
+ U3 = U3 -
|
|
|
+ productCommits[j][i] * currx * currx -
|
|
|
+ U2[j] * currx;
|
|
|
+ U4 = U4 - seedCommits[j][i] * currx * currx;
|
|
|
+ }
|
|
|
+
|
|
|
+ oracleInput << U1;
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ oracleInput << U2[j];
|
|
|
+ oracleInput << U3 << U4;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (x != oracle(oracleInput.str()))
|
|
|
+ {
|
|
|
+ std::cerr << "Reordered + power things not generated by permutation matrix." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (size_t i = 0; i < seedCommits.size(); i++)
|
|
|
+ {
|
|
|
+ Twistpoint sum = seedCommits[i][0];
|
|
|
+
|
|
|
+ for (size_t j = 1; j < seedCommits[i].size(); j++)
|
|
|
+ sum = sum + seedCommits[i][j];
|
|
|
+
|
|
|
+ if (sum != Twistpoint())
|
|
|
+ {
|
|
|
+ std::cerr << "seed commits did not sum to 0, aborting." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+std::vector<Proof> PrsonaBase::generate_user_tally_proofs(
|
|
|
+ const std::vector<std::vector<Scalar>>& permutations,
|
|
|
+ const Scalar& power,
|
|
|
+ const Twistpoint& nextGenerator,
|
|
|
+ const std::vector<std::vector<Scalar>>& permutationSeeds,
|
|
|
+ const std::vector<std::vector<Scalar>>& userTallySeeds,
|
|
|
+ const std::vector<Twistpoint>& currPseudonyms,
|
|
|
+ const std::vector<Twistpoint>& userTallyMasks,
|
|
|
+ const std::vector<Twistpoint>& userTallyMessages,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& userTallyMaskCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& userTallyMessageCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& userTallySeedCommits) const
|
|
|
+{
|
|
|
+ std::vector<Proof> retval;
|
|
|
+
|
|
|
+ if (!SERVER_IS_MALICIOUS)
|
|
|
+ {
|
|
|
+ retval.push_back(Proof("PROOF"));
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+
|
|
|
+ Proof first;
|
|
|
+ retval.push_back(first);
|
|
|
+
|
|
|
+ Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
+ Twistpoint h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h << nextGenerator;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < currPseudonyms.size(); i++)
|
|
|
+ oracleInput << currPseudonyms[i];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < userTallyMasks.size(); i++)
|
|
|
+ oracleInput << userTallyMasks[i];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < userTallyMessages.size(); i++)
|
|
|
+ oracleInput << userTallyMessages[i];
|
|
|
+
|
|
|
+ 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 < userTallyMaskCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < userTallyMaskCommits[i].size(); j++)
|
|
|
+ oracleInput << userTallyMaskCommits[i][j];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < userTallyMessageCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < userTallyMessageCommits[i].size(); j++)
|
|
|
+ oracleInput << userTallyMessageCommits[i][j];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < userTallySeedCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < userTallySeedCommits[i].size(); j++)
|
|
|
+ oracleInput << userTallySeedCommits[i][j];
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ Twistpoint U1, U2, U3, U4, U5, U6, U7;
|
|
|
+
|
|
|
+ currb2.set_random();
|
|
|
+ currt1.set_random();
|
|
|
+ currt2.set_random();
|
|
|
+
|
|
|
+ U1 = g * currb2 + h * currt1;
|
|
|
+ U2 = userTallyMasks[j] * (b1 * permutations[j][i] + currb2 * power) +
|
|
|
+ currPseudonyms[j] * (permutations[j][i] * b1 * userTallySeeds[i][j] + power * currb2 * userTallySeeds[i][j] + permutations[j][i] * power * currt2) +
|
|
|
+ h * currt2;
|
|
|
+ U3 = userTallyMasks[j] * (b1 * currb2) +
|
|
|
+ currPseudonyms[j] * (b1 * currb2 * userTallySeeds[i][j] + permutations[j][i] * b1 * currt2 + power * currb2 * currt2);
|
|
|
+ U4 = currPseudonyms[j] * (b1 * currb2 * currt2);
|
|
|
+ U5 = userTallyMessages[j] * currb2 +
|
|
|
+ nextGenerator * (permutations[j][i] * currt2 + userTallySeeds[i][j] * currb2) +
|
|
|
+ h * currt2;
|
|
|
+ U6 = nextGenerator * (currb2 * currt2);
|
|
|
+ U7 = g * currt2;
|
|
|
+
|
|
|
+ currProof.curvepointUniversals.push_back(U2);
|
|
|
+ currProof.curvepointUniversals.push_back(U3);
|
|
|
+ currProof.curvepointUniversals.push_back(U5);
|
|
|
+
|
|
|
+ oracleInput << U1 << U2 << U3 << U4 << U5 << U6 << U7;
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ Scalar f2 = permutations[j][i] * x + b2[i][j];
|
|
|
+ Scalar z1 = permutationSeeds[j][i] * x + t1[i][j];
|
|
|
+ Scalar z2 = userTallySeeds[i][j] * x + t2[i][j];
|
|
|
+
|
|
|
+ retval[piIndex].responseParts.push_back(f2);
|
|
|
+ retval[piIndex].responseParts.push_back(z1);
|
|
|
+ retval[piIndex].responseParts.push_back(z2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return retval;
|
|
|
+}
|
|
|
+
|
|
|
+bool PrsonaBase::verify_user_tally_proofs(
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
+ const Twistpoint& nextGenerator,
|
|
|
+ const std::vector<Twistpoint>& currPseudonyms,
|
|
|
+ const std::vector<Twistpoint>& userTallyMasks,
|
|
|
+ const std::vector<Twistpoint>& userTallyMessages,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& userTallyMaskCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& userTallyMessageCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& userTallySeedCommits) const
|
|
|
+{
|
|
|
+ if (pi.empty())
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (!SERVER_IS_MALICIOUS)
|
|
|
+ return pi[0].hbc == "PROOF";
|
|
|
+
|
|
|
+ Twistpoint g = EL_GAMAL_GENERATOR;
|
|
|
+ Twistpoint h = elGamalBlindGenerator;
|
|
|
+
|
|
|
+ std::stringstream oracleInput;
|
|
|
+ oracleInput << g << h << nextGenerator;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < currPseudonyms.size(); i++)
|
|
|
+ oracleInput << currPseudonyms[i];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < userTallyMasks.size(); i++)
|
|
|
+ oracleInput << userTallyMasks[i];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < userTallyMessages.size(); i++)
|
|
|
+ oracleInput << userTallyMessages[i];
|
|
|
+
|
|
|
+ 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 < userTallyMaskCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < userTallyMaskCommits[i].size(); j++)
|
|
|
+ oracleInput << userTallyMaskCommits[i][j];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < userTallyMessageCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < userTallyMessageCommits[i].size(); j++)
|
|
|
+ oracleInput << userTallyMessageCommits[i][j];
|
|
|
+
|
|
|
+ for (size_t i = 0; i < userTallySeedCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < userTallySeedCommits[i].size(); j++)
|
|
|
+ oracleInput << userTallySeedCommits[i][j];
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ Twistpoint U1, U2, U3, U4, U5, U6, U7;
|
|
|
+ U2 = pi[piIndex].curvepointUniversals[0];
|
|
|
+ U3 = pi[piIndex].curvepointUniversals[1];
|
|
|
+ U5 = pi[piIndex].curvepointUniversals[2];
|
|
|
+
|
|
|
+ Scalar f2 = pi[piIndex].responseParts[0];
|
|
|
+ Scalar z1 = pi[piIndex].responseParts[1];
|
|
|
+ Scalar z2 = pi[piIndex].responseParts[2];
|
|
|
+
|
|
|
+ U1 = g * f2 + h * z1 - permutationCommits[j][i] * x;
|
|
|
+
|
|
|
+ U4 = userTallyMasks[j] * (f1 * f2 * x) +
|
|
|
+ currPseudonyms[j] * (f1 * f2 * z2) +
|
|
|
+ h * (z2 * x * x) -
|
|
|
+ userTallyMaskCommits[i][j] * (x * x * x) -
|
|
|
+ U2 * (x * x) -
|
|
|
+ U3 * x;
|
|
|
+
|
|
|
+ U6 = userTallyMessages[j] * (f2 * x) +
|
|
|
+ nextGenerator * (f2 * z2) +
|
|
|
+ h * (z2 * x) -
|
|
|
+ userTallyMessageCommits[i][j] * (x * x) -
|
|
|
+ U5 * x;
|
|
|
+
|
|
|
+ U7 = g * z2 - userTallySeedCommits[i][j] * x;
|
|
|
+
|
|
|
+ oracleInput << U1 << U2 << U3 << U4 << U5 << U6 << U7;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (x != oracle(oracleInput.str()))
|
|
|
+ {
|
|
|
+ std::cerr << "User tallies not generated by permutation matrix." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (size_t i = 0; i < userTallySeedCommits.size(); i++)
|
|
|
+ {
|
|
|
+ Twistpoint sum = userTallySeedCommits[i][0];
|
|
|
+
|
|
|
+ for (size_t j = 1; j < userTallySeedCommits[i].size(); j++)
|
|
|
+ sum = sum + userTallySeedCommits[i][j];
|
|
|
+
|
|
|
+ if (sum != Twistpoint())
|
|
|
+ {
|
|
|
+ std::cerr << "seed commits did not sum to 0, aborting." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|