#ifndef __PRSONA_SERVER_HPP #define __PRSONA_SERVER_HPP #include #include #include "BGN.hpp" #include "Curvepoint.hpp" #include "Bipoint.hpp" #include "base.hpp" #include "EGCiphertext.hpp" #include "proof.hpp" class PrsonaServer : public PrsonaBase { public: // CONSTRUCTORS PrsonaServer( size_t numServers); PrsonaServer( size_t numServers, const BGN& other_bgn); PrsonaServer( const PrsonaServer& other); PrsonaServer( PrsonaServer&& other); PrsonaServer &operator=( const PrsonaServer& other); PrsonaServer &operator=( PrsonaServer&& other); ~PrsonaServer(); // BASIC PUBLIC SYSTEM INFO GETTERS BGNPublicKey get_bgn_public_key() const; size_t get_num_clients() const; size_t get_num_servers() const; Twistpoint get_fresh_generator( std::vector& pi ) const; // FRESH GENERATOR CALCULATION Twistpoint add_curr_seed_to_generator( std::vector& pi, const Twistpoint& currGenerator ) const; Twistpoint add_next_seed_to_generator( std::vector& pi, const Twistpoint& currGenerator ) const; Twistpoint add_rand_seed_to_generator( std::vector& pi, const Twistpoint& currGenerator ) const; // ENCRYPTED DATA GETTERS std::vector get_current_votes_by( Proof& pi, const Twistpoint& shortTermPublicKey ) const; std::vector> get_all_current_votes( Proof& pi ) const; EGCiphertext get_current_user_encrypted_tally( Proof& pi, const Twistpoint& shortTermPublicKey ) const; CurveBipoint get_current_server_encrypted_tally( Proof& pi, const Twistpoint& shortTermPublicKey ) const; std::vector get_current_pseudonyms( Proof& pi ) const; std::vector get_current_pseudonyms() const; // PROOF COMMITMENT GETTERS Proof get_vote_row_commitment( const Twistpoint& request ) const; Proof get_vote_matrix_commitment() const; Proof get_user_tally_commitment( const Twistpoint& request ) const; Proof get_server_tally_commitment( const Twistpoint& request ) const; Proof get_pseudonyms_commitment() const; void print_current_commitments() const; // CLIENT INTERACTIONS void add_new_client( std::vector& proofOfValidAddition, const Proof& proofOfValidKey, const Twistpoint& shortTermPublicKey); bool receive_vote( const std::vector& pi, const std::vector& newVotes, const Twistpoint& shortTermPublicKey); void print_scores( const std::vector& scores); // CONSTRUCTOR HELPERS const BGN& get_bgn_details() const; bool initialize_fresh_generator( const std::vector& pi, const Twistpoint& firstGenerator); bool set_EG_blind_generator( const std::vector& pi, const Twistpoint& currGenerator); // EPOCH ROUNDS void build_up_midway_pseudonyms( std::vector>>& pi, std::vector>>& permutationCommits, std::vector>>& freshPseudonymCommits, std::vector>>& freshPseudonymSeedCommits, std::vector>>& serverTallyCommits, std::vector>>>& partwayVoteMatrixCommits, std::vector>>>& finalVoteMatrixCommits, Twistpoint& nextGenerator); void hbc_build_up_midway_pseudonyms( std::vector& generatorProof, std::vector& newFreshPseudonyms, std::vector& newServerTallies, std::vector>& newVoteMatrix, Twistpoint& nextGenerator); void break_down_midway_pseudonyms( const std::vector& generatorProof, std::vector>>& pi, std::vector>>& permutationCommits, std::vector>>& freshPseudonymCommits, std::vector>>& freshPseudonymSeedCommits, std::vector>>& serverTallyCommits, std::vector>>>& partwayVoteMatrixCommits, std::vector>>>& finalVoteMatrixCommits, std::vector>>& userTallyMaskCommits, std::vector>>& userTallyMessageCommits, std::vector>>& userTallySeedCommits, const Twistpoint& nextGenerator); void hbc_break_down_midway_pseudonyms( const std::vector& generatorProof, std::vector& newFreshPseudonyms, std::vector& newServerTallies, std::vector>& newVoteMatrix, std::vector& newUserTallies, const Twistpoint& nextGenerator); bool accept_epoch_updates( const std::vector>& pi, const std::vector>& permutationCommits, const std::vector>& freshPseudonymCommits, const std::vector>& freshPseudonymSeedCommits, const std::vector>& serverTallyCommits, const std::vector>>& partwayVoteMatrixCommits, const std::vector>>& finalVoteMatrixCommits, const std::vector>& userTallyMaskCommits, const std::vector>& userTallyMessageCommits, const std::vector>& userTallySeedCommits, const Twistpoint& nextGenerator, bool doUserTallies); bool hbc_accept_epoch_updates( const std::vector& newFreshPseudonyms, const std::vector& newServerTallies, const std::vector>& newVoteMatrix, const std::vector& newUserTallies, bool doUserTallies); // DATA MAINTENANCE void export_new_user_update( std::vector& otherPreviousVoteTallies, std::vector& otherCurrentPseudonyms, std::vector& otherCurrentUserEncryptedTallies, std::vector>& otherVoteMatrix ) const; bool import_new_user_update( const std::vector& pi, const std::vector& otherPreviousVoteTallies, const std::vector& otherCurrentPseudonyms, const std::vector& otherCurrentUserEncryptedTallies, const std::vector>& otherVoteMatrix); // SCORE TALLYING std::vector tally_scores(); Scalar get_max_possible_score(); void receive_tallied_scores( const std::vector& userTallyScores, const std::vector& serverTallyScores); void encrypt( CurveBipoint& element, const Scalar& value); // MULTI-THREADING friend void generate_permutation_commitment_r( const void *a, void *b, const void *c, void *d); friend void generate_pseudonym_commitment_r( const void *a, void *b, const void *c, const void *d, void *e, void *f); friend void generate_server_tally_commitment_r( const void *a, void *b, const void *c, void *d); friend void generate_matrix_commitment_r( const void *a, void *b, void *c, void *d, const void *e, const void *f, void *g, void *h); friend void generate_user_tally_commitment_r( const void *a, const void *b, const void *c, const void *d, const void *e, void *f, void *g, void *h, void *i, void *j, void *k); friend void generate_permutation_proof_r( const void *a, void *b, const void *c, const void *d, const void *e); friend void generate_pseudonym_proof_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g, const void *h, const void *i, const void *j); friend void generate_server_tally_proof_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g, const void *h, const void *i, const void *j); friend void generate_first_half_matrix_proof_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g, const void *h); friend void generate_second_half_matrix_proof_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g, const void *h); friend void generate_user_tally_proof_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g, const void *h, const void *i, const void *j, const void *k, const void *l, const void *m, const void *n); friend void generate_tensor_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g, const void *h, const void *i, const void *j); friend void verify_permutation_r( const void *a, void *b, const void *c, const void *d); friend void verify_pseudonym_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g); friend void verify_server_tally_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g, const void *h); friend void verify_first_half_matrix_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g); friend void verify_second_half_matrix_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g); friend void verify_user_tally_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g, const void *h, const void *i, const void *j); friend void verify_tensor_r( const void *a, void *b, const void *c, const void *d, const void *e, const void *f, const void *g, const void *h); private: // constants for servers size_t numServers; // Identical between all servers (but collaboratively constructed) std::mutex *decryptMtx; BGN bgnSystem; // Private; different for each server Scalar currentSeed; Scalar nextSeed; // The actual data, which is collaboratively updated by all servers std::vector currentGeneratorProof; Twistpoint currentFreshGenerator; std::vector previousVoteTallies; std::vector currentPseudonyms; std::vector currentUserEncryptedTallies; std::vector> voteMatrix; void remove(); void copy(const PrsonaServer& other); /** * NOTE: voteMatrix structure: * Each element represents a vote by applied to . * The outer vector is a vector of rows and the inner vector is * a vector of encrypted votes. */ // An imaginary class; it's just used right now to coordinate servers // in memory instead of via network action. friend class PrsonaServerEntity; // EPOCH HELPERS std::vector> epoch_calculations( std::vector>& permutationCommits, std::vector>& freshPseudonymCommits, std::vector>& freshPseudonymSeedCommits, std::vector>& serverTallyCommits, std::vector>>& partwayVoteMatrixCommits, std::vector>>& finalVoteMatrixCommits, std::vector>& userTallyMaskCommits, std::vector>& userTallyMessageCommits, std::vector>& userTallySeedCommits, const Scalar& power, const Twistpoint& nextGenerator, bool doUserTallies); void hbc_epoch_calculations( std::vector& newFreshPseudonyms, std::vector& newServerTallies, std::vector>& newVoteMatrix, std::vector& newUserTallies, const Scalar& power, const Twistpoint& nextGenerator, bool doUserTallies); void hbc_shuffle_vote_matrix( std::vector>& newVoteMatrix, const std::vector>& oldVoteMatrix, const std::vector shuffleOrder ) const; std::vector> generate_permutation_matrix( const Scalar& reorderSeed ) const; std::vector generate_hbc_shuffle( const Scalar& reorderSeed ) const; std::vector> generate_commitment_matrix( const std::vector>& permutations, std::vector>& seeds ) const; std::vector> generate_pseudonym_matrix( const std::vector>& permutations, const Scalar& power, std::vector>& seeds, std::vector>& seedCommits ) const; std::vector> generate_server_tally_matrix( const std::vector>& permutations, std::vector>& seeds ) const; std::vector>> generate_vote_tensor( const std::vector>& permutations, const std::vector>& currVoteMatrix, std::vector>>& seeds, bool inverted ) const; std::vector> calculate_next_vote_matrix( const std::vector>>& voteTensor ) const; void generate_vote_tensor_proofs( std::vector>& pi, const std::vector>& permutations, const std::vector>& permutationSeeds, const std::vector>>& matrixSeeds, const std::vector>& currMatrix, const std::vector>& permutationCommits, const std::vector>>& matrixCommits, bool inverted ) const; bool verify_vote_tensor_proofs( const std::vector>& pi, size_t start_offset, const std::vector>& currMatrix, const std::vector>& permutationCommits, const std::vector>>& matrixCommits, bool inverted ) const; void generate_user_tally_matrix( const std::vector>& permutations, const Scalar& power, const Twistpoint& nextGenerator, const std::vector& currPseudonyms, std::vector& masks, std::vector>& maskCommits, std::vector& messages, std::vector>& messageCommits, std::vector>& userTallySeeds, std::vector>& userTallySeedCommits ) const; template std::vector> generate_reordered_plus_power_matrix( const std::vector>& permutations, const Scalar& power, const std::vector& oldValues, std::vector>& seeds, std::vector>& seedCommits, const T& h ) const; template std::vector> generate_reordered_matrix( const std::vector>& permutations, const std::vector& oldValues, std::vector>& seeds, const T& h, bool cancelOut ) const; template std::vector> transpose_matrix( const std::vector>& input ) const; std::vector sort_data( const std::vector& inputs ) const; // A helper class for "ordering" data and for binary search struct SortingType { Twistpoint pseudonym; size_t index; bool operator<( const SortingType& rhs ) const { return pseudonym < rhs.pseudonym; } }; template T encrypt( const T& g, const T& h, const Scalar& plaintext, const Scalar& lambda ) const; bool update_data( const std::vector>& freshPseudonymCommits, const std::vector>& serverTallyCommits, const std::vector>>& voteMatrixCommits, const std::vector>& userTallyMaskCommits, const std::vector>& userTallyMessageCommits); bool hbc_update_data( const std::vector& newFreshPseudonyms, const std::vector& newServerTallies, const std::vector>& newVoteMatrix, const std::vector& newUserTallies); bool pseudonyms_sorted( const std::vector newPseudonyms ) const; // DATA SAFEKEEPING std::vector order_data(); // BINARY SEARCH size_t binary_search( const Twistpoint& index ) const; // VALID VOTE PROOFS bool verify_vote_proof( const std::vector& pi, const std::vector& oldVotes, const std::vector& newVotes, const Twistpoint& shortTermPublicKey ) const; }; #endif