|
@@ -9,6 +9,18 @@ Curvepoint PrsonaClient::elGamalGenerator = Curvepoint();
|
|
|
bool PrsonaClient::malicious_server = false;
|
|
|
bool PrsonaClient::malicious_client = false;
|
|
|
|
|
|
+mpz_class log2(mpz_class x)
|
|
|
+{
|
|
|
+ mpz_class retval = 0;
|
|
|
+ while (x > 0)
|
|
|
+ {
|
|
|
+ retval++;
|
|
|
+ x = x >> 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return retval;
|
|
|
+}
|
|
|
+
|
|
|
PrsonaClient::PrsonaClient(const BGNPublicKey& serverPublicKey, const Curvepoint& elGamalBlindGenerator)
|
|
|
: serverPublicKey(serverPublicKey), elGamalBlindGenerator(elGamalBlindGenerator), max_checked(0)
|
|
|
{
|
|
@@ -66,7 +78,7 @@ void PrsonaClient::receive_fresh_generator(const Proof& pi, const Curvepoint& fr
|
|
|
currentFreshGenerator = freshGenerator;
|
|
|
}
|
|
|
|
|
|
-void PrsonaClient::receive_vote_tally(const Proof& pi, const EGCiphertext& score, bool isDefault)
|
|
|
+void PrsonaClient::receive_vote_tally(const Proof& pi, const EGCiphertext& score, bool isDefault, const Scalar& randomizationMask)
|
|
|
{
|
|
|
if (isDefault)
|
|
|
{
|
|
@@ -86,6 +98,7 @@ void PrsonaClient::receive_vote_tally(const Proof& pi, const EGCiphertext& score
|
|
|
}
|
|
|
|
|
|
currentEncryptedScore = score;
|
|
|
+ currentRandomizationMask = randomizationMask;
|
|
|
decrypt_score(score);
|
|
|
}
|
|
|
|
|
@@ -111,20 +124,202 @@ void PrsonaClient::receive_encrypted_votes(const Proof& pi, const std::vector<Cu
|
|
|
currEncryptedVotes = votes;
|
|
|
}
|
|
|
|
|
|
-Proof PrsonaClient::generate_reputation_proof() const
|
|
|
+std::vector<Proof> PrsonaClient::generate_reputation_proof(const Scalar& threshold) const
|
|
|
+{
|
|
|
+ std::vector<Proof> retval;
|
|
|
+
|
|
|
+ if (threshold > currentScore)
|
|
|
+ return retval;
|
|
|
+
|
|
|
+ if (!malicious_client)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+ currProof.basic = "PROOF";
|
|
|
+
|
|
|
+ retval.push_back(currProof);
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+
|
|
|
+ // retval.push_back(generate_ownership_proof());
|
|
|
+
|
|
|
+ // mpz_class proofVal = currentScore.curveSub(threshold).toInt();
|
|
|
+ // mpz_class proofBits = log2(currEncryptedVotes.size() * 3 - threshold.toInt());
|
|
|
+
|
|
|
+ // std::vector<Scalar> masksPerBit;
|
|
|
+ // masksPerBit.push_back(currentRandomizationMask);
|
|
|
+ // for (size_t i = 1; i < proofBits; i++)
|
|
|
+ // {
|
|
|
+ // Scalar currMask;
|
|
|
+ // currMask.set_random();
|
|
|
+
|
|
|
+ // masksPerBit.push_back(currMask);
|
|
|
+ // masksPerBit[0] = masksPerBit[0].curveSub(currMask.curveMult(Scalar(1 << i)));
|
|
|
+ // }
|
|
|
+
|
|
|
+ // for (size_t i = 0; i < proofBits; i++)
|
|
|
+ // {
|
|
|
+ // Proof currProof;
|
|
|
+ // std::stringstream oracleInput;
|
|
|
+ // oracleInput << currentFreshGenerator << elGamalBlindGenerator;
|
|
|
+
|
|
|
+ // mpz_class currBit = proofVal & (1 << i);
|
|
|
+
|
|
|
+ // Curvepoint currentCommitment = currentFreshGenerator * masksPerBit[i] + elGamalBlindGenerator * Scalar(currBit);
|
|
|
+ // currProof.partialUniversals.push_back(currentCommitment);
|
|
|
+ // oracleInput << currentCommitment;
|
|
|
+
|
|
|
+ // if (currBit)
|
|
|
+ // {
|
|
|
+ // Scalar u_0, c, c_0, c_1, z_0, z_1;
|
|
|
+ // u_0.set_random();
|
|
|
+ // c_1.set_random();
|
|
|
+ // z_1.set_random();
|
|
|
+
|
|
|
+ // Curvepoint U_0 = currentFreshGenerator * u_0;
|
|
|
+ // Curvepoint U_1 = currentFreshGenerator * z_1 - currentCommitment * c_1 + elGamalBlindGenerator;
|
|
|
+ // currProof.initParts.push_back(U_0);
|
|
|
+ // currProof.initParts.push_back(U_1);
|
|
|
+ // oracleInput << U_0 << U_1;
|
|
|
+
|
|
|
+ // c = oracle(oracleInput.str());
|
|
|
+ // c_0 = c.curveSub(c_1);
|
|
|
+ // z_0 = c_0.curveMult(masksPerBit[i]).curveAdd(u_0);
|
|
|
+
|
|
|
+ // currProof.challengeParts.push_back(c_0);
|
|
|
+ // currProof.challengeParts.push_back(c_1);
|
|
|
+ // currProof.responseParts.push_back(z_0);
|
|
|
+ // currProof.responseParts.push_back(z_1);
|
|
|
+ // }
|
|
|
+ // else
|
|
|
+ // {
|
|
|
+ // Scalar u_1, c, c_0, c_1, z_0, z_1;
|
|
|
+ // u_1.set_random();
|
|
|
+ // c_0.set_random();
|
|
|
+ // z_0.set_random();
|
|
|
+
|
|
|
+ // Curvepoint U_0 = currentFreshGenerator * z_0 - currentCommitment * c_0;
|
|
|
+ // Curvepoint U_1 = currentFreshGenerator * u_1;
|
|
|
+ // currProof.initParts.push_back(U_0);
|
|
|
+ // currProof.initParts.push_back(U_1);
|
|
|
+ // oracleInput << U_0 << U_1;
|
|
|
+
|
|
|
+ // c = oracle(oracleInput.str());
|
|
|
+ // c_1 = c.curveSub(c_0);
|
|
|
+ // z_1 = c_1.curveMult(masksPerBit[i]).curveAdd(u_1);
|
|
|
+
|
|
|
+ // currProof.challengeParts.push_back(c_0);
|
|
|
+ // currProof.challengeParts.push_back(c_1);
|
|
|
+ // currProof.responseParts.push_back(z_0);
|
|
|
+ // currProof.responseParts.push_back(z_1);
|
|
|
+ // }
|
|
|
+
|
|
|
+ // retval.push_back(currProof);
|
|
|
+ // }
|
|
|
+
|
|
|
+ // return retval;
|
|
|
+
|
|
|
+ Proof currProof;
|
|
|
+ currProof.basic = "PROOF";
|
|
|
+
|
|
|
+ retval.push_back(currProof);
|
|
|
+ return retval;
|
|
|
+}
|
|
|
+
|
|
|
+bool PrsonaClient::verify_reputation_proof(const std::vector<Proof>& pi, const Curvepoint& shortTermPublicKey, const Scalar& threshold) const
|
|
|
+{
|
|
|
+ if (pi.empty())
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (!malicious_client)
|
|
|
+ return pi[0].basic == "PROOF";
|
|
|
+
|
|
|
+ // if (!verify_ownership_proof(pi[0], shortTermPublicKey))
|
|
|
+ // return false;
|
|
|
+
|
|
|
+ // Curvepoint X;
|
|
|
+ // for (size_t i = 1; i < pi.size(); i++)
|
|
|
+ // {
|
|
|
+ // X = X + pi[i].partialUniversals[0] * Scalar(1 << (i - 1));
|
|
|
+
|
|
|
+ // std::stringstream oracleInput;
|
|
|
+ // oracleInput << currentFreshGenerator << elGamalBlindGenerator << pi[i].partialUniversals[0];
|
|
|
+ // oracleInput << pi[i].initParts[0] << pi[i].initParts[1];
|
|
|
+
|
|
|
+ // Scalar c = oracle(oracleInput.str());
|
|
|
+
|
|
|
+ // if (c != pi[i].challengeParts[0] + pi[i].challengeParts[1])
|
|
|
+ // return false;
|
|
|
+
|
|
|
+ // if (currentFreshGenerator * pi[i].responseParts[0] != pi[i].initParts[0] + pi[i].partialUniversals[0] * pi[i].challengeParts[0])
|
|
|
+ // return false;
|
|
|
+
|
|
|
+ // if (currentFreshGenerator * pi[i].responseParts[1] != pi[i].initParts[1] + pi[i].partialUniversals[0] * pi[i].challengeParts[1] - elGamalBlindGenerator)
|
|
|
+ // return false;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // Proof unused, serverProof;
|
|
|
+ // Scalar alsoUnused;
|
|
|
+ // EGCiphertext encryptedScore = servers.get_current_tally(unused, serverProof, shortTermPublicKey, false, alsoUnused);
|
|
|
+
|
|
|
+ // Scalar negThreshold;
|
|
|
+ // negThreshold = Scalar(0).curveSub(threshold);
|
|
|
+
|
|
|
+ // Curvepoint scoreCommitment = encryptedScore.encryptedMessage + elGamalBlindGenerator * negThreshold;
|
|
|
+ // if (X != scoreCommitment)
|
|
|
+ // return false;
|
|
|
+
|
|
|
+ // return true;
|
|
|
+
|
|
|
+ return pi[0].basic == "PROOF";
|
|
|
+}
|
|
|
+
|
|
|
+Proof PrsonaClient::generate_ownership_proof() const
|
|
|
{
|
|
|
+ Proof retval;
|
|
|
if (!malicious_client)
|
|
|
- return "PROOF";
|
|
|
+ {
|
|
|
+ retval.basic = "PROOF";
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+
|
|
|
+ // std::stringstream oracleInput;
|
|
|
+
|
|
|
+ // Scalar r;
|
|
|
+ // r.set_random();
|
|
|
|
|
|
- return "PROOF";
|
|
|
+ // Curvepoint shortTermPublicKey = currentFreshGenerator * longTermPrivateKey;
|
|
|
+ // Curvepoint u = currentFreshGenerator * r;
|
|
|
+ // oracleInput << currentFreshGenerator << shortTermPublicKey << u;
|
|
|
+
|
|
|
+ // Scalar c = oracle(oracleInput.str());
|
|
|
+ // Scalar z = r.curveAdd(c.curveMult(longTermPrivateKey));
|
|
|
+
|
|
|
+ // retval.basic = "PROOF";
|
|
|
+ // retval.initParts.push_back(u);
|
|
|
+ // retval.responseParts.push_back(z);
|
|
|
+
|
|
|
+ // return retval;
|
|
|
+
|
|
|
+ retval.basic = "PROOF";
|
|
|
+ return retval;
|
|
|
}
|
|
|
|
|
|
-bool PrsonaClient::verify_reputation_proof(const Proof& pi, const Curvepoint& shortTermPublicKey) const
|
|
|
+bool PrsonaClient::verify_ownership_proof(const Proof& pi, const Curvepoint& shortTermPublicKey) const
|
|
|
{
|
|
|
if (!malicious_client)
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
+
|
|
|
+ // Curvepoint u = pi.initParts[0];
|
|
|
+
|
|
|
+ // std::stringstream oracleInput;
|
|
|
+ // oracleInput << currentFreshGenerator << shortTermPublicKey << u;
|
|
|
+ // Scalar c = oracle(oracleInput.str());
|
|
|
+
|
|
|
+ // Scalar z = pi.responseParts[0];
|
|
|
|
|
|
- return pi == "PROOF";
|
|
|
+ // return (currentFreshGenerator * z) == (shortTermPublicKey * c + u);
|
|
|
+
|
|
|
+ return pi.basic == "PROOF";
|
|
|
}
|
|
|
|
|
|
void PrsonaClient::decrypt_score(const EGCiphertext& score)
|
|
@@ -137,6 +332,7 @@ void PrsonaClient::decrypt_score(const EGCiphertext& score)
|
|
|
if (lookup != decryption_memoizer.end())
|
|
|
{
|
|
|
currentScore = lookup->second;
|
|
|
+ // std::cout << "Decrypted score: " << currentScore << std::endl;
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -153,68 +349,81 @@ void PrsonaClient::decrypt_score(const EGCiphertext& score)
|
|
|
|
|
|
decryption_memoizer[decryptionCandidate] = max_checked;
|
|
|
currentScore = max_checked;
|
|
|
+ // std::cout << "Decrypted score: " << currentScore << std::endl;
|
|
|
}
|
|
|
|
|
|
Proof PrsonaClient::generate_stpk_proof() const
|
|
|
{
|
|
|
+ Proof retval;
|
|
|
+
|
|
|
if (!malicious_client)
|
|
|
- return "PROOF";
|
|
|
+ {
|
|
|
+ retval.basic = "PROOF";
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
|
|
|
- return "PROOF";
|
|
|
+ retval.basic = "PROOF";
|
|
|
+ return retval;
|
|
|
}
|
|
|
|
|
|
bool PrsonaClient::verify_generator_proof(const Proof& pi, const Curvepoint& generator) const
|
|
|
{
|
|
|
if (!malicious_server)
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
}
|
|
|
|
|
|
bool PrsonaClient::verify_default_tally_proof(const Proof& pi, const EGCiphertext& score) const
|
|
|
{
|
|
|
if (!malicious_server)
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
}
|
|
|
|
|
|
bool PrsonaClient::verify_valid_tally_proof(const Proof& pi, const EGCiphertext& score) const
|
|
|
{
|
|
|
if (!malicious_server)
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
}
|
|
|
|
|
|
bool PrsonaClient::verify_default_votes_proof(const Proof& pi, const std::vector<CurveBipoint>& votes) const
|
|
|
{
|
|
|
if (!malicious_server)
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
}
|
|
|
|
|
|
bool PrsonaClient::verify_valid_votes_proof(const Proof& pi, const std::vector<CurveBipoint>& votes) const
|
|
|
{
|
|
|
if (!malicious_server)
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
}
|
|
|
|
|
|
Proof PrsonaClient::generate_vote_proof(const std::vector<CurveBipoint>& encryptedVotes, const std::vector<Scalar>& vote) const
|
|
|
{
|
|
|
+ Proof retval;
|
|
|
+
|
|
|
if (!malicious_client)
|
|
|
- return "PROOF";
|
|
|
+ {
|
|
|
+ retval.basic = "PROOF";
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
|
|
|
- return "PROOF";
|
|
|
+ retval.basic = "PROOF";
|
|
|
+ return retval;
|
|
|
}
|
|
|
|
|
|
bool PrsonaClient::verify_score_proof(const Proof& pi) const
|
|
|
{
|
|
|
if (!malicious_server)
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
|
|
|
- return pi == "PROOF";
|
|
|
+ return pi.basic == "PROOF";
|
|
|
}
|