Skip to content

Commit

Permalink
Parallelizing the functions that add blinded histogram noise. (#1165)
Browse files Browse the repository at this point in the history
1. Parallelizing the functions that add the blinded histogram noises.
Most of the noises added are the blinded histogram noises, so
parallelizing this step will help speed up the computation.
2. Updating the llv2 encryption test to make it consistent with the llv2
protocol.
  • Loading branch information
ple13 authored Aug 15, 2023
1 parent f149d4d commit d1f5d00
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,15 @@ absl::StatusOr<std::vector<ElGamalEcPointPair>> GetSameKeyAggregatorMatrixBase(
// Adds encrypted blinded-histogram-noise registers to the end of data.
// returns the number of such noise registers added.
absl::StatusOr<int64_t> AddBlindedHistogramNoise(
ProtocolCryptor& protocol_cryptor, int total_sketches_count,
MultithreadingHelper& helper, int total_sketches_count,
const math::DistributedNoiser& distributed_noiser, size_t pos,
std::string& data) {
ASSIGN_OR_RETURN(
std::string blinded_histogram_noise_key_ec,
protocol_cryptor.MapToCurve(kBlindedHistogramNoiseRegisterKey));
ASSIGN_OR_RETURN(std::string blinded_histogram_noise_key_ec,
helper.GetProtocolCryptor().MapToCurve(
kBlindedHistogramNoiseRegisterKey));

int64_t noise_register_added = 0;
std::vector<std::string> register_id_ecs;

for (int k = 1; k <= total_sketches_count; ++k) {
// The random number of distinct register_ids that should appear k times.
Expand All @@ -286,33 +287,39 @@ absl::StatusOr<int64_t> AddBlindedHistogramNoise(
// The prefix is to ensure the value is not in the regular id space.
std::string register_id =
absl::StrCat("blinded_histogram_noise",
protocol_cryptor.NextRandomBigNumAsString());
helper.GetProtocolCryptor().NextRandomBigNumAsString());
ASSIGN_OR_RETURN(std::string register_id_ec,
protocol_cryptor.MapToCurve(register_id));
// Add k registers with the same register_id but different keys and
// counts.
helper.GetProtocolCryptor().MapToCurve(register_id));
for (int j = 0; j < k; ++j) {
// Add register_id
RETURN_IF_ERROR(EncryptCompositeElGamalAndWriteToString(
protocol_cryptor, CompositeType::kFull, register_id_ec, pos, data));
pos += kBytesPerCipherText;
// Add register key, which is the constant blinded_histogram_noise_key.
RETURN_IF_ERROR(EncryptCompositeElGamalAndWriteToString(
protocol_cryptor, CompositeType::kFull,
blinded_histogram_noise_key_ec, pos, data));
pos += kBytesPerCipherText;
// Add register count, which can be arbitrary value. use the same value
// as key here.
RETURN_IF_ERROR(EncryptCompositeElGamalAndWriteToString(
protocol_cryptor, CompositeType::kFull,
blinded_histogram_noise_key_ec, pos, data));
pos += kBytesPerCipherText;

++noise_register_added;
register_id_ecs.push_back(register_id_ec);
}
noise_register_added += k;
}
}

absl::AnyInvocable<absl::Status(ProtocolCryptor&, size_t)> f =
[&](ProtocolCryptor& cryptor, size_t index) -> absl::Status {
size_t current_pos = pos + kBytesPerCipherRegister * index;
// Add register_id
RETURN_IF_ERROR(EncryptCompositeElGamalAndWriteToString(
helper.GetProtocolCryptor(), CompositeType::kFull,
register_id_ecs[index], current_pos, data));
current_pos += kBytesPerCipherText;
// Add register key, which is the constant blinded_histogram_noise_key.
RETURN_IF_ERROR(EncryptCompositeElGamalAndWriteToString(
helper.GetProtocolCryptor(), CompositeType::kFull,
blinded_histogram_noise_key_ec, current_pos, data));
current_pos += kBytesPerCipherText;
// Add register count, which can be arbitrary value. use the same value
// as key here.
RETURN_IF_ERROR(EncryptCompositeElGamalAndWriteToString(
helper.GetProtocolCryptor(), CompositeType::kFull,
blinded_histogram_noise_key_ec, current_pos, data));
current_pos += kBytesPerCipherText;
return absl::OkStatus();
};
RETURN_IF_ERROR(helper.Execute(noise_register_added, f));

return noise_register_added;
}

