Browse Source

Merge main

Sajin Sasy 1 year ago
parent
commit
f21edf4dc8

+ 94 - 0
Enclave/OblivAlgs/ORExpand.cpp

@@ -0,0 +1,94 @@
+#include "ORExpand.hpp"
+
+#ifdef TEST_OREXPAND
+void test_ORExpand()
+{
+    size_t block_size = 48;
+    uint32_t N = 16;
+
+    uint32_t dest_specified[] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14};
+    size_t dest_specified_len = sizeof(dest_specified)/sizeof(uint32_t);
+    unsigned char *buf = new unsigned char[N*block_size];
+    uint32_t *dest = new uint32_t[N];
+    for (size_t i=0;i<dest_specified_len;++i) {
+        dest[i] = dest_specified[i];
+    }
+    for (size_t i=dest_specified_len;i<N;++i) {
+        dest[i] = 0xffffffff;
+    }
+
+    for (size_t i=0;i<N;++i) {
+        for (size_t j=0;j<block_size;j+=2) {
+            buf[i*block_size+j] = (unsigned char)i;
+            buf[i*block_size+j+1] = (unsigned char)j/2;
+        }
+    }
+
+    ORExpand<OSWAP_16X>(buf, dest, block_size, N);
+
+    for(size_t i=0;i<N;++i) {
+        printf("%2d ", i);
+        if (dest[i] == 0xffffffff) {
+            printf("PD ");
+        } else {
+            printf("%2d ", dest[i]);
+        }
+        for (size_t j=0;j<block_size;++j) {
+            printf("%02x", buf[i*block_size+j]);
+        }
+        printf("\n");
+    }
+
+    delete[] buf;
+    delete[] dest;
+}
+
+void test_ORExpand_parallel(threadid_t nthreads)
+{
+    size_t block_size = 384;
+    uint32_t N = 500000;
+
+    unsigned char *buf = new unsigned char[N*block_size];
+    uint32_t *dest = new uint32_t[N];
+    uint32_t next_dest = 0;
+    for (uint32_t i=0;i<N;++i) {
+        // Randomly decide whether i is real or dummy
+        bool keep = getRandomBit();
+        if (keep) {
+            dest[next_dest] = i;
+            ++next_dest;
+        }
+    }
+    for (uint32_t i=next_dest;i<N;++i) {
+        dest[i] = 0xffffffff;
+    }
+
+    for (size_t i=0;i<N;++i) {
+        for (size_t j=0;j<block_size;j+=2) {
+            buf[i*block_size+j] = (unsigned char)i;
+            buf[i*block_size+j+1] = (unsigned char)j/2;
+        }
+    }
+
+    ORExpand_parallel<OSWAP_16X>(buf, dest, block_size, N, nthreads);
+
+    for(uint32_t i=0;i<N;++i) {
+        assert(dest[i] == 0xffffffff || dest[i] == i);
+        if (N < 200) {
+            printf("%2d ", i);
+            if (dest[i] == 0xffffffff) {
+                printf("   ");
+            } else {
+                printf("%2d ", dest[i]);
+            }
+            for (size_t j=0;j<block_size;++j) {
+                printf("%02x", buf[i*block_size+j]);
+            }
+            printf("\n");
+        }
+    }
+
+    delete[] buf;
+    delete[] dest;
+}
+#endif

+ 114 - 0
Enclave/OblivAlgs/ORExpand.hpp

