|  | @@ -171,7 +171,7 @@ DPFnode CDPF::leaf(value_t input, size_t &aes_ops) const
 | 
	
		
			
				|  |  |  //
 | 
	
		
			
				|  |  |  // Cost:
 | 
	
		
			
				|  |  |  // 1 word sent in 1 message
 | 
	
		
			
				|  |  | -// 3*VALUE_BITS - 22 = 170 local AES operations
 | 
	
		
			
				|  |  | +// 2*VALUE_BITS - 14 = 114 local AES operations
 | 
	
		
			
				|  |  |  std::tuple<RegBS,RegBS,RegBS> CDPF::compare(MPCTIO &tio, yield_t &yield,
 | 
	
		
			
				|  |  |      RegAS x, size_t &aes_ops)
 | 
	
		
			
				|  |  |  {
 | 
	
	
		
			
				|  | @@ -202,82 +202,87 @@ std::tuple<RegBS,RegBS,RegBS> CDPF::compare(MPCTIO &tio, yield_t &yield,
 | 
	
		
			
				|  |  |  // is needed.
 | 
	
		
			
				|  |  |  //
 | 
	
		
			
				|  |  |  // Cost:
 | 
	
		
			
				|  |  | -// 3*VALUE_BITS - 22 = 170 local AES operations
 | 
	
		
			
				|  |  | +// 2*VALUE_BITS - 14 = 114 local AES operations
 | 
	
		
			
				|  |  |  std::tuple<RegBS,RegBS,RegBS> CDPF::compare(value_t S, size_t &aes_ops)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      RegBS gt, eq;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    // Now we're going to simultaneously descend the DPF tree for
 | 
	
		
			
				|  |  | -    // the values S and T = S + 2^63.  Note that the 1 values of V
 | 
	
		
			
				|  |  | -    // (see the explanation of the algorithm in cdpf.hpp) are those
 | 
	
		
			
				|  |  | -    // values _strictly_ larger than S and smaller than T (noting
 | 
	
		
			
				|  |  | -    // they can "wrap around" 2^64).  In level 1 of the tree, the
 | 
	
		
			
				|  |  | -    // paths to S and T will necessarily be at the two different
 | 
	
		
			
				|  |  | -    // children of the root seed, but they could be in either order.
 | 
	
		
			
				|  |  | -    // From then on, they will proceed in lockstep, either both
 | 
	
		
			
				|  |  | -    // going left, or both going right.  If they both go left, we
 | 
	
		
			
				|  |  | -    // also compute the right sibling on the S path, and add it to
 | 
	
		
			
				|  |  | -    // the gt flag.  If they both go right, we also compute the left
 | 
	
		
			
				|  |  | -    // sibling on the T path, and add it to the gt flag.  When we
 | 
	
		
			
				|  |  | -    // hit the leaves, the gt flag will account for all of the
 | 
	
		
			
				|  |  | -    // complete leaf nodes strictly greater than S and strictly less
 | 
	
		
			
				|  |  | -    // than T.  Then we just have to pull out the parity of the
 | 
	
		
			
				|  |  | -    // appropriate bits in the two leaf nodes containing S and T
 | 
	
		
			
				|  |  | -    // respectively to complete the computation of gt, and also to
 | 
	
		
			
				|  |  | -    // get the single bit eq.
 | 
	
		
			
				|  |  | +    // Now we're going to simultaneously descend the DPF tree for the
 | 
	
		
			
				|  |  | +    // values S and T = S + 2^63.  Note that the 1 values of V (see the
 | 
	
		
			
				|  |  | +    // explanation of the algorithm in cdpf.hpp) are those values
 | 
	
		
			
				|  |  | +    // _strictly_ larger than S and smaller than T (noting they can
 | 
	
		
			
				|  |  | +    // "wrap around" 2^64).  In level 1 of the tree, the paths to S and
 | 
	
		
			
				|  |  | +    // T will necessarily be at the two different children of the root
 | 
	
		
			
				|  |  | +    // seed, but they could be in either order.  From then on, they will
 | 
	
		
			
				|  |  | +    // proceed in lockstep, either both going left, or both going right.
 | 
	
		
			
				|  |  | +    // If they both go left, we also compute the flag for the right
 | 
	
		
			
				|  |  | +    // sibling on the S path (which will be the XOR of the left sibling
 | 
	
		
			
				|  |  | +    // and the parent), and add it to the gt flag.  If they both go
 | 
	
		
			
				|  |  | +    // right, we also include the left sibling on the T path (which will
 | 
	
		
			
				|  |  | +    // be the XOR of the right sibling and the parent), and add it to
 | 
	
		
			
				|  |  | +    // the gt flag.  When we hit the leaves, the gt flag will account
 | 
	
		
			
				|  |  | +    // for all of the complete leaf nodes strictly greater than S and
 | 
	
		
			
				|  |  | +    // strictly less than T.  Then we just have to pull out the parity
 | 
	
		
			
				|  |  | +    // of the appropriate bits in the two leaf nodes containing S and T
 | 
	
		
			
				|  |  | +    // respectively to complete the computation of gt, and also to get
 | 
	
		
			
				|  |  | +    // the single bit eq.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    // Invariant: Snode is the node on level curlevel on the path to
 | 
	
		
			
				|  |  | -    // S, and Tnode is the node on level curlevel on the path to
 | 
	
		
			
				|  |  | -    // T = S + 2^63.
 | 
	
		
			
				|  |  |      nbits_t curlevel = 0;
 | 
	
		
			
				|  |  |      const nbits_t depth = VALUE_BITS - 7;
 | 
	
		
			
				|  |  | -    DPFnode Snode = seed;
 | 
	
		
			
				|  |  | -    DPFnode Tnode = seed;
 | 
	
		
			
				|  |  | +    DPFnode Sparent = seed;
 | 
	
		
			
				|  |  | +    DPFnode Tparent = seed;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // The top level is the only place where the paths to S and T go
 | 
	
		
			
				|  |  |      // in different directions.
 | 
	
		
			
				|  |  |      bool Sdir = !!(S & (value_t(1)<<63));
 | 
	
		
			
				|  |  | -    Snode = descend(Snode, curlevel, Sdir, aes_ops);
 | 
	
		
			
				|  |  | -    Tnode = descend(Tnode, curlevel, !Sdir, aes_ops);
 | 
	
		
			
				|  |  | +    DPFnode Snode = descend(Sparent, curlevel, Sdir, aes_ops);
 | 
	
		
			
				|  |  | +    DPFnode Tnode = descend(Tparent, curlevel, !Sdir, aes_ops);
 | 
	
		
			
				|  |  |      curlevel = 1;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    // The last level is special
 | 
	
		
			
				|  |  | +    // Invariant: Snode is the node on level curlevel on the path to
 | 
	
		
			
				|  |  | +    // S, and Tnode is the node on level curlevel on the path to
 | 
	
		
			
				|  |  | +    // T = S + 2^63.  Sparent and Tparent are the parents of Snode and
 | 
	
		
			
				|  |  | +    // Tnode respectively.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // The last level is special, so terminate the loop 1 before the end
 | 
	
		
			
				|  |  |      while(curlevel < depth-1) {
 | 
	
		
			
				|  |  |          Sdir = !!(S & (value_t(1)<<((depth+7)-curlevel-1)));
 | 
	
		
			
				|  |  | +        Sparent = Snode;
 | 
	
		
			
				|  |  | +        Tparent = Tnode;
 | 
	
		
			
				|  |  | +        Snode = descend(Sparent, curlevel, Sdir, aes_ops);
 | 
	
		
			
				|  |  | +        Tnode = descend(Tparent, curlevel, Sdir, aes_ops);
 | 
	
		
			
				|  |  | +        ++curlevel;
 | 
	
		
			
				|  |  |          if (Sdir == 0) {
 | 
	
		
			
				|  |  | -            // They're both going left; include the right child of
 | 
	
		
			
				|  |  | -            // Snode in the gt computation
 | 
	
		
			
				|  |  | -            DPFnode gtnode = descend(Snode, curlevel, 1, aes_ops);
 | 
	
		
			
				|  |  | -            gt ^= get_lsb(gtnode);
 | 
	
		
			
				|  |  | +            // They both went left; include the right child of
 | 
	
		
			
				|  |  | +            // Sparent in the gt computation
 | 
	
		
			
				|  |  | +            gt ^= get_lsb(Sparent) ^ get_lsb(Snode);
 | 
	
		
			
				|  |  |          } else {
 | 
	
		
			
				|  |  | -            // They're both going right; include the left child of
 | 
	
		
			
				|  |  | -            // Tnode in the gt computation
 | 
	
		
			
				|  |  | -            DPFnode gtnode = descend(Tnode, curlevel, 0, aes_ops);
 | 
	
		
			
				|  |  | -            gt ^= get_lsb(gtnode);
 | 
	
		
			
				|  |  | +            // Theye both went right; include the left child of
 | 
	
		
			
				|  |  | +            // Tparent in the gt computation
 | 
	
		
			
				|  |  | +            gt ^= get_lsb(Tparent) ^ get_lsb(Tnode);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        Snode = descend(Snode, curlevel, Sdir, aes_ops);
 | 
	
		
			
				|  |  | -        Tnode = descend(Tnode, curlevel, Sdir, aes_ops);
 | 
	
		
			
				|  |  | -        ++curlevel;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      // Now we're at the level just above the leaves.  If we go left,
 | 
	
		
			
				|  |  | -    // include *all* the bits (not just the low bit) of the right
 | 
	
		
			
				|  |  | -    // child of Snode, and if we go right, include all the bits of
 | 
	
		
			
				|  |  | -    // the left child of Tnode.
 | 
	
		
			
				|  |  | +    // include *all* the bits (not just the low bit) of the right child
 | 
	
		
			
				|  |  | +    // of Sparent (which will be the flag bit of Sparent XORed with the
 | 
	
		
			
				|  |  | +    // parity of all the bits of Snode), and if we go right, include all
 | 
	
		
			
				|  |  | +    // the bits of the left child of Tnode (which will be the flag bit
 | 
	
		
			
				|  |  | +    // of Tparent XORed with the parity of all the bits of Tnode).
 | 
	
		
			
				|  |  |      Sdir = !!(S & (value_t(1)<<((depth+7)-curlevel-1)));
 | 
	
		
			
				|  |  | +    Sparent = Snode;
 | 
	
		
			
				|  |  | +    Tparent = Tnode;
 | 
	
		
			
				|  |  | +    Snode = descend_to_leaf(Sparent, Sdir, aes_ops);
 | 
	
		
			
				|  |  | +    Tnode = descend_to_leaf(Tparent, Sdir, aes_ops);
 | 
	
		
			
				|  |  | +    ++curlevel;
 | 
	
		
			
				|  |  |      if (Sdir == 0) {
 | 
	
		
			
				|  |  | -        // They're both going left; include the right child of
 | 
	
		
			
				|  |  | +        // They both went left; include the right child of
 | 
	
		
			
				|  |  |          // Snode in the gt computation
 | 
	
		
			
				|  |  | -        DPFnode gtnode = descend_to_leaf(Snode, 1, aes_ops);
 | 
	
		
			
				|  |  | -        gt ^= parity(gtnode);
 | 
	
		
			
				|  |  | +        gt ^= get_lsb(Sparent) ^ parity(Snode);
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  |          // They're both going right; include the left child of
 | 
	
		
			
				|  |  |          // Tnode in the gt computation
 | 
	
		
			
				|  |  | -        DPFnode gtnode = descend_to_leaf(Tnode, 0, aes_ops);
 | 
	
		
			
				|  |  | -        gt ^= parity(gtnode);
 | 
	
		
			
				|  |  | +        gt ^= get_lsb(Tparent) ^ parity(Tnode);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    Snode = descend_to_leaf(Snode, Sdir, aes_ops);
 | 
	
		
			
				|  |  | -    Tnode = descend_to_leaf(Tnode, Sdir, aes_ops);
 | 
	
		
			
				|  |  | -    ++curlevel;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // Now Snode and Tnode are the leaves containing S and T
 | 
	
		
			
				|  |  |      // respectively.  Pull out the bit in Snode for S itself into eq,
 |