Skip to content

Commit

Permalink
Create dummy compactor (#253)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #253

Create an insecure version of a compactor network. Our dummy compactor first reveals both metadata and labels and then selects only data that are labeled as 1.

Update: the dummy compactor is updated according to the new compactor API.

Reviewed By: chualynn

Differential Revision: D37364313

fbshipit-source-id: 99e0e602559c695eb88260152a5c9db204ac4b8c
  • Loading branch information
arisa77 authored and facebook-github-bot committed Jun 30, 2022
1 parent 52fde4e commit 1d58088
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 1 deletion.
73 changes: 73 additions & 0 deletions fbpcf/mpc_std_lib/compactor/DummyCompactor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include "fbpcf/mpc_std_lib/compactor/ICompactor.h"

namespace fbpcf::mpc_std_lib::compactor::insecure {

/*
* This compactor reveals both metadata (i.e., batches) and labels and selects
* all items whose labels are assigned to 1. It is only meant to be used as a
* placeholder in tests.
*/

/*
* We assume that there are two parties. In our implementation, a party with a
* smaller id is assigned to party0 and the other party is assigned to party1.
*/

template <typename T, typename LabelT>
class DummyCompactor final : public ICompactor<T, LabelT> {
public:
explicit DummyCompactor(int myId, int partnerId)
: myId_(myId), partnerId_(partnerId) {}
std::pair<T, LabelT> compaction(
const T& src,
const LabelT& label,
bool /*shouldRevealSize*/) const override {
auto party0 =
(myId_ < partnerId_) ? myId_ : partnerId_; // a party with a smaller id
auto party1 =
(myId_ < partnerId_) ? partnerId_ : myId_; // a party with a larger id

// reveal labels and src to both parties
auto revealedLabel0 =
label.openToParty(party0).getValue(); // reveal to Party0
auto revealedLabel1 =
label.openToParty(party1).getValue(); // reveal to Party1
auto plaintextLabel = (myId_ == party0) ? revealedLabel0 : revealedLabel1;

auto revealedSrc0 = src.openToParty(party0).getValue(); // reveal to Party0
auto revealedSrc1 = src.openToParty(party1).getValue(); // reveal to Party1
auto plaintextSrc = (myId_ == party0) ? revealedSrc0 : revealedSrc1;

// select items whose labels are 1.
auto compactifiedSrc = plaintextSrc;
auto compactifiedLabel = plaintextLabel;
size_t inputSize = plaintextLabel.size();
size_t outputSize = 0;
for (size_t j = 0; j < inputSize; j++) {
if (plaintextLabel[j]) {
compactifiedSrc[outputSize] = std::move(compactifiedSrc.at(j));
compactifiedLabel[outputSize] = std::move(plaintextLabel.at(j));
outputSize++;
}
}
compactifiedSrc.resize(outputSize); // compactify
compactifiedLabel.resize(outputSize); // compactify

return std::make_pair(
T(compactifiedSrc, party0), LabelT(compactifiedLabel, party0));
}

private:
int myId_;
int partnerId_;
};
} // namespace fbpcf::mpc_std_lib::compactor::insecure
30 changes: 30 additions & 0 deletions fbpcf/mpc_std_lib/compactor/DummyCompactorFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include "fbpcf/mpc_std_lib/compactor/DummyCompactor.h"
#include "fbpcf/mpc_std_lib/compactor/ICompactorFactory.h"

namespace fbpcf::mpc_std_lib::compactor::insecure {

template <typename T, typename LabelT>
class DummyCompactorFactory final : public ICompactorFactory<T, LabelT> {
public:
explicit DummyCompactorFactory(int myId, int partnerId)
: myId_(myId), partnerId_(partnerId) {}

std::unique_ptr<ICompactor<T, LabelT>> create() override {
return std::make_unique<DummyCompactor<T, LabelT>>(myId_, partnerId_);
}

private:
int myId_;
int partnerId_;
};

} // namespace fbpcf::mpc_std_lib::compactor::insecure
2 changes: 1 addition & 1 deletion fbpcf/mpc_std_lib/compactor/ICompactor.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

#pragma once

#include "fbpcf/mpc_std_lib/util/util.h"
namespace fbpcf::mpc_std_lib::compactor {

/*
Expand Down
142 changes: 142 additions & 0 deletions fbpcf/mpc_std_lib/compactor/test/CompactorTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <future>
#include <memory>
#include <random>
#include <unordered_map>

#include "fbpcf/engine/communication/test/AgentFactoryCreationHelper.h"
#include "fbpcf/mpc_std_lib/compactor/DummyCompactor.h"
#include "fbpcf/mpc_std_lib/compactor/DummyCompactorFactory.h"
#include "fbpcf/mpc_std_lib/compactor/ICompactor.h"
#include "fbpcf/mpc_std_lib/compactor/ICompactorFactory.h"
#include "fbpcf/mpc_std_lib/util/test/util.h"
#include "fbpcf/mpc_std_lib/util/util.h"
#include "fbpcf/scheduler/SchedulerHelper.h"
#include "fbpcf/test/TestHelper.h"

namespace fbpcf::mpc_std_lib::compactor {

const int8_t width = 63;
template <int schedulerId>
using SecUnsignedIntBatch = frontend::Integer<
frontend::Secret<frontend::Batch<frontend::Unsigned<width>>>,
schedulerId>;
template <int schedulerId>
using SecBitBatch = frontend::Bit<true, schedulerId, true>;

std::vector<bool> generateRandomBinaryVector(size_t size) {
std::random_device rd;
std::mt19937_64 e(rd());
std::uniform_int_distribution<int32_t> randomBit(0, 1);

std::vector<bool> rst(size);
for (size_t i = 0; i < size; i++) {
rst[i] = randomBit(e);
}
return rst;
}

/*
* Given a vector, an element i is attributed to a
* binary label 0/1. Return only elements that are labeled as 1.
*/
std::vector<uint64_t> getOnesValues(
const std::vector<uint64_t>& src,
const std::vector<bool>& label) {
std::vector<uint64_t> rst;
for (size_t i = 0; i < src.size(); i++) {
if (label.at(i)) {
rst.push_back(src[i]);
}
}
return rst;
}

/*
* It generates metadata and binary labels for inputs to a compaction algorithm
* and obtain expected results of metadata.
*/
std::tuple<std::vector<uint64_t>, std::vector<bool>, std::vector<uint64_t>>
generateTestData(size_t batchSize) {
std::vector<uint64_t> testData(batchSize);
std::iota(testData.begin(), testData.end(), 1);
auto testLabel = generateRandomBinaryVector(batchSize);
auto expectedData = getOnesValues(testData, testLabel);

return {testData, testLabel, expectedData};
}

template <int schedulerId, typename T>
std::tuple<std::vector<T>, std::vector<bool>> task(
std::unique_ptr<
ICompactor<SecUnsignedIntBatch<schedulerId>, SecBitBatch<schedulerId>>>
compactor,
const std::vector<T>& src,
const std::vector<bool>& label,
bool shouldRevealSize) {
// generate secret values
auto secSrc = SecUnsignedIntBatch<schedulerId>(src, 0);
auto secLabel = SecBitBatch<schedulerId>(label, 0);

// run a compaction algorithm
auto [compactifiedSrc, compactifiedLabel] =
compactor->compaction(secSrc, secLabel, shouldRevealSize);

// get plaintext results
auto rstSrc = compactifiedSrc.openToParty(0).getValue();
auto rstLabel = compactifiedLabel.openToParty(0).getValue();

return {rstSrc, rstLabel};
}

TEST(compactorTest, testDummyCompactor) {
auto agentFactories = engine::communication::getInMemoryAgentFactory(2);
setupRealBackend<0, 1>(*agentFactories[0], *agentFactories[1]);

insecure::DummyCompactorFactory<SecUnsignedIntBatch<0>, SecBitBatch<0>>
factory0(0, 1);
insecure::DummyCompactorFactory<SecUnsignedIntBatch<1>, SecBitBatch<1>>
factory1(1, 0);

auto compactor0 = factory0.create();
auto compactor1 = factory1.create();

size_t batchSize = 5;
bool shouldRevealSize = true;

auto [testData, testLabel, expectedData] = generateTestData(batchSize);
size_t expectedOutputSize = expectedData.size();

auto future0 = std::async(
task<0, uint64_t>,
std::move(compactor0),
testData,
testLabel,
shouldRevealSize);
auto future1 = std::async(
task<1, uint64_t>,
std::move(compactor1),
testData,
testLabel,
shouldRevealSize);
auto [rstData0, rstLabel0] = future0.get();
future1.get();

ASSERT_EQ(rstLabel0.size(), expectedOutputSize);
testVectorEq(rstLabel0, std::vector<bool>(expectedOutputSize, true));
ASSERT_EQ(rstData0.size(), expectedOutputSize);
testVectorEq(rstData0, expectedData);
}

} // namespace fbpcf::mpc_std_lib::compactor

0 comments on commit 1d58088

Please sign in to comment.