Skip to content

Commit

Permalink
Update function signatures of UDP InputProcessor
Browse files Browse the repository at this point in the history
Summary:
Updates the signatures of `CompactionBasedInputProcessor` functions to slightly change the workflow of `getPlaintextData` logic, as well as adding the data structs that will be used for serialization / deserialization logic in `compactData`

Rather than relying on the `getUnionMap` to shuffle the data in place, it will instead assume that the method for generation of `unionMap` is randomly secure. The high level algorithm is as follows:

1. Generate a random permutation of PID elements (i.e. `[1,3,4,0,2]` indicates the order of PID's in shuffled data)
2. Create the union map where -1 indicates dummy row, and `value > 0` indicates the index of that row in plaintext data after applying permutation to PID's (i.e. if PID `1` and `3` are dummy rows the map is `[1, -1, 2,-1,0]`). Not that the `maximumVal+1` (3) indicates the number of partner input rows. Each value appears once in the `unionMap`
3. In the prepare plaintext data step, it will generate a reverse unionMap without dummy rows. The plaintext data will be serialized by iterating through the reverse map in order and taking the input data at that location (i.e. `[4, 0, 2]`).

{F785701567}

Reviewed By: chennyc

Differential Revision: D40687410

fbshipit-source-id: 82f622ce1cbe94eb5ec091196a19b471c10834d6
  • Loading branch information
Tal Davidi authored and facebook-github-bot committed Oct 26, 2022
1 parent afe31a1 commit 35a2529
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,14 @@ class CompactionBasedInputProcessor : public IInputProcessor<schedulerId> {
auto unionMap = shuffleAndGetUnionMap();
auto intersectionMap = getIntersectionMap(unionMap);

auto plaintextData = preparePlaintextData();
auto plaintextData = preparePlaintextData(unionMap);

compactData(intersectionMap, plaintextData);
extractCompactedData();
auto publisherPartnerJointMetadataShares =
compactData(intersectionMap, plaintextData);

extractCompactedData(
std::get<0>(publisherPartnerJointMetadataShares),
std::get<1>(publisherPartnerJointMetadataShares));
}

const LiftGameProcessedData<schedulerId>& getLiftGameProcessedData()
Expand All @@ -59,26 +63,58 @@ class CompactionBasedInputProcessor : public IInputProcessor<schedulerId> {
}

private:
// shuffles the input data and returns the union map
struct PartnerRow {
bool anyValidPurchaseTimestamp;
uint32_t cohortGroupId;
};

struct PartnerConversionRow {
uint32_t purchaseTimestamp;
uint32_t thresholdTimestamp;
int32_t purchaseValue;
int64_t purchaseValueSquared;
};

struct PublisherRow {
bool breakdownId;
bool controlPopulation;
bool isValidOpportunityTimestamp;
bool testReach;
uint32_t opportunityTimestamp;
};

// Update the values if changing the structs above. This class handles it's
// own serialization / deserialization. using sizeof() will not work because a
// bool will take 1 byte in memory
const int PARTNER_ROW_SIZE_BYTES = 5;
const int PARTNER_CONVERSION_ROW_SIZE_BYTES = 20;
const int PUBLISHER_ROW_BYTES = 5;

// unionMap[i] = j indicates PID i will point to index j in plaintext data
// note that j in [0,intersectionSize) rather than [0, unionSize)
// unionMap[i] = -1 indicates PID i is a dummy row
std::vector<int32_t> shuffleAndGetUnionMap();

// runs adapter algorithm to get intsersection map
std::vector<int32_t> getIntersectionMap(const std::vector<int32_t>& unionMap);

// Serializes input data into rows of fixed width. Different implementations
// for publisher and partner
std::vector<std::vector<unsigned char>> preparePlaintextData();
std::vector<std::vector<unsigned char>> preparePlaintextData(
const std::vector<int32_t>& unionMap);

/* Runs data processor algorithm to get intersected secret share data
* intersectionMap is the map of other player. Results are stored in
* publisherDataShares_ and partnerDataShares_
* intersectionMap is the map of other player. First element is publisher
* metadata shares, second is partner metadata shares
*/
void compactData(
std::pair<SecString, SecString> compactData(
const std::vector<int32_t>& intersectionMap,
const std::vector<std::vector<unsigned char>>& plaintextData);

// deserializes the compacted data into MPC structured values
void extractCompactedData();
void extractCompactedData(
const SecString& publisherDataShares,
const SecString& partnerDataShares);

int32_t myRole_;

Expand All @@ -90,9 +126,6 @@ class CompactionBasedInputProcessor : public IInputProcessor<schedulerId> {
InputData inputData_;
int32_t numConversionsPerUser_;

SecString publisherDataShares_;
SecString partnerDataShares_;

LiftGameProcessedData<schedulerId> liftGameProcessedData_;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,61 @@ CompactionBasedInputProcessor<schedulerId>::getIntersectionMap(

template <int schedulerId>
std::vector<std::vector<unsigned char>>
CompactionBasedInputProcessor<schedulerId>::preparePlaintextData() {
CompactionBasedInputProcessor<schedulerId>::preparePlaintextData(
const std::vector<int32_t>& unionMap) {
throw std::runtime_error("Not implemented");
}

template <int schedulerId>
void CompactionBasedInputProcessor<schedulerId>::compactData(
std::pair<
typename CompactionBasedInputProcessor<schedulerId>::SecString,
typename CompactionBasedInputProcessor<schedulerId>::SecString>
CompactionBasedInputProcessor<schedulerId>::compactData(
const std::vector<int32_t>& intersectionMap,
const std::vector<std::vector<unsigned char>>& plaintextData) {
int32_t myDataWidth = plaintextData[0].size();
int32_t myRows = plaintextData.size();

auto publisherDataSize = common::shareIntFrom<
auto publisherRows = common::shareIntFrom<
schedulerId,
sizeof(myDataWidth) * 8,
sizeof(myRows) * 8,
common::PUBLISHER,
common::PARTNER>(myRole_, myDataWidth);
common::PARTNER>(myRole_, myRows);

auto partnerDataSize = common::shareIntFrom<
auto partnerRows = common::shareIntFrom<
schedulerId,
sizeof(myDataWidth) * 8,
sizeof(myRows) * 8,
common::PARTNER,
common::PUBLISHER>(myRole_, myDataWidth);
common::PUBLISHER>(myRole_, myRows);
SecString publisherDataShares;
SecString partnerDataShares;

if (myRole_ == common::PUBLISHER) {
publisherDataShares_ =
publisherDataShares =
dataProcessor_->processMyData(plaintextData, intersectionMap.size());
partnerDataShares_ = dataProcessor_->processPeersData(
inputData_.getNumRows(), intersectionMap, partnerDataSize);
partnerDataShares = dataProcessor_->processPeersData(
partnerRows,
intersectionMap,
PARTNER_CONVERSION_ROW_SIZE_BYTES * numConversionsPerUser_ +
PARTNER_ROW_SIZE_BYTES);
} else if (myRole_ == common::PARTNER) {
publisherDataShares_ = dataProcessor_->processPeersData(
inputData_.getNumRows(), intersectionMap, publisherDataSize);
partnerDataShares_ =
publisherDataShares = dataProcessor_->processPeersData(
publisherRows, intersectionMap, PUBLISHER_ROW_BYTES);
partnerDataShares =
dataProcessor_->processMyData(plaintextData, intersectionMap.size());
}

return std::make_pair<
typename CompactionBasedInputProcessor<schedulerId>::SecString,
typename CompactionBasedInputProcessor<schedulerId>::SecString>(
std::move(publisherDataShares), std::move(partnerDataShares));
}

template <int schedulerId>
void CompactionBasedInputProcessor<schedulerId>::extractCompactedData() {
void CompactionBasedInputProcessor<schedulerId>::extractCompactedData(
const typename CompactionBasedInputProcessor<schedulerId>::SecString&
publisherDataShares,
const typename CompactionBasedInputProcessor<schedulerId>::SecString&
partnerDataShares) {
throw std::runtime_error("Not implemented");
}

Expand Down

0 comments on commit 35a2529

Please sign in to comment.