Prechádzať zdrojové kódy

Addressing IG's code review (contd.)

sshsshy 7 mesiacov pred
rodič
commit
7ab221c22b
4 zmenil súbory, kde vykonal 378 pridanie a 319 odobranie
  1. 262 214
      avl.cpp
  2. 35 28
      avl.hpp
  3. 69 67
      bst.cpp
  4. 12 10
      bst.hpp

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 262 - 214
avl.cpp


+ 35 - 28
avl.hpp

@@ -11,19 +11,26 @@
 #include "options.hpp"
 #include "bst.hpp"
 
-#define KNRM  "\x1B[0m"
-#define KRED  "\x1B[31m"
-#define KGRN  "\x1B[32m"
-#define KYEL  "\x1B[33m"
-#define KBLU  "\x1B[34m"
-#define KMAG  "\x1B[35m"
-#define KCYN  "\x1B[36m"
-#define KWHT  "\x1B[37m"
-
-#define OPT_ON 0
-// #define RANDOMIZE 0
-// #define DEBUG 0
-// #define DEBUG_BB 0
+/*
+    Macro definitions:
+ 
+    AVL_OPT_ON: Turn AVL optimizations on
+        Optimizations:
+        - Use incremental DPFs for traversing the tree
+        - Use updates instead of writes when possible
+
+    RANDOMIZE: Randomize keys of items inserted. When turned off, items 
+    with incremental keys are inserted  
+
+    DEBUG: General debug flag
+
+    DEBUG_BB: Debug flag for balance bit computations
+*/
+
+#define AVL_OPT_ON
+// #define AVL_RANDOMIZE_INSERTS
+// #define AVL_DEBUG
+// #define AVL_DEBUG_BB
 
 /*
   For AVL tree we'll treat the pointers fields as:
@@ -49,11 +56,11 @@ inline int AVL_TTL(size_t n) {
 }
 
 inline RegXS getAVLLeftPtr(RegXS pointer){
-    return ((pointer&(0xFFFFFFFF00000000))>>33);
+    return (pointer>>33);
 }
 
 inline RegXS getAVLRightPtr(RegXS pointer){
-    return ((pointer&(0x00000001FFFFFFFF))>>2);
+    return ((pointer&(0x00000001FFFFFFFC))>>2);
 }
 
 inline void setAVLLeftPtr(RegXS &pointer, RegXS new_ptr){
@@ -68,14 +75,14 @@ inline void setAVLRightPtr(RegXS &pointer, RegXS new_ptr){
 
 inline RegBS getLeftBal(RegXS pointer){
     RegBS bal_l;
-    bool bal_l_bit = ((pointer.share() & (0x0000000000000002))>>1) & 1;
+    bool bal_l_bit = ((pointer.share() & (0x0000000000000002))>>1);
     bal_l.set(bal_l_bit);
     return bal_l;
 }
 
 inline RegBS getRightBal(RegXS pointer){
     RegBS bal_r;
-    bool bal_r_bit = (pointer.share() & (0x0000000000000001)) & 1;
+    bool bal_r_bit = (pointer.share() & (0x0000000000000001));
     bal_r.set(bal_r_bit);
     return bal_r;
 }
@@ -142,7 +149,7 @@ class AVL {
 
     std::tuple<RegBS, RegBS, RegXS, RegBS> insert(MPCTIO &tio, yield_t &yield, RegXS ptr,
         RegXS ins_addr, RegAS ins_key, Duoram<Node>::Flat &A, int TTL, RegBS isDummy, 
-        avl_insert_return *ret);
+        avl_insert_return &ret);
 
     void rotate(MPCTIO &tio, yield_t &yield, RegXS &gp_pointers, RegXS p_ptr,
         RegXS &p_pointers, RegXS c_ptr, RegXS &c_pointers, RegBS dir_gpp,
@@ -152,7 +159,7 @@ class AVL {
         RegBS bal_l, RegBS bal_r, RegBS bal_upd, RegBS child_dir);
 
     void updateChildPointers(MPCTIO &tio, yield_t &yield, RegXS &left, RegXS &right,
-          RegBS c_prime, avl_del_return ret_struct);
+          RegBS c_prime, const avl_del_return &ret_struct);
 
     void fixImbalance(MPCTIO &tio, yield_t &yield, Duoram<Node>::Flat &A, 
         Duoram<Node>::OblivIndex<RegXS,1> oidx, RegXS oidx_oldptrs, RegXS ptr, 
@@ -172,6 +179,12 @@ class AVL {
     bool lookup(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS key,
         Duoram<Node>::Flat &A, int TTL, RegBS isDummy, Node *ret_node);
 
+    void pretty_print(const std::vector<Node> &R, value_t node,
+        const std::string &prefix, bool is_left_child, bool is_right_child);
+
+    std::tuple<bool, bool, bool, address_t> check_avl(const std::vector<Node> &R,
+        value_t node, value_t min_key, value_t max_key);
+
   public:
     AVL(int num_players, size_t size) : oram(num_players, size) {
         this->MAX_SIZE = size;
@@ -188,13 +201,11 @@ class AVL {
         empty_locations.clear();
     }
 
-    size_t numEmptyLocations(){
-        return(empty_locations.size());
-    };
-
     void insert(MPCTIO &tio, yield_t &yield, const Node &node);
 
-    // Deletes the first node that matches del_key
+    // Deletes the first node that matches del_key. If an item with del_key
+    // does not exist in the tree, it results in an explicit (non-oblivious)
+    //  failure.
     bool del(MPCTIO &tio, yield_t &yield, RegAS del_key);
 
     // Returns the first node that matches key
@@ -205,11 +216,7 @@ class AVL {
 
     // Display and correctness check functions
     void pretty_print(MPCTIO &tio, yield_t &yield);
-    void pretty_print(const std::vector<Node> &R, value_t node,
-        const std::string &prefix, bool is_left_child, bool is_right_child);
     void check_avl(MPCTIO &tio, yield_t &yield);
-    std::tuple<bool, bool, bool, address_t> check_avl(const std::vector<Node> &R,
-        value_t node, value_t min_key, value_t max_key);
     void print_oram(MPCTIO &tio, yield_t &yield);
 
     // For test functions ONLY:

+ 69 - 67
bst.cpp

@@ -37,8 +37,8 @@ bool reconstruct_RegBS(MPCTIO &tio, yield_t &yield, RegBS flag) {
     return reconstructed_flag.bshare;
 }
 
-/* 
-    A function to assign a new random 8-bit key to a node, and resets its 
+/*
+    A function to assign a new random 8-bit key to a node, and resets its
     pointers to zeroes. The node is assigned a new random 64-bit value.
 */
 static void randomize_node(Node &a) {
@@ -48,13 +48,13 @@ static void randomize_node(Node &a) {
 }
 
 /*
-    A function to perform key comparsions for BST traversal. 
+    A function to perform key comparsions for BST traversal.
     Inputs: k1 = key of node in the tree, k2 = insertion/deletion/lookup key.
-    Evaluates (k2-k1), and combines the lt and eq flag into one (flag to go 
+    Evaluates (k2-k1), and combines the lt and eq flag into one (flag to go
     left), and keeps the gt flag as is (flag to go right) during traversal.
-    
+
 */
-std::tuple<RegBS, RegBS> compare_keys(MPCTIO tio, yield_t &yield, RegAS k1, 
+std::tuple<RegBS, RegBS> compare_keys(MPCTIO tio, yield_t &yield, RegAS k1,
         RegAS k2) {
     CDPF cdpf = tio.cdpf(yield);
     auto [lt, eq, gt] = cdpf.compare(tio, yield, k2 - k1, tio.aes_ops());
@@ -65,17 +65,17 @@ std::tuple<RegBS, RegBS> compare_keys(MPCTIO tio, yield_t &yield, RegAS k1,
 // Assuming pointer of 64 bits is split as:
 // - 32 bits Left ptr (L)
 // - 32 bits Right ptr (R)
-// The pointers are stored as: (L << 32) | R 
+// The pointers are stored as: (L << 32) | R
 
-inline RegXS extractLeftPtr(RegXS pointer){ 
-    return ((pointer&(0xFFFFFFFF00000000))>>32); 
+inline RegXS extractLeftPtr(RegXS pointer){
+    return ((pointer&(0xFFFFFFFF00000000))>>32);
 }
 
 inline RegXS extractRightPtr(RegXS pointer){
-    return (pointer&(0x00000000FFFFFFFF)); 
+    return (pointer&(0x00000000FFFFFFFF));
 }
 
-inline void setLeftPtr(RegXS &pointer, RegXS new_ptr){ 
+inline void setLeftPtr(RegXS &pointer, RegXS new_ptr){
     pointer&=(0x00000000FFFFFFFF);
     pointer+=(new_ptr<<32);
 }
@@ -207,9 +207,9 @@ void BST::check_bst(MPCTIO &tio, yield_t &yield) {
 
 /*
     The recursive insert() call, invoked by the wrapper insert() function.
-    
+
     Takes as input the pointer to the current node in tree traversal (ptr),
-    the new node to be inserted (new_node), the underlying Duoram as a 
+    the new node to be inserted (new_node), the underlying Duoram as a
     flat (A), and the Time-To_live TTL, and a shared flag (isDummy) which
     tracks if the operation is dummy/real.
 
@@ -228,10 +228,10 @@ std::tuple<RegXS, RegBS> BST::insert(MPCTIO &tio, yield_t &yield, RegXS ptr,
 
     // Depending on [lteq, gt] select the next ptr/index as
     // upper 32 bits of cnode.pointers if lteq
-    // lower 32 bits of cnode.pointers if gt 
+    // lower 32 bits of cnode.pointers if gt
     RegXS left = extractLeftPtr(cnode.pointers);
     RegXS right = extractRightPtr(cnode.pointers);
-    
+
     RegXS next_ptr;
     mpc_select(tio, yield, next_ptr, gt, left, right, 32);
 
@@ -241,13 +241,13 @@ std::tuple<RegXS, RegBS> BST::insert(MPCTIO &tio, yield_t &yield, RegXS ptr,
     RegBS F_z = dpf.is_zero(tio, yield, next_ptr, aes_ops);
     RegBS F_i;
 
-    // F_i: If this was last node on path (F_z) && isNotDummy: 
+    // F_i: If this was last node on path (F_z) && isNotDummy:
     //          insert new_node here.
     mpc_and(tio, yield, F_i, (isNotDummy), F_z);
-     
+
     isDummy^=F_i;
     auto [wptr, direction] = insert(tio, yield, next_ptr, new_node, A, TTL-1, isDummy);
-    
+
     RegXS ret_ptr;
     RegBS ret_direction;
     // If we insert here (F_i), return the ptr to this node as wptr
@@ -258,7 +258,7 @@ std::tuple<RegXS, RegBS> BST::insert(MPCTIO &tio, yield_t &yield, RegXS ptr,
         //ret_direction = direction + F_i (direction - gt)
         { mpc_and(tio, yield, ret_direction, F_i, direction^gt);});
 
-    ret_direction^=direction;  
+    ret_direction^=direction;
 
     return {ret_ptr, ret_direction};
 }
@@ -288,7 +288,7 @@ void BST::insert(MPCTIO &tio, yield_t &yield, const Node &node, Duoram<Node>::Fl
         bool insertAtEmptyLocation = (empty_locations.size() > 0);
         if(insertAtEmptyLocation) {
             insert_address = empty_locations.back();
-            empty_locations.pop_back(); 
+            empty_locations.pop_back();
             A[insert_address] = node;
         } else {
             new_id = 1 + num_items;
@@ -305,14 +305,14 @@ void BST::insert(MPCTIO &tio, yield_t &yield, const Node &node, Duoram<Node>::Fl
         RegXS left_ptr = extractLeftPtr(pointers);
         RegXS right_ptr = extractRightPtr(pointers);
         RegXS new_right_ptr, new_left_ptr;
-    
-        RegBS not_direction = direction; 
+
+        RegBS not_direction = direction;
         if (player0) {
             not_direction^=1;
         }
-    
-        run_coroutines(tio, 
-            [&tio, &new_right_ptr, direction, right_ptr, insert_address](yield_t &yield) 
+
+        run_coroutines(tio,
+            [&tio, &new_right_ptr, direction, right_ptr, insert_address](yield_t &yield)
             { mpc_select(tio, yield, new_right_ptr, direction, right_ptr, insert_address);},
             [&tio, &new_left_ptr, not_direction, left_ptr, insert_address](yield_t &yield)
             { mpc_select(tio, yield, new_left_ptr, not_direction, left_ptr, insert_address);});
@@ -320,7 +320,7 @@ void BST::insert(MPCTIO &tio, yield_t &yield, const Node &node, Duoram<Node>::Fl
         setLeftPtr(pointers, new_left_ptr);
         setRightPtr(pointers, new_right_ptr);
         A[wptr].NODE_POINTERS = pointers;
-    } 
+    }
 }
 
 /*
@@ -360,10 +360,10 @@ RegBS BST::lookup(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS key, Duoram<Node
 
     // Depending on [lteq, gt] select the next ptr/index as
     // upper 32 bits of cnode.pointers if lteq
-    // lower 32 bits of cnode.pointers if gt 
+    // lower 32 bits of cnode.pointers if gt
     RegXS left = extractLeftPtr(cnode.pointers);
     RegXS right = extractRightPtr(cnode.pointers);
-    
+
     RegXS next_ptr;
 
     RegBS F_found;
@@ -371,7 +371,7 @@ RegBS BST::lookup(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS key, Duoram<Node
     // then we found the node to return
     RegBS isNotDummy = isDummy ^ (!tio.player());
 
-    // Note: This logic returns the last matched key and value. 
+    // Note: This logic returns the last matched key and value.
     // Returning the first one incurs an additional round.
     std::vector<coro_t> coroutines;
     coroutines.emplace_back(
@@ -391,7 +391,7 @@ RegBS BST::lookup(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS key, Duoram<Node
         { mpc_or(tio, yield, isDummy, isDummy, eq);});
     run_coroutines(tio, coroutines);
 
-    #ifdef BST_DEBUG 
+    #ifdef BST_DEBUG
         size_t ckey = mpc_reconstruct(tio, yield, cnode.key, 64);
         size_t lkey = mpc_reconstruct(tio, yield, key, 64);
         bool rec_lt = mpc_reconstruct(tio, yield, lt);
@@ -402,10 +402,10 @@ RegBS BST::lookup(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS key, Duoram<Node
         printf("rec_lt = %d, rec_eq = %d, rec_gt = %d\n", rec_lt, rec_eq, rec_gt);
         printf("rec_isDummy/found = %d ,rec_f_found = %d, cnode.key = %ld, lookup key = %ld\n", rec_found, rec_f_found, ckey, lkey);
     #endif
-    
+
     RegBS found = lookup(tio, yield, next_ptr, key, A, TTL-1, isDummy, ret_node);
 
-    return found;    
+    return found;
 }
 
 RegBS BST::lookup(MPCTIO &tio, yield_t &yield, RegAS key, Node *ret_node) {
@@ -432,10 +432,10 @@ RegBS BST::lookup(MPCTIO &tio, yield_t &yield, RegAS key, Node *ret_node) {
 
 /*
     The recursive del() call, invoked by the wrapper del() function.
-    
+
     Takes as input the pointer to the current node in tree traversal (ptr),
-    the key to be deleted (del_key), the underlying Duoram as a 
-    flat (A), Flags af (already found) and fs (find successor), the 
+    the key to be deleted (del_key), the underlying Duoram as a
+    flat (A), Flags af (already found) and fs (find successor), the
     Time-To_live TTL. Finally, a return structure ret_struct that tracks
     the location of the successor node and the node to delete to perform
     the actual deletion after the recursive traversal; which is required in
@@ -446,15 +446,15 @@ RegBS BST::lookup(MPCTIO &tio, yield_t &yield, RegAS key, Node *ret_node) {
 */
 
 bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
-     Duoram<Node>::Flat &A, RegBS af, RegBS fs, int TTL, 
+     Duoram<Node>::Flat &A, RegBS af, RegBS fs, int TTL,
     del_return &ret_struct) {
     bool player0 = tio.player()==0;
     //printf("TTL = %d\n", TTL);
     if(TTL==0) {
         //Reconstruct and return af
         bool success = reconstruct_RegBS(tio, yield, af);
-        //printf("Reconstructed flag = %d\n", success); 
-        if(player0) { 
+        //printf("Reconstructed flag = %d\n", success);
+        if(player0) {
             ret_struct.F_r^=1;
         }
         return success;
@@ -466,11 +466,11 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
         Node node = A[ptr];
         RegXS left = extractLeftPtr(node.pointers);
         RegXS right = extractRightPtr(node.pointers);
-        
+
         CDPF cdpf = tio.cdpf(yield);
         size_t &aes_ops = tio.aes_ops();
         RegBS l0, r0, lt, eq, gt;
-        // l0: Is left child 0 
+        // l0: Is left child 0
         // r0: Is right child 0
         run_coroutines(tio,
             [&tio, &l0, left, &aes_ops, &cdpf](yield_t &yield)
@@ -495,7 +495,7 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
         printf("cdpf.compare results: lt = %d, eq = %d, gt = %d\n", lt_rec, eq_rec, gt_rec);
         */
 
-        // c is the direction bit for next_ptr 
+        // c is the direction bit for next_ptr
         // (c=0: go left or c=1: go right)
         RegBS c = gt;
         // lf = local found. We found the key to delete in this level.
@@ -507,12 +507,12 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
         // F_1 = l0 \xor r0
         F_1 = l0 ^ r0;
 
-        // We set next ptr based on c, but we need to handle three 
+        // We set next ptr based on c, but we need to handle three
         // edge cases where we do not go by just the comparison result
         RegXS next_ptr;
         RegBS c_prime;
         // Case 1: found the node here (lf): we traverse down the lone child path.
-        // or we are finding successor (fs) and there is no left child. 
+        // or we are finding successor (fs) and there is no left child.
         RegBS F_c1, F_c2, F_c3, F_c4;
 
         // Case 1: lf & F_1
@@ -522,7 +522,7 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
             [&tio, &F_0, l0, r0] (yield_t &yield)
             // F_0 = l0 & r0
             { mpc_and(tio, yield, F_0, l0, r0);});
-        
+
         // F_2 = !(F_0 + F_1) (Only 1 of F_0, F_1, and F_2 can be true)
         F_2 = F_0 ^ F_1;
         if(player0)
@@ -547,13 +547,13 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
             // In find successor case, so find inorder successor
             // (Go right and then find leftmost child.)
             { mpc_and(tio, yield, F_c2, lf, F_2);});
-        
+
         /*
         // Reconstruct and Debug Block 2
         bool F_c2_rec, s1_rec;
         F_c2_rec = mpc_reconstruct(tio, yield, F_c2);
-        s1_rec = mpc_reconstruct(tio, yield, s1); 
-        c_prime_rec = mpc_reconstruct(tio, yield, c_prime); 
+        s1_rec = mpc_reconstruct(tio, yield, s1);
+        c_prime_rec = mpc_reconstruct(tio, yield, c_prime);
         printf("c_prime = %d, F_c2 = %d, s1 = %d\n", c_prime_rec, F_c2_rec, s1_rec);
         */
 
@@ -562,7 +562,7 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
             { mpc_select(tio, yield, c_prime, F_c2, c_prime, s1);},
             [&tio, &F_c3, fs, F_2](yield_t &yield)
             // Case 3: finding successor (fs) and node has both children (F_2)
-            // Go left. 
+            // Go left.
             { mpc_and(tio, yield, F_c3, fs, F_2);});
 
         run_coroutines(tio,
@@ -577,7 +577,7 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
         mpc_select(tio, yield, c_prime, F_c4, c_prime, l0);
 
         RegBS af_prime, fs_prime;
-        run_coroutines(tio, 
+        run_coroutines(tio,
             [&tio, &next_ptr, c_prime, left, right](yield_t &yield)
             // Set next_ptr
             { mpc_select(tio, yield, next_ptr, c_prime, left, right, 32);},
@@ -597,7 +597,7 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
             return 0;
         }
 
-        //printf("TTL = %d\n", TTL); 
+        //printf("TTL = %d\n", TTL);
         RegBS F_rs_right, F_rs_left, not_c_prime=c_prime;
         if(player0) {
             not_c_prime^=1;
@@ -630,22 +630,22 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
         setRightPtr(new_ptr, right);
         A[ptr].NODE_POINTERS = new_ptr;
 
-        // Update the return structure 
+        // Update the return structure
         RegBS F_nd, F_ns, F_r, not_af = af, not_F_2 = F_2;
         if(player0) {
             not_af^=1;
             not_F_2^=1;
         }
-        // F_ns = fs & l0 
+        // F_ns = fs & l0
         // Finding successor flag & no more left child = F_c4
         F_ns = F_c4;
-    
-        run_coroutines(tio, 
+
+        run_coroutines(tio,
             [&tio, &ret_struct, F_c2](yield_t &yield)
             { mpc_or(tio, yield, ret_struct.F_ss, ret_struct.F_ss, F_c2);},
             [&tio, &F_nd, lf, not_af](yield_t &yield)
             { mpc_and(tio, yield, F_nd, lf, not_af);});
-            
+
 
         // F_r = F_d.(!F_2)
         // If we have to delete here, and it doesn't have two children we have to
@@ -662,13 +662,15 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
             [&tio, &ret_struct, F_r, ptr](yield_t &yield)
             { mpc_select(tio, yield, ret_struct.ret_ptr, F_r, ptr, ret_struct.ret_ptr);});
 
-        //We don't empty the key and value of the node with del_key in the ORAM 
+        //We don't empty the key and value of the node with del_key in the ORAM
         return 1;
     }
 }
 
 /*
     The main del() function.
+    Trying to delete an item that does not exist in the tree will result in
+    an explicit (non-oblivious) failure.
 
     Takes as input the key to delete (del_key).
     Returns success/fail bit.
@@ -684,22 +686,22 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegAS del_key) {
         empty_locations.emplace_back(root);
         A[root] = zero;
         num_items--;
-        return 1; 
+        return 1;
     } else {
         int TTL = num_items;
         // Flags for already found (af) item to delete and find successor (fs)
         // if this deletion requires a successor swap
         RegBS af;
         RegBS fs;
-        del_return ret_struct; 
+        del_return ret_struct;
         auto A = oram.flat(tio, yield);
-        int success = del(tio, yield, root, del_key, A, af, fs, TTL, ret_struct); 
-        printf ("Success =  %d\n", success); 
+        int success = del(tio, yield, root, del_key, A, af, fs, TTL, ret_struct);
+        printf ("Success =  %d\n", success);
         if(!success){
             return 0;
         }
         else{
-            num_items--; 
+            num_items--;
             /*
             printf("In delete's swap portion\n");
             Node del_node = A.reconstruct(A[ret_struct.N_d]);
@@ -712,8 +714,8 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegAS del_key) {
             Node suc_node = A[ret_struct.N_s];
             RegAS zero_as; RegXS zero_xs;
             RegXS empty_loc, temp_root = root;
-         
-            run_coroutines(tio, 
+
+            run_coroutines(tio,
                 [&tio, &temp_root, ret_struct](yield_t &yield)
                 { mpc_select(tio, yield, temp_root, ret_struct.F_r, temp_root, ret_struct.ret_ptr);},
                 [&tio, &del_node, ret_struct, suc_node](yield_t &yield)
@@ -771,15 +773,15 @@ void bst(MPCIO &mpcio,
         int insert_array[] = {10, 10, 13, 11, 14, 8, 15, 20, 17, 19, 7, 12};
         //int insert_array[] = {1, 2, 3, 4, 5, 6};
         size_t insert_array_size = sizeof(insert_array)/sizeof(int);
-        Node node; 
+        Node node;
         for(size_t i = 0; i<insert_array_size; i++) {
           randomize_node(node);
           node.key.set(insert_array[i] * tio.player());
           tree.insert(tio, yield, node);
         }
-       
+
         tree.pretty_print(tio, yield);
-         
+
         RegAS del_key;
 
         printf("\n\nDelete %x\n", 20);
@@ -863,7 +865,7 @@ void bst(MPCIO &mpcio,
             if(rec_found) {
                 printf("Lookup Success\n");
                 size_t value = mpc_reconstruct(tio, yield, node.value, 64);
-                printf("value = %lx\n", value);    
+                printf("value = %lx\n", value);
             } else {
                 printf("Lookup Failed\n");
             }

+ 12 - 10
bst.hpp

@@ -120,9 +120,9 @@ struct Node {
 };
 
 /*
-    A function to perform key comparsions for BST traversal. 
+    A function to perform key comparsions for BST traversal.
     Inputs: k1 = key of node in the tree, k2 = insertion/deletion/lookup key.
-    Evaluates (k2-k1), and combines the lt and eq flag into one (flag to go 
+    Evaluates (k2-k1), and combines the lt and eq flag into one (flag to go
     left), and keeps the gt flag as is (flag to go right) during traversal.
     Returns the shared bit flags lteq (go left) and gt (go right).
 */
@@ -161,7 +161,7 @@ struct del_return {
 };
 
 class BST {
-  private: 
+  private:
     Duoram<Node> oram;
     RegXS root;
 
@@ -175,10 +175,10 @@ class BST {
     void insert(MPCTIO &tio, yield_t &yield, const Node &node, Duoram<Node>::Flat &A);
 
     bool del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
-        Duoram<Node>::Flat &A, RegBS F_af, RegBS F_fs, int TTL, 
+        Duoram<Node>::Flat &A, RegBS F_af, RegBS F_fs, int TTL,
         del_return &ret_struct);
 
-    RegBS lookup(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS key, 
+    RegBS lookup(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS key,
         Duoram<Node>::Flat &A, int TTL, RegBS isDummy, Node *ret_node);
 
     void pretty_print(const std::vector<Node> &R, value_t node,
@@ -188,7 +188,7 @@ class BST {
         value_t node, value_t min_key, value_t max_key);
 
   public:
-    BST(int num_players, size_t size) : oram(num_players, size) {  
+    BST(int num_players, size_t size) : oram(num_players, size) {
         this->MAX_SIZE = size;
     };
 
@@ -196,8 +196,10 @@ class BST {
     // Inserts the provided node into the BST
     void insert(MPCTIO &tio, yield_t &yield, Node &node);
 
-    // Deletes the first node that matches del_key from the BST
-    bool del(MPCTIO &tio, yield_t &yield, RegAS del_key); 
+    // Deletes the first node that matches del_key from the BST.
+    // If an item with del_key does not exist in the tree, it results in an
+    // explicit (non-oblivious) failure.
+    bool del(MPCTIO &tio, yield_t &yield, RegAS del_key);
 
     // Returns the first node that matches key in the BST
     RegBS lookup(MPCTIO &tio, yield_t &yield, RegAS key, Node *ret_node);
@@ -210,14 +212,14 @@ class BST {
     // Check BST correctness
     void check_bst(MPCTIO &tio, yield_t &yield);
 
-    // Debugging Functions    
+    // Debugging Functions
 
     #ifdef BST_DEBUG
 
         // Print the underlying ORAM state
         void print_oram(MPCTIO &tio, yield_t &yield);
 
-        // Check the number of empty locations in ORAM 
+        // Check the number of empty locations in ORAM
         // (Locations freed up after a delete operation, reusable for next insert.)
         size_t numEmptyLocations(){
             return(empty_locations.size());

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov