mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-09 13:37:58 -05:00
110 lines
3.1 KiB
C++
110 lines
3.1 KiB
C++
/*
|
|
* PersonalPrep.cpp
|
|
*
|
|
*/
|
|
|
|
#ifndef GC_PERSONALPREP_HPP_
|
|
#define GC_PERSONALPREP_HPP_
|
|
|
|
#include "PersonalPrep.h"
|
|
|
|
namespace GC
|
|
{
|
|
|
|
template<class T>
|
|
PersonalPrep<T>::PersonalPrep(DataPositions& usage, int input_player) :
|
|
BufferPrep<T>(usage), input_player(input_player)
|
|
{
|
|
assert((input_player >= 0) or (input_player == SECURE));
|
|
}
|
|
|
|
template<class T>
|
|
void PersonalPrep<T>::buffer_personal_triples()
|
|
{
|
|
buffer_personal_triples(OnlineOptions::singleton.batch_size);
|
|
}
|
|
|
|
template<class T>
|
|
void PersonalPrep<T>::buffer_personal_triples(size_t batch_size, ThreadQueues* queues)
|
|
{
|
|
TripleShuffleSacrifice<T> sacri;
|
|
batch_size = max(batch_size, (size_t)sacri.minimum_n_outputs()) + sacri.C;
|
|
vector<array<T, 3>> triples(batch_size);
|
|
|
|
if (queues)
|
|
{
|
|
PersonalTripleJob job(&triples, input_player);
|
|
int start = queues->distribute(job, batch_size);
|
|
buffer_personal_triples(triples, start, batch_size);
|
|
queues->wrap_up(job);
|
|
}
|
|
else
|
|
buffer_personal_triples(triples, 0, batch_size);
|
|
|
|
auto &party = ShareThread<typename T::whole_type>::s();
|
|
assert(party.P != 0);
|
|
assert(party.MC != 0);
|
|
auto& MC = party.MC->get_part_MC();
|
|
auto& P = *party.P;
|
|
GlobalPRNG G(P);
|
|
vector<T> shares;
|
|
for (int i = 0; i < sacri.C; i++)
|
|
{
|
|
int challenge = G.get_uint(triples.size());
|
|
for (auto& x : triples[challenge])
|
|
shares.push_back(x);
|
|
triples.erase(triples.begin() + challenge);
|
|
}
|
|
PointerVector<typename T::open_type> opened;
|
|
MC.POpen(opened, shares, P);
|
|
for (int i = 0; i < sacri.C; i++)
|
|
{
|
|
array<typename T::open_type, 3> triple({{opened.next(), opened.next(),
|
|
opened.next()}});
|
|
if (triple[0] * triple[1] != triple[2])
|
|
{
|
|
cout << triple[2] << " != " << triple[0] * triple[1] << " = "
|
|
<< triple[0] << " * " << triple[1] << endl;
|
|
throw runtime_error("personal triple incorrect");
|
|
}
|
|
}
|
|
|
|
this->triples.insert(this->triples.end(), triples.begin(), triples.end());
|
|
}
|
|
|
|
template<class T>
|
|
void PersonalPrep<T>::buffer_personal_triples(vector<array<T, 3>>& triples,
|
|
size_t begin, size_t end)
|
|
{
|
|
#ifdef VERBOSE_EDA
|
|
fprintf(stderr, "personal triples %zu to %zu\n", begin, end);
|
|
RunningTimer timer;
|
|
#endif
|
|
auto& party = ShareThread<typename T::whole_type>::s();
|
|
auto& MC = party.MC->get_part_MC();
|
|
auto& P = *party.P;
|
|
assert(input_player < P.num_players());
|
|
typename T::Input input(MC, *this, P);
|
|
input.reset_all(P);
|
|
for (size_t i = begin; i < end; i++)
|
|
{
|
|
typename T::open_type x[2];
|
|
for (int j = 0; j < 2; j++)
|
|
this->get_input(triples[i][j], x[j], input_player);
|
|
if (P.my_num() == input_player)
|
|
input.add_mine(x[0] * x[1], T::default_length);
|
|
else
|
|
input.add_other(input_player);
|
|
}
|
|
input.exchange();
|
|
for (size_t i = begin; i < end; i++)
|
|
triples[i][2] = input.finalize(input_player, T::default_length);
|
|
#ifdef VERBOSE_EDA
|
|
fprintf(stderr, "personal triples took %f seconds\n", timer.elapsed());
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|