123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- #include "mpcops.hpp"
- #include "bitutils.hpp"
- void mpc_mul(MPCTIO &tio, yield_t &yield,
- RegAS &z, RegAS x, RegAS y,
- nbits_t nbits)
- {
- const value_t mask = MASKBITS(nbits);
-
- mpc_cross(tio, yield, z, x, y, nbits);
-
- z.ashare = (z.ashare + x.ashare * y.ashare) & mask;
- }
- void mpc_cross(MPCTIO &tio, yield_t &yield,
- RegAS &z, RegAS x, RegAS y,
- nbits_t nbits)
- {
- const value_t mask = MASKBITS(nbits);
- size_t nbytes = BITBYTES(nbits);
- auto [X, Y, Z] = tio.multtriple(yield);
-
- value_t blind_x = (x.ashare + X) & mask;
- value_t blind_y = (y.ashare + Y) & mask;
- tio.queue_peer(&blind_x, nbytes);
- tio.queue_peer(&blind_y, nbytes);
- yield();
-
- value_t peer_blind_x=0, peer_blind_y=0;
- tio.recv_peer(&peer_blind_x, nbytes);
- tio.recv_peer(&peer_blind_y, nbytes);
- z.ashare = ((x.ashare * peer_blind_y) - (Y * peer_blind_x) + Z) & mask;
- }
- void mpc_valuemul(MPCTIO &tio, yield_t &yield,
- RegAS &z, value_t x,
- nbits_t nbits, bool tally)
- {
- const value_t mask = MASKBITS(nbits);
- size_t nbytes = BITBYTES(nbits);
- auto [X, Z] = tio.halftriple(yield, tally);
-
- value_t blind_x = (x + X) & mask;
- tio.queue_peer(&blind_x, nbytes);
- yield();
-
- value_t peer_blind_y=0;
- tio.recv_peer(&peer_blind_y, nbytes);
- if (tio.player() == 0) {
- z.ashare = ((x * peer_blind_y) + Z) & mask;
- } else if (tio.player() == 1) {
- z.ashare = ((-X * peer_blind_y) + Z) & mask;
- }
- }
- void mpc_flagmult(MPCTIO &tio, yield_t &yield,
- RegAS &z, RegBS f, RegAS y,
- nbits_t nbits)
- {
- const value_t mask = MASKBITS(nbits);
-
- value_t bs_fval = value_t(f.bshare);
- RegAS fval;
- fval.ashare = bs_fval;
- mpc_cross(tio, yield, z, y*(1-2*bs_fval), fval, nbits);
-
- z.ashare = (z.ashare + bs_fval*y.ashare) & mask;
-
-
-
-
- }
- void mpc_select(MPCTIO &tio, yield_t &yield,
- RegAS &z, RegBS f, RegAS x, RegAS y,
- nbits_t nbits)
- {
- const value_t mask = MASKBITS(nbits);
-
- mpc_flagmult(tio, yield, z, f, y-x, nbits);
- z.ashare = (z.ashare + x.ashare) & mask;
- }
- void mpc_select(MPCTIO &tio, yield_t &yield,
- RegXS &z, RegBS f, RegXS x, RegXS y,
- nbits_t nbits)
- {
- const value_t mask = MASKBITS(nbits);
- size_t nbytes = BITBYTES(nbits);
-
- value_t fext = (-value_t(f.bshare)) & mask;
-
- auto [X, Y, Z] = tio.valselecttriple(yield);
- bit_t blind_f = f.bshare ^ X;
- value_t d = (x.xshare ^ y.xshare) & mask;
- value_t blind_d = (d ^ Y) & mask;
-
- tio.queue_peer(&blind_f, sizeof(blind_f));
- tio.queue_peer(&blind_d, nbytes);
- yield();
-
- bit_t peer_blind_f = 0;
- value_t peer_blind_d;
- tio.recv_peer(&peer_blind_f, sizeof(peer_blind_f));
- peer_blind_f &= 1;
- tio.recv_peer(&peer_blind_d, nbytes);
- peer_blind_d &= mask;
-
- value_t peer_blind_fext = -value_t(peer_blind_f);
- z.xshare = ((fext & peer_blind_d) ^ (Y & peer_blind_fext) ^
- (fext & d) ^ (Z ^ x.xshare)) & mask;
- }
- void mpc_select(MPCTIO &tio, yield_t &yield,
- RegBS &z, RegBS f, RegBS x, RegBS y)
- {
-
- mpc_and(tio, yield, z, f, y^x);
- z ^= x;
- }
- void mpc_oswap(MPCTIO &tio, yield_t &yield,
- RegAS &x, RegAS &y, RegBS f,
- nbits_t nbits)
- {
- const value_t mask = MASKBITS(nbits);
-
-
- RegAS s;
- mpc_flagmult(tio, yield, s, f, y-x, nbits);
- x.ashare = (x.ashare + s.ashare) & mask;
- y.ashare = (y.ashare - s.ashare) & mask;
- }
- void mpc_xs_to_as(MPCTIO &tio, yield_t &yield,
- RegAS &as_x, RegXS xs_x,
- nbits_t nbits, bool tally)
- {
- const value_t mask = MASKBITS(nbits);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- RegAS as_bitand[nbits-1];
- std::vector<coro_t> coroutines;
- for (nbits_t i=0; i<nbits-1; ++i) {
- coroutines.emplace_back(
- [&tio, &as_bitand, &xs_x, i, nbits, tally](yield_t &yield) {
- mpc_valuemul(tio, yield, as_bitand[i],
- (xs_x.xshare>>i)&1, nbits, tally);
- });
- }
- run_coroutines(yield, coroutines);
- value_t as_C = 0;
- for (nbits_t i=0; i<nbits-1; ++i) {
- as_C += (as_bitand[i].ashare<<(i+1));
- }
- as_x.ashare = (xs_x.xshare - as_C) & mask;
- }
- value_t mpc_reconstruct(MPCTIO &tio, yield_t &yield,
- RegXS x, nbits_t nbits)
- {
- RegXS res;
- size_t nbytes = BITBYTES(nbits);
- if (tio.player() < 2) {
- tio.queue_peer(&x, nbytes);
- yield();
- tio.recv_peer(&res, nbytes);
- res ^= x;
- } else {
- yield();
- }
- return res.xshare;
- }
- value_t mpc_reconstruct(MPCTIO &tio, yield_t &yield,
- RegAS x, nbits_t nbits)
- {
- RegAS res;
- size_t nbytes = BITBYTES(nbits);
- if (tio.player() < 2) {
- tio.queue_peer(&x, nbytes);
- yield();
- tio.recv_peer(&res, nbytes);
- res += x;
- } else {
- yield();
- }
- return res.ashare;
- }
- bool mpc_reconstruct(MPCTIO &tio, yield_t &yield, RegBS f)
- {
- RegBS res;
- if (tio.player() < 2) {
- tio.queue_peer(&f, 1);
- yield();
- tio.recv_peer(&res, 1);
- res ^= f;
- } else {
- yield();
- }
- return res.bshare;
- }
- void mpc_reconstruct_choice(MPCTIO &tio, yield_t &yield,
- DPFnode &z, RegBS f, DPFnode x, DPFnode y)
- {
-
- DPFnode fext = if128_mask[f.bshare];
-
- auto [X, Y, Z] = tio.nodeselecttriple(yield);
- bit_t blind_f = f.bshare ^ X;
- DPFnode d = x ^ y;
- DPFnode blind_d = d ^ Y;
-
- tio.queue_peer(&blind_f, sizeof(blind_f));
- tio.queue_peer(&blind_d, sizeof(blind_d));
- yield();
-
- bit_t peer_blind_f = 0;
- DPFnode peer_blind_d;
- tio.recv_peer(&peer_blind_f, sizeof(peer_blind_f));
- tio.recv_peer(&peer_blind_d, sizeof(peer_blind_d));
-
- DPFnode peer_blind_fext = if128_mask[peer_blind_f];
- DPFnode zshare =
- (fext & peer_blind_d) ^ (Y & peer_blind_fext) ^
- (fext & d) ^ (Z ^ x);
-
- tio.queue_peer(&zshare, sizeof(zshare));
- yield();
- DPFnode peer_zshare;
- tio.recv_peer(&peer_zshare, sizeof(peer_zshare));
- z = zshare ^ peer_zshare;
- }
- void mpc_and(MPCTIO &tio, yield_t &yield,
- RegBS &z, RegBS x, RegBS y)
- {
-
- auto T = tio.bitselecttriple(yield);
- bit_t blind_x = x.bshare ^ T.X;
- bit_t blind_y = y.bshare ^ T.Y;
-
- uint8_t v = (blind_x << 1) | blind_y;
- tio.queue_peer(&v, sizeof(v));
- yield();
-
- bit_t peer_blind_x = 0;
- bit_t peer_blind_y = 0;
- uint8_t peer_v = 0;
- tio.recv_peer(&peer_v, sizeof(peer_v));
- peer_blind_x = (peer_v >> 1) & 1;
- peer_blind_y = peer_v & 1;
-
- z.bshare = (x.bshare & peer_blind_y) ^ (T.Y & peer_blind_x) ^
- (x.bshare & y.bshare) ^ T.Z;
- }
- void mpc_or(MPCTIO &tio, yield_t &yield,
- RegBS &z, RegBS x, RegBS y)
- {
- if (tio.player() == 0) {
- x.bshare = !x.bshare;
- y.bshare = !y.bshare;
- }
- mpc_and(tio, yield, z, x, y);
- if (tio.player() == 0) {
- z.bshare = !z.bshare;
- }
- }
|