Expand Down Expand Up @@ -817,7 +824,7 @@ absl::StatusOr<CompleteSetupPhaseResponse> CompleteSetupPhase(
// 1. Add blinded histogram noise.
ASSIGN_OR_RETURN(
int64_t blinded_histogram_noise_count,
AddBlindedHistogramNoise(multithreading_helper->GetProtocolCryptor(),
AddBlindedHistogramNoise(*multithreading_helper,
noise_parameters.total_sketches_count(),
*blind_histogram_noiser, pos, *response_crv));
pos += kBytesPerCipherRegister * blinded_histogram_noise_count;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,14 @@ int64_t CountUniqueElements(const std::vector<std::string>& arr) {
// Adds encrypted blinded-histogram-noise registers to the end of data.
// returns the number of such noise registers added.
absl::StatusOr<int64_t> AddReachOnlyBlindedHistogramNoise(
ProtocolCryptor& protocol_cryptor, int total_sketches_count,
MultithreadingHelper& helper, int total_sketches_count,
const math::DistributedNoiser& distributed_noiser, size_t pos,
std::string& data, int64_t& num_unique_noise_id) {
int64_t noise_register_added = 0;
num_unique_noise_id = 0;

std::vector<std::string> register_id_ecs;

for (int k = 1; k <= total_sketches_count; ++k) {
// The random number of distinct register_ids that should appear k times.
ASSIGN_OR_RETURN(int64_t noise_register_count_for_bucket_k,
Expand All @@ -172,21 +174,28 @@ absl::StatusOr<int64_t> AddReachOnlyBlindedHistogramNoise(
// The prefix is to ensure the value is not in the regular id space.
std::string register_id =
absl::StrCat("blinded_histogram_noise",
protocol_cryptor.NextRandomBigNumAsString());
helper.GetProtocolCryptor().NextRandomBigNumAsString());
ASSIGN_OR_RETURN(std::string register_id_ec,
protocol_cryptor.MapToCurve(register_id));
// Add k registers with the same register_id.
helper.GetProtocolCryptor().MapToCurve(register_id));
for (int j = 0; j < k; ++j) {
// Add register_id
RETURN_IF_ERROR(EncryptCompositeElGamalAndWriteToString(
protocol_cryptor, CompositeType::kFull, register_id_ec, pos, data));
pos += kBytesPerCipherText;

++noise_register_added;
register_id_ecs.push_back(register_id_ec);
}
noise_register_added += k;
}
}

absl::AnyInvocable<absl::Status(ProtocolCryptor&, size_t)> f =
[&](ProtocolCryptor& cryptor, size_t index) -> absl::Status {
size_t current_pos = pos + kBytesPerCipherText * index;
// Add register_id
RETURN_IF_ERROR(EncryptCompositeElGamalAndWriteToString(
helper.GetProtocolCryptor(), CompositeType::kFull,
register_id_ecs[index], current_pos, data));
current_pos += kBytesPerCipherText;
return absl::OkStatus();
};
RETURN_IF_ERROR(helper.Execute(noise_register_added, f));

return noise_register_added;
}

Expand Down Expand Up @@ -396,9 +405,9 @@ absl::StatusOr<CompleteReachOnlySetupPhaseResponse> CompleteReachOnlySetupPhase(
ASSIGN_OR_RETURN(
int64_t blinded_histogram_noise_count,
AddReachOnlyBlindedHistogramNoise(
multithreading_helper->GetProtocolCryptor(),
noise_parameters.total_sketches_count(), *blind_histogram_noiser,
pos, *response_crv, excessive_noise_count));
*multithreading_helper, noise_parameters.total_sketches_count(),
*blind_histogram_noiser, pos, *response_crv,
excessive_noise_count));
pos += kBytesPerCipherText * blinded_histogram_noise_count;
// 2. Add noise for publisher noise. Publisher noise count is at least 1.
ASSIGN_OR_RETURN(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,28 +329,27 @@ class TestData {
EXPECT_THAT(complete_setup_phase_response_2.combined_register_vector(),
IsBlockSorted(kBytesPerEncryptedRegister));

// Setup phase at Duchy 3.
// We assume all test data comes from duchy 1 in the test, so there is only
// noise from duchy 3 (if configured)
// Combine all CRVs.
std::string combine_data = absl::StrCat(
complete_setup_phase_response_1.combined_register_vector(),
complete_setup_phase_response_2.combined_register_vector());

// Setup phase at Duchy 3 (The aggregator).
// Duchy 1 and 2 send their modified combined_register_vectors to Duchy 3.
CompleteSetupPhaseRequest complete_setup_phase_request_3;
if (reach_noise_parameters != nullptr) {
*complete_setup_phase_request_3.mutable_noise_parameters() =
*reach_noise_parameters;
}
complete_setup_phase_request_3.set_noise_mechanism(noise_mechanism);
complete_setup_phase_request_3.set_parallelism(kParallelism);
complete_setup_phase_request_3.set_combined_register_vector(combine_data);

ASSIGN_OR_RETURN(CompleteSetupPhaseResponse complete_setup_phase_response_3,
CompleteSetupPhase(complete_setup_phase_request_3));
EXPECT_THAT(complete_setup_phase_response_3.combined_register_vector(),
IsBlockSorted(kBytesPerEncryptedRegister));

// Combine all CRVs.
std::string combine_data = absl::StrCat(
complete_setup_phase_response_1.combined_register_vector(),
complete_setup_phase_response_2.combined_register_vector(),
complete_setup_phase_response_3.combined_register_vector());

// Execution phase one at duchy 1 (non-aggregator).
CompleteExecutionPhaseOneRequest complete_execution_phase_one_request_1;
*complete_execution_phase_one_request_1.mutable_local_el_gamal_key_pair() =
Expand All @@ -360,7 +359,7 @@ class TestData {
complete_execution_phase_one_request_1.set_curve_id(kTestCurveId);
complete_execution_phase_one_request_1.set_parallelism(kParallelism);
complete_execution_phase_one_request_1.set_combined_register_vector(
combine_data);
complete_setup_phase_response_3.combined_register_vector());
ASSIGN_OR_RETURN(
CompleteExecutionPhaseOneResponse
complete_execution_phase_one_response_1,
Expand Down

0 comments on commit d1f5d00

Please sign in to comment.