Przeglądaj źródła

Addressing IG's code review (contd.)

sshsshy 2 lat temu
rodzic
commit
7ab221c22b
4 zmienionych plików z 378 dodań i 319 usunięć
  1. 262 214
      avl.cpp
  2. 35 28
      avl.hpp
  3. 69 67
      bst.cpp
  4. 12 10
      bst.hpp

Plik diff jest za duży
+ 262 - 214
avl.cpp


+ 35 - 28
avl.hpp

@@ -11,19 +11,26 @@
 #include "options.hpp"
 #include "options.hpp"
 #include "bst.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:
   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){
 inline RegXS getAVLLeftPtr(RegXS pointer){
-    return ((pointer&(0xFFFFFFFF00000000))>>33);
+    return (pointer>>33);
 }
 }
 
 
 inline RegXS getAVLRightPtr(RegXS pointer){
 inline RegXS getAVLRightPtr(RegXS pointer){
-    return ((pointer&(0x00000001FFFFFFFF))>>2);
+    return ((pointer&(0x00000001FFFFFFFC))>>2);
 }
 }
 
 
 inline void setAVLLeftPtr(RegXS &pointer, RegXS new_ptr){
 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){
 inline RegBS getLeftBal(RegXS pointer){
     RegBS bal_l;
     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);
     bal_l.set(bal_l_bit);
     return bal_l;
     return bal_l;
 }
 }
 
 
 inline RegBS getRightBal(RegXS pointer){
 inline RegBS getRightBal(RegXS pointer){
     RegBS bal_r;
     RegBS bal_r;
-    bool bal_r_bit = (pointer.share() & (0x0000000000000001)) & 1;
+    bool bal_r_bit = (pointer.share() & (0x0000000000000001));
     bal_r.set(bal_r_bit);
     bal_r.set(bal_r_bit);
     return bal_r;
     return bal_r;
 }
 }
