From b99e2de60f7102b155f571681ee4208064f2d72c Mon Sep 17 00:00:00 2001 From: Vincent Ehrmanntraut Date: Mon, 9 Dec 2024 11:48:18 +0100 Subject: [PATCH] Semi-honest replicated sharing now has parallel shuffling --- Processor/Processor.hpp | 2 +- Programs/Source/test_permute.mpc | 3 +- Protocols/Rep3Shuffler.h | 2 +- Protocols/Rep3Shuffler.hpp | 105 +++++++++++++++++++++++++++++-- Protocols/SecureShuffle.h | 2 +- Protocols/SecureShuffle.hpp | 2 +- 6 files changed, 106 insertions(+), 10 deletions(-) diff --git a/Processor/Processor.hpp b/Processor/Processor.hpp index dbe93b87..1290ff97 100644 --- a/Processor/Processor.hpp +++ b/Processor/Processor.hpp @@ -896,7 +896,7 @@ void SubProcessor::apply_shuffle(const Instruction& instruction, const auto& args = instruction.get_start(); const auto n_shuffles = args.size() / 5; - vector sizes(n_shuffles, 0); + vector sizes(n_shuffles, 0); vector destinations(n_shuffles, 0); vector sources(n_shuffles, 0); vector unit_sizes(n_shuffles, 0); diff --git a/Programs/Source/test_permute.mpc b/Programs/Source/test_permute.mpc index 1d33a122..2565adbd 100644 --- a/Programs/Source/test_permute.mpc +++ b/Programs/Source/test_permute.mpc @@ -55,4 +55,5 @@ def test_allocator(): arr3.secure_permute(p3) # test_allocator() -test_case([5, 10, 20], 10) \ No newline at end of file +test_case([5, 10, 20], 10) +test_case([5, 10, 15, 20], 20) \ No newline at end of file diff --git a/Protocols/Rep3Shuffler.h b/Protocols/Rep3Shuffler.h index 78b25c3a..b3de8496 100644 --- a/Protocols/Rep3Shuffler.h +++ b/Protocols/Rep3Shuffler.h @@ -29,7 +29,7 @@ public: void apply(vector& a, size_t n, int unit_size, size_t output_base, size_t input_base, shuffle_type& shuffle, bool reverse); - void applyMultiple(vector& a, vector& sizes, vector& destinations, vector& sources, + void applyMultiple(vector& a, vector& sizes, vector& destinations, vector& sources, vector& unit_sizes, vector& handles, vector& reverse, store_type& store); void inverse_permutation(vector& stack, size_t n, size_t output_base, diff --git a/Protocols/Rep3Shuffler.hpp b/Protocols/Rep3Shuffler.hpp index 25181afe..0b7ecd16 100644 --- a/Protocols/Rep3Shuffler.hpp +++ b/Protocols/Rep3Shuffler.hpp @@ -120,17 +120,112 @@ void Rep3Shuffler::apply(vector& a, size_t n, int unit_size, } template -void Rep3Shuffler::applyMultiple(vector& a, vector& sizes, vector& destinations, vector& sources, - vector& unit_sizes, vector& handles, vector& reverse, store_type& store) { +void Rep3Shuffler::applyMultiple(vector& a, vector& sizes, vector& destinations, vector& sources, + vector& unit_sizes, vector& handles, vector& reverses, store_type& store) { const auto n_shuffles = sizes.size(); assert(sources.size() == n_shuffles); assert(destinations.size() == n_shuffles); assert(unit_sizes.size() == n_shuffles); assert(handles.size() == n_shuffles); - assert(reverse.size() == n_shuffles); + assert(reverses.size() == n_shuffles); - for (size_t i = 0; i < n_shuffles; i++) { - this->apply(a, sizes[i], unit_sizes[i], destinations[i], sources[i], store.get(handles[i]), reverse[i]); + assert(proc.P.num_players() == 3); + assert(not T::malicious); + assert(not T::dishonest_majority); + + // for (size_t i = 0; i < n_shuffles; i++) { + // this->apply(a, sizes[i], unit_sizes[i], destinations[i], sources[i], store.get(handles[i]), reverses[i]); + // } + + vector> to_shuffle; + for (size_t current_shuffle = 0; current_shuffle < n_shuffles; current_shuffle++) { + assert(sizes[current_shuffle] % unit_sizes[current_shuffle] == 0); + vector x; + for (size_t j = 0; j < sizes[current_shuffle]; j++) + x.push_back(a[sources[current_shuffle] + j]); + to_shuffle.push_back(x); + + const auto shuffle = store.get(handles[current_shuffle]); + if (shuffle.empty()) + throw runtime_error("shuffle has been deleted"); + } + + + typename T::Input input(proc); + + for (int pass = 0; pass < 3; pass++) + { + input.reset_all(proc.P); + + for (size_t current_shuffle = 0; current_shuffle < n_shuffles; current_shuffle++) { + const auto n = sizes[current_shuffle]; + const auto unit_size = unit_sizes[current_shuffle]; + const auto shuffle = store.get(handles[current_shuffle]); + const auto reverse = reverses[current_shuffle]; + const auto current_to_shuffle = to_shuffle[current_shuffle]; + + vector to_share(n); + int i; + if (reverse) + i = 2 - pass; + else + i = pass; + + if (proc.P.get_player(i) == 0) { + for (size_t j = 0; j < n / unit_size; j++) + for (int k = 0; k < unit_size; k++) + if (reverse) + to_share.at(j * unit_size + k) = current_to_shuffle.at( + shuffle[0].at(j) * unit_size + k).sum(); + else + to_share.at(shuffle[0].at(j) * unit_size + k) = + current_to_shuffle.at(j * unit_size + k).sum(); + } + else if (proc.P.get_player(i) == 1) + { + for (size_t j = 0; j < n / unit_size; j++) + for (int k = 0; k < unit_size; k++) + if (reverse) + to_share[j * unit_size + k] = current_to_shuffle[shuffle[1][j] * unit_size + k][0]; + else + to_share[shuffle[1][j] * unit_size + k] = current_to_shuffle[j * unit_size + k][0]; + } + + if (proc.P.get_player(i) < 2) + for (auto& x : to_share) + input.add_mine(x); + for (int k = 0; k < 2; k++) + input.add_other((-i + 3 + k) % 3); + } + + input.exchange(); + to_shuffle.clear(); + + for (size_t current_shuffle = 0; current_shuffle < n_shuffles; current_shuffle++) { + const auto n = sizes[current_shuffle]; + const auto reverse = reverses[current_shuffle]; + + int i; + if (reverse) + i = 2 - pass; + else + i = pass; + + vector tmp; + for (size_t j = 0; j < n; j++) + { + T x = input.finalize((-i + 3) % 3) + input.finalize((-i + 4) % 3); + tmp.push_back(x); + } + to_shuffle.push_back(tmp); + } + } + + for (size_t current_shuffle = 0; current_shuffle < n_shuffles; current_shuffle++) { + const auto n = sizes[current_shuffle]; + + for (size_t i = 0; i < n; i++) + a[destinations[current_shuffle] + i] = to_shuffle[current_shuffle][i]; } } diff --git a/Protocols/SecureShuffle.h b/Protocols/SecureShuffle.h index d2f5cfc0..d73189d6 100644 --- a/Protocols/SecureShuffle.h +++ b/Protocols/SecureShuffle.h @@ -104,7 +104,7 @@ public: void apply(vector& a, size_t n, int unit_size, size_t output_base, size_t input_base, shuffle_type& shuffle, bool reverse); - void applyMultiple(vector& a, vector& sizes, vector& destinations, vector& sources, + void applyMultiple(vector& a, vector& sizes, vector& destinations, vector& sources, vector& unit_sizes, vector& handles, vector& reverse, store_type& store); /** diff --git a/Protocols/SecureShuffle.hpp b/Protocols/SecureShuffle.hpp index 46c2f5f7..f45a63e1 100644 --- a/Protocols/SecureShuffle.hpp +++ b/Protocols/SecureShuffle.hpp @@ -98,7 +98,7 @@ void SecureShuffle::apply(vector& a, size_t n, int unit_size, size_t outpu template -void SecureShuffle::applyMultiple(vector& a, vector& sizes, vector& destinations, vector& sources, +void SecureShuffle::applyMultiple(vector& a, vector& sizes, vector& destinations, vector& sources, vector& unit_sizes, vector& handles, vector& reverse, store_type& store) { const auto n_shuffles = sizes.size(); assert(sources.size() == n_shuffles);