Browse Source

This compiles, but has bugs right now. The current issue I'm looking at is that, the other ways I've tested it, the fresh pseudonyms are generated correctly, but the proofs of their generation are not verifying. Specifically, when proving that a piece of the result is valid, the proof succeeds if it was generated as the product of a 0 from the permutation matrix and the original pseudonym, but fails if it was generated as the product of a 1 from the permutation matrix and the original pseudonym. I am debugging this now.

tristangurtler 3 years ago
parent
commit
0c958cdddb
7 changed files with 1849 additions and 161 deletions
  1. 52 6
      prsona/inc/base.hpp
  2. 158 26
      prsona/inc/server.hpp
  3. 4 2
      prsona/inc/serverEntity.hpp
  4. 574 23
      prsona/src/base.cpp
  5. 12 14
      prsona/src/main.cpp
  6. 933 22
      prsona/src/server.cpp
  7. 116 68
      prsona/src/serverEntity.cpp

+ 52 - 6
prsona/inc/base.hpp

@@ -138,7 +138,6 @@ class PrsonaBase {
             const std::vector<Proof>& pi,
             const Curvepoint& currentFreshGenerator,
             const Curvepoint& shortTermPublicKey,
-            const Curvepoint& elGamalBlindGenerator,
             const CurveBipoint& curveG,
             const CurveBipoint& curveH,
             const TwistBipoint& twistG,
@@ -150,12 +149,59 @@ class PrsonaBase {
         ) const;
 
         // EPOCH PROOFS
-        Proof generate_proof_of_added_user() const;
-        Proof generate_proof_of_correct_tally() const;
-        Proof generate_proof_of_correct_sum() const;
-        Proof generate_proof_of_shuffle() const;
+        std::vector<Proof> 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;
 
-        bool verify_update_proof(const Proof& pi) const;
+        bool verify_valid_permutation_proof(
+            const std::vector<Proof>& pi,
+            const std::vector<std::vector<Curvepoint>>& commits
+        ) const;
+
+        std::vector<Proof> 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;
+
+        bool 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;
+
+        template <typename T>
+        std::vector<Proof> 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;
+
+        template <typename T>
+        bool 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;
 
         // SERVER AGREEMENT PROOFS
         Proof generate_valid_vote_row_proof(

+ 158 - 26
prsona/inc/server.hpp

@@ -58,6 +58,8 @@ class PrsonaServer : public PrsonaBase {
             const std::vector<CurveBipoint>& newVotes,
             const Curvepoint& shortTermPublicKey);
 
+        void print_scores(const std::vector<TwistBipoint>& scores);
+
     private:
         // constants for servers
         const size_t numServers;
@@ -101,39 +103,140 @@ class PrsonaServer : public PrsonaBase {
         
         // SCORE TALLYING
         std::vector<Scalar> tally_scores();
-        Scalar get_max_possible_score(Proof& pi);
+        Scalar get_max_possible_score();
         
         // EPOCH ROUNDS
         void build_up_midway_pseudonyms(
-            Proof& pi, Curvepoint& nextGenerator);
+            std::vector<std::vector<std::vector<Proof>>>& pi,
+            std::vector<std::vector<std::vector<Curvepoint>>>& permutationCommits,
+            std::vector<std::vector<std::vector<Curvepoint>>>& freshPseudonymCommits,
+            std::vector<std::vector<std::vector<Curvepoint>>>& freshPseudonymSeedCommits,
+            std::vector<std::vector<std::vector<TwistBipoint>>>& serverTallyCommits,
+            std::vector<std::vector<std::vector<std::vector<std::vector<CurveBipoint>>>>>& voteMatrixCommits,
+            Curvepoint& nextGenerator);
         void break_down_midway_pseudonyms(
-            Proof& pi, const Curvepoint& nextGenerator);
+            std::vector<Proof>& generatorProof,
+            std::vector<std::vector<std::vector<Proof>>>& pi,
+            std::vector<std::vector<std::vector<Curvepoint>>>& permutationCommits,
+            std::vector<std::vector<std::vector<Curvepoint>>>& freshPseudonymCommits,
+            std::vector<std::vector<std::vector<Curvepoint>>>& freshPseudonymSeedCommits,
+            std::vector<std::vector<std::vector<TwistBipoint>>>& serverTallyCommits,
+            std::vector<std::vector<std::vector<std::vector<std::vector<CurveBipoint>>>>>& voteMatrixCommits,
+            std::vector<std::vector<std::vector<std::vector<Curvepoint>>>>& userTallyCommits,
+            std::vector<std::vector<std::vector<Curvepoint>>>& userTallyMaskSeedCommits,
+            const Curvepoint& nextGenerator);
 
-        // DATA MAINTENANCE
-        bool import_new_user_update(
-            const std::vector<Proof>& pi,
-            const std::vector<TwistBipoint>& otherPreviousVoteTallies,
-            const std::vector<Curvepoint>& otherCurrentPseudonyms,
-            const std::vector<EGCiphertext>& otherCurrentUserEncryptedTallies,
-            const std::vector<std::vector<CurveBipoint>>& otherVoteMatrix
-        );
-        void import_updates(
-            const Proof& pi,
-            const std::vector<TwistBipoint>& otherPreviousVoteTallies,
-            const std::vector<Curvepoint>& otherCurrentPseudonyms,
-            const std::vector<EGCiphertext>& otherCurrentUserEncryptedTallies,
-            const std::vector<std::vector<CurveBipoint>>& otherVoteMatrix
-        );
-        void export_updates(
-            std::vector<TwistBipoint>& otherPreviousVoteTally,
-            std::vector<Curvepoint>& otherCurrentPseudonyms,
-            std::vector<EGCiphertext>& otherCurrentUserEncryptedTallies,
-            std::vector<std::vector<CurveBipoint>>& otherVoteMatrix
+        // EPOCH HELPERS
+        std::vector<std::vector<Proof>> epoch_calculations(
+            std::vector<std::vector<Curvepoint>>& permutationCommits,
+            std::vector<std::vector<Curvepoint>>& freshPseudonymCommits,
+            std::vector<std::vector<Curvepoint>>& freshPseudonymSeedCommits,
+            std::vector<std::vector<TwistBipoint>>& serverTallyCommits,
+            std::vector<std::vector<std::vector<std::vector<CurveBipoint>>>>& voteMatrixCommits,
+            std::vector<std::vector<std::vector<Curvepoint>>>& userTallyCommits,
+            std::vector<std::vector<Curvepoint>> & userTallyMaskSeedCommits,
+            const Scalar& power,
+            bool doUserTallies);
+
+        bool accept_epoch_updates(
+            const std::vector<std::vector<Proof>>& pi,
+            const std::vector<std::vector<Curvepoint>>& permutationCommits,
+            const std::vector<std::vector<Curvepoint>>& freshPseudonymCommits,
+            const std::vector<std::vector<Curvepoint>>& freshPseudonymSeedCommits,
+            const std::vector<std::vector<TwistBipoint>>& serverTallyCommits,
+            const std::vector<std::vector<std::vector<std::vector<CurveBipoint>>>>& voteMatrixCommits,
+            const std::vector<std::vector<std::vector<Curvepoint>>>& userTallyCommits,
+            const std::vector<std::vector<Curvepoint>>& userTallyMaskSeedCommits,
+            bool doUserTallies);
+
+        std::vector<std::vector<Scalar>> generate_permutation_matrix(
+            const Scalar& reorderSeed
+        ) const;
+        std::vector<std::vector<Curvepoint>> generate_commitment_matrix(
+            const std::vector<std::vector<Scalar>>& permutations,
+            std::vector<std::vector<Scalar>>& seeds
         ) const;
 
-        // DATA SAFEKEEPING
-        void rerandomize_data();
-        std::vector<size_t> order_data(Proof& pi);
+        std::vector<std::vector<Curvepoint>> generate_pseudonym_matrix(
+            const std::vector<std::vector<Scalar>>& permutations,
+            const Scalar& power,
+            std::vector<std::vector<Scalar>>& seeds,
+            std::vector<std::vector<Curvepoint>>& seedCommits
+        ) const;
+
+        std::vector<std::vector<TwistBipoint>> generate_server_tally_matrix(
+            const std::vector<std::vector<Scalar>>& permutations,
+            std::vector<std::vector<Scalar>>& seeds
+        ) const;
+
+        std::vector<std::vector<std::vector<CurveBipoint>>> generate_vote_tensor(
+            const std::vector<std::vector<Scalar>>& permutations,
+            const std::vector<std::vector<CurveBipoint>>& currVoteMatrix,
+            std::vector<std::vector<std::vector<Scalar>>>& seeds,
+            bool inverted
+        ) const;
+
+        std::vector<std::vector<CurveBipoint>> calculate_next_vote_matrix(
+            const std::vector<std::vector<std::vector<CurveBipoint>>>& voteTensor
+        ) const;
+
+        void generate_vote_tensor_proofs(
+            std::vector<std::vector<Proof>>& pi,
+            const std::vector<std::vector<Scalar>>& permutations,
+            const std::vector<std::vector<Scalar>>& permutationSeeds,
+            const std::vector<std::vector<std::vector<Scalar>>>& matrixSeeds,
+            const std::vector<std::vector<CurveBipoint>>& currMatrix,
+            const std::vector<std::vector<Curvepoint>>& permutationCommits,
+            const std::vector<std::vector<std::vector<CurveBipoint>>>& matrixCommits,
+            bool inverted
+        ) const;
+        bool verify_vote_tensor_proofs(
+            const std::vector<std::vector<Proof>>& pi,
+            size_t start_offset,
+            const std::vector<std::vector<CurveBipoint>>& currMatrix,
+            const std::vector<std::vector<Curvepoint>>& permutationCommits,
+            const std::vector<std::vector<std::vector<CurveBipoint>>>& matrixCommits,
+            bool inverted
+        ) const;
+
+        std::vector<std::vector<std::vector<Curvepoint>>> generate_user_tally_matrix(
+            const std::vector<std::vector<Scalar>>& permutations,
+            const Scalar& power,
+            std::vector<Curvepoint>& masks,
+            std::vector<Curvepoint>& messages,
+            std::vector<std::vector<Scalar>>& maskSeeds,
+            std::vector<std::vector<Curvepoint>>& maskSeedCommits,
+            std::vector<std::vector<Scalar>>& messageSeeds
+        ) const;
+
+        template <typename T>
+        std::vector<std::vector<T>> generate_reordered_plus_power_matrix(
+            const std::vector<std::vector<Scalar>>& permutations,
+            const Scalar& power,
+            const std::vector<T>& oldValues,
+            std::vector<std::vector<Scalar>>& seeds,
+            std::vector<std::vector<Curvepoint>>& seedCommits,
+            const T& h
+        ) const;
+
+        template <typename T>
+        std::vector<std::vector<T>> generate_reordered_matrix(
+            const std::vector<std::vector<Scalar>>& permutations,
+            const std::vector<T>& oldValues,
+            std::vector<std::vector<Scalar>>& seeds,
+            const T& h,
+            bool inverted,
+            bool cancelOut
+        ) const;
+
+        template <typename T>
+        std::vector<std::vector<T>> transpose_matrix(
+            const std::vector<std::vector<T>>& input
+        ) const;
+
+        std::vector<size_t> sort_data(
+            const std::vector<Curvepoint>& inputs
+        ) const;
 
         // A helper class for "ordering" data and for binary search
         struct SortingType {
@@ -143,6 +246,35 @@ class PrsonaServer : public PrsonaBase {
             bool operator<( const SortingType& rhs ) const
                 { return pseudonym < rhs.pseudonym; }
         };
+
+        template <typename T>
+        T encrypt(
+            const T& g,
+            const T& h,
+            const Scalar& plaintext,
+            const Scalar& lambda
+        ) const;
+
+        bool update_data(
+            const std::vector<std::vector<Curvepoint>>& freshPseudonymCommits,
+            const std::vector<std::vector<TwistBipoint>>& serverTallyCommits,
+            const std::vector<std::vector<std::vector<CurveBipoint>>>& voteMatrixCommits,
+            const std::vector<std::vector<std::vector<Curvepoint>>>& userTallyCommits);
+
+        bool pseudonyms_sorted(
+            const std::vector<Curvepoint> newPseudonyms
+        ) const;
+
+        // DATA MAINTENANCE
+        bool import_new_user_update(
+            const std::vector<Proof>& pi,
+            const std::vector<TwistBipoint>& otherPreviousVoteTallies,
+            const std::vector<Curvepoint>& otherCurrentPseudonyms,
+            const std::vector<EGCiphertext>& otherCurrentUserEncryptedTallies,
+            const std::vector<std::vector<CurveBipoint>>& otherVoteMatrix);
+
+        // DATA SAFEKEEPING
+        std::vector<size_t> order_data();
         
         // BINARY SEARCH
         size_t binary_search(const Curvepoint& index) const;

+ 4 - 2
prsona/inc/serverEntity.hpp

@@ -101,8 +101,8 @@ class PrsonaServerEntity {
         void transmit_updates(PrsonaClient& currUser, size_t which) const;
 
         // EPOCH
-        void epoch(Proof& pi);
-        void epoch(Proof& pi, size_t which);
+        void epoch();
+        void epoch(size_t which);
 
         void print_scores() const;
         void print_votes() const;
@@ -114,6 +114,8 @@ class PrsonaServerEntity {
         std::vector<EGCiphertext> tally_scores(
             const Curvepoint& nextGenerator,
             size_t which);
+        void distribute_tallied_scores(
+            const std::vector<EGCiphertext>& scores);
         
         // BINARY SEARCH
         size_t binary_search(

+ 574 - 23
prsona/src/base.cpp

@@ -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;

+ 12 - 14
prsona/src/main.cpp

@@ -133,12 +133,10 @@ vector<double> transmit_votes_to_servers(
 // Time how long it takes to do the operations associated with an epoch
 double epoch(PrsonaServerEntity& servers)
 {
-    Proof unused;
-
     // Do the epoch server calculations
     chrono::high_resolution_clock::time_point t0 =
         chrono::high_resolution_clock::now();
-    servers.epoch(unused);
+    servers.epoch();
     chrono::high_resolution_clock::time_point t1 =
         chrono::high_resolution_clock::now();
 
@@ -281,9 +279,9 @@ int main(int argc, char *argv[])
 
     // Defaults
     size_t numServers = 2;
-    size_t numUsers = 5;
-    size_t numRounds = 3;
-    size_t numVotesPerRound = 3;
+    size_t numUsers = 3;
+    size_t numRounds = 1;
+    size_t numVotesPerRound = 1;
     bool maliciousServers = true;
     bool maliciousClients = true;
     string seedStr = "seed";
@@ -374,15 +372,15 @@ int main(int argc, char *argv[])
             << " seconds per user" << endl << endl;
     }
 
-    // Pick random users for our tests
-    uniform_int_distribution<size_t> userDistribution(0, numUsers - 1);
-    size_t user_a = userDistribution(generator);
-    size_t user_b = user_a;
-    while (user_b == user_a)
-        user_b = userDistribution(generator);
+    // // Pick random users for our tests
+    // uniform_int_distribution<size_t> userDistribution(0, numUsers - 1);
+    // size_t user_a = userDistribution(generator);
+    // size_t user_b = user_a;
+    // while (user_b == user_a)
+    //     user_b = userDistribution(generator);
 
-    test_reputation_proof(generator, users[user_a], users[user_b]);
-    test_vote_proof(generator, users[user_a], servers);
+    // test_reputation_proof(generator, users[user_a], users[user_b]);
+    // test_vote_proof(generator, users[user_a], servers);
 
     return 0;
 }

File diff suppressed because it is too large
+ 933 - 22
prsona/src/server.cpp


+ 116 - 68
prsona/src/serverEntity.cpp

@@ -349,22 +349,22 @@ void PrsonaServerEntity::add_new_client(PrsonaClient& newUser, size_t which)
         proofOfCorrectAddition, proofOfValidSTPK, shortTermPublicKey);
 
     // Then, export the data to the rest of the servers
-    std::vector<TwistBipoint> previousVoteTally;
+    std::vector<TwistBipoint> previousVoteTallies;
     std::vector<Curvepoint> currentPseudonyms;
     std::vector<EGCiphertext> currentUserEncryptedTallies;
     std::vector<std::vector<CurveBipoint>> voteMatrix;
-    servers[which].export_updates(
-        previousVoteTally,
-        currentPseudonyms,
-        currentUserEncryptedTallies,
-        voteMatrix);
+
+    previousVoteTallies = servers[which].previousVoteTallies;
+    currentPseudonyms = servers[which].currentPseudonyms;
+    currentUserEncryptedTallies = servers[which].currentUserEncryptedTallies;
+    voteMatrix = servers[which].voteMatrix;
 
     for (size_t j = 1; j < servers[which].get_num_servers(); j++)
     {
         size_t index = (which + j) % servers[which].get_num_servers();
         servers[index].import_new_user_update(
             proofOfCorrectAddition,
-            previousVoteTally,
+            previousVoteTallies,
             currentPseudonyms,
             currentUserEncryptedTallies,
             voteMatrix);
@@ -435,81 +435,124 @@ void PrsonaServerEntity::transmit_updates(
  * EPOCH
  */
 
-void PrsonaServerEntity::epoch(Proof& pi)
+void PrsonaServerEntity::epoch()
 {
-    epoch(pi, 0);
+    epoch(0);
 }
 
 // Do the epoch process
-void PrsonaServerEntity::epoch(Proof& pi, size_t which)
+void PrsonaServerEntity::epoch(size_t which)
 {
     Curvepoint nextGenerator = PrsonaServer::EL_GAMAL_GENERATOR;
     
-    std::vector<TwistBipoint> previousVoteTally;
-    std::vector<Curvepoint> currentPseudonyms;
-    std::vector<EGCiphertext> currentUserEncryptedTallies;
-    std::vector<Proof> currentTallyProofs;
-    std::vector<std::vector<CurveBipoint>> voteMatrix;
+    std::vector<std::vector<std::vector<Proof>>> pi;
+    std::vector<std::vector<std::vector<Curvepoint>>> permutationCommits;
+    std::vector<std::vector<std::vector<Curvepoint>>> freshPseudonymCommits;
+    std::vector<std::vector<std::vector<Curvepoint>>> freshPseudonymSeedCommits;
+    std::vector<std::vector<std::vector<TwistBipoint>>> serverTallyCommits;
+    std::vector<std::vector<std::vector<std::vector<std::vector<CurveBipoint>>>>> voteMatrixCommits;
+    std::vector<std::vector<std::vector<std::vector<Curvepoint>>>> userTallyCommits;
+    std::vector<std::vector<std::vector<Curvepoint>>> userTallyMaskSeedCommits;
+
+    std::vector<std::vector<Proof>> generator_proof_holder(1);
+    pi.push_back(generator_proof_holder);
 
     // go from A_0 to A_0.5
     for (size_t i = 0; i < servers[which].get_num_servers(); i++)
     {
-        size_t index = (which + i) % servers[which].get_num_servers();
-        size_t nextIndex = (which + i + 1) % servers[which].get_num_servers();
+        if (i > 0)
+            continue;
+        
+        size_t realI = (which + i) % servers[which].get_num_servers();
 
-        servers[index].build_up_midway_pseudonyms(pi, nextGenerator);
-        servers[index].export_updates(
-            previousVoteTally,
-            currentPseudonyms,
-            currentUserEncryptedTallies,
-            voteMatrix);
-        servers[nextIndex].import_updates(
-            pi,
-            previousVoteTally,
-            currentPseudonyms,
-            currentUserEncryptedTallies,
-            voteMatrix);
-    }
+        std::cout << "Building up on server " << realI << "." << std::endl;
 
-    /* Imagine that server 0 is encrypting these, then would do a ZKP that it
-     * knows a secret mask and encrypted the correct value everyone else already
-     * knows. Everyone else then adds a mask and proves they added a secret mask
-     * to the committed values. */
-    currentUserEncryptedTallies =
-        tally_scores(nextGenerator, which);
-    
-    // go from A_0.5 to A_1
-    for (size_t i = 0; i < servers[which].get_num_servers(); i++)
-    {
-        size_t index = (which + i) % servers[which].get_num_servers();
-        size_t nextIndex = (which + i + 1) % servers[which].get_num_servers();
-        
-        servers[index].break_down_midway_pseudonyms(pi, nextGenerator);
-        servers[index].export_updates(
-            previousVoteTally,
-            currentPseudonyms,
-            currentUserEncryptedTallies,
-            voteMatrix);
-        servers[nextIndex].import_updates(
+        servers[realI].build_up_midway_pseudonyms(
             pi,
-            previousVoteTally,
-            currentPseudonyms,
-            currentUserEncryptedTallies,
-            voteMatrix);
+            permutationCommits,
+            freshPseudonymCommits,
+            freshPseudonymSeedCommits,
+            serverTallyCommits,
+            voteMatrixCommits,
+            nextGenerator);
+
+        for (size_t j = 1; j < servers[which].get_num_servers(); j++)
+        {
+            std::vector<std::vector<std::vector<Curvepoint>>> currUserTallyCommits;
+            std::vector<std::vector<Curvepoint>> currUserTallyMaskSeedCommits;
+
+            size_t realJ = (which + j) % servers[which].get_num_servers();
+
+            std::cout << "Giving to server " << realJ << "." << std::endl;
+
+            servers[realJ].accept_epoch_updates(
+                pi[i + 1],
+                permutationCommits[i],
+                freshPseudonymCommits[i],
+                freshPseudonymSeedCommits[i],
+                serverTallyCommits[i],
+                voteMatrixCommits[i],
+                currUserTallyCommits,
+                currUserTallyMaskSeedCommits,
+                false);
+        }
     }
 
-    // At the end, make sure all servers have same information
-    for (size_t i = 1; i < servers[which].get_num_servers() - 1; i++)
-    {
-        size_t index = (which + i) % servers[which].get_num_servers();
+    // std::vector<Proof> generator_proof = pi[0][0];
+    // pi.clear();
+    // permutationCommits.clear();
+    // freshPseudonymCommits.clear();
+    // freshPseudonymSeedCommits.clear();
+    // serverTallyCommits.clear();
+    // voteMatrixCommits.clear();
+
+    // std::cout << "Tallying scores." << std::endl;
+
+    // /* Imagine that server 0 is encrypting these, then would do a ZKP that it
+    //  * knows a secret mask and encrypted the correct value everyone else already
+    //  * knows. Everyone else then adds a mask and proves they added a secret mask
+    //  * to the committed values. */
+    // std::vector<EGCiphertext> currentUserEncryptedTallies =
+    //     tally_scores(nextGenerator, which);
+    // distribute_tallied_scores(currentUserEncryptedTallies);
+    
+    // // go from A_0.5 to A_1
+    // for (size_t i = 0; i < servers[which].get_num_servers(); i++)
+    // {
+    //     size_t realI = (which + i) % servers[which].get_num_servers();
 
-        servers[index].import_updates(
-            pi,
-            previousVoteTally,
-            currentPseudonyms,
-            currentUserEncryptedTallies,
-            voteMatrix);
-    }
+    //     std::cout << "Breaking down on server " << realI << "." << std::endl;
+        
+    //     servers[realI].break_down_midway_pseudonyms(
+    //         generator_proof,
+    //         pi,
+    //         permutationCommits,
+    //         freshPseudonymCommits,
+    //         freshPseudonymSeedCommits,
+    //         serverTallyCommits,
+    //         voteMatrixCommits,
+    //         userTallyCommits,
+    //         userTallyMaskSeedCommits,
+    //         nextGenerator);
+        
+    //     for (size_t j = 1; j < servers[which].get_num_servers(); j++)
+    //     {
+    //         size_t realJ = (which + j) % servers[which].get_num_servers();
+
+    //         std::cout << "Giving to server " << realJ << "." << std::endl;
+
+    //         servers[realJ].accept_epoch_updates(
+    //             pi[i],
+    //             permutationCommits[i],
+    //             freshPseudonymCommits[i],
+    //             freshPseudonymSeedCommits[i],
+    //             serverTallyCommits[i],
+    //             voteMatrixCommits[i],
+    //             userTallyCommits[i],
+    //             userTallyMaskSeedCommits[i],
+    //             true);
+    //     }
+    // }
 }
 
 void PrsonaServerEntity::print_scores() const
@@ -562,10 +605,9 @@ std::vector<EGCiphertext> PrsonaServerEntity::tally_scores(
     size_t which)
 {
     std::vector<EGCiphertext> retval;
-    Proof maxScoreProof;
     std::vector<Scalar> decryptedTalliedScores = servers[which].tally_scores();
     mpz_class maxScorePossibleThisRound =
-        servers[which].get_max_possible_score(maxScoreProof).toInt() *
+        servers[which].get_max_possible_score().toInt() *
         PrsonaBase::get_max_allowed_vote();
     mpz_class topOfScoreRange =
         decryptedTalliedScores.size() * PrsonaBase::get_max_allowed_vote();
@@ -594,10 +636,16 @@ std::vector<EGCiphertext> PrsonaServerEntity::tally_scores(
             (servers[which].get_blinding_generator() * decryptedTalliedScores[i]);
     }
 
-    servers[which].currentUserEncryptedTallies = retval;
     return retval;
 }
 
+void PrsonaServerEntity::distribute_tallied_scores(
+    const std::vector<EGCiphertext>& scores)
+{
+    for (size_t i = 0; i < servers[0].get_num_servers(); i++)
+        servers[i].currentUserEncryptedTallies = scores;
+}
+
 /*
  * BINARY SEARCH
  */

Some files were not shown because too many files changed in this diff