mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-09 13:37:58 -05:00
248 lines
7.0 KiB
C++
248 lines
7.0 KiB
C++
/*
|
|
* MalRepRingPrep.cpp
|
|
*
|
|
*/
|
|
|
|
#ifndef PROTOCOlS_MALREPRINGPREP_HPP_
|
|
#define PROTOCOlS_MALREPRINGPREP_HPP_
|
|
|
|
#include "MalRepRingPrep.h"
|
|
#include "MaliciousRepPrep.h"
|
|
#include "MalRepRingOptions.h"
|
|
#include "ShuffleSacrifice.h"
|
|
#include "Processor/OnlineOptions.h"
|
|
|
|
#include "ShuffleSacrifice.hpp"
|
|
|
|
template<class T>
|
|
MalRepRingPrep<T>::MalRepRingPrep(SubProcessor<T>*, DataPositions& usage) :
|
|
BufferPrep<T>(usage)
|
|
{
|
|
}
|
|
|
|
template<class T>
|
|
RingOnlyBitsFromSquaresPrep<T>::RingOnlyBitsFromSquaresPrep(SubProcessor<T>*,
|
|
DataPositions& usage) :
|
|
BufferPrep<T>(usage)
|
|
{
|
|
}
|
|
|
|
template<class T>
|
|
SimplerMalRepRingPrep<T>::SimplerMalRepRingPrep(SubProcessor<T>* proc,
|
|
DataPositions& usage) :
|
|
BufferPrep<T>(usage), MalRepRingPrep<T>(proc, usage),
|
|
RingOnlyBitsFromSquaresPrep<T>(proc, usage)
|
|
{
|
|
}
|
|
|
|
template<class T>
|
|
MalRepRingPrepWithBits<T>::MalRepRingPrepWithBits(SubProcessor<T>* proc,
|
|
DataPositions& usage) :
|
|
BufferPrep<T>(usage), BitPrep<T>(proc, usage),
|
|
RingPrep<T>(proc, usage),
|
|
MaliciousDabitOnlyPrep<T>(proc, usage),
|
|
MaliciousRingPrep<T>(proc, usage), MalRepRingPrep<T>(proc, usage),
|
|
RingOnlyBitsFromSquaresPrep<T>(proc, usage),
|
|
SimplerMalRepRingPrep<T>(proc, usage)
|
|
{
|
|
}
|
|
|
|
template<class T>
|
|
void MalRepRingPrep<T>::buffer_triples()
|
|
{
|
|
if (MalRepRingOptions::singleton.shuffle)
|
|
shuffle_buffer_triples();
|
|
else
|
|
simple_buffer_triples();
|
|
}
|
|
|
|
template<class T>
|
|
void MalRepRingPrep<T>::buffer_squares()
|
|
{
|
|
typedef typename T::prep_type prep_type;
|
|
DataPositions _;
|
|
MaliciousRepPrep<prep_type> prep(_);
|
|
assert(this->proc != 0);
|
|
prep.init_honest(this->proc->P);
|
|
prep.buffer_size = BaseMachine::batch_size<T>(DATA_SQUARE,
|
|
this->buffer_size);
|
|
prep.buffer_squares();
|
|
for (auto& x : prep.squares)
|
|
this->squares.push_back({{x[0], x[1]}});
|
|
prep.squares.clear();
|
|
}
|
|
|
|
template<class T>
|
|
void MalRepRingPrep<T>::simple_buffer_triples()
|
|
{
|
|
typedef typename T::prep_type prep_type;
|
|
DataPositions _;
|
|
MaliciousRepPrep<prep_type> prep(_);
|
|
assert(this->proc != 0);
|
|
prep.init_honest(this->proc->P);
|
|
prep.buffer_size = this->buffer_size;
|
|
prep.buffer_triples();
|
|
for (auto& x : prep.triples)
|
|
this->triples.push_back({{x[0], x[1], x[2]}});
|
|
prep.triples.clear();
|
|
}
|
|
|
|
template<class T>
|
|
void MalRepRingPrep<T>::shuffle_buffer_triples()
|
|
{
|
|
assert(T::SECURITY <= OnlineOptions::singleton.security_parameter);
|
|
assert(this->proc != 0);
|
|
typename T::MAC_Check MC;
|
|
shuffle_triple_generation(this->triples, this->proc->P, MC);
|
|
}
|
|
|
|
template<class T>
|
|
void shuffle_triple_generation(vector<array<T, 3>>& triples, Player& P,
|
|
typename T::MAC_Check& MC, int n_bits = -1, ThreadQueues* queues = 0)
|
|
{
|
|
RunningTimer timer;
|
|
TripleShuffleSacrifice<T> sacrifice;
|
|
vector<array<T, 3>> check_triples;
|
|
int buffer_size = sacrifice.minimum_n_inputs(OnlineOptions::singleton.batch_size);
|
|
|
|
// optimistic triple generation
|
|
Replicated<T> protocol(P);
|
|
generate_triples(check_triples, buffer_size, &protocol, n_bits);
|
|
|
|
#ifdef VERBOSE_SHUFFLE
|
|
double gen_time = timer.elapsed();
|
|
cerr << "Triple generation took " << gen_time << " seconds" << endl;
|
|
#endif
|
|
|
|
sacrifice.triple_sacrifice(triples, check_triples, P, MC, queues);
|
|
|
|
#ifdef VERBOSE_SHUFFLE
|
|
cerr << "Triple sacrifice took " << timer.elapsed() - gen_time << " seconds" << endl;
|
|
cerr << "Total shuffle triple generation took " << timer.elapsed() << " seconds" << endl;
|
|
#endif
|
|
}
|
|
|
|
template<class T>
|
|
TripleShuffleSacrifice<T>::TripleShuffleSacrifice()
|
|
{
|
|
}
|
|
|
|
template<class T>
|
|
TripleShuffleSacrifice<T>::TripleShuffleSacrifice(int B, int C) :
|
|
ShuffleSacrifice(B, C)
|
|
{
|
|
}
|
|
|
|
template<class T>
|
|
void TripleShuffleSacrifice<T>::triple_sacrifice(vector<array<T, 3>>& triples,
|
|
vector<array<T, 3>>& check_triples, Player& P,
|
|
typename T::MAC_Check& MC, ThreadQueues* queues)
|
|
{
|
|
int buffer_size = check_triples.size();
|
|
size_t N = (buffer_size - C) / B;
|
|
|
|
shuffle(check_triples, P);
|
|
|
|
// opening C triples
|
|
vector<T> shares;
|
|
for (int i = 0; i < C; i++)
|
|
{
|
|
for (int j = 0; j < 3; j++)
|
|
shares.push_back(check_triples.back()[j]);
|
|
check_triples.pop_back();
|
|
}
|
|
vector<typename T::open_type> opened;
|
|
MC.POpen(opened, shares, P);
|
|
for (int i = 0; i < C; i++)
|
|
if (typename T::clear(opened[3 * i] * opened[3 * i + 1]) != opened[3 * i + 2])
|
|
throw Offline_Check_Error("shuffle opening");
|
|
|
|
// triples might be same as check_triples
|
|
if (triples.size() < N)
|
|
triples.resize(N);
|
|
|
|
if (queues)
|
|
{
|
|
TripleSacrificeJob job(&triples, &check_triples);
|
|
int start = queues->distribute(job, N);
|
|
triple_sacrifice(triples, check_triples, P, MC, start, N);
|
|
if (start)
|
|
queues->wrap_up(job);
|
|
}
|
|
else
|
|
triple_sacrifice(triples, check_triples, P, MC, 0, N);
|
|
|
|
triples.resize(N);
|
|
}
|
|
|
|
template<class T>
|
|
void TripleShuffleSacrifice<T>::triple_sacrifice(vector<array<T, 3>>& triples,
|
|
vector<array<T, 3>>& check_triples, Player& P,
|
|
typename T::MAC_Check& MC, int begin, int end)
|
|
{
|
|
#ifdef VERBOSE_SHUFFLE
|
|
cerr << "sacrificing triples " << begin << " to " << end << endl;
|
|
#endif
|
|
// sacrifice buckets
|
|
vector<T> masked;
|
|
int buffer_size = check_triples.size();
|
|
int N = buffer_size / B;
|
|
int size = end - begin;
|
|
masked.reserve(2 * size);
|
|
assert(size_t(end * B) <= check_triples.size());
|
|
for (int i = begin; i < end; i++)
|
|
{
|
|
T& a = check_triples[i][0];
|
|
T& b = check_triples[i][1];
|
|
for (int j = 1; j < B; j++)
|
|
{
|
|
T& f = check_triples[i + N * j][0];
|
|
T& g = check_triples[i + N * j][1];
|
|
masked.push_back(a - f);
|
|
masked.push_back(b - g);
|
|
}
|
|
}
|
|
vector<typename T::open_type> opened;
|
|
MC.POpen(opened, masked, P);
|
|
auto it = opened.begin();
|
|
vector<T> checks;
|
|
checks.reserve(2 * size);
|
|
for (int i = begin; i < end; i++)
|
|
{
|
|
T& b = check_triples[i][1];
|
|
T& c = check_triples[i][2];
|
|
for (int j = 1; j < B; j++)
|
|
{
|
|
T& f = check_triples[i + N * j][0];
|
|
T& h = check_triples[i + N * j][2];
|
|
typename T::open_type& rho = *(it++);
|
|
typename T::open_type& sigma = *(it++);
|
|
checks.push_back(c - h - b * rho - f * sigma);
|
|
}
|
|
triples[i] = check_triples[i];
|
|
}
|
|
MC.CheckFor(0, checks, P);
|
|
}
|
|
|
|
template<class T>
|
|
void RingOnlyBitsFromSquaresPrep<T>::buffer_bits()
|
|
{
|
|
auto proc = this->proc;
|
|
assert(proc != 0);
|
|
typedef typename T::SquareToBitShare BitShare;
|
|
typename BitShare::MAC_Check MC;
|
|
DataPositions usage;
|
|
typename BitShare::SquarePrep prep(0, usage);
|
|
SubProcessor<BitShare> bit_proc(MC, prep, proc->P);
|
|
prep.set_proc(&bit_proc);
|
|
bits_from_square_in_ring(this->bits, this->buffer_size, &prep);
|
|
}
|
|
|
|
template<class T>
|
|
void MalRepRingPrep<T>::buffer_inputs(int player)
|
|
{
|
|
this->buffer_inputs_as_usual(player, this->proc);
|
|
}
|
|
|
|
#endif
|