@@ -0,0 +1,114 @@
+#ifndef __OREXPAND_HPP__
+#define __OREXPAND_HPP__
+
+#include <cstddef>
+#include <cstdint>
+
+#include "utils.hpp"
+#include "oasm_lib.h"
+
+// Notation: for an array A, let A[lo..hi] denote the subarray of
+// A that is A[lo], A[lo+1], ..., A[hi-1].  That is, it is inclusive of
+// lo and exclusive of hi.  The length of the subarray is hi-lo.  If
+// lo < mid < hi, then A[lo..mid] and A[mid..hi] are a partition of
+// A[lo..hi] into two non-empty non-overlapping pieces whose union is
+// exactly A[lo..hi].
+
+// This file implements oblivious recursive expansion (ORExpand), which
+// is basically ORCompact (the TightCompact function in
+// TightCompaction_v2.tcc) run backwards (doing the OSwaps in reverse
+// order).
+
+// Throughout this file, "buf" is the data buffer, composed of blocks
+// that are each block_size bytes long.  block_size must be a size
+// supported by the corresponding OSwap_Style.  "dest" is an array of
+// destinations.  The idea is that if the input to ORExpand has, say,
+// dest[7] = 19, then the block at index 7 in the input buf will end up
+// at index 19 in the output buf (treating buf as an array of
+// block_size-byte blocks).
+
+// These functions do _not_ implement arbitrary permutations, however
+// (see the WaksmanNetwork.* files for that).  They will only expand a
+// contiguous range of blocks into a possibly non-contiguous range,
+// inserting padding blocks in the intervening spaces, and preserving
+// the order of the non-padding blocks.  The contiguous range may (in
+// some cases; see below) start at some offset z, rather than at the
+// beginning of the (sub)array, however, in which case the contiguous
+// range may "wrap around" to the beginning of the (sub)array.
+
+// Note that A[lo+((z+k) mod (hi-lo))] is element k (starting from 0) of a
+// contiguous range in A[lo..hi], starting at offset z, and wrapping
+// around if necessary.
+
+// We denote block i of buf (buf[i]) as a padding block by setting
+// dest[i] = 0xffffffff.
+
+// Therefore, suppose we are working on the subarray buf[lo..hi] (that
+// is, we only perform operations on buf[lo..hi] and on the
+// corresponding dest[lo..hi], and all elements of dest[lo..hi] are
+// either themselves in the range lo..hi (inclusive of lo and exclusive
+// of hi) or are 0xffffffff). If there are r non-padding blocks (and so
+// hi-lo-r padding blocks), and the offset is z, then on input, we must
+// have:
+//
+// lo <= dest[lo+(z mod (hi-lo))]
+//     < dest[lo+((z+1) mod (hi-lo))]
+//     < dest[lo+((z+2) mod (hi-lo))]
+//     ...
+//     < dest[lo+((z+(r-1)) mod (hi-lo))]
+//     < hi
+//
+// and the other elements of dest[lo..hi] are 0xffffffff.
+
+// Note that while the offset may cause the _indices_ to wrap around,
+// the dest _values_ have no offset, and cannot wrap around.
+
+// The restriction on z is that if hi-lo is _not_ a power of 2, then z
+// must be 0, and indeed lo must be 0 (and so the contiguous range of
+// non-padding blocks must start at the beginning of the array).
+
+// Note that z does not need to be passed explicitly; it is implied by
+// the contents of dest.  In fact, the algorithm does not even need to
+// compute it explicitly.
+
+// The values passed are not private, but the _contents_ of the buf and
+// dest arrays are.
+
+template <OSwap_Style oswap_style>
+void ORExpand(unsigned char *buf, uint32_t *dest, size_t block_size,
+    uint32_t lo, uint32_t hi);
+
+// A convenience wrapper for the initial call.  Here, N is the length of
+// the input arrays (in block_size-byte blocks for buf, and in 32-bit
+// words for dest).  z must be 0, so the non-padding elements of dest
+// must be at the beginning.
+
+template <OSwap_Style oswap_style>
+void ORExpand(unsigned char *buf, uint32_t *dest, size_t block_size,
+        uint32_t N) {
+    ORExpand<oswap_style>(buf, dest, block_size, 0, N);
+}
+
+// Multithreaded versions of ORExpand and its convenience wrapper
+
+template <OSwap_Style oswap_style>
+void ORExpand_parallel(unsigned char *buf, uint32_t *dest,
+    size_t block_size, uint32_t lo, uint32_t hi, threadid_t nthreads);
+
+template <OSwap_Style oswap_style>
+void ORExpand_parallel(unsigned char *buf, uint32_t *dest,
+    size_t block_size, uint32_t N, threadid_t nthreads) {
+    ORExpand_parallel<oswap_style>(buf, dest, block_size, 0, N, nthreads);
+}
+
+// #define PROFILE_OREXPAND
+// #define TEST_OREXPAND
+
+#include "ORExpand.tcc"
+
+#ifdef TEST_OREXPAND
+void test_ORExpand();
+void test_ORExpand_parallel(threadid_t nthreads);
+#endif
+
+#endif