@@ -142,7 +149,7 @@ class AVL {
 
 
     std::tuple<RegBS, RegBS, RegXS, RegBS> insert(MPCTIO &tio, yield_t &yield, RegXS ptr,
     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, 
         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,
     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,
         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);
         RegBS bal_l, RegBS bal_r, RegBS bal_upd, RegBS child_dir);
 
 
     void updateChildPointers(MPCTIO &tio, yield_t &yield, RegXS &left, RegXS &right,
     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, 
     void fixImbalance(MPCTIO &tio, yield_t &yield, Duoram<Node>::Flat &A, 
         Duoram<Node>::OblivIndex<RegXS,1> oidx, RegXS oidx_oldptrs, RegXS ptr, 
         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,
     bool lookup(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS key,
         Duoram<Node>::Flat &A, int TTL, RegBS isDummy, Node *ret_node);
         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:
   public:
     AVL(int num_players, size_t size) : oram(num_players, size) {
     AVL(int num_players, size_t size) : oram(num_players, size) {
         this->MAX_SIZE = size;
         this->MAX_SIZE = size;
@@ -188,13 +201,11 @@ class AVL {
         empty_locations.clear();
         empty_locations.clear();
     }
     }
 
 
-    size_t numEmptyLocations(){
-        return(empty_locations.size());
-    };
-
     void insert(MPCTIO &tio, yield_t &yield, const Node &node);
     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);
     bool del(MPCTIO &tio, yield_t &yield, RegAS del_key);
 
 
     // Returns the first node that matches key
     // Returns the first node that matches key
@@ -205,11 +216,7 @@ class AVL {
 
 
     // Display and correctness check functions
     // Display and correctness check functions
     void pretty_print(MPCTIO &tio, yield_t &yield);
     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);
     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);
     void print_oram(MPCTIO &tio, yield_t &yield);
 
 
     // For test functions ONLY:
     // 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;
     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.
     pointers to zeroes. The node is assigned a new random 64-bit value.
 */
 */
 static void randomize_node(Node &a) {
 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.
     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.
     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) {
         RegAS k2) {
     CDPF cdpf = tio.cdpf(yield);
     CDPF cdpf = tio.cdpf(yield);
     auto [lt, eq, gt] = cdpf.compare(tio, yield, k2 - k1, tio.aes_ops());
     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:
 // Assuming pointer of 64 bits is split as:
 // - 32 bits Left ptr (L)
 // - 32 bits Left ptr (L)
 // - 32 bits Right ptr (R)
 // - 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){
 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&=(0x00000000FFFFFFFF);
     pointer+=(new_ptr<<32);
     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.
     The recursive insert() call, invoked by the wrapper insert() function.
-    
+
     Takes as input the pointer to the current node in tree traversal (ptr),
     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
     flat (A), and the Time-To_live TTL, and a shared flag (isDummy) which
     tracks if the operation is dummy/real.
     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
     // Depending on [lteq, gt] select the next ptr/index as
     // upper 32 bits of cnode.pointers if lteq
     // 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 left = extractLeftPtr(cnode.pointers);
     RegXS right = extractRightPtr(cnode.pointers);
     RegXS right = extractRightPtr(cnode.pointers);
-    
+
     RegXS next_ptr;
     RegXS next_ptr;
     mpc_select(tio, yield, next_ptr, gt, left, right, 32);
     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_z = dpf.is_zero(tio, yield, next_ptr, aes_ops);
     RegBS F_i;
     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.
     //          insert new_node here.
     mpc_and(tio, yield, F_i, (isNotDummy), F_z);
     mpc_and(tio, yield, F_i, (isNotDummy), F_z);
-     
+
     isDummy^=F_i;
     isDummy^=F_i;
     auto [wptr, direction] = insert(tio, yield, next_ptr, new_node, A, TTL-1, isDummy);
     auto [wptr, direction] = insert(tio, yield, next_ptr, new_node, A, TTL-1, isDummy);
-    
+
     RegXS ret_ptr;
     RegXS ret_ptr;
     RegBS ret_direction;
     RegBS ret_direction;
     // If we insert here (F_i), return the ptr to this node as wptr
     // 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)
         //ret_direction = direction + F_i (direction - gt)
         { mpc_and(tio, yield, ret_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};
     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);
         bool insertAtEmptyLocation = (empty_locations.size() > 0);
         if(insertAtEmptyLocation) {
         if(insertAtEmptyLocation) {
             insert_address = empty_locations.back();
             insert_address = empty_locations.back();
-            empty_locations.pop_back(); 
+            empty_locations.pop_back();
             A[insert_address] = node;
             A[insert_address] = node;
         } else {
         } else {
             new_id = 1 + num_items;
             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 left_ptr = extractLeftPtr(pointers);
         RegXS right_ptr = extractRightPtr(pointers);
         RegXS right_ptr = extractRightPtr(pointers);
         RegXS new_right_ptr, new_left_ptr;
         RegXS new_right_ptr, new_left_ptr;
-    
-        RegBS not_direction = direction; 
+
+        RegBS not_direction = direction;
         if (player0) {
         if (player0) {
             not_direction^=1;
             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);},
             { 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)
             [&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);});
             { 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);
         setLeftPtr(pointers, new_left_ptr);
         setRightPtr(pointers, new_right_ptr);
         setRightPtr(pointers, new_right_ptr);
         A[wptr].NODE_POINTERS = pointers;
         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
     // Depending on [lteq, gt] select the next ptr/index as
     // upper 32 bits of cnode.pointers if lteq
     // 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 left = extractLeftPtr(cnode.pointers);
     RegXS right = extractRightPtr(cnode.pointers);
     RegXS right = extractRightPtr(cnode.pointers);
-    
+
     RegXS next_ptr;
     RegXS next_ptr;
 
 
     RegBS F_found;
     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
     // then we found the node to return
     RegBS isNotDummy = isDummy ^ (!tio.player());
     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.
     // Returning the first one incurs an additional round.
     std::vector<coro_t> coroutines;
     std::vector<coro_t> coroutines;
     coroutines.emplace_back(
     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);});
         { mpc_or(tio, yield, isDummy, isDummy, eq);});
     run_coroutines(tio, coroutines);
     run_coroutines(tio, coroutines);
 
 
