forked from FudanMPL/Garnet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
YaoGarbler.cpp
executable file
·122 lines (110 loc) · 2.89 KB
/
YaoGarbler.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* YaoGarbler.cpp
*
*/
#include "YaoGarbler.h"
#include "YaoGate.h"
#include "GC/ThreadMaster.hpp"
#include "GC/Processor.hpp"
#include "GC/Program.hpp"
#include "GC/Machine.hpp"
#include "GC/Secret.hpp"
#include "GC/Thread.hpp"
#include "Tools/MMO.hpp"
#include "YaoWire.hpp"
thread_local YaoGarbler* YaoGarbler::singleton = 0;
YaoGarbler::YaoGarbler(int thread_num, YaoGarbleMaster& master) :
GC::Thread<GC::Secret<YaoGarbleWire>>(thread_num, master),
YaoCommon<YaoGarbleWire>(master),
master(master),
and_proc_timer(CLOCK_PROCESS_CPUTIME_ID),
and_main_thread_timer(CLOCK_THREAD_CPUTIME_ID),
player(master.N, 1, "thread" + to_string(thread_num)),
ot_ext(OTExtensionWithMatrix::setup(player,
master.get_delta().get<__m128i>(), SENDER, true))
{
prng.ReSeed();
set_n_program_threads(master.machine.nthreads);
this->init(*this);
if (continuous())
taint();
else
{
processor.out.activate(false);
if (not master.opts.cmd_private_output_file.empty())
cerr << "Garbling party cannot output with one-shot computation"
<< endl;
}
}
YaoGarbler::~YaoGarbler()
{
#ifdef VERBOSE
cerr << "Number of AND gates: " << counter << endl;
#endif
#ifdef YAO_TIMINGS
cout << "AND time: " << and_timer.elapsed() << endl;
cout << "AND process timer: " << and_proc_timer.elapsed() << endl;
cout << "AND main thread timer: " << and_main_thread_timer.elapsed() << endl;
cout << "AND prepare timer: " << and_prepare_timer.elapsed() << endl;
cout << "AND wait timer: " << and_wait_timer.elapsed() << endl;
for (auto& x : timers)
cout << x.first << " time:" << x.second.elapsed() << endl;
#endif
}
void YaoGarbler::run(GC::Program& program)
{
singleton = this;
GC::BreakType b = GC::TIME_BREAK;
while(GC::DONE_BREAK != b)
{
try
{
b = program.execute(processor, master.memory, -1);
}
catch (needs_cleaning& e)
{
if (not continuous())
throw runtime_error("run-time branching impossible with garbling at once");
processor.PC--;
}
send(*P);
gates.clear();
output_masks.clear();
if (continuous())
process_receiver_inputs();
}
}
void YaoGarbler::post_run()
{
if (not continuous())
{
P->send_long(1, YaoCommon::DONE);
process_receiver_inputs();
}
}
void YaoGarbler::send(Player& P)
{
#ifdef DEBUG_YAO
cerr << "sending " << gates.size() << " gates and " <<
output_masks.size() << " output masks at " << processor.PC << endl;
#endif
P.send_long(1, YaoCommon::MORE);
size_t size = gates.size();
P.send_to(1, gates);
gates.allocate(2 * size);
P.send_to(1, output_masks);
}
void YaoGarbler::process_receiver_inputs()
{
while (not receiver_input_keys.empty())
{
vector<Key>& inputs = receiver_input_keys.front();
BitVector _;
ot_ext.extend_correlated(inputs.size(), _);
octetStream os;
for (size_t i = 0; i < inputs.size(); i++)
os.serialize(inputs[i] ^ ot_ext.senderOutputMatrices[0][i]);
player.send(os);
receiver_input_keys.pop_front();
}
}