+ 232 - 0
Enclave/OblivAlgs/ORExpand.tcc

@@ -0,0 +1,232 @@
+// See ORExpand.hpp for explanations of notation and inputs.
+// Particularly note that all subarrays [lo..hi] are _inclusive_ of lo
+// but _exclusive_ of hi.
+
+// buf is an array of block_size-byte blocks. dest is an array of 32-bit
+// words.  We are given two (contiguous) subarrays [lo..mid] and
+// [mid..hi], and indices a and b with a in [lo..mid] and b in
+// [mid..hi].  If (mid <= dest[a] < hi) or (lo <= dest[b] <= mid), then
+// swap dest[a] with dest[b] and buf[a] with buf[b]; otherwise, do not.
+// However, all tests and swaps must be done obliviously to the values
+// of dest[a] and dest[b] (and the contents of buf).  It's OK to not be
+// oblivious to the values of lo, mid, hi, a, and b themselves, however.
+template <OSwap_Style oswap_style>
+static inline void mid_oswap(unsigned char *buf, uint32_t *dest,
+    size_t block_size, uint32_t lo, uint32_t mid, uint32_t hi,
+    uint32_t a, uint32_t b)
+{
+    uint32_t desta = dest[a];
+    uint32_t destb = dest[b];
+    uint8_t swap_flag = ((mid <= desta) & (desta < hi))
+        | ((lo <= destb) & (destb < mid));
+    // The next line could be optimized with some inline assembly, since
+    // we've already loaded desta and destb, so we could obliviously
+    // swap those registers, and then non-obliviously write them back
+    // out to dest[a] and dest[b].
+    oswap_buffer<OSWAP_4>((unsigned char *)(dest+a),
+        (unsigned char *)(dest+b), 4, swap_flag);
+    oswap_buffer<oswap_style>(buf+a*block_size, buf+b*block_size,
+        (uint32_t)block_size, swap_flag);
+}
+
+template <OSwap_Style oswap_style>
+void ORExpand(unsigned char *buf, uint32_t *dest, size_t block_size,
+    uint32_t lo, uint32_t hi)
+{
+    // Passing hi < lo is an illegal input
+    assert(hi >= lo);
+
+    // The length of the subarray
+    const uint32_t N = hi-lo;
+
+    // Nothing to do on inputs where [lo..hi] has length 0 or 1
+    if (N < 2) {
+        return;
+    }
+
+    // The largest power of 2 strictly less than N
+    const uint32_t N2 = uint32_t(pow2_lt(N));
+
+    // We divide [lo..hi] (of length N) into two pieces:
+    // [lo..mid] and [mid..hi], where [mid..hi] has length N2 (the
+    // largest power of 2 strictly less than N).  Note that mid is just
+    // _somewhere_ in the middle of [lo..hi]; it will not be the exact
+    // midpoint if N is not itself a power of 2.  (It will be the exact
+    // midpoint if N is a power of 2, however.)
+    const uint32_t mid = hi-N2;
+
+    // N1 is the length of [lo..mid].  Note that N1 <= N2, with equality
+    // if and only if N is a power of 2.
+    const uint32_t N1 = N-N2;
+
+    // We're going to do N1 oblivious swaps on the buf and dest arrays,
+    // between items lo+i and hi-N1+i for 0 <= i < N1.  If dest[lo+i]
+    // lies in [mid..hi] (and is not 0xffffffff to indicate padding)
+    // _or_ if dest[hi-N1+i] lies in [lo..mid] (again and is not
+    // 0xffffffff), then we swap them and their corresponding buf
+    // blocks.  The cool part is that it cannot be the case that both
+    // dest[lo+i] and dest[hi-N1+i] are not padding and they both have
+    // values on the same side of mid.  Why is that?
+
+    // Case 1: If dest[lo+i] < dest[hi-N1+i], then all of the blocks
+    // from lo+i to hi-N1+1 inclusive must be non-padding blocks, and
+    // since this contiguous block has strictly increasing values, it
+    // must be that dest[hi-N1+i] - dest[lo+i] >= (hi-N1+i)-(lo+i) =
+    // N-N1 = N2.  Since the lengths of [lo..mid] and [mid..hi] are each
+    // at most N2, dest[lo+i] and dest[hi-N1+i] cannot be both in the
+    // same one of those subarrays.
+
+    // Case 2: If dest[hi-N1+i] < dest[lo+i], then the contiguous range
+    // of non-padding blocks wraps around hi back to lo, so we must have
+    // that dest[lo+i] - dest[hi-N1+i] >= (hi+i) - (hi-N1+i) = N1, and
+    // also since the range wraps around, it must start at a non-zero
+    // offset z, which means that N had to be a power of 2, and so
+    // N1=N2.  Therefore dest[lo+i] - dest[hi-N1+i] >= N2, and as above,
+    // dest[lo+i] and dest[hi-N1+i] cannot both be in [lo..mid] or both
+    // be in [mid..hi], each of which has length N1=N2.
+
+    // So these oblivious swaps will ensure that all the blocks with
+    // dest in [lo..mid] end up in [lo..mid] and all the blocks with
+    // dest in [mid..hi] end up in [mid..hi].  In addition, the property
+    // that all the non-padding blocks are contiguous (possibly wrapping
+    // around for the [mid..hi] subarray which has length a power of 2)
+    // and monotonicly increasing are preserved for both the [lo..mid]
+    // and [mid..hi] subarrays.
+
+    for (uint32_t i=0; i<N1; ++i) {
+        mid_oswap<oswap_style>(buf, dest, block_size, lo, mid, hi,
+            lo+i, hi-N1+i);
+    }
+
+    // And now we just recurse on the two subarrays.
+    ORExpand<oswap_style>(buf, dest, block_size, lo, mid);
+    ORExpand<oswap_style>(buf, dest, block_size, mid, hi);
+}
+
+// Multithreaded version of ORExpand
+
+struct mid_oswap_range_args {
+    unsigned char *buf;
+    uint32_t *dest;
+    size_t block_size;
+    uint32_t lo, mid, hi, a, b, num;
+};
+
+template <OSwap_Style oswap_style>
+static void *mid_oswap_range_launch(void *voidargs)
+{
+    const mid_oswap_range_args *args =
+        (mid_oswap_range_args*)voidargs;
+    for (uint32_t i=0; i<args->num; ++i) {
+        mid_oswap<oswap_style>(args->buf, args->dest, args->block_size,
+            args->lo, args->mid, args->hi,
+            args->a + i, args->b + i);
+    }
+    return NULL;
+}
+
+struct ORExpand_parallel_args {
+    unsigned char *buf;
+    uint32_t *dest;
+    size_t block_size;
+    uint32_t lo, hi;
+    threadid_t nthreads;
+};
+
+template <OSwap_Style oswap_style>
+static void* ORExpand_parallel_launch(void *voidargs)
+{
+    const ORExpand_parallel_args* args =
+        (ORExpand_parallel_args*)voidargs;
+    ORExpand_parallel<oswap_style>(args->buf, args->dest,
+        args->block_size, args->lo, args->hi, args->nthreads);
+    return NULL;
+}
+
+// See ORExpand, above, for detailed comments as to how this algorithm
+// works.
+template <OSwap_Style oswap_style>
+void ORExpand_parallel(unsigned char *buf, uint32_t *dest,
+    size_t block_size, uint32_t lo, uint32_t hi, threadid_t nthreads)
+{
+    // Passing hi < lo is an illegal input
+    assert(hi >= lo);
+
+    // The length of the subarray
+    const uint32_t N = hi-lo;
+
+    // Nothing to do on inputs where [lo..hi] has length 0 or 1
+    if (N < 2) {
+        return;
+    }
+
+    // Use the single-threaded version if nthreads <= 1
+    if (nthreads <= 1) {
+#ifdef PROFILE_OREXPAND
+        unsigned long start = printf_with_rtclock("Thread %u starting ORExpand(N=%u, lo=%u, hi=%u, nthreads=%hu)\n", g_thread_id, N, lo, hi, nthreads);
+#endif
+        ORExpand<oswap_style>(buf, dest, block_size, lo, hi);
+#ifdef PROFILE_OREXPAND
+        printf_with_rtclock_diff(start, "Thread %u ending ORExpand(N=%u, lo=%u, hi=%u, nthreads=%hu)\n", g_thread_id, N, lo, hi, nthreads);
+#endif
+        return;
+    }
+
+#ifdef PROFILE_OREXPAND
+    unsigned long start = printf_with_rtclock("Thread %u starting ORExpand(N=%u, lo=%u, hi=%u, nthreads=%hu)\n", g_thread_id, N, lo, hi, nthreads);
+#endif
+
+    // The largest power of 2 strictly less than N
+    const uint32_t N2 = uint32_t(pow2_lt(N));
+    const uint32_t mid = hi-N2;
+    const uint32_t N1 = N-N2;
+
+    mid_oswap_range_args args[nthreads];
+    uint32_t inc = N1 / nthreads;
+    uint32_t extra = N1 % nthreads;
+    uint32_t last = 0;
+    for (threadid_t i=0; i<nthreads; ++i) {
+        uint32_t num = inc + (i < extra);
+        args[i] = { buf, dest, block_size, lo, mid, hi, lo+last,
+            hi-N1+last, num };
+        last += num;
+    }
+
+    // Launch all but the first section into other threads
+    for (threadid_t i=1; i<nthreads; ++i) {
+        threadpool_dispatch(g_thread_id+i,
+            mid_oswap_range_launch<oswap_style>, args+i);
+    }
+
+    // Do the first section ourselves
+    mid_oswap_range_launch<oswap_style>(args);
+
+    // Join the threads
+    for (threadid_t i=1; i<nthreads; ++i) {
+        threadpool_join(g_thread_id+i, NULL);
+    }
+
+    // Use half the threads for the left subarray and half for the right
+    // subarray (this choice could be improved if N1 << N2, perhaps).
+    threadid_t lthreads = nthreads / 2;
+    threadid_t rthreads = nthreads - lthreads;
+
+    threadid_t rightthreadid = g_thread_id + lthreads;
+
+    ORExpand_parallel_args rightargs = {
+        buf, dest, block_size, mid, hi, rthreads
+    };
+    threadpool_dispatch(rightthreadid,
+        ORExpand_parallel_launch<oswap_style>, &rightargs);
+
+    // Do the left subarray ourselves (with lthreads threads)
+    ORExpand_parallel<oswap_style>(buf, dest, block_size, lo, mid,
+        lthreads);
+
+    // Join the thread
+    threadpool_join(rightthreadid, NULL);
+
+#ifdef PROFILE_OREXPAND
+    printf_with_rtclock_diff(start, "Thread %u ending ORExpand(N=%u, lo=%u, hi=%u, nthreads=%hu)\n", g_thread_id, N, lo, hi, nthreads);
+#endif
+}

