|
@@ -193,7 +193,7 @@ inline typename RDPF<WIDTH>::LeafNode RDPF<WIDTH>::descend_to_leaf(
|
|
|
bool flag = get_lsb(parent);
|
|
|
prg(prgout, parent, whichchild, aes_ops);
|
|
|
if (flag) {
|
|
|
- LeafNode CW = li[0].leaf_cw;
|
|
|
+ LeafNode CW = li[maxdepth-parentdepth-1].leaf_cw;
|
|
|
LeafNode CWR = CW;
|
|
|
bit_t cfbit = !!(leaf_cfbits &
|
|
|
(value_t(1)<<(maxdepth-parentdepth-1)));
|
|
@@ -211,9 +211,15 @@ T& operator>>(T &is, RDPF<WIDTH> &rdpf)
|
|
|
is.read((char *)&rdpf.seed, sizeof(rdpf.seed));
|
|
|
rdpf.whichhalf = get_lsb(rdpf.seed);
|
|
|
uint8_t depth;
|
|
|
- // Add 64 to depth to indicate an expanded RDPF
|
|
|
+ // Add 64 to depth to indicate an expanded RDPF, and add 128 to
|
|
|
+ // indicate an incremental RDPF
|
|
|
is.read((char *)&depth, sizeof(depth));
|
|
|
bool read_expanded = false;
|
|
|
+ bool read_incremental = false;
|
|
|
+ if (depth > 128) {
|
|
|
+ read_incremental = true;
|
|
|
+ depth -= 128;
|
|
|
+ }
|
|
|
if (depth > 64) {
|
|
|
read_expanded = true;
|
|
|
depth -= 64;
|
|
@@ -227,19 +233,22 @@ T& operator>>(T &is, RDPF<WIDTH> &rdpf)
|
|
|
is.read((char *)&cw, sizeof(cw));
|
|
|
rdpf.cw.push_back(cw);
|
|
|
}
|
|
|
+ nbits_t num_leaflevels = read_incremental ? depth : 1;
|
|
|
+ rdpf.li.resize(num_leaflevels);
|
|
|
if (read_expanded) {
|
|
|
- rdpf.li[0].expansion.resize(1<<depth);
|
|
|
- is.read((char *)rdpf.li[0].expansion.data(),
|
|
|
- sizeof(rdpf.li[0].expansion[0])<<depth);
|
|
|
+ for(nbits_t i=0; i<num_leaflevels; ++i) {
|
|
|
+ nbits_t level = depth-i;
|
|
|
+ rdpf.li[i].expansion.resize(1<<level);
|
|
|
+ is.read((char *)rdpf.li[i].expansion.data(),
|
|
|
+ sizeof(rdpf.li[i].expansion[0])<<level);
|
|
|
+ }
|
|
|
}
|
|
|
value_t cfbits = 0;
|
|
|
is.read((char *)&cfbits, BITBYTES(depth-1));
|
|
|
rdpf.cfbits = cfbits;
|
|
|
- nbits_t num_leaflevels = 1;
|
|
|
value_t leaf_cfbits = 0;
|
|
|
is.read((char *)&leaf_cfbits, BITBYTES(num_leaflevels));
|
|
|
rdpf.leaf_cfbits = leaf_cfbits;
|
|
|
- rdpf.li.resize(num_leaflevels);
|
|
|
for (nbits_t i=0; i<num_leaflevels; ++i) {
|
|
|
is.read((char *)&rdpf.li[i].leaf_cw,
|
|
|
sizeof(rdpf.li[i].leaf_cw));
|
|
@@ -271,16 +280,23 @@ T& write_maybe_expanded(T &os, const RDPF<WIDTH> &rdpf,
|
|
|
write_expansion = true;
|
|
|
expanded_depth += 64;
|
|
|
}
|
|
|
+ // If we're writing an incremental RDPF, add 128 to depth
|
|
|
+ if (rdpf.li.size() > 1) {
|
|
|
+ expanded_depth += 128;
|
|
|
+ }
|
|
|
os.write((const char *)&expanded_depth, sizeof(expanded_depth));
|
|
|
for (uint8_t i=0; i<depth-1; ++i) {
|
|
|
os.write((const char *)&rdpf.cw[i], sizeof(rdpf.cw[i]));
|
|
|
}
|
|
|
+ nbits_t num_leaflevels = rdpf.li.size();
|
|
|
if (write_expansion) {
|
|
|
- os.write((const char *)rdpf.li[0].expansion.data(),
|
|
|
- sizeof(rdpf.li[0].expansion[0])<<depth);
|
|
|
+ for(nbits_t i=0; i<num_leaflevels; ++i) {
|
|
|
+ nbits_t level = depth-i;
|
|
|
+ os.write((const char *)rdpf.li[i].expansion.data(),
|
|
|
+ sizeof(rdpf.li[i].expansion[0])<<level);
|
|
|
+ }
|
|
|
}
|
|
|
os.write((const char *)&rdpf.cfbits, BITBYTES(depth-1));
|
|
|
- nbits_t num_leaflevels = 1;
|
|
|
os.write((const char *)&rdpf.leaf_cfbits, BITBYTES(num_leaflevels));
|
|
|
for (nbits_t i=0; i<num_leaflevels; ++i) {
|
|
|
os.write((const char *)&rdpf.li[i].leaf_cw,
|
|
@@ -802,7 +818,7 @@ static inline void create_level(MPCTIO &tio, yield_t &yield,
|
|
|
assert(low_sum & 1);
|
|
|
li.unit_sum_inverse = inverse_value_t(low_sum);
|
|
|
}
|
|
|
- } else if (level == depth-1) {
|
|
|
+ } else if constexpr (!std::is_same_v<NT, DPFnode>) {
|
|
|
yield();
|
|
|
}
|
|
|
}
|
|
@@ -839,7 +855,7 @@ RDPF<WIDTH>::RDPF(MPCTIO &tio, yield_t &yield,
|
|
|
DPFnode *nextlevel = new DPFnode[1];
|
|
|
nextlevel[0] = seed;
|
|
|
|
|
|
- li.resize(1);
|
|
|
+ li.resize(incremental ? depth : 1);
|
|
|
|
|
|
// Construct each intermediate level
|
|
|
while(level < depth) {
|
|
@@ -848,20 +864,21 @@ RDPF<WIDTH>::RDPF(MPCTIO &tio, yield_t &yield,
|
|
|
delete[] curlevel;
|
|
|
curlevel = nextlevel;
|
|
|
nextlevel = NULL;
|
|
|
- if (save_expansion && level == depth-1) {
|
|
|
- li[0].expansion.resize(1<<depth);
|
|
|
- leaflevel = li[0].expansion.data();
|
|
|
- } else if (level == depth-1) {
|
|
|
- leaflevel = new LeafNode[1<<depth];
|
|
|
- } else {
|
|
|
+ if (save_expansion && (incremental || level == depth-1)) {
|
|
|
+ li[depth-1-level].expansion.resize(1<<(level+1));
|
|
|
+ leaflevel = li[depth-1-level].expansion.data();
|
|
|
+ } else if (incremental || level == depth-1) {
|
|
|
+ leaflevel = new LeafNode[1<<(level+1)];
|
|
|
+ }
|
|
|
+ if (level < depth-1) {
|
|
|
nextlevel = new DPFnode[1<<(level+1)];
|
|
|
}
|
|
|
}
|
|
|
- // Invariant: curlevel has 2^level elements; nextlevel has
|
|
|
- // 2^{level+1} DPFnode elements if we're not at the last level,
|
|
|
- // and leaflevel has 2^{level+1} LeafNode elements if we are at
|
|
|
- // a leaf level (the last level always, and all levels if we are
|
|
|
- // making an incremental RDPF).
|
|
|
+ // Invariant: curlevel has 2^level DPFnode elements; nextlevel
|
|
|
+ // has 2^{level+1} DPFnode elements if we're not at the last
|
|
|
+ // level, and leaflevel has 2^{level+1} LeafNode elements if we
|
|
|
+ // are at a leaf level (the last level always, and all levels if
|
|
|
+ // we are making an incremental RDPF).
|
|
|
|
|
|
// The bit-shared choice bit is bit (depth-level-1) of the
|
|
|
// XOR-shared target index
|
|
@@ -870,20 +887,24 @@ RDPF<WIDTH>::RDPF(MPCTIO &tio, yield_t &yield,
|
|
|
|
|
|
if (level < depth-1) {
|
|
|
DPFnode CW;
|
|
|
+ // This field is ignored when we're not expanding to a leaf
|
|
|
+ // level, but it needs to be an lvalue reference.
|
|
|
+ int noleafinfo = 0;
|
|
|
create_level(tio, yield, curlevel, nextlevel, player, level,
|
|
|
- depth, bs_choice, CW, cfbit, save_expansion, li[0],
|
|
|
+ depth, bs_choice, CW, cfbit, save_expansion, noleafinfo,
|
|
|
aes_ops);
|
|
|
cfbits |= (value_t(cfbit)<<level);
|
|
|
if (player < 2) {
|
|
|
cw.push_back(CW);
|
|
|
}
|
|
|
- } else {
|
|
|
+ }
|
|
|
+ if (incremental || level == depth-1) {
|
|
|
LeafNode CW;
|
|
|
create_level(tio, yield, curlevel, leaflevel, player, level,
|
|
|
- depth, bs_choice, CW, cfbit, save_expansion, li[0],
|
|
|
- aes_ops);
|
|
|
+ depth, bs_choice, CW, cfbit, save_expansion,
|
|
|
+ li[depth-level-1], aes_ops);
|
|
|
leaf_cfbits |= (value_t(cfbit)<<(depth-level-1));
|
|
|
- li[0].leaf_cw = CW;
|
|
|
+ li[depth-level-1].leaf_cw = CW;
|
|
|
}
|
|
|
|
|
|
if (!save_expansion) {
|
|
@@ -902,8 +923,8 @@ typename RDPF<WIDTH>::LeafNode
|
|
|
RDPF<WIDTH>::leaf(address_t input, size_t &aes_ops) const
|
|
|
{
|
|
|
// If we have a precomputed expansion, just use it
|
|
|
- if (li[0].expansion.size()) {
|
|
|
- return li[0].expansion[input];
|
|
|
+ if (li[maxdepth-curdepth].expansion.size()) {
|
|
|
+ return li[maxdepth-curdepth].expansion[input];
|
|
|
}
|
|
|
|
|
|
DPFnode node = seed;
|
|
@@ -924,8 +945,8 @@ void RDPF<WIDTH>::expand(size_t &aes_ops)
|
|
|
{
|
|
|
nbits_t depth = this->depth();
|
|
|
size_t num_leaves = size_t(1)<<depth;
|
|
|
- if (li[0].expansion.size() == num_leaves) return;
|
|
|
- li[0].expansion.resize(num_leaves);
|
|
|
+ if (li[maxdepth-depth].expansion.size() == num_leaves) return;
|
|
|
+ li[maxdepth-depth].expansion.resize(num_leaves);
|
|
|
address_t index = 0;
|
|
|
address_t lastindex = 0;
|
|
|
DPFnode *path = new DPFnode[depth];
|
|
@@ -933,8 +954,10 @@ void RDPF<WIDTH>::expand(size_t &aes_ops)
|
|
|
for (nbits_t i=1;i<depth;++i) {
|
|
|
path[i] = descend(path[i-1], i-1, 0, aes_ops);
|
|
|
}
|
|
|
- li[0].expansion[index++] = descend_to_leaf(path[depth-1], depth-1, 0, aes_ops);
|
|
|
- li[0].expansion[index++] = descend_to_leaf(path[depth-1], depth-1, 1, aes_ops);
|
|
|
+ li[maxdepth-depth].expansion[index++] =
|
|
|
+ descend_to_leaf(path[depth-1], depth-1, 0, aes_ops);
|
|
|
+ li[maxdepth-depth].expansion[index++] =
|
|
|
+ descend_to_leaf(path[depth-1], depth-1, 1, aes_ops);
|
|
|
while(index < num_leaves) {
|
|
|
// Invariant: lastindex and index will both be even, and
|
|
|
// index=lastindex+2
|
|
@@ -954,8 +977,10 @@ void RDPF<WIDTH>::expand(size_t &aes_ops)
|
|
|
path[i+1] = descend(path[i], i, 0, aes_ops);
|
|
|
}
|
|
|
lastindex = index;
|
|
|
- li[0].expansion[index++] = descend_to_leaf(path[depth-1], depth-1, 0, aes_ops);
|
|
|
- li[0].expansion[index++] = descend_to_leaf(path[depth-1], depth-1, 1, aes_ops);
|
|
|
+ li[maxdepth-depth].expansion[index++] =
|
|
|
+ descend_to_leaf(path[depth-1], depth-1, 0, aes_ops);
|
|
|
+ li[maxdepth-depth].expansion[index++] =
|
|
|
+ descend_to_leaf(path[depth-1], depth-1, 1, aes_ops);
|
|
|
}
|
|
|
|
|
|
delete[] path;
|