|  | @@ -122,7 +122,11 @@ void make_epoch(
 | 
	
		
			
				|  |  |      obtain_update_locks(updateLock, serverIPs, serverPorts, selfIP, selfPort, bandwidthData);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // Do the first half of the epoch calculations (building up the intermediary values)
 | 
	
		
			
				|  |  | -    std::vector<Proof> generatorProof = epoch_build_up(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, civetServer, buildUpOutputMtx, buildUpOutputFilename, usageMtx, usageFilename, bandwidthData);
 | 
	
		
			
				|  |  | +    std::vector<Proof> generatorProof;
 | 
	
		
			
				|  |  | +    if (prsonaServer->is_server_malicious())
 | 
	
		
			
				|  |  | +        generatorProof = epoch_build_up(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, civetServer, buildUpOutputMtx, buildUpOutputFilename, usageMtx, usageFilename, bandwidthData);
 | 
	
		
			
				|  |  | +    else
 | 
	
		
			
				|  |  | +        generatorProof = hbc_epoch_build_up(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, civetServer, buildUpOutputMtx, buildUpOutputFilename, usageMtx, usageFilename, bandwidthData);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // Tally up the current scores at the end of the epoch for the users
 | 
	
		
			
				|  |  |      std::vector<EGCiphertext> currentUserEncryptedTallies;
 | 
	
	
		
			
				|  | @@ -133,7 +137,10 @@ void make_epoch(
 | 
	
		
			
				|  |  |      distribute_tallied_scores(prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, currentUserEncryptedTallies, currentServerEncryptedTallies, bandwidthData);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // Do the second half of the epoch calculations (breaking down values to their final values, to be given to users)
 | 
	
		
			
				|  |  | -    epoch_break_down(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, generatorProof, nextGenerator, civetServer, breakDownOutputMtx, breakDownOutputFilename, usageMtx, usageFilename, bandwidthData);
 | 
	
		
			
				|  |  | +    if (prsonaServer->is_server_malicious())
 | 
	
		
			
				|  |  | +        epoch_break_down(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, generatorProof, nextGenerator, civetServer, breakDownOutputMtx, breakDownOutputFilename, usageMtx, usageFilename, bandwidthData);
 | 
	
		
			
				|  |  | +    else
 | 
	
		
			
				|  |  | +        hbc_epoch_break_down(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, generatorProof, nextGenerator, civetServer, breakDownOutputMtx, breakDownOutputFilename, usageMtx, usageFilename, bandwidthData);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // Indicate we are in a new epoch
 | 
	
		
			
				|  |  |      epochNum.fetch_add(1);
 | 
	
	
		
			
				|  | @@ -595,6 +602,118 @@ std::vector<Proof> epoch_build_up(
 | 
	
		
			
				|  |  |      return generatorProofHolder[0];
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +std::vector<Proof> hbc_epoch_build_up(
 | 
	
		
			
				|  |  | +    std::default_random_engine& rng,
 | 
	
		
			
				|  |  | +    PrsonaServer *prsonaServer,
 | 
	
		
			
				|  |  | +    const std::vector<std::string>& serverIPs,
 | 
	
		
			
				|  |  | +    const std::vector<int>& serverPorts,
 | 
	
		
			
				|  |  | +    const std::string& selfIP,
 | 
	
		
			
				|  |  | +    int selfPort,
 | 
	
		
			
				|  |  | +    Twistpoint& nextGenerator,
 | 
	
		
			
				|  |  | +    const CivetServer& civetServer,
 | 
	
		
			
				|  |  | +    std::mutex& outputMtx,
 | 
	
		
			
				|  |  | +    const std::string& outputFilename,
 | 
	
		
			
				|  |  | +    std::mutex& usageMtx,
 | 
	
		
			
				|  |  | +    const std::string& usageFilename,
 | 
	
		
			
				|  |  | +    std::vector<size_t>& overallBandwidthData)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    std::vector<Proof> generatorProof;
 | 
	
		
			
				|  |  | +    std::vector<Twistpoint> newFreshPseudonyms;
 | 
	
		
			
				|  |  | +    std::vector<CurveBipoint> newServerTallies;
 | 
	
		
			
				|  |  | +    std::vector<std::vector<TwistBipoint>> newVoteMatrix;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Go through each server to perform the epoch calculation at hand
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < serverIPs.size(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        // When it's our turn, do things as normal
 | 
	
		
			
				|  |  | +        if (serverIPs[i] == selfIP && serverPorts[i] == selfPort)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            newFreshPseudonyms.clear();
 | 
	
		
			
				|  |  | +            newServerTallies.clear();
 | 
	
		
			
				|  |  | +            newVoteMatrix.clear();
 | 
	
		
			
				|  |  | +            std::vector<size_t> bandwidthData(2);
 | 
	
		
			
				|  |  | +            std::vector<std::vector<size_t>> otherBandwidthDataBefore;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            std::vector<size_t> serverBandwidthDataBefore = get_server_log_data(civetServer.getContext());
 | 
	
		
			
				|  |  | +            std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +            clock_t cpuTimeBefore = clock();
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            // Perform the actual calculation
 | 
	
		
			
				|  |  | +            prsonaServer->hbc_build_up_midway_pseudonyms(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, nextGenerator);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            std::vector<EGCiphertext> newUserTallies;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Serialize the relevant data
 | 
	
		
			
				|  |  | +            std::string data = make_hbc_epoch_update_string(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            struct synchronization_tool sync;
 | 
	
		
			
				|  |  | +            std::vector<struct mg_connection *> conns;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Distribute the data to each server (in parallel, roughly)
 | 
	
		
			
				|  |  | +            std::unique_lock<std::mutex> lck(sync.mtx);
 | 
	
		
			
				|  |  | +            sync.val = 1;
 | 
	
		
			
				|  |  | +            for (size_t j = 0; j < serverIPs.size(); j++)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                // But, obviously, don't send it back to ourselves
 | 
	
		
			
				|  |  | +                if (i == j)
 | 
	
		
			
				|  |  | +                    continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // Send that data
 | 
	
		
			
				|  |  | +                struct mg_connection *currConn = distribute_epoch_updates(serverIPs[j], serverPorts[j], data, &sync);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                otherBandwidthDataBefore.push_back(get_conn_log_data(mg_get_context(currConn), false));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // But keep track of that connection, as we can't close it until we know the server's gotten its data
 | 
	
		
			
				|  |  | +                conns.push_back(currConn);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Wait for the other servers to all report back that they have received the update
 | 
	
		
			
				|  |  | +            while (sync.val < serverIPs.size())
 | 
	
		
			
				|  |  | +                sync.cv.wait(lck);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            for (size_t j = 0; j < conns.size(); j++)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                std::vector<size_t> currBandwidthDataAfter = get_conn_log_data(mg_get_context(conns[j]), false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                bandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[j][0];
 | 
	
		
			
				|  |  | +                bandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[j][1];
 | 
	
		
			
				|  |  | +                overallBandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[j][0];
 | 
	
		
			
				|  |  | +                overallBandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[j][1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                mg_close_connection(conns[j]);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            clock_t cpuTimeAfter = clock();
 | 
	
		
			
				|  |  | +            std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +            std::vector<size_t> serverBandwidthDataAfter = get_server_log_data(civetServer.getContext());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            std::vector<double> timingData(2);
 | 
	
		
			
				|  |  | +            timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
 | 
	
		
			
				|  |  | +            timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            bandwidthData[0] += serverBandwidthDataAfter[0] - serverBandwidthDataBefore[0];
 | 
	
		
			
				|  |  | +            bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            write_log_data(outputMtx, outputFilename, timingData, bandwidthData);
 | 
	
		
			
				|  |  | +            write_usage_data(usageMtx, usageFilename);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else    // When it's another server's turn, tell them to do their part
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            // Serialize the request
 | 
	
		
			
				|  |  | +            std::string data = make_epoch_initiator_string(generatorProof, nextGenerator);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            std::vector<std::vector<Proof>> generatorProofHolder;
 | 
	
		
			
				|  |  | +            generatorProofHolder.push_back(generatorProof);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // And have them do that request
 | 
	
		
			
				|  |  | +            nextGenerator = initiate_epoch_updates(rng, serverIPs[i], serverPorts[i], data, false, generatorProofHolder, overallBandwidthData);
 | 
	
		
			
				|  |  | +            generatorProof = generatorProofHolder[0];
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return generatorProof;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  void epoch_break_down(
 | 
	
		
			
				|  |  |      std::default_random_engine& rng,
 | 
	
		
			
				|  |  |      PrsonaServer *prsonaServer,
 | 
	
	
		
			
				|  | @@ -715,6 +834,114 @@ void epoch_break_down(
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +void hbc_epoch_break_down(
 | 
	
		
			
				|  |  | +    std::default_random_engine& rng,
 | 
	
		
			
				|  |  | +    PrsonaServer *prsonaServer,
 | 
	
		
			
				|  |  | +    const std::vector<std::string>& serverIPs,
 | 
	
		
			
				|  |  | +    const std::vector<int>& serverPorts,
 | 
	
		
			
				|  |  | +    const std::string& selfIP,
 | 
	
		
			
				|  |  | +    int selfPort,
 | 
	
		
			
				|  |  | +    const std::vector<Proof>& generatorProof,
 | 
	
		
			
				|  |  | +    const Twistpoint& nextGenerator,
 | 
	
		
			
				|  |  | +    const CivetServer& civetServer,
 | 
	
		
			
				|  |  | +    std::mutex& outputMtx,
 | 
	
		
			
				|  |  | +    const std::string& outputFilename,
 | 
	
		
			
				|  |  | +    std::mutex& usageMtx,
 | 
	
		
			
				|  |  | +    const std::string& usageFilename,
 | 
	
		
			
				|  |  | +    std::vector<size_t>& overallBandwidthData)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    std::vector<Twistpoint> newFreshPseudonyms;
 | 
	
		
			
				|  |  | +    std::vector<CurveBipoint> newServerTallies;
 | 
	
		
			
				|  |  | +    std::vector<std::vector<TwistBipoint>> newVoteMatrix;
 | 
	
		
			
				|  |  | +    std::vector<EGCiphertext> newUserTallies;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Go through each server to perform the epoch calculation at hand
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < serverIPs.size(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        // When it's our turn, do things as normal
 | 
	
		
			
				|  |  | +        if (serverIPs[i] == selfIP && serverPorts[i] == selfPort)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            newFreshPseudonyms.clear();
 | 
	
		
			
				|  |  | +            newServerTallies.clear();
 | 
	
		
			
				|  |  | +            newVoteMatrix.clear();
 | 
	
		
			
				|  |  | +            newUserTallies.clear();
 | 
	
		
			
				|  |  | +            std::vector<size_t> bandwidthData(2);
 | 
	
		
			
				|  |  | +            std::vector<std::vector<size_t>> otherBandwidthDataBefore;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            std::vector<size_t> serverBandwidthDataBefore = get_server_log_data(civetServer.getContext());
 | 
	
		
			
				|  |  | +            std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +            clock_t cpuTimeBefore = clock();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Perform the actual calculation
 | 
	
		
			
				|  |  | +            prsonaServer->hbc_break_down_midway_pseudonyms(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Serialize the relevant data
 | 
	
		
			
				|  |  | +            std::string data = make_hbc_epoch_update_string(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, true);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            struct synchronization_tool sync;
 | 
	
		
			
				|  |  | +            std::vector<struct mg_connection *> conns;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Distribute the data to each server (in parallel, roughly)
 | 
	
		
			
				|  |  | +            std::unique_lock<std::mutex> lck(sync.mtx);
 | 
	
		
			
				|  |  | +            sync.val = 1;
 | 
	
		
			
				|  |  | +            for (size_t j = 0; j < serverIPs.size(); j++)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                // But, obviously, don't send it back to ourselves
 | 
	
		
			
				|  |  | +                if (i == j)
 | 
	
		
			
				|  |  | +                    continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // Send that data
 | 
	
		
			
				|  |  | +                struct mg_connection *currConn = distribute_epoch_updates(serverIPs[j], serverPorts[j], data, &sync);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                otherBandwidthDataBefore.push_back(get_conn_log_data(mg_get_context(currConn), false));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // But keep track of that connection, as we can't close it until we know the server's gotten its data
 | 
	
		
			
				|  |  | +                conns.push_back(currConn);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Wait for the other servers to all report back that they have received the update
 | 
	
		
			
				|  |  | +            while (sync.val < serverIPs.size())
 | 
	
		
			
				|  |  | +                sync.cv.wait(lck);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            for (size_t j = 0; j < conns.size(); j++)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                std::vector<size_t> currBandwidthDataAfter = get_conn_log_data(mg_get_context(conns[j]), false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                bandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[j][0];
 | 
	
		
			
				|  |  | +                bandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[j][1];
 | 
	
		
			
				|  |  | +                overallBandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[j][0];
 | 
	
		
			
				|  |  | +                overallBandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[j][1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                mg_close_connection(conns[j]);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            clock_t cpuTimeAfter = clock();
 | 
	
		
			
				|  |  | +            std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +            std::vector<size_t> serverBandwidthDataAfter = get_server_log_data(civetServer.getContext());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            std::vector<double> timingData(2);
 | 
	
		
			
				|  |  | +            timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
 | 
	
		
			
				|  |  | +            timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            bandwidthData[0] += serverBandwidthDataAfter[0] - serverBandwidthDataBefore[0];
 | 
	
		
			
				|  |  | +            bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            write_log_data(outputMtx, outputFilename, timingData, bandwidthData);
 | 
	
		
			
				|  |  | +            write_usage_data(usageMtx, usageFilename);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else    // When it's another server's turn, tell them to do their part
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            std::vector<std::vector<Proof>> unused;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Serialize the request
 | 
	
		
			
				|  |  | +            std::string data = make_epoch_initiator_string(generatorProof, nextGenerator);
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            // And have them do that request
 | 
	
		
			
				|  |  | +            initiate_epoch_updates(rng, serverIPs[i], serverPorts[i], data, true, unused, overallBandwidthData);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /*
 | 
	
		
			
				|  |  |   * HELPERS FOR EPOCH HELPERS
 | 
	
		
			
				|  |  |   */
 | 
	
	
		
			
				|  | @@ -1168,6 +1395,53 @@ std::string make_epoch_update_string(
 | 
	
		
			
				|  |  |      return buffer.str();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +std::string make_hbc_epoch_update_string(
 | 
	
		
			
				|  |  | +    const std::vector<Proof>& generatorProof,
 | 
	
		
			
				|  |  | +    const std::vector<Twistpoint>& newFreshPseudonyms,
 | 
	
		
			
				|  |  | +    const std::vector<CurveBipoint>& newServerTallies,
 | 
	
		
			
				|  |  | +    const std::vector<std::vector<TwistBipoint>>& newVoteMatrix,
 | 
	
		
			
				|  |  | +    const std::vector<EGCiphertext>& newUserTallies,
 | 
	
		
			
				|  |  | +    const Twistpoint& nextGenerator,
 | 
	
		
			
				|  |  | +    bool doUserTallies)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    std::stringstream buffer;
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    BinarySizeT sizeOfVector;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    sizeOfVector.set(generatorProof.size());
 | 
	
		
			
				|  |  | +    buffer << sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +        buffer << generatorProof[i];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    sizeOfVector.set(newFreshPseudonyms.size());
 | 
	
		
			
				|  |  | +    buffer << sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +        buffer << newFreshPseudonyms[i];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    sizeOfVector.set(newServerTallies.size());
 | 
	
		
			
				|  |  | +    buffer << sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +        buffer << newServerTallies[i];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    sizeOfVector.set(newVoteMatrix.size());
 | 
	
		
			
				|  |  | +    buffer << sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +        for (size_t j = 0; j < sizeOfVector.val(); j++)
 | 
	
		
			
				|  |  | +            buffer << newVoteMatrix[i][j];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    sizeOfVector.set(newUserTallies.size());
 | 
	
		
			
				|  |  | +    buffer << sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +        buffer << newUserTallies[i];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    buffer << nextGenerator;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    BinaryBool flag(doUserTallies);
 | 
	
		
			
				|  |  | +    buffer << flag;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return buffer.str();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  ssize_t read_epoch_update_string(
 | 
	
		
			
				|  |  |      const char *filename,
 | 
	
		
			
				|  |  |      std::vector<std::vector<Proof>>& pi,
 | 
	
	
		
			
				|  | @@ -1366,6 +1640,91 @@ ssize_t read_epoch_update_string(
 | 
	
		
			
				|  |  |      return retval;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +ssize_t read_hbc_epoch_update_string(
 | 
	
		
			
				|  |  | +    const char *filename,
 | 
	
		
			
				|  |  | +    std::vector<Proof>& generatorProof,
 | 
	
		
			
				|  |  | +    std::vector<Twistpoint>& newFreshPseudonyms,
 | 
	
		
			
				|  |  | +    std::vector<CurveBipoint>& newServerTallies,
 | 
	
		
			
				|  |  | +    std::vector<std::vector<TwistBipoint>>& newVoteMatrix,
 | 
	
		
			
				|  |  | +    std::vector<EGCiphertext>& newUserTallies,
 | 
	
		
			
				|  |  | +    Twistpoint& nextGenerator,
 | 
	
		
			
				|  |  | +    bool& doUserTallies)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    std::ifstream file(filename);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    file.ignore(std::numeric_limits<std::streamsize>::max());
 | 
	
		
			
				|  |  | +    std::streamsize retval = file.gcount();
 | 
	
		
			
				|  |  | +    file.clear();
 | 
	
		
			
				|  |  | +    file.seekg(0, std::ios_base::beg);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    BinarySizeT sizeOfVector;
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    generatorProof.clear();
 | 
	
		
			
				|  |  | +    newFreshPseudonyms.clear();
 | 
	
		
			
				|  |  | +    newServerTallies.clear();
 | 
	
		
			
				|  |  | +    newVoteMatrix.clear();
 | 
	
		
			
				|  |  | +    newUserTallies.clear();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    file >> sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        Proof currProof;
 | 
	
		
			
				|  |  | +        file >> currProof;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        generatorProof.push_back(currProof);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    file >> sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        Twistpoint currFreshPseudonym;
 | 
	
		
			
				|  |  | +        file >> currFreshPseudonym;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        newFreshPseudonyms.push_back(currFreshPseudonym);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    file >> sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        CurveBipoint currServerTally;
 | 
	
		
			
				|  |  | +        file >> currServerTally;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        newServerTallies.push_back(currServerTally);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    file >> sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        std::vector<TwistBipoint> currRow;
 | 
	
		
			
				|  |  | +        for (size_t j = 0; j < sizeOfVector.val(); j++)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            TwistBipoint currVote;
 | 
	
		
			
				|  |  | +            file >> currVote;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            currRow.push_back(currVote);    
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        newVoteMatrix.push_back(currRow);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    file >> sizeOfVector;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < sizeOfVector.val(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        EGCiphertext currUserTally;
 | 
	
		
			
				|  |  | +        file >> currUserTally;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        newUserTallies.push_back(currUserTally);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    file >> nextGenerator;
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    BinaryBool binaryDoUserTallies;
 | 
	
		
			
				|  |  | +    file >> binaryDoUserTallies;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    doUserTallies = binaryDoUserTallies.val();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return retval;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /**********************************************************
 | 
	
		
			
				|  |  |   ****                                                  ****
 | 
	
		
			
				|  |  |   ****  other server-relevant handler member functions  ****
 | 
	
	
		
			
				|  | @@ -1782,15 +2141,24 @@ void PrsonaServerWebSocketHandler::generate_response(
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // EPOCH ROUNDS
 | 
	
		
			
				|  |  |          case PRSONA_PERFORM_EPOCH_BUILD_UP:
 | 
	
		
			
				|  |  | -            build_up_midway_pseudonyms(server, conn, filename);
 | 
	
		
			
				|  |  | +            if (prsonaServer->is_server_malicious())
 | 
	
		
			
				|  |  | +                build_up_midway_pseudonyms(server, conn, filename);
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +                hbc_build_up_midway_pseudonyms(server, conn, filename);
 | 
	
		
			
				|  |  |              break;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          case PRSONA_PERFORM_EPOCH_BREAK_DOWN:
 | 
	
		
			
				|  |  | -            break_down_midway_pseudonyms(server, conn, filename);
 | 
	
		
			
				|  |  | +            if (prsonaServer->is_server_malicious())
 | 
	
		
			
				|  |  | +                break_down_midway_pseudonyms(server, conn, filename);
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +                hbc_break_down_midway_pseudonyms(server, conn, filename);
 | 
	
		
			
				|  |  |              break;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          case PRSONA_RECEIVE_EPOCH_UPDATE:
 | 
	
		
			
				|  |  | -            accept_epoch_updates(server, conn, filename);
 | 
	
		
			
				|  |  | +            if (prsonaServer->is_server_malicious())
 | 
	
		
			
				|  |  | +                accept_epoch_updates(server, conn, filename);
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +                hbc_accept_epoch_updates(server, conn, filename);
 | 
	
		
			
				|  |  |              break;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // DISTRIBUTED BGN
 | 
	
	
		
			
				|  | @@ -2656,6 +3024,91 @@ void PrsonaServerWebSocketHandler::build_up_midway_pseudonyms(
 | 
	
		
			
				|  |  |      mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +void PrsonaServerWebSocketHandler::hbc_build_up_midway_pseudonyms(
 | 
	
		
			
				|  |  | +    CivetServer *civetServer,
 | 
	
		
			
				|  |  | +    struct mg_connection *conn,
 | 
	
		
			
				|  |  | +    const char *filename)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    std::vector<Proof> generatorProof;
 | 
	
		
			
				|  |  | +    Twistpoint nextGenerator;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Un-serialize request
 | 
	
		
			
				|  |  | +    ssize_t bandwidthRcv = read_epoch_initiator_string(filename, generatorProof, nextGenerator);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<Twistpoint> newFreshPseudonyms;
 | 
	
		
			
				|  |  | +    std::vector<CurveBipoint> newServerTallies;
 | 
	
		
			
				|  |  | +    std::vector<std::vector<TwistBipoint>> newVoteMatrix;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<size_t> bandwidthData(2);
 | 
	
		
			
				|  |  | +    std::vector<std::vector<size_t>> otherBandwidthDataBefore;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<size_t> serverBandwidthDataBefore = get_server_log_data(civetServer->getContext());
 | 
	
		
			
				|  |  | +    std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +    clock_t cpuTimeBefore = clock();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Do actual epoch calculation
 | 
	
		
			
				|  |  | +    prsonaServer->hbc_build_up_midway_pseudonyms(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, nextGenerator);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<EGCiphertext> newUserTallies;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Serialize update data
 | 
	
		
			
				|  |  | +    std::string data = make_hbc_epoch_update_string(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    struct synchronization_tool sync;
 | 
	
		
			
				|  |  | +    std::vector<struct mg_connection *> conns;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Connect to all other servers (roughly in parallel)
 | 
	
		
			
				|  |  | +    std::unique_lock<std::mutex> lck(sync.mtx);
 | 
	
		
			
				|  |  | +    sync.val = 1;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < serverIPs.size(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        if (serverIPs[i] == selfIP && serverPorts[i] == selfPort)
 | 
	
		
			
				|  |  | +            continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // Send them update data
 | 
	
		
			
				|  |  | +        struct mg_connection *currConn = distribute_epoch_updates(serverIPs[i], serverPorts[i], data, &sync);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        conns.push_back(currConn);
 | 
	
		
			
				|  |  | +        otherBandwidthDataBefore.push_back(get_conn_log_data(mg_get_context(currConn), false));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Wait for all to acknowledge receipt of the update data
 | 
	
		
			
				|  |  | +    while (sync.val < serverIPs.size())
 | 
	
		
			
				|  |  | +        sync.cv.wait(lck);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Close connections
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < conns.size(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        std::vector<size_t> currBandwidthDataAfter = get_conn_log_data(mg_get_context(conns[i]), false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        bandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[i][0];
 | 
	
		
			
				|  |  | +        bandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[i][1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        mg_close_connection(conns[i]);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    clock_t cpuTimeAfter = clock();
 | 
	
		
			
				|  |  | +    std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +    std::vector<size_t> serverBandwidthDataAfter = get_server_log_data(civetServer->getContext());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<double> timingData(2);
 | 
	
		
			
				|  |  | +    timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
 | 
	
		
			
				|  |  | +    timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    bandwidthData[0] += serverBandwidthDataAfter[0] - serverBandwidthDataBefore[0] + bandwidthRcv;
 | 
	
		
			
				|  |  | +    bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    write_log_data(buildUpOutputMtx, buildUpOutputFilename, timingData, bandwidthData);
 | 
	
		
			
				|  |  | +    write_usage_data(usageMtx, usageFilename);
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    // Serialize response
 | 
	
		
			
				|  |  | +    data = make_epoch_initiator_string(generatorProof, nextGenerator);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Send response
 | 
	
		
			
				|  |  | +    mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
 | 
	
		
			
				|  |  | +    mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  void PrsonaServerWebSocketHandler::break_down_midway_pseudonyms(
 | 
	
		
			
				|  |  |      CivetServer *civetServer,
 | 
	
		
			
				|  |  |      struct mg_connection *conn,
 | 
	
	
		
			
				|  | @@ -2744,6 +3197,88 @@ void PrsonaServerWebSocketHandler::break_down_midway_pseudonyms(
 | 
	
		
			
				|  |  |      mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +void PrsonaServerWebSocketHandler::hbc_break_down_midway_pseudonyms(
 | 
	
		
			
				|  |  | +    CivetServer *civetServer,
 | 
	
		
			
				|  |  | +    struct mg_connection *conn,
 | 
	
		
			
				|  |  | +    const char *filename)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    std::vector<Proof> generatorProof;
 | 
	
		
			
				|  |  | +    Twistpoint nextGenerator;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Un-serialize request
 | 
	
		
			
				|  |  | +    ssize_t bandwidthRcv = read_epoch_initiator_string(filename, generatorProof, nextGenerator);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<Twistpoint> newFreshPseudonyms;
 | 
	
		
			
				|  |  | +    std::vector<CurveBipoint> newServerTallies;
 | 
	
		
			
				|  |  | +    std::vector<std::vector<TwistBipoint>> newVoteMatrix;
 | 
	
		
			
				|  |  | +    std::vector<EGCiphertext> newUserTallies;
 | 
	
		
			
				|  |  | +    std::vector<size_t> bandwidthData(2);
 | 
	
		
			
				|  |  | +    std::vector<std::vector<size_t>> otherBandwidthDataBefore;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<size_t> serverBandwidthDataBefore = get_server_log_data(civetServer->getContext());
 | 
	
		
			
				|  |  | +    std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +    clock_t cpuTimeBefore = clock();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Perform the actual calculation
 | 
	
		
			
				|  |  | +    prsonaServer->hbc_break_down_midway_pseudonyms(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Serialize the relevant data
 | 
	
		
			
				|  |  | +    std::string data = make_hbc_epoch_update_string(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, true);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    struct synchronization_tool sync;
 | 
	
		
			
				|  |  | +    std::vector<struct mg_connection *> conns;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Connect to all other servers (roughly in parallel)
 | 
	
		
			
				|  |  | +    std::unique_lock<std::mutex> lck(sync.mtx);
 | 
	
		
			
				|  |  | +    sync.val = 1;
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < serverIPs.size(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        if (serverIPs[i] == selfIP && serverPorts[i] == selfPort)
 | 
	
		
			
				|  |  | +            continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // Send them update data
 | 
	
		
			
				|  |  | +        struct mg_connection *currConn = distribute_epoch_updates(serverIPs[i], serverPorts[i], data, &sync);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        conns.push_back(currConn);
 | 
	
		
			
				|  |  | +        otherBandwidthDataBefore.push_back(get_conn_log_data(mg_get_context(currConn), false));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Wait for all to acknowledge receipt of the update data
 | 
	
		
			
				|  |  | +    while (sync.val < serverIPs.size())
 | 
	
		
			
				|  |  | +        sync.cv.wait(lck);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Close connections
 | 
	
		
			
				|  |  | +    for (size_t i = 0; i < conns.size(); i++)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        std::vector<size_t> currBandwidthDataAfter = get_conn_log_data(mg_get_context(conns[i]), false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        bandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[i][0];
 | 
	
		
			
				|  |  | +        bandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[i][1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        mg_close_connection(conns[i]);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    clock_t cpuTimeAfter = clock();
 | 
	
		
			
				|  |  | +    std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +    std::vector<size_t> serverBandwidthDataAfter = get_server_log_data(civetServer->getContext());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<double> timingData(2);
 | 
	
		
			
				|  |  | +    timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
 | 
	
		
			
				|  |  | +    timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    bandwidthData[0] += serverBandwidthDataAfter[0] - serverBandwidthDataBefore[0] + bandwidthRcv;
 | 
	
		
			
				|  |  | +    bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    write_log_data(breakDownOutputMtx, breakDownOutputFilename, timingData, bandwidthData);
 | 
	
		
			
				|  |  | +    write_usage_data(usageMtx, usageFilename);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Keep our epoch value up-to-date
 | 
	
		
			
				|  |  | +    epochNum.fetch_add(1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Tell initiator we have finished
 | 
	
		
			
				|  |  | +    mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  void PrsonaServerWebSocketHandler::accept_epoch_updates(
 | 
	
		
			
				|  |  |      CivetServer *civetServer,
 | 
	
		
			
				|  |  |      struct mg_connection *conn,
 | 
	
	
		
			
				|  | @@ -2791,6 +3326,48 @@ void PrsonaServerWebSocketHandler::accept_epoch_updates(
 | 
	
		
			
				|  |  |      mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +void PrsonaServerWebSocketHandler::hbc_accept_epoch_updates(
 | 
	
		
			
				|  |  | +    CivetServer *civetServer,
 | 
	
		
			
				|  |  | +    struct mg_connection *conn,
 | 
	
		
			
				|  |  | +    const char *filename)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    std::vector<Proof> generatorProof;
 | 
	
		
			
				|  |  | +    std::vector<Twistpoint> newFreshPseudonyms;
 | 
	
		
			
				|  |  | +    std::vector<CurveBipoint> newServerTallies;
 | 
	
		
			
				|  |  | +    std::vector<std::vector<TwistBipoint>> newVoteMatrix;
 | 
	
		
			
				|  |  | +    std::vector<EGCiphertext> newUserTallies;
 | 
	
		
			
				|  |  | +    Twistpoint nextGenerator;
 | 
	
		
			
				|  |  | +    bool doUserTallies;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Un-serialize request
 | 
	
		
			
				|  |  | +    ssize_t bandwidthRcv = read_hbc_epoch_update_string(filename, generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, doUserTallies);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<size_t> bandwidthDataBefore = get_server_log_data(civetServer->getContext());
 | 
	
		
			
				|  |  | +    std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +    clock_t cpuTimeBefore = clock();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Load data into server object
 | 
	
		
			
				|  |  | +    prsonaServer->hbc_accept_epoch_updates(newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, doUserTallies);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    clock_t cpuTimeAfter = clock();
 | 
	
		
			
				|  |  | +    std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
 | 
	
		
			
				|  |  | +    std::vector<size_t> bandwidthDataAfter = get_server_log_data(civetServer->getContext());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<double> timingData(2);
 | 
	
		
			
				|  |  | +    timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
 | 
	
		
			
				|  |  | +    timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<size_t> bandwidthData(2);
 | 
	
		
			
				|  |  | +    bandwidthData[0] = bandwidthDataAfter[0] - bandwidthDataBefore[0] + bandwidthRcv;
 | 
	
		
			
				|  |  | +    bandwidthData[1] = bandwidthDataAfter[1] - bandwidthDataBefore[1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    write_log_data(updateOutputMtx, updateOutputFilename, timingData, bandwidthData);
 | 
	
		
			
				|  |  | +    write_usage_data(usageMtx, usageFilename);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Acknowledge receipt of request
 | 
	
		
			
				|  |  | +    mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /*
 | 
	
		
			
				|  |  |   * DISTRIBUTED BGN
 | 
	
		
			
				|  |  |   */
 |