|
@@ -107,6 +107,33 @@ bool PrsonaBase::set_EG_blind_generator(
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * BINARY SEARCH
|
|
|
+ */
|
|
|
+
|
|
|
+/* Completely normal binary search
|
|
|
+ * There might be a standard function for this in <algorithms>?
|
|
|
+ * But it returns an iterator, not a size_t, so less useful. */
|
|
|
+size_t PrsonaBase::binary_search(
|
|
|
+ const std::vector<Curvepoint> list, const Curvepoint& index) const
|
|
|
+{
|
|
|
+ size_t lo, hi;
|
|
|
+ lo = 0;
|
|
|
+ hi = list.size() - 1;
|
|
|
+
|
|
|
+ while (lo < hi)
|
|
|
+ {
|
|
|
+ size_t mid = (lo + hi) / 2;
|
|
|
+ if (list[mid] < index)
|
|
|
+ lo = mid + 1;
|
|
|
+ else if (index == list[mid])
|
|
|
+ return mid;
|
|
|
+ else hi = mid - 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return lo;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* SCHNORR PROOFS
|
|
|
*/
|
|
@@ -162,7 +189,7 @@ Proof PrsonaBase::generate_ownership_proof(
|
|
|
if (!CLIENT_IS_MALICIOUS)
|
|
|
{
|
|
|
Proof retval;
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
|
|
|
return retval;
|
|
|
}
|
|
@@ -176,7 +203,7 @@ bool PrsonaBase::verify_ownership_proof(
|
|
|
const Curvepoint& commitment) const
|
|
|
{
|
|
|
if (!CLIENT_IS_MALICIOUS)
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
|
|
|
Scalar c = pi.challengeParts[0];
|
|
|
Scalar z = pi.responseParts[0];
|
|
@@ -195,14 +222,14 @@ Proof PrsonaBase::add_to_generator_proof(
|
|
|
Proof retval;
|
|
|
if (!CLIENT_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
Curvepoint nextGenerator = currGenerator * seed;
|
|
|
retval = schnorr_generation(currGenerator, nextGenerator, seed);
|
|
|
|
|
|
- retval.partialUniversals.push_back(currGenerator);
|
|
|
+ retval.curvepointUniversals.push_back(currGenerator);
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
@@ -219,20 +246,20 @@ bool PrsonaBase::verify_generator_proof(
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
for (size_t i = 0; i < pi.size(); i++)
|
|
|
- retval = retval && pi[i].basic == "PROOF";
|
|
|
+ retval = retval && pi[i].hbc == "PROOF";
|
|
|
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- if (pi[0].partialUniversals[0] != EL_GAMAL_GENERATOR)
|
|
|
+ if (pi[0].curvepointUniversals[0] != EL_GAMAL_GENERATOR)
|
|
|
return false;
|
|
|
|
|
|
for (size_t i = 0; i < pi.size(); i++)
|
|
|
{
|
|
|
- Curvepoint generator = pi[i].partialUniversals[0];
|
|
|
+ Curvepoint generator = pi[i].curvepointUniversals[0];
|
|
|
Curvepoint commitment = (i == pi.size() - 1 ?
|
|
|
currGenerator :
|
|
|
- pi[i + 1].partialUniversals[0]);
|
|
|
+ pi[i + 1].curvepointUniversals[0]);
|
|
|
Scalar c = pi[i].challengeParts[0];
|
|
|
Scalar z = pi[i].responseParts[0];
|
|
|
|
|
@@ -316,7 +343,7 @@ std::vector<Proof> PrsonaBase::generate_reputation_proof(
|
|
|
r = masksPerBit[i];
|
|
|
|
|
|
c = g * r + h * m;
|
|
|
- currProof.partialUniversals.push_back(c);
|
|
|
+ currProof.curvepointUniversals.push_back(c);
|
|
|
|
|
|
c_a = g * s + h * a;
|
|
|
|
|
@@ -374,14 +401,14 @@ bool PrsonaBase::verify_reputation_proof(
|
|
|
}
|
|
|
|
|
|
if (!CLIENT_IS_MALICIOUS)
|
|
|
- return pi[0].basic == "PROOF";
|
|
|
+ return pi[0].hbc == "PROOF";
|
|
|
|
|
|
- Scalar c, z;
|
|
|
- c = pi[0].challengeParts[0];
|
|
|
- z = pi[0].responseParts[0];
|
|
|
+ Scalar ownerChallenge, ownerResponse;
|
|
|
+ ownerChallenge = pi[0].challengeParts[0];
|
|
|
+ ownerResponse = pi[0].responseParts[0];
|
|
|
|
|
|
// User should be able to prove they are who they say they are
|
|
|
- if (!schnorr_verification(generator, owner, c, z))
|
|
|
+ if (!schnorr_verification(generator, owner, ownerChallenge, ownerResponse))
|
|
|
{
|
|
|
std::cerr << "Schnorr proof failed, aborting." << std::endl;
|
|
|
return false;
|
|
@@ -393,7 +420,7 @@ bool PrsonaBase::verify_reputation_proof(
|
|
|
for (size_t i = 1; i < pi.size(); i++)
|
|
|
{
|
|
|
Curvepoint c, g, h;
|
|
|
- c = pi[i].partialUniversals[0];
|
|
|
+ c = pi[i].curvepointUniversals[0];
|
|
|
g = commitment.mask;
|
|
|
h = elGamalBlindGenerator;
|
|
|
|
|
@@ -493,8 +520,7 @@ std::vector<Proof> PrsonaBase::generate_vote_proof(
|
|
|
power =
|
|
|
power.curveSub((a.curveAdd(a).curveAdd(a)).curveMult(votes[i]));
|
|
|
CurveBipoint C_b = g * power + h * t_1;
|
|
|
- currProof.partialUniversals.push_back(C_b[0]);
|
|
|
- currProof.partialUniversals.push_back(C_b[1]);
|
|
|
+ currProof.curveBipointUniversals.push_back(C_b);
|
|
|
|
|
|
CurveBipoint C_c = g * a.curveMult(a.curveMult(votes[i])) +
|
|
|
h * t_2;
|
|
@@ -544,8 +570,7 @@ std::vector<Proof> PrsonaBase::generate_vote_proof(
|
|
|
newEncryptedVotes[i] * c_n;
|
|
|
|
|
|
CurveBipoint C_b = g * commitmentLambda_1 + h * commitmentLambda_2;
|
|
|
- currProof.partialUniversals.push_back(C_b[0]);
|
|
|
- currProof.partialUniversals.push_back(C_b[1]);
|
|
|
+ currProof.curveBipointUniversals.push_back(C_b);
|
|
|
|
|
|
Scalar f_c_n = f.curveSub(c_n);
|
|
|
Scalar c_n2_f = c_n.curveAdd(c_n).curveSub(f);
|
|
@@ -592,7 +617,7 @@ bool PrsonaBase::verify_vote_proof(
|
|
|
|
|
|
// Base case
|
|
|
if (!CLIENT_IS_MALICIOUS)
|
|
|
- return pi[0].basic == "PROOF";
|
|
|
+ return pi[0].hbc == "PROOF";
|
|
|
|
|
|
// User should be able to prove they are who they say they are
|
|
|
if (!verify_ownership_proof(pi[0], freshGenerator, owner))
|
|
@@ -611,11 +636,8 @@ bool PrsonaBase::verify_vote_proof(
|
|
|
for (size_t i = 1; i < pi.size(); i++)
|
|
|
{
|
|
|
size_t voteIndex = i - 1;
|
|
|
- Curvepoint C_b_0, C_b_1;
|
|
|
- C_b_0 = pi[i].partialUniversals[0];
|
|
|
- C_b_1 = pi[i].partialUniversals[1];
|
|
|
-
|
|
|
- CurveBipoint C_b(C_b_0, C_b_1);
|
|
|
+ CurveBipoint C_b;
|
|
|
+ C_b = pi[i].curveBipointUniversals[0];
|
|
|
|
|
|
Scalar c_r, c_n, z_r, f, z_na, z_nb;
|
|
|
c_r = pi[i].challengeParts[0];
|
|
@@ -651,131 +673,246 @@ bool PrsonaBase::verify_vote_proof(
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * EPOCH PROOFS
|
|
|
+ * NEW USER PROOFS
|
|
|
*/
|
|
|
|
|
|
-bool PrsonaBase::verify_update_proof(
|
|
|
- const Proof& pi) const
|
|
|
+std::vector<Proof> PrsonaBase::generate_proof_of_added_user(
|
|
|
+ const Scalar& twistBipointSeed,
|
|
|
+ const Scalar& EGCiphertextSeed,
|
|
|
+ const std::vector<Scalar>& curveBipointSelfSeeds,
|
|
|
+ const std::vector<Scalar>& curveBipointOtherSeeds) const
|
|
|
{
|
|
|
+ std::vector<Proof> retval;
|
|
|
+
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ {
|
|
|
+ retval.push_back(Proof("PROOF"));
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
|
|
|
- return pi.basic == "PROOF";
|
|
|
-}
|
|
|
+ Proof currProof;
|
|
|
+ currProof.responseParts.push_back(twistBipointSeed);
|
|
|
+ retval.push_back(currProof);
|
|
|
|
|
|
-/*
|
|
|
- * SERVER AGREEMENT PROOFS
|
|
|
- */
|
|
|
+ currProof.responseParts.clear();
|
|
|
+ currProof.responseParts.push_back(EGCiphertextSeed);
|
|
|
+ retval.push_back(currProof);
|
|
|
+
|
|
|
+ currProof.responseParts.clear();
|
|
|
+ for (size_t i = 0; i < curveBipointSelfSeeds.size(); i++)
|
|
|
+ currProof.responseParts.push_back(curveBipointSelfSeeds[i]);
|
|
|
+ retval.push_back(currProof);
|
|
|
|
|
|
-Proof PrsonaBase::generate_valid_default_tally_proof() const
|
|
|
+ currProof.responseParts.clear();
|
|
|
+ for (size_t i = 0; i < curveBipointOtherSeeds.size(); i++)
|
|
|
+ currProof.responseParts.push_back(curveBipointOtherSeeds[i]);
|
|
|
+ retval.push_back(currProof);
|
|
|
+
|
|
|
+ return retval;
|
|
|
+}
|
|
|
+
|
|
|
+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,
|
|
|
+ const TwistBipoint& twistH,
|
|
|
+ size_t selfIndex,
|
|
|
+ const EGCiphertext& userEncryptedScore,
|
|
|
+ const TwistBipoint& serverEncryptedScore,
|
|
|
+ const std::vector<std::vector<CurveBipoint>> encryptedVoteMatrix) const
|
|
|
{
|
|
|
- Proof retval;
|
|
|
+ if (pi.empty())
|
|
|
+ {
|
|
|
+ std::cerr << "Proof empty." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
+ return pi[0].hbc == "PROOF";
|
|
|
+
|
|
|
+ Scalar currSeed = pi[0].responseParts[0];
|
|
|
+ if (serverEncryptedScore !=
|
|
|
+ twistG * DEFAULT_TALLY + twistH * currSeed)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
- return retval;
|
|
|
+ std::cerr << "Issue in server encrypted score." << std::endl;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- retval.basic = "PROOF";
|
|
|
- return retval;
|
|
|
+ currSeed = pi[1].responseParts[0];
|
|
|
+ if (userEncryptedScore.mask != shortTermPublicKey * currSeed)
|
|
|
+ {
|
|
|
+ std::cerr << "Issue in user encrypted score: mask." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (userEncryptedScore.encryptedMessage !=
|
|
|
+ currentFreshGenerator * currSeed + elGamalBlindGenerator * DEFAULT_TALLY)
|
|
|
+ {
|
|
|
+ std::cerr << "Issue in user encrypted score: value." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (size_t i = 0; i < pi[2].responseParts.size(); i++)
|
|
|
+ {
|
|
|
+ CurveBipoint currVote = encryptedVoteMatrix[selfIndex][i];
|
|
|
+ currSeed = pi[2].responseParts[i];
|
|
|
+
|
|
|
+ if (i == selfIndex)
|
|
|
+ {
|
|
|
+ if (currVote !=
|
|
|
+ curveG * Scalar(MAX_ALLOWED_VOTE) + curveH * currSeed)
|
|
|
+ {
|
|
|
+ std::cerr << "Issue in self vote." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (currVote !=
|
|
|
+ curveG * DEFAULT_VOTE + curveH * currSeed)
|
|
|
+ {
|
|
|
+ std::cerr << "Issue in vote by verifier for user " << i + 1
|
|
|
+ << " of " << pi[2].responseParts.size() << "." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (size_t i = 0; i < pi[3].responseParts.size(); i++)
|
|
|
+ {
|
|
|
+ CurveBipoint currVote = encryptedVoteMatrix[i][selfIndex];
|
|
|
+ currSeed = pi[3].responseParts[i];
|
|
|
+
|
|
|
+ if (i != selfIndex)
|
|
|
+ {
|
|
|
+ if (currVote !=
|
|
|
+ curveG * DEFAULT_VOTE + curveH * currSeed)
|
|
|
+ {
|
|
|
+ std::cerr << "Issue in vote for verifier by user " << i + 1
|
|
|
+ << " of " << pi[3].responseParts.size() << "." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaBase::generate_valid_fresh_generator_proof() const
|
|
|
+/*
|
|
|
+ * EPOCH PROOFS
|
|
|
+ */
|
|
|
+
|
|
|
+Proof PrsonaBase::generate_proof_of_correct_tally() const
|
|
|
{
|
|
|
Proof retval;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaBase::generate_votes_valid_proof() const
|
|
|
+Proof PrsonaBase::generate_proof_of_correct_sum() const
|
|
|
{
|
|
|
Proof retval;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaBase::generate_proof_of_added_user() const
|
|
|
+Proof PrsonaBase::generate_proof_of_shuffle() const
|
|
|
{
|
|
|
Proof retval;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaBase::generate_score_proof() const
|
|
|
+bool PrsonaBase::verify_update_proof(
|
|
|
+ const Proof& pi) const
|
|
|
+{
|
|
|
+ if (!SERVER_IS_MALICIOUS)
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
+
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * SERVER AGREEMENT PROOFS
|
|
|
+ */
|
|
|
+
|
|
|
+Proof PrsonaBase::generate_valid_user_tally_proof() const
|
|
|
{
|
|
|
Proof retval;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaBase::generate_proof_of_correct_tally() const
|
|
|
+Proof PrsonaBase::generate_valid_server_tally_proof() const
|
|
|
{
|
|
|
Proof retval;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaBase::generate_proof_of_correct_sum() const
|
|
|
+Proof PrsonaBase::generate_valid_vote_row_proof() const
|
|
|
{
|
|
|
Proof retval;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaBase::generate_proof_of_shuffle() const
|
|
|
+Proof PrsonaBase::generate_valid_vote_matrix_proof() const
|
|
|
{
|
|
|
Proof retval;
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
@@ -785,58 +922,50 @@ Proof PrsonaBase::generate_valid_pseudonyms_proof() const
|
|
|
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
{
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval.basic = "PROOF";
|
|
|
+ retval.hbc = "PROOF";
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-bool PrsonaBase::verify_valid_tally_proof(const Proof& pi) const
|
|
|
-{
|
|
|
- if (!SERVER_IS_MALICIOUS)
|
|
|
- return pi.basic == "PROOF";
|
|
|
-
|
|
|
- return pi.basic == "PROOF";
|
|
|
-}
|
|
|
-
|
|
|
-bool PrsonaBase::verify_score_proof(const Proof& pi) const
|
|
|
+bool PrsonaBase::verify_valid_user_tally_proof(const Proof& pi) const
|
|
|
{
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
}
|
|
|
|
|
|
-bool PrsonaBase::verify_default_tally_proof(const Proof& pi) const
|
|
|
+bool PrsonaBase::verify_valid_server_tally_proof(const Proof& pi) const
|
|
|
{
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
}
|
|
|
|
|
|
-bool PrsonaBase::verify_default_votes_proof(const Proof& pi) const
|
|
|
+bool PrsonaBase::verify_valid_vote_row_proof(const Proof& pi) const
|
|
|
{
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
}
|
|
|
|
|
|
-bool PrsonaBase::verify_valid_votes_proof(const Proof& pi) const
|
|
|
+bool PrsonaBase::verify_valid_vote_matrix_proof(const Proof& pi) const
|
|
|
{
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
}
|
|
|
|
|
|
bool PrsonaBase::verify_valid_pseudonyms_proof(const Proof& pi) const
|
|
|
{
|
|
|
if (!SERVER_IS_MALICIOUS)
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
|
|
|
- return pi.basic == "PROOF";
|
|
|
+ return pi.hbc == "PROOF";
|
|
|
}
|