|
@@ -1077,55 +1077,48 @@ static void sort_test(MPCIO &mpcio,
|
|
++args;
|
|
++args;
|
|
}
|
|
}
|
|
|
|
|
|
- int num_threads = opts.num_threads;
|
|
|
|
- boost::asio::thread_pool pool(num_threads);
|
|
|
|
- for (int thread_num = 0; thread_num < num_threads; ++thread_num) {
|
|
|
|
- boost::asio::post(pool, [&mpcio, thread_num, depth, len] {
|
|
|
|
- MPCTIO tio(mpcio, thread_num);
|
|
|
|
- run_coroutines(tio, [&tio, depth, len] (yield_t &yield) {
|
|
|
|
- address_t size = address_t(1)<<depth;
|
|
|
|
- // size_t &aes_ops = tio.aes_ops();
|
|
|
|
- Duoram<RegAS> oram(tio.player(), size);
|
|
|
|
- auto A = oram.flat(tio, yield);
|
|
|
|
- A.explicitonly(true);
|
|
|
|
- // Initialize the memory to random values in parallel
|
|
|
|
- std::vector<coro_t> coroutines;
|
|
|
|
- for (address_t i=0; i<size; ++i) {
|
|
|
|
- coroutines.emplace_back(
|
|
|
|
- [&A, i](yield_t &yield) {
|
|
|
|
- auto Acoro = A.context(yield);
|
|
|
|
- RegAS v;
|
|
|
|
- v.randomize(62);
|
|
|
|
- Acoro[i] += v;
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- run_coroutines(yield, coroutines);
|
|
|
|
- A.bitonic_sort(0, len);
|
|
|
|
|
|
+ MPCTIO tio(mpcio, 0, opts.num_threads);
|
|
|
|
+ run_coroutines(tio, [&tio, depth, len] (yield_t &yield) {
|
|
|
|
+ address_t size = address_t(1)<<depth;
|
|
|
|
+ // size_t &aes_ops = tio.aes_ops();
|
|
|
|
+ Duoram<RegAS> oram(tio.player(), size);
|
|
|
|
+ auto A = oram.flat(tio, yield);
|
|
|
|
+ A.explicitonly(true);
|
|
|
|
+ // Initialize the memory to random values in parallel
|
|
|
|
+ std::vector<coro_t> coroutines;
|
|
|
|
+ for (address_t i=0; i<size; ++i) {
|
|
|
|
+ coroutines.emplace_back(
|
|
|
|
+ [&A, i](yield_t &yield) {
|
|
|
|
+ auto Acoro = A.context(yield);
|
|
|
|
+ RegAS v;
|
|
|
|
+ v.randomize(62);
|
|
|
|
+ Acoro[i] += v;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ run_coroutines(yield, coroutines);
|
|
|
|
+ A.bitonic_sort(0, len);
|
|
|
|
+ if (depth <= 10) {
|
|
|
|
+ oram.dump();
|
|
|
|
+ }
|
|
|
|
+ auto check = A.reconstruct();
|
|
|
|
+ bool fail = false;
|
|
|
|
+ if (tio.player() == 0) {
|
|
|
|
+ for (address_t i=0;i<size;++i) {
|
|
if (depth <= 10) {
|
|
if (depth <= 10) {
|
|
- oram.dump();
|
|
|
|
|
|
+ printf("%04x %016lx\n", i, check[i].share());
|
|
}
|
|
}
|
|
- auto check = A.reconstruct();
|
|
|
|
- bool fail = false;
|
|
|
|
- if (tio.player() == 0) {
|
|
|
|
- for (address_t i=0;i<size;++i) {
|
|
|
|
- if (depth <= 10) {
|
|
|
|
- printf("%04x %016lx\n", i, check[i].share());
|
|
|
|
- }
|
|
|
|
- if (i>0 && i<len &&
|
|
|
|
- check[i].share() < check[i-1].share()) {
|
|
|
|
- fail = true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (fail) {
|
|
|
|
- printf("FAIL\n");
|
|
|
|
- } else {
|
|
|
|
- printf("PASS\n");
|
|
|
|
- }
|
|
|
|
|
|
+ if (i>0 && i<len &&
|
|
|
|
+ check[i].share() < check[i-1].share()) {
|
|
|
|
+ fail = true;
|
|
}
|
|
}
|
|
- });
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- pool.join();
|
|
|
|
|
|
+ }
|
|
|
|
+ if (fail) {
|
|
|
|
+ printf("FAIL\n");
|
|
|
|
+ } else {
|
|
|
|
+ printf("PASS\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
static void pad_test(MPCIO &mpcio,
|
|
static void pad_test(MPCIO &mpcio,
|
|
@@ -1156,7 +1149,7 @@ static void pad_test(MPCIO &mpcio,
|
|
A[i] = v;
|
|
A[i] = v;
|
|
}
|
|
}
|
|
A.explicitonly(false);
|
|
A.explicitonly(false);
|
|
- // Add 0 to A[0], which reblinds the whole database
|
|
|
|
|
|
+ // Obliviously add 0 to A[0], which reblinds the whole database
|
|
RegAS z;
|
|
RegAS z;
|
|
A[z] += z;
|
|
A[z] += z;
|
|
auto check = A.reconstruct();
|
|
auto check = A.reconstruct();
|
|
@@ -1179,8 +1172,12 @@ static void pad_test(MPCIO &mpcio,
|
|
}
|
|
}
|
|
printf("\n");
|
|
printf("\n");
|
|
for (address_t i=0; i<maxsize; ++i) {
|
|
for (address_t i=0; i<maxsize; ++i) {
|
|
|
|
+ value_t offset = 0xdeadbeef;
|
|
|
|
+ if (player) {
|
|
|
|
+ offset = -offset;
|
|
|
|
+ }
|
|
RegAS ind;
|
|
RegAS ind;
|
|
- ind.set(player*i);
|
|
|
|
|
|
+ ind.set(player*i+offset);
|
|
RegAS v = P[ind];
|
|
RegAS v = P[ind];
|
|
if (depth <= 10) {
|
|
if (depth <= 10) {
|
|
value_t vval = mpc_reconstruct(tio, yield, v);
|
|
value_t vval = mpc_reconstruct(tio, yield, v);
|
|
@@ -1214,74 +1211,85 @@ static void bsearch_test(MPCIO &mpcio,
|
|
++args;
|
|
++args;
|
|
}
|
|
}
|
|
|
|
|
|
- int num_threads = opts.num_threads;
|
|
|
|
- boost::asio::thread_pool pool(num_threads);
|
|
|
|
- for (int thread_num = 0; thread_num < num_threads; ++thread_num) {
|
|
|
|
- boost::asio::post(pool, [&mpcio, thread_num, depth, len, target] {
|
|
|
|
- MPCTIO tio(mpcio, thread_num);
|
|
|
|
- run_coroutines(tio, [&tio, depth, len, target] (yield_t &yield) {
|
|
|
|
- address_t size = address_t(1)<<depth;
|
|
|
|
- RegAS tshare;
|
|
|
|
- if (tio.player() == 2) {
|
|
|
|
- // Send shares of the target to the computational
|
|
|
|
- // players
|
|
|
|
- RegAS tshare0, tshare1;
|
|
|
|
- tshare0.randomize();
|
|
|
|
- tshare1.set(target-tshare0.share());
|
|
|
|
- tio.iostream_p0() << tshare0;
|
|
|
|
- tio.iostream_p1() << tshare1;
|
|
|
|
- printf("Using target = %016lx\n", target);
|
|
|
|
- yield();
|
|
|
|
- } else {
|
|
|
|
- // Get the share of the target
|
|
|
|
- tio.iostream_server() >> tshare;
|
|
|
|
- }
|
|
|
|
|
|
+ MPCTIO tio(mpcio, 0, opts.num_threads);
|
|
|
|
+ run_coroutines(tio, [&tio, depth, len, target] (yield_t &yield) {
|
|
|
|
+ RegAS tshare;
|
|
|
|
+ if (tio.player() == 2) {
|
|
|
|
+ // Send shares of the target to the computational
|
|
|
|
+ // players
|
|
|
|
+ RegAS tshare0, tshare1;
|
|
|
|
+ tshare0.randomize();
|
|
|
|
+ tshare1.set(target-tshare0.share());
|
|
|
|
+ tio.iostream_p0() << tshare0;
|
|
|
|
+ tio.iostream_p1() << tshare1;
|
|
|
|
+ printf("Using target = %016lx\n", target);
|
|
|
|
+ yield();
|
|
|
|
+ } else {
|
|
|
|
+ // Get the share of the target
|
|
|
|
+ tio.iostream_server() >> tshare;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Create a random database and sort it
|
|
|
|
+ // size_t &aes_ops = tio.aes_ops();
|
|
|
|
+ Duoram<RegAS> oram(tio.player(), len);
|
|
|
|
+ auto A = oram.flat(tio, yield);
|
|
|
|
+ A.explicitonly(true);
|
|
|
|
+ // Initialize the memory to random values in parallel
|
|
|
|
+ std::vector<coro_t> coroutines;
|
|
|
|
+ for (address_t i=0; i<len; ++i) {
|
|
|
|
+ coroutines.emplace_back(
|
|
|
|
+ [&A, i](yield_t &yield) {
|
|
|
|
+ auto Acoro = A.context(yield);
|
|
|
|
+ RegAS v;
|
|
|
|
+ v.randomize(62);
|
|
|
|
+ Acoro[i] += v;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ run_coroutines(yield, coroutines);
|
|
|
|
+ A.bitonic_sort(0, len);
|
|
|
|
+ A.explicitonly(false);
|
|
|
|
|
|
- // Create a random database and sort it
|
|
|
|
- // size_t &aes_ops = tio.aes_ops();
|
|
|
|
- Duoram<RegAS> oram(tio.player(), size);
|
|
|
|
- auto A = oram.flat(tio, yield);
|
|
|
|
- A.explicitonly(true);
|
|
|
|
- // Initialize the memory to random values in parallel
|
|
|
|
- std::vector<coro_t> coroutines;
|
|
|
|
- for (address_t i=0; i<size; ++i) {
|
|
|
|
- coroutines.emplace_back(
|
|
|
|
- [&A, i](yield_t &yield) {
|
|
|
|
- auto Acoro = A.context(yield);
|
|
|
|
- RegAS v;
|
|
|
|
- v.randomize(62);
|
|
|
|
- Acoro[i] += v;
|
|
|
|
- });
|
|
|
|
|
|
+ // Binary search for the target
|
|
|
|
+ RegAS tindex = A.obliv_binary_search(tshare);
|
|
|
|
+
|
|
|
|
+ // Check the answer
|
|
|
|
+ size_t size = size_t(1) << depth;
|
|
|
|
+ value_t checkindex = mpc_reconstruct(tio, yield, tindex);
|
|
|
|
+ value_t checktarget = mpc_reconstruct(tio, yield, tshare);
|
|
|
|
+ auto check = A.reconstruct();
|
|
|
|
+ bool fail = false;
|
|
|
|
+ if (tio.player() == 0) {
|
|
|
|
+ for (address_t i=0;i<len;++i) {
|
|
|
|
+ if (depth <= 10) {
|
|
|
|
+ printf("%c%04x %016lx\n",
|
|
|
|
+ (i == checkindex ? '*' : ' '),
|
|
|
|
+ i, check[i].share());
|
|
}
|
|
}
|
|
- run_coroutines(yield, coroutines);
|
|
|
|
- A.bitonic_sort(0, len);
|
|
|
|
-
|
|
|
|
- // Binary search for the target
|
|
|
|
- RegAS tindex = A.obliv_binary_search(tshare);
|
|
|
|
-
|
|
|
|
- // Check the answer
|
|
|
|
- if (tio.player() == 1) {
|
|
|
|
- tio.iostream_peer() << tindex;
|
|
|
|
- } else if (tio.player() == 0) {
|
|
|
|
- RegAS peer_tindex;
|
|
|
|
- tio.iostream_peer() >> peer_tindex;
|
|
|
|
- tindex += peer_tindex;
|
|
|
|
|
|
+ if (i>0 && i<len &&
|
|
|
|
+ check[i].share() < check[i-1].share()) {
|
|
|
|
+ fail = true;
|
|
}
|
|
}
|
|
- if (depth <= 10) {
|
|
|
|
- auto check = A.reconstruct();
|
|
|
|
- if (tio.player() == 0) {
|
|
|
|
- for (address_t i=0;i<size;++i) {
|
|
|
|
- printf("%04x %016lx\n", i, check[i].share());
|
|
|
|
- }
|
|
|
|
|
|
+ if (i == checkindex) {
|
|
|
|
+ // check[i] should be >= target, and check[i-1]
|
|
|
|
+ // should be < target
|
|
|
|
+ if ((i < len && check[i].share() < checktarget) ||
|
|
|
|
+ (i > 0 && check[i-1].share() >= checktarget)) {
|
|
|
|
+ fail = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (tio.player() == 0) {
|
|
|
|
- printf("Found index = %lx\n", tindex.share());
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- pool.join();
|
|
|
|
|
|
+ }
|
|
|
|
+ printf("Target = %016lx\n", checktarget);
|
|
|
|
+ printf("Found index = %02lx\n", checkindex);
|
|
|
|
+ if (checkindex > size) {
|
|
|
|
+ fail = true;
|
|
|
|
+ }
|
|
|
|
+ if (fail) {
|
|
|
|
+ printf("FAIL\n");
|
|
|
|
+ } else {
|
|
|
|
+ printf("PASS\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
void online_main(MPCIO &mpcio, const PRACOptions &opts, char **args)
|
|
void online_main(MPCIO &mpcio, const PRACOptions &opts, char **args)
|