-    #ifdef BST_DEBUG 
+    #ifdef BST_DEBUG
         size_t ckey = mpc_reconstruct(tio, yield, cnode.key, 64);
         size_t ckey = mpc_reconstruct(tio, yield, cnode.key, 64);
         size_t lkey = mpc_reconstruct(tio, yield, key, 64);
         size_t lkey = mpc_reconstruct(tio, yield, key, 64);
         bool rec_lt = mpc_reconstruct(tio, yield, lt);
         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_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);
         printf("rec_isDummy/found = %d ,rec_f_found = %d, cnode.key = %ld, lookup key = %ld\n", rec_found, rec_f_found, ckey, lkey);
     #endif
     #endif
-    
+
     RegBS found = lookup(tio, yield, next_ptr, key, A, TTL-1, isDummy, ret_node);
     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) {
 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.
     The recursive del() call, invoked by the wrapper del() function.
-    
+
     Takes as input the pointer to the current node in tree traversal (ptr),
     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
     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 location of the successor node and the node to delete to perform
     the actual deletion after the recursive traversal; which is required in
     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,
 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) {
     del_return &ret_struct) {
     bool player0 = tio.player()==0;
     bool player0 = tio.player()==0;
     //printf("TTL = %d\n", TTL);
     //printf("TTL = %d\n", TTL);
     if(TTL==0) {
     if(TTL==0) {
         //Reconstruct and return af
         //Reconstruct and return af
         bool success = reconstruct_RegBS(tio, yield, 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;
             ret_struct.F_r^=1;
         }
         }
         return success;
         return success;
@@ -466,11 +466,11 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegXS ptr, RegAS del_key,
         Node node = A[ptr];
         Node node = A[ptr];
         RegXS left = extractLeftPtr(node.pointers);
         RegXS left = extractLeftPtr(node.pointers);
         RegXS right = extractRightPtr(node.pointers);
         RegXS right = extractRightPtr(node.pointers);
-        
+
         CDPF cdpf = tio.cdpf(yield);
         CDPF cdpf = tio.cdpf(yield);
         size_t &aes_ops = tio.aes_ops();
         size_t &aes_ops = tio.aes_ops();
         RegBS l0, r0, lt, eq, gt;
         RegBS l0, r0, lt, eq, gt;
-        // l0: Is left child 0 
+        // l0: Is left child 0
         // r0: Is right child 0
         // r0: Is right child 0
         run_coroutines(tio,
         run_coroutines(tio,
             [&tio, &l0, left, &aes_ops, &cdpf](yield_t &yield)
             [&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);
         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)
         // (c=0: go left or c=1: go right)
         RegBS c = gt;
         RegBS c = gt;
         // lf = local found. We found the key to delete in this level.
         // 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 \xor r0
         F_1 = l0 ^ 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
         // edge cases where we do not go by just the comparison result
         RegXS next_ptr;
         RegXS next_ptr;
         RegBS c_prime;
         RegBS c_prime;
         // Case 1: found the node here (lf): we traverse down the lone child path.
         // 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;
         RegBS F_c1, F_c2, F_c3, F_c4;
 
 
         // Case 1: lf & F_1
         // 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)
             [&tio, &F_0, l0, r0] (yield_t &yield)
             // F_0 = l0 & r0
             // F_0 = l0 & r0
             { mpc_and(tio, 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) (Only 1 of F_0, F_1, and F_2 can be true)
         F_2 = F_0 ^ F_1;
         F_2 = F_0 ^ F_1;
         if(player0)
         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
             // In find successor case, so find inorder successor
             // (Go right and then find leftmost child.)
             // (Go right and then find leftmost child.)
             { mpc_and(tio, yield, F_c2, lf, F_2);});
             { mpc_and(tio, yield, F_c2, lf, F_2);});
-        
+
         /*
         /*
         // Reconstruct and Debug Block 2
         // Reconstruct and Debug Block 2
         bool F_c2_rec, s1_rec;
         bool F_c2_rec, s1_rec;
         F_c2_rec = mpc_reconstruct(tio, yield, F_c2);
         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);
         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);},
             { mpc_select(tio, yield, c_prime, F_c2, c_prime, s1);},
             [&tio, &F_c3, fs, F_2](yield_t &yield)
             [&tio, &F_c3, fs, F_2](yield_t &yield)
             // Case 3: finding successor (fs) and node has both children (F_2)
             // 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);});
             { mpc_and(tio, yield, F_c3, fs, F_2);});
 
 
         run_coroutines(tio,
         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);
         mpc_select(tio, yield, c_prime, F_c4, c_prime, l0);
 
 
         RegBS af_prime, fs_prime;
         RegBS af_prime, fs_prime;
-        run_coroutines(tio, 
+        run_coroutines(tio,
             [&tio, &next_ptr, c_prime, left, right](yield_t &yield)
             [&tio, &next_ptr, c_prime, left, right](yield_t &yield)
             // Set next_ptr
             // Set next_ptr
             { mpc_select(tio, yield, next_ptr, c_prime, left, right, 32);},
             { 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;
             return 0;
         }
         }
 
 
-        //printf("TTL = %d\n", TTL); 
+        //printf("TTL = %d\n", TTL);
         RegBS F_rs_right, F_rs_left, not_c_prime=c_prime;
         RegBS F_rs_right, F_rs_left, not_c_prime=c_prime;
         if(player0) {
         if(player0) {
             not_c_prime^=1;
             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);
         setRightPtr(new_ptr, right);
         A[ptr].NODE_POINTERS = new_ptr;
         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;
         RegBS F_nd, F_ns, F_r, not_af = af, not_F_2 = F_2;
         if(player0) {
         if(player0) {
             not_af^=1;
             not_af^=1;
             not_F_2^=1;
             not_F_2^=1;
         }
         }
-        // F_ns = fs & l0 
+        // F_ns = fs & l0
         // Finding successor flag & no more left child = F_c4
         // Finding successor flag & no more left child = F_c4
         F_ns = F_c4;
         F_ns = F_c4;
-    
-        run_coroutines(tio, 
+
+        run_coroutines(tio,
             [&tio, &ret_struct, F_c2](yield_t &yield)
             [&tio, &ret_struct, F_c2](yield_t &yield)
             { mpc_or(tio, yield, ret_struct.F_ss, ret_struct.F_ss, F_c2);},
             { mpc_or(tio, yield, ret_struct.F_ss, ret_struct.F_ss, F_c2);},
             [&tio, &F_nd, lf, not_af](yield_t &yield)
             [&tio, &F_nd, lf, not_af](yield_t &yield)
             { mpc_and(tio, yield, F_nd, lf, not_af);});
             { mpc_and(tio, yield, F_nd, lf, not_af);});
-            
+
 
 
         // F_r = F_d.(!F_2)
         // F_r = F_d.(!F_2)
         // If we have to delete here, and it doesn't have two children we have to
         // 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)
             [&tio, &ret_struct, F_r, ptr](yield_t &yield)
             { mpc_select(tio, yield, ret_struct.ret_ptr, F_r, ptr, ret_struct.ret_ptr);});
             { 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;
         return 1;
     }
     }
 }
 }
 
 
 /*
 /*
     The main del() function.
     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).
     Takes as input the key to delete (del_key).
     Returns success/fail bit.
     Returns success/fail bit.
@@ -684,22 +686,22 @@ bool BST::del(MPCTIO &tio, yield_t &yield, RegAS del_key) {
         empty_locations.emplace_back(root);
         empty_locations.emplace_back(root);
         A[root] = zero;
         A[root] = zero;
         num_items--;
         num_items--;
-        return 1; 
+        return 1;
     } else {
     } else {
         int TTL = num_items;
         int TTL = num_items;
         // Flags for already found (af) item to delete and find successor (fs)
         // Flags for already found (af) item to delete and find successor (fs)
         // if this deletion requires a successor swap
         // if this deletion requires a successor swap
         RegBS af;
         RegBS af;
         RegBS fs;
         RegBS fs;
-        del_return ret_struct; 
+        del_return ret_struct;
         auto A = oram.flat(tio, yield);
         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){
         if(!success){
             return 0;
             return 0;
         }
         }
         else{
         else{
-            num_items--; 
+            num_items--;
             /*
             /*
             printf("In delete's swap portion\n");
             printf("In delete's swap portion\n");
             Node del_node = A.reconstruct(A[ret_struct.N_d]);
             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];
             Node suc_node = A[ret_struct.N_s];
             RegAS zero_as; RegXS zero_xs;
             RegAS zero_as; RegXS zero_xs;
             RegXS empty_loc, temp_root = root;
             RegXS empty_loc, temp_root = root;
-         
-            run_coroutines(tio, 
+
+            run_coroutines(tio,
                 [&tio, &temp_root, ret_struct](yield_t &yield)
                 [&tio, &temp_root, ret_struct](yield_t &yield)
                 { mpc_select(tio, yield, temp_root, ret_struct.F_r, temp_root, ret_struct.ret_ptr);},
                 { 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)
                 [&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[] = {10, 10, 13, 11, 14, 8, 15, 20, 17, 19, 7, 12};
         //int insert_array[] = {1, 2, 3, 4, 5, 6};
         //int insert_array[] = {1, 2, 3, 4, 5, 6};
         size_t insert_array_size = sizeof(insert_array)/sizeof(int);
         size_t insert_array_size = sizeof(insert_array)/sizeof(int);
-        Node node; 
+        Node node;
         for(size_t i = 0; i<insert_array_size; i++) {
         for(size_t i = 0; i<insert_array_size; i++) {
           randomize_node(node);
           randomize_node(node);
           node.key.set(insert_array[i] * tio.player());
           node.key.set(insert_array[i] * tio.player());
           tree.insert(tio, yield, node);
           tree.insert(tio, yield, node);
         }
         }
-       
+
         tree.pretty_print(tio, yield);
         tree.pretty_print(tio, yield);
-         
+
         RegAS del_key;
         RegAS del_key;
 
 
         printf("\n\nDelete %x\n", 20);
         printf("\n\nDelete %x\n", 20);
@@ -863,7 +865,7 @@ void bst(MPCIO &mpcio,
             if(rec_found) {
             if(rec_found) {
                 printf("Lookup Success\n");
                 printf("Lookup Success\n");
                 size_t value = mpc_reconstruct(tio, yield, node.value, 64);
                 size_t value = mpc_reconstruct(tio, yield, node.value, 64);
-                printf("value = %lx\n", value);    
+                printf("value = %lx\n", value);
             } else {
             } else {
                 printf("Lookup Failed\n");
                 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.
     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.
     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).
     Returns the shared bit flags lteq (go left) and gt (go right).
 */
 */
@@ -161,7 +161,7 @@ struct del_return {
 };
 };
 
 
 class BST {
 class BST {
-  private: 
+  private:
     Duoram<Node> oram;
     Duoram<Node> oram;
     RegXS root;
     RegXS root;
 
 
@@ -175,10 +175,10 @@ class BST {
     void insert(MPCTIO &tio, yield_t &yield, const Node &node, Duoram<Node>::Flat &A);
     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,
     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);
         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);
         Duoram<Node>::Flat &A, int TTL, RegBS isDummy, Node *ret_node);
 
 
     void pretty_print(const std::vector<Node> &R, value_t 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);
         value_t node, value_t min_key, value_t max_key);
 
 
   public:
   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;
         this->MAX_SIZE = size;
     };
     };
 
 
@@ -196,8 +196,10 @@ class BST {
     // Inserts the provided node into the BST
     // Inserts the provided node into the BST
     void insert(MPCTIO &tio, yield_t &yield, Node &node);
     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
     // Returns the first node that matches key in the BST
     RegBS lookup(MPCTIO &tio, yield_t &yield, RegAS key, Node *ret_node);
     RegBS lookup(MPCTIO &tio, yield_t &yield, RegAS key, Node *ret_node);
@@ -210,14 +212,14 @@ class BST {
     // Check BST correctness
     // Check BST correctness
     void check_bst(MPCTIO &tio, yield_t &yield);
     void check_bst(MPCTIO &tio, yield_t &yield);
 
 
-    // Debugging Functions    
+    // Debugging Functions
 
 
     #ifdef BST_DEBUG
     #ifdef BST_DEBUG
 
 
         // Print the underlying ORAM state
         // Print the underlying ORAM state
         void print_oram(MPCTIO &tio, yield_t &yield);
         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.)
         // (Locations freed up after a delete operation, reusable for next insert.)
         size_t numEmptyLocations(){
         size_t numEmptyLocations(){
             return(empty_locations.size());
             return(empty_locations.size());

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików