I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 87953c4b authored by zzz's avatar zzz
Browse files

* Peer Selector: Make strict order opaque to hash value

parent be480d57
No related branches found
No related tags found
No related merge requests found
...@@ -11,6 +11,7 @@ import java.util.Set; ...@@ -11,6 +11,7 @@ import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.crypto.SHA256Generator;
import net.i2p.data.DataFormatException; import net.i2p.data.DataFormatException;
import net.i2p.data.Hash; import net.i2p.data.Hash;
import net.i2p.data.RouterInfo; import net.i2p.data.RouterInfo;
...@@ -477,6 +478,19 @@ public abstract class TunnelPeerSelector { ...@@ -477,6 +478,19 @@ public abstract class TunnelPeerSelector {
Collections.sort(rv, new HashComparator(hash)); 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 class HashComparator implements Comparator {
private Hash _hash; private Hash _hash;
...@@ -484,8 +498,14 @@ public abstract class TunnelPeerSelector { ...@@ -484,8 +498,14 @@ public abstract class TunnelPeerSelector {
_hash = h; _hash = h;
} }
public int compare(Object l, Object r) { public int compare(Object l, Object r) {
BigInteger ll = PeerSelector.getDistance(_hash, (Hash) l); byte[] data = new byte[2*Hash.HASH_LENGTH];
BigInteger rr = PeerSelector.getDistance(_hash, (Hash) r); 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); return ll.compareTo(rr);
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment