diff --git a/rust/src/ffi.rs b/rust/src/ffi.rs
index 035949d14d21a1094665ec04ba0cb27ae8c07b6f..8cd2c418646941d311d9fab1db3804ca5d766a6c 100644
--- a/rust/src/ffi.rs
+++ b/rust/src/ffi.rs
@@ -44,6 +44,7 @@ pub struct Blob
 }
 
 #[repr(C)]
+#[derive(PartialEq)]
 pub struct InfoHash
 {
     pub d: [u8; HASH_LEN],
@@ -144,6 +145,7 @@ extern {
     pub fn dht_infohash_print(h: *const InfoHash) -> *const c_char;
     pub fn dht_infohash_random(h: *mut InfoHash);
     pub fn dht_infohash_get(h: *mut InfoHash, dat: *mut u8, dat_size: size_t);
+    pub fn dht_infohash_from_hex(h: *mut InfoHash, dat: *const c_char);
     pub fn dht_infohash_is_zero(j: *const InfoHash) -> bool;
 
     // dht::PkId
diff --git a/rust/src/infohash.rs b/rust/src/infohash.rs
index df11ccd28ea4574e6906403458fda7bff9a9c265..a661bd3646731d5cfd4babc01bc5616403794fef 100644
--- a/rust/src/infohash.rs
+++ b/rust/src/infohash.rs
@@ -55,6 +55,15 @@ impl InfoHash {
         h
     }
 
+    pub fn from_hex(data: &str) -> InfoHash {
+        let mut h = InfoHash::new();
+        unsafe {
+            let c_str = CString::new(data).unwrap();
+            dht_infohash_from_hex(&mut h, c_str.as_ptr());
+        }
+        h
+    }
+
     pub fn is_zero(&self) -> bool {
         unsafe {
             dht_infohash_is_zero(self)
diff --git a/rust/src/value.rs b/rust/src/value.rs
index 9bee6493107272908fcc9267e3adf504d726be89..4794f15a8bbe7c04c843be956105c344368b4d4b 100644
--- a/rust/src/value.rs
+++ b/rust/src/value.rs
@@ -65,7 +65,7 @@ impl Value {
         }
     }
 
-    fn recipient(&self) -> InfoHash {
+    pub fn recipient(&self) -> InfoHash {
         unsafe {
             dht_value_get_recipient(self)
         }