From 87953c4b9374764d80d9843c3b5de65290bbd8b5 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Wed, 27 May 2009 16:59:38 +0000 Subject: [PATCH] * Peer Selector: Make strict order opaque to hash value --- .../tunnel/pool/TunnelPeerSelector.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) 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 92e4545171..c515310051 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); } } -- GitLab