diff --git a/include/opendht/infohash.h b/include/opendht/infohash.h
index 2dadb14b1b5094214075fe0b47796bbcedd266f8..0329d904bb9d60b0ce75c5c5fee6f00621041db1 100644
--- a/include/opendht/infohash.h
+++ b/include/opendht/infohash.h
@@ -216,3 +216,22 @@ public:
 };
 
 }
+
+namespace std
+{
+    template<>
+    struct hash<dht::InfoHash>
+    {
+        typedef dht::InfoHash argument_type;
+        typedef std::size_t result_type;
+ 
+        result_type operator()(dht::InfoHash const& s) const
+        {
+            result_type r {};
+            std::hash<uint8_t> hash_fn;
+            for (size_t i = 0; i < HASH_LEN; i++)
+                r = r ^ (hash_fn(s[i]) << i*4);
+            return r;
+        }
+    };
+}
diff --git a/python/opendht.pyx b/python/opendht.pyx
index e960326bdbaa9e8cb118afc4c1b42e32aa7132e8..3e58fb43430d337436bbb437bca41d84ce2670f3 100644
--- a/python/opendht.pyx
+++ b/python/opendht.pyx
@@ -66,15 +66,28 @@ cdef class InfoHash(_WithID):
     cdef cpp.InfoHash _infohash
     def __init__(self, bytes str=b''):
         self._infohash = cpp.InfoHash(str)
-    def getBit(self, bit):
+    def __bool__(InfoHash self):
+        return not (self._infohash == cpp.InfoHash())
+    def __richcmp__(InfoHash self, InfoHash other, int op):
+        if op == 0:
+            return self._infohash < other._infohash
+        if op == 1:
+            return self._infohash < other._infohash or self._infohash == other._infohash
+        if op == 2:
+            return self._infohash == other._infohash
+        return NotImplemented
+    def __hash__(self):
+        cdef cpp.hash[cpp.InfoHash] hash_fn
+        return hash_fn.get(self._infohash)
+    def getBit(InfoHash self, bit):
         return self._infohash.getBit(bit)
-    def setBit(self, bit, b):
+    def setBit(InfoHash self, bit, b):
         self._infohash.setBit(bit, b)
-    def getId(self):
+    def getId(InfoHash self):
         return self
-    def toString(self):
+    def toString(InfoHash self):
         return self._infohash.toString()
-    def toFloat(self):
+    def toFloat(InfoHash self):
         return self._infohash.toFloat()
     @staticmethod
     def commonBits(InfoHash a, InfoHash b):
diff --git a/python/opendht_cpp.pxd b/python/opendht_cpp.pxd
index 23cde35b5f5fa268c43b31a3ff569155519fcc66..5ee950459833a96adc33b33d2d1a581c6a862ff0 100644
--- a/python/opendht_cpp.pxd
+++ b/python/opendht_cpp.pxd
@@ -12,7 +12,12 @@ cdef extern from "<memory>" namespace "std" nogil:
         shared_ptr() except +
         T* get()
         T operator*()
-        void reset(T*);
+        void reset(T*)
+
+cdef extern from "<functional>" namespace "std" nogil:
+    cdef cppclass hash[T]:
+        hash() except +
+        size_t get "operator()"(T)
 
 cdef extern from "<future>" namespace "std" nogil:
     cdef cppclass shared_future[T]:
@@ -38,6 +43,8 @@ cdef extern from "opendht/infohash.h" namespace "dht":
         InfoHash get(string s)
         @staticmethod
         InfoHash getRandom()
+        bool operator==(InfoHash)
+        bool operator<(InfoHash)
 
 cdef extern from "opendht/crypto.h" namespace "dht::crypto":
     ctypedef pair[shared_ptr[PrivateKey], shared_ptr[Certificate]] Identity