#include // arc4random_buf #include "rdpf.hpp" #include "bitutils.hpp" #include "mpcops.hpp" #include "aes.hpp" #include "prg.hpp" // Don't warn if we never actually use these functions static void dump_node(DPFnode node, const char *label = NULL) __attribute__ ((unused)); static void dump_level(DPFnode *nodes, size_t num, const char *label = NULL) __attribute__ ((unused)); static void dump_node(DPFnode node, const char *label) { if (label) printf("%s: ", label); for(int i=0;i<16;++i) { printf("%02x", ((unsigned char *)&node)[15-i]); } printf("\n"); } static void dump_level(DPFnode *nodes, size_t num, const char *label) { if (label) printf("%s:\n", label); for (size_t i=0;i coroutines; coroutines.emplace_back( [&](yield_t &yield) { tio.queue_peer(&our_parity_bit, 1); yield(); uint8_t peer_parity_byte; tio.recv_peer(&peer_parity_byte, 1); peer_parity_bit = peer_parity_byte & 1; }); coroutines.emplace_back( [&](yield_t &yield) { mpc_reconstruct_choice(tio, yield, CW, bs_choice, (R ^ our_parity), L); }); run_coroutines(yield, coroutines); bool parity_bit = our_parity_bit ^ peer_parity_bit; cfbits |= (size_t(parity_bit)<depth(); size_t num_leaves = size_t(1)< index goes for example from (in binary) // 010010110 -> 010011000, then index_xor will be // 000001110 and how_many_1_bits will be 3. // That indicates that path[depth-3] was a left child, and now // we need to change it to a right child by descending right // from path[depth-4], and then filling the path after that with // left children. path[depth-how_many_1_bits] = descend(path[depth-how_many_1_bits-1], depth-how_many_1_bits-1, 1, op_counter); for (nbits_t i = depth-how_many_1_bits; i < depth-1; ++i) { path[i+1] = descend(path[i], i, 0, op_counter); } lastindex = index; expansion[index++] = descend(path[depth-1], depth-1, 0, op_counter); expansion[index++] = descend(path[depth-1], depth-1, 1, op_counter); } delete[] path; } // Construct three RDPFs of the given depth all with the same randomly // generated target index. RDPFTriple::RDPFTriple(MPCTIO &tio, yield_t &yield, nbits_t depth, bool save_expansion) { // Pick a random XOR share of the target xs_target.randomize(depth); // Now create three RDPFs with that target, and also convert the XOR // shares of the target to additive shares std::vector coroutines; for (int i=0;i<3;++i) { coroutines.emplace_back( [&, i](yield_t &yield) { dpf[i] = RDPF(tio, yield, xs_target, depth, save_expansion); }); } coroutines.emplace_back( [&](yield_t &yield) { mpc_xs_to_as(tio, yield, as_target, xs_target, depth); }); run_coroutines(yield, coroutines); } RDPFTriple::node RDPFTriple::descend(const RDPFTriple::node &parent, nbits_t parentdepth, bit_t whichchild, size_t &op_counter) const { auto [P0, P1, P2] = parent; DPFnode C0, C1, C2; C0 = dpf[0].descend(P0, parentdepth, whichchild, op_counter); C1 = dpf[1].descend(P1, parentdepth, whichchild, op_counter); C2 = dpf[2].descend(P2, parentdepth, whichchild, op_counter); return std::make_tuple(C0,C1,C2); } RDPFPair::node RDPFPair::descend(const RDPFPair::node &parent, nbits_t parentdepth, bit_t whichchild, size_t &op_counter) const { auto [P0, P1] = parent; DPFnode C0, C1; C0 = dpf[0].descend(P0, parentdepth, whichchild, op_counter); C1 = dpf[1].descend(P1, parentdepth, whichchild, op_counter); return std::make_tuple(C0,C1); }