diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java
index 92e4545171cac325a29e91147e752ceffed3e72a..c515310051d3e6973ee19f86b1cd8799eb62bd15 100644
--- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java
+++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java
@@ -11,6 +11,7 @@ import java.util.Set;
 import java.util.StringTokenizer;
 
 import net.i2p.I2PAppContext;
+import net.i2p.crypto.SHA256Generator;
 import net.i2p.data.DataFormatException;
 import net.i2p.data.Hash;
 import net.i2p.data.RouterInfo;
@@ -477,6 +478,19 @@ public abstract class TunnelPeerSelector {
             Collections.sort(rv, new HashComparator(hash));
     }
 
+    /**
+     *  Implement a deterministic comparison that cannot be predicted by
+     *  others. A naive implementation (using the distance from a random key)
+     *  allows an attacker who runs two routers with hashes far apart
+     *  to maximize his chances of those two routers being at opposite
+     *  ends of a tunnel.
+     *
+     *  Previous:
+     *     d(l, h) - d(r, h)
+     *
+     *  Now:
+     *     d((H(l+h), h) - d(H(r+h), h)
+     */
     private class HashComparator implements Comparator {
         private Hash _hash;
 
@@ -484,8 +498,14 @@ public abstract class TunnelPeerSelector {
             _hash = h;
         }
         public int compare(Object l, Object r) {
-            BigInteger ll = PeerSelector.getDistance(_hash, (Hash) l);
-            BigInteger rr = PeerSelector.getDistance(_hash, (Hash) r);
+            byte[] data = new byte[2*Hash.HASH_LENGTH];
+            System.arraycopy(_hash.getData(), 0, data, Hash.HASH_LENGTH, Hash.HASH_LENGTH);
+            System.arraycopy(((Hash) l).getData(), 0, data, 0, Hash.HASH_LENGTH);
+            Hash lh = SHA256Generator.getInstance().calculateHash(data);
+            System.arraycopy(((Hash) r).getData(), 0, data, 0, Hash.HASH_LENGTH);
+            Hash rh = SHA256Generator.getInstance().calculateHash(data);
+            BigInteger ll = PeerSelector.getDistance(_hash, lh);
+            BigInteger rr = PeerSelector.getDistance(_hash, rh);
             return ll.compareTo(rr);
         }
     }