diff --git a/Cargo.lock b/Cargo.lock
index f1f4cc636a9011212f306fa3f575d2f00aaa3cbf..0e06666e0c76a58cabcf2001a1a516943092eee9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -107,7 +107,7 @@ dependencies = [
 
 [[package]]
 name = "duniter-wotb"
-version = "0.7.0"
+version = "0.7.1"
 dependencies = [
  "bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/wotb/Cargo.toml b/wotb/Cargo.toml
index b37f08c63dca1e32ea16e19de9c27fc8343f536a..2977ee583d4aff8441d85394d8daa3e5377df931 100644
--- a/wotb/Cargo.toml
+++ b/wotb/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "duniter-wotb"
-version = "0.7.0"
+version = "0.7.1"
 authors = ["nanocryk <nanocryk@duniter.org>", "elois <elois@duniter.org>"]
 description = "Makes Web of Trust computations for the Duniter project."
 repository = "https://git.duniter.org/nodes/rust/duniter-rs"
diff --git a/wotb/lib.rs b/wotb/lib.rs
index 1a6fed792e1465fd3cb9491b7730cea7b86827ca..21767540d87c164dc6de54cdeadbfd35cf174c9d 100644
--- a/wotb/lib.rs
+++ b/wotb/lib.rs
@@ -828,5 +828,39 @@ mod tests {
                 outdistanced: false,
             },)
         );
+
+        // Test centralities computation in g1_genesis wot
+        let wot_size = wot3.size();
+        let members_count = wot3.get_enabled().len() as u64;
+        assert_eq!(members_count, 59);
+        let oriented_couples_count: u64 = members_count * (members_count - 1);
+        let mut centralities = vec![0; wot_size];
+        for i in 0..wot_size {
+            for j in 0..wot_size {
+                let paths = wot3.get_paths(NodeId(i), NodeId(j), 5);
+                let mut intermediate_members: Vec<NodeId> = Vec::new();
+                for path in paths {
+                    if path.len() > 2 {
+                        for node_id in &path[1..path.len() - 1] {
+                            if !intermediate_members.contains(node_id) {
+                                intermediate_members.push(*node_id);
+                            }
+                        }
+                    }
+                }
+                let centralities_copy = centralities.clone();
+                for node_id in intermediate_members {
+                    let centrality = &centralities_copy[node_id.0];
+                    if let Some(tmp) = centralities.get_mut(node_id.0) {
+                        *tmp = *centrality + 1;
+                    }
+                }
+            }
+        }
+        let mut relative_centralities = Vec::with_capacity(wot_size);
+        for centrality in centralities {
+            relative_centralities.push((centrality * 100_000 / oriented_couples_count) as usize);
+        }
+        assert_eq!(relative_centralities.len(), 59);
     }
 }
diff --git a/wotb/rusty.rs b/wotb/rusty.rs
index 9429690ccba6a7312b76dbb24ecb78c2c03f9cd5..8506ed13dd8d295b6f6afdccd73dcf5f34a984c8 100644
--- a/wotb/rusty.rs
+++ b/wotb/rusty.rs
@@ -219,33 +219,67 @@ impl WebOfTrust for RustyWebOfTrust {
     }
 
     fn get_paths(&self, from: NodeId, to: NodeId, k_max: u32) -> Vec<Vec<NodeId>> {
-        if from == to {
-            vec![vec![to]]
-        } else if k_max > 0 {
-            self.nodes[to.0]
-                .links_source
-                .par_iter()
-                .map(|&source| self.get_paths(from, source, k_max - 1))
-                .map(|paths| {
-                    paths
-                        .iter()
-                        .map(|path| {
-                            let mut path = path.clone();
-                            path.push(to);
-                            path
-                        })
-                        .collect::<Vec<Vec<NodeId>>>()
-                })
-                .reduce(
-                    || vec![],
-                    |mut acc, mut paths| {
-                        acc.append(&mut paths);
-                        acc
-                    },
-                )
-        } else {
-            vec![]
+        // 1. We explore the k_max area around `to`, and only remember backward
+        //    links of the smallest distance.
+
+        // Stores for each node its distance to `to` node and its backward links.
+        // By default all nodes are out of range (`k_max + 1`) and links are known.
+        let mut graph: Vec<(u32, Vec<usize>)> =
+            self.nodes.iter().map(|_| (k_max + 1, vec![])).collect();
+        // `to` node is at distance 0, and have no backward links.
+        graph[to.0] = (0, vec![]);
+        // Explored zone border.
+        let mut border = HashSet::new();
+        border.insert(to.0);
+
+        for distance in 1..(k_max + 1) {
+            let mut next_border = HashSet::new();
+
+            for node in border {
+                for source in &self.nodes[node].links_source {
+                    if graph[source.0].0 > distance {
+                        // shorter path, we replace
+                        graph[source.0] = (distance, vec![node]);
+                        next_border.insert(source.0);
+                    } else if graph[source.0].0 == distance {
+                        // same length, we combine
+                        graph[source.0].1.push(node);
+                        next_border.insert(source.0);
+                    }
+                }
+            }
+
+            border = next_border;
+        }
+
+        // 2. If `from` is found, we follow the backward links and build paths.
+        //    For each path, we look at the last element sources and build new paths with them.
+        let mut paths = vec![vec![from]];
+
+        for _ in 1..(k_max + 1) {
+            let mut new_paths = vec![];
+
+            for path in &paths {
+                let node = path.last().unwrap();
+
+                if node == &to {
+                    // If path is complete, we keep it.
+                    new_paths.push(path.clone())
+                } else {
+                    // If not complete we comlete paths
+                    let sources = &graph[node.0];
+                    for source in &sources.1 {
+                        let mut new_path = path.clone();
+                        new_path.push(NodeId(*source));
+                        new_paths.push(new_path);
+                    }
+                }                
+            }
+
+            paths = new_paths;
         }
+
+        paths
     }
 
     fn compute_distance(&self, params: WotDistanceParameters) -> Option<WotDistance> {