+ 5 - 2
Enclave/OblivAlgs/TightCompaction_v2.tcc

@@ -4,15 +4,18 @@
 #include "pthread.h"
 #include "pthread.h"
 
 
 /*
 /*
-   TightCompaction (Non-Order Preserving Tight Compaction):
+   TightCompaction (Order Preserving Tight Compaction):
 
 
-   Non-Order Preserving TightCompaction can take an input array of blocks of
+   Order Preserving TightCompaction can take an input array of blocks of
    block_size bytes each, and an array of "marked" elements with ones at the
    block_size bytes each, and an array of "marked" elements with ones at the
    indices corresponding to the blocks that need to be compacted.
    indices corresponding to the blocks that need to be compacted.
    It returns the input array TightCompact-ed, i.e. all the real blocks are
    It returns the input array TightCompact-ed, i.e. all the real blocks are
    moved to the start of the array, or compacted to an input index
    moved to the start of the array, or compacted to an input index
    (with wraparound)
    (with wraparound)
 
 
+   This is the Oblivious Recusrive Compaction (ORCompact) algorithm from
+   our CCS 2022 paper "Fast Fully Oblivious Compaction and Shuffling".
+
  */
  */
 
 
 template <OSwap_Style oswap_style>
 template <OSwap_Style oswap_style>

+ 0 - 9
Enclave/OblivAlgs/utils.cpp

@@ -372,15 +372,6 @@ uint64_t pow2_lt(uint64_t N) {
 }
 }
 
 
 
 
-// Returns largest power of two greater than N
-uint64_t pow2_gt(uint64_t N) {
-  uint64_t N1 = 1;
-  while (N1 < N) {
-    N1 <<= 1;
-  }
-  return N1;
-}
-
 #ifndef BEFTS_MODE
 #ifndef BEFTS_MODE
 /*
 /*
  * printf:
  * printf:

+ 0 - 1
Enclave/OblivAlgs/utils.hpp

@@ -99,7 +99,6 @@
   int calculatelog2(uint64_t value);
   int calculatelog2(uint64_t value);
   int calculatelog2_floor(uint64_t value);
   int calculatelog2_floor(uint64_t value);
   uint64_t pow2_lt(uint64_t N);
   uint64_t pow2_lt(uint64_t N);
-  uint64_t pow2_gt(uint64_t N);
 
 
   void merge(unsigned char *data, size_t l, size_t m, size_t r, unsigned char* (*comparator)(unsigned char*, unsigned char*));
   void merge(unsigned char *data, size_t l, size_t m, size_t r, unsigned char* (*comparator)(unsigned char*, unsigned char*));
   void mergeSort(unsigned char *data, size_t data_size, size_t start_index, size_t end_index, unsigned char* (*comparator)(unsigned char*, unsigned char*));
   void mergeSort(unsigned char *data, size_t data_size, size_t start_index, size_t end_index, unsigned char* (*comparator)(unsigned char*, unsigned char*));

+ 1 - 0
Enclave/storage.cpp

@@ -1,6 +1,7 @@
 #include "utils.hpp"
 #include "utils.hpp"
 #include "config.hpp"
 #include "config.hpp"
 #include "storage.hpp"
 #include "storage.hpp"
+#include "ORExpand.hpp"
 
 
 // Handle the messages received by a storage node
 // Handle the messages received by a storage node
 void storage_received(const uint8_t *msgs, uint32_t num_msgs)
 void storage_received(const uint8_t *msgs, uint32_t num_msgs)

+ 45 - 6
Makefile

@@ -310,7 +310,7 @@ clean:
 
 
 depend:
 depend:
 	makedepend -Y -- -IApp -IUntrusted -- $(App_Cpp_Files)
 	makedepend -Y -- -IApp -IUntrusted -- $(App_Cpp_Files)
-	makedepend -a -Y -- -IEnclave -- $(Enclave_Cpp_Files)
+	makedepend -a -Y -- -IEnclave -IEnclave/OblivAlgs -- $(Enclave_Cpp_Files)
 
 
 # DO NOT DELETE
 # DO NOT DELETE
 
 
@@ -325,19 +325,58 @@ App/teems.o: App/net.hpp App/start.hpp
 Untrusted/Untrusted.o: Untrusted/Untrusted.hpp Enclave/enclave_api.h
 Untrusted/Untrusted.o: Untrusted/Untrusted.hpp Enclave/enclave_api.h
 Untrusted/Untrusted.o: Untrusted/Enclave_u.h
 Untrusted/Untrusted.o: Untrusted/Enclave_u.h
 
 
-Enclave/comms.o: Enclave/Enclave_t.h Enclave/enclave_api.h Enclave/config.hpp
+Enclave/comms.o: Enclave/Enclave_t.h Enclave/enclave_api.h
+Enclave/comms.o: Enclave/OblivAlgs/utils.hpp Enclave/OblivAlgs/CONFIG.h
+Enclave/comms.o: Enclave/OblivAlgs/oasm_lib.h Enclave/OblivAlgs/oasm_lib.tcc
+Enclave/comms.o: Enclave/OblivAlgs/foav.h Enclave/config.hpp
 Enclave/comms.o: Enclave/enclave_api.h Enclave/route.hpp Enclave/comms.hpp
 Enclave/comms.o: Enclave/enclave_api.h Enclave/route.hpp Enclave/comms.hpp
 Enclave/config.o: Enclave/Enclave_t.h Enclave/enclave_api.h Enclave/comms.hpp
 Enclave/config.o: Enclave/Enclave_t.h Enclave/enclave_api.h Enclave/comms.hpp
-Enclave/config.o: Enclave/enclave_api.h Enclave/config.hpp Enclave/route.hpp Enclave/ingest.hpp
+Enclave/config.o: Enclave/enclave_api.h Enclave/config.hpp
+Enclave/config.o: Enclave/OblivAlgs/utils.hpp Enclave/OblivAlgs/CONFIG.h
+Enclave/config.o: Enclave/OblivAlgs/oasm_lib.h Enclave/OblivAlgs/oasm_lib.tcc
+Enclave/config.o: Enclave/OblivAlgs/foav.h Enclave/route.hpp Enclave/ingest.hpp
+Enclave/obliv.o: Enclave/OblivAlgs/oasm_lib.h Enclave/OblivAlgs/CONFIG.h
+Enclave/obliv.o: Enclave/OblivAlgs/oasm_lib.tcc Enclave/OblivAlgs/foav.h
 Enclave/obliv.o: Enclave/enclave_api.h Enclave/obliv.hpp
 Enclave/obliv.o: Enclave/enclave_api.h Enclave/obliv.hpp
 Enclave/route.o: Enclave/Enclave_t.h Enclave/enclave_api.h Enclave/config.hpp
 Enclave/route.o: Enclave/Enclave_t.h Enclave/enclave_api.h Enclave/config.hpp
-Enclave/route.o: Enclave/enclave_api.h Enclave/sort.hpp Enclave/comms.hpp
+Enclave/route.o: Enclave/enclave_api.h Enclave/OblivAlgs/utils.hpp
+Enclave/route.o: Enclave/OblivAlgs/CONFIG.h Enclave/OblivAlgs/oasm_lib.h
+Enclave/route.o: Enclave/OblivAlgs/oasm_lib.tcc Enclave/OblivAlgs/foav.h
+Enclave/route.o: Enclave/sort.hpp Enclave/OblivAlgs/WaksmanNetwork.hpp
+Enclave/route.o: Enclave/OblivAlgs/RecursiveShuffle.hpp
+Enclave/route.o: Enclave/OblivAlgs/TightCompaction_v2.hpp
+Enclave/route.o: Enclave/OblivAlgs/TightCompaction_v2.tcc
+Enclave/route.o: Enclave/OblivAlgs/RecursiveShuffle.tcc
+Enclave/route.o: Enclave/OblivAlgs/aes.hpp
+Enclave/route.o: Enclave/OblivAlgs/WaksmanNetwork.tcc Enclave/comms.hpp
 Enclave/route.o: Enclave/obliv.hpp Enclave/storage.hpp Enclave/route.hpp
 Enclave/route.o: Enclave/obliv.hpp Enclave/storage.hpp Enclave/route.hpp
 Enclave/ingest.o: Enclave/Enclave_t.h Enclave/enclave_api.h Enclave/config.hpp
 Enclave/ingest.o: Enclave/Enclave_t.h Enclave/enclave_api.h Enclave/config.hpp
 Enclave/ingest.o: Enclave/route.hpp
 Enclave/ingest.o: Enclave/route.hpp
-Enclave/sort.o: Enclave/sort.hpp
+Enclave/sort.o: Enclave/sort.hpp Enclave/OblivAlgs/WaksmanNetwork.hpp
+Enclave/sort.o: Enclave/OblivAlgs/oasm_lib.h Enclave/OblivAlgs/CONFIG.h
+Enclave/sort.o: Enclave/OblivAlgs/oasm_lib.tcc Enclave/OblivAlgs/foav.h
+Enclave/sort.o: Enclave/OblivAlgs/utils.hpp Enclave/Enclave_t.h
+Enclave/sort.o: Enclave/enclave_api.h Enclave/OblivAlgs/RecursiveShuffle.hpp
+Enclave/sort.o: Enclave/OblivAlgs/TightCompaction_v2.hpp
+Enclave/sort.o: Enclave/OblivAlgs/TightCompaction_v2.tcc
+Enclave/sort.o: Enclave/OblivAlgs/RecursiveShuffle.tcc
+Enclave/sort.o: Enclave/OblivAlgs/aes.hpp
+Enclave/sort.o: Enclave/OblivAlgs/WaksmanNetwork.tcc
+Enclave/storage.o: Enclave/OblivAlgs/utils.hpp Enclave/Enclave_t.h
+Enclave/storage.o: Enclave/enclave_api.h Enclave/OblivAlgs/CONFIG.h
+Enclave/storage.o: Enclave/OblivAlgs/oasm_lib.h
+Enclave/storage.o: Enclave/OblivAlgs/oasm_lib.tcc Enclave/OblivAlgs/foav.h
 Enclave/storage.o: Enclave/config.hpp Enclave/enclave_api.h
 Enclave/storage.o: Enclave/config.hpp Enclave/enclave_api.h
-Enclave/storage.o: Enclave/storage.hpp
+Enclave/storage.o: Enclave/storage.hpp Enclave/OblivAlgs/ORExpand.hpp
+Enclave/storage.o: Enclave/OblivAlgs/ORExpand.tcc
+Enclave/OblivAlgs/ORExpand.o: Enclave/OblivAlgs/ORExpand.hpp
+Enclave/OblivAlgs/ORExpand.o: Enclave/OblivAlgs/oasm_lib.h
+Enclave/OblivAlgs/ORExpand.o: Enclave/OblivAlgs/CONFIG.h
+Enclave/OblivAlgs/ORExpand.o: Enclave/OblivAlgs/oasm_lib.tcc
+Enclave/OblivAlgs/ORExpand.o: Enclave/OblivAlgs/foav.h
+Enclave/OblivAlgs/ORExpand.o: Enclave/OblivAlgs/ORExpand.tcc
+Enclave/OblivAlgs/ORExpand.o: Enclave/OblivAlgs/utils.hpp Enclave/Enclave_t.h
+Enclave/OblivAlgs/ORExpand.o: Enclave/enclave_api.h
 Enclave/OblivAlgs/RecursiveShuffle.o: Enclave/OblivAlgs/oasm_lib.h
 Enclave/OblivAlgs/RecursiveShuffle.o: Enclave/OblivAlgs/oasm_lib.h
 Enclave/OblivAlgs/RecursiveShuffle.o: Enclave/OblivAlgs/CONFIG.h
 Enclave/OblivAlgs/RecursiveShuffle.o: Enclave/OblivAlgs/CONFIG.h
 Enclave/OblivAlgs/RecursiveShuffle.o: Enclave/OblivAlgs/oasm_lib.tcc
 Enclave/OblivAlgs/RecursiveShuffle.o: Enclave/OblivAlgs/oasm_lib.tcc