123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- #include <stdio.h>
- template <typename T>
- Duoram<T>::Duoram(int player, size_t size) : player(player),
- oram_size(size), p0_blind(blind), p1_blind(peer_blinded_db) {
- if (player < 2) {
- database.resize(size);
- blind.resize(size);
- peer_blinded_db.resize(size);
- } else {
- p0_blind.resize(size);
- p1_blind.resize(size);
- }
- }
- template <typename T>
- void Duoram<T>::dump() const
- {
- for (size_t i=0; i<oram_size; ++i) {
- if (player < 2) {
- printf("%04lx %016lx %016lx %016lx\n",
- i, database[i].share(), blind[i].share(),
- peer_blinded_db[i].share());
- } else {
- printf("%04lx %016lx %016lx\n",
- i, p0_blind[i].share(), p1_blind[i].share());
- }
- }
- printf("\n");
- }
- template <typename T>
- std::vector<T> Duoram<T>::Shape::reconstruct() const
- {
- int player = tio.player();
- std::vector<T> res;
- res.resize(duoram.size());
-
- if (player == 1) {
- tio.queue_peer(duoram.database.data(), duoram.size()*sizeof(T));
- } else if (player == 0) {
- tio.recv_peer(res.data(), duoram.size()*sizeof(T));
- for(size_t i=0;i<duoram.size();++i) {
- res[i] += duoram.database[i];
- }
- }
-
-
- return res;
- }
- template <typename T>
- T Duoram<T>::Shape::reconstruct(const T& share) const
- {
- int player = tio.player();
- T res;
-
- if (player == 1) {
- tio.queue_peer(&share, sizeof(T));
- } else if (player == 0) {
- tio.recv_peer(&res, sizeof(T));
- res += share;
- }
-
-
- return res;
- }
- template <typename T>
- void Duoram<T>::Shape::set_shape_size(size_t sz)
- {
- shape_size = sz;
-
-
-
- if (sz > 1) {
- addr_size = 64-__builtin_clzll(sz-1);
- addr_mask = address_t((size_t(1)<<addr_size)-1);
- } else {
- addr_size = 0;
- addr_mask = 0;
- }
- }
- template <typename T>
- Duoram<T>::Flat::Flat(Duoram &duoram, MPCTIO &tio, yield_t &yield,
- size_t start, size_t len) : Shape(*this, duoram, tio, yield)
- {
- size_t parentsize = duoram.size();
- if (start > parentsize) {
- start = parentsize;
- }
- this->start = start;
- size_t maxshapesize = parentsize - start;
- if (len > maxshapesize || len == 0) {
- len = maxshapesize;
- }
- this->set_shape_size(len);
- }
- template <typename T>
- Duoram<T>::Shape::MemRefAS::operator T()
- {
- T res;
- int player = shape.tio.player();
- if (player < 2) {
-
- RDPFTriple dt = shape.tio.rdpftriple(shape.addr_size);
-
- RegAS indoffset = idx;
- indoffset -= dt.as_target;
-
- RDPFPair dp(std::move(dt), 0, player == 0 ? 2 : 1);
-
- shape.tio.queue_peer(&indoffset, BITBYTES(shape.addr_size));
- shape.tio.queue_server(&indoffset, BITBYTES(shape.addr_size));
- shape.yield();
-
- RegAS peerindoffset;
- shape.tio.recv_peer(&peerindoffset, BITBYTES(shape.addr_size));
-
- auto indshift = combine(indoffset, peerindoffset, shape.addr_size);
-
- StreamEval ev(dp, -indshift, shape.tio.aes_ops());
- for (size_t i=0; i<shape.shape_size; ++i) {
- auto L = ev.next();
-
- auto [V0, V1] = dp.unit<T>(L);
-
-
- auto [DB, BL, PBD] = shape.get_comp(i);
- res += (DB + PBD) * V0.share() - BL * (V1-V0).share();
- }
-
- T gamma;
- shape.tio.iostream_server() >> gamma;
- res += gamma;
- } else {
-
- RDPFPair dp = shape.tio.rdpfpair(shape.addr_size);
- RegAS p0indoffset, p1indoffset;
-
-
- shape.tio.recv_p0(&p0indoffset, BITBYTES(shape.addr_size));
- shape.tio.recv_p1(&p1indoffset, BITBYTES(shape.addr_size));
- auto indshift = combine(p0indoffset, p1indoffset, shape.addr_size);
-
- T gamma0, gamma1;
- StreamEval ev(dp, -indshift, shape.tio.aes_ops());
- for (size_t i=0; i<shape.shape_size; ++i) {
- auto L = ev.next();
-
- auto [V0, V1] = dp.unit<T>(L);
-
-
- auto [BL0, BL1] = shape.get_server(i);
- gamma0 -= BL0 * V1.share();
- gamma1 -= BL1 * V0.share();
- }
-
- T rho;
- rho.randomize();
- gamma0 += rho;
- gamma1 -= rho;
-
- shape.tio.iostream_p0() << gamma0;
- shape.tio.iostream_p1() << gamma1;
- }
- return res;
- }
- template <typename T>
- typename Duoram<T>::Shape::MemRefAS
- &Duoram<T>::Shape::MemRefAS::operator+=(const T& M)
- {
- int player = shape.tio.player();
- if (player < 2) {
-
- RDPFTriple dt = shape.tio.rdpftriple(shape.addr_size);
-
- RegAS indoffset = idx;
- indoffset -= dt.as_target;
- auto Moffset = std::make_tuple(M, M, M);
- Moffset -= dt.scaled_value<T>();
-
-
- shape.tio.queue_peer(&indoffset, BITBYTES(shape.addr_size));
- shape.tio.iostream_peer() << Moffset;
- shape.tio.queue_server(&indoffset, BITBYTES(shape.addr_size));
- shape.tio.iostream_server() << std::get<1>(Moffset) <<
- std::get<2>(Moffset);
- shape.yield();
-
- RegAS peerindoffset;
- std::tuple<T,T,T> peerMoffset;
- shape.tio.recv_peer(&peerindoffset, BITBYTES(shape.addr_size));
- shape.tio.iostream_peer() >> peerMoffset;
-
- auto indshift = combine(indoffset, peerindoffset, shape.addr_size);
- auto Mshift = combine(Moffset, peerMoffset);
-
- StreamEval ev(dt, -indshift, shape.tio.aes_ops());
- for (size_t i=0; i<shape.shape_size; ++i) {
- auto L = ev.next();
-
- auto [V0, V1, V2] = dt.scaled<T>(L) + dt.unit<T>(L) * Mshift;
-
-
- auto [DB, BL, PBD] = shape.get_comp(i);
- DB += V0;
- if (player == 0) {
- BL -= V1;
- PBD += V2-V0;
- } else {
- BL -= V2;
- PBD += V1-V0;
- }
- }
- } else {
-
- RDPFPair dp = shape.tio.rdpfpair(shape.addr_size);
- RegAS p0indoffset, p1indoffset;
- std::tuple<T,T> p0Moffset, p1Moffset;
-
-
- shape.tio.recv_p0(&p0indoffset, BITBYTES(shape.addr_size));
- shape.tio.iostream_p0() >> p0Moffset;
- shape.tio.recv_p1(&p1indoffset, BITBYTES(shape.addr_size));
- shape.tio.iostream_p1() >> p1Moffset;
- auto indshift = combine(p0indoffset, p1indoffset, shape.addr_size);
- auto Mshift = combine(p0Moffset, p1Moffset);
-
- StreamEval ev(dp, -indshift, shape.tio.aes_ops());
- for (size_t i=0; i<shape.shape_size; ++i) {
- auto L = ev.next();
-
- auto V = dp.scaled<T>(L) + dp.unit<T>(L) * Mshift;
-
-
-
- shape.get_server(i) -= V;
- }
- }
- return *this;
- }
|