diff --git a/wotb/data/legacy.rs b/wotb/data/legacy.rs
index 4aa3262cd10607b2e6957d6bdc2d67ebf75fab60..202807a26632302fe6f4cb7eda4c5d2a6d5521e7 100644
--- a/wotb/data/legacy.rs
+++ b/wotb/data/legacy.rs
@@ -16,16 +16,16 @@
 //! Provide a legacy implementation of `WebOfTrust` storage and calculations.
 //! Its mostly translated directly from the original C++ code.
 
-use std::collections::HashSet;
 use std::collections::hash_set::Iter;
+use std::collections::HashSet;
 use std::fs::File;
 use std::io::prelude::*;
 
 use bincode::{deserialize, serialize, Infinite};
 
 use super::{HasLinkResult, NewLinkResult, RemLinkResult};
-use WebOfTrust;
 use NodeId;
+use WebOfTrust;
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
 struct Node {
diff --git a/wotb/data/rusty.rs b/wotb/data/rusty.rs
index 1a47cfc515c12c22ac952a55bb7d94df48c6653f..e55fefaf88b5445c4e0fbdac482eefe0317a256e 100644
--- a/wotb/data/rusty.rs
+++ b/wotb/data/rusty.rs
@@ -15,11 +15,11 @@
 
 //! Experimental implementation of the Web of Trust in a more "rusty" style.
 
-use std::collections::HashSet;
-use rayon::prelude::*;
-use WebOfTrust;
 use super::{HasLinkResult, NewLinkResult, RemLinkResult};
+use rayon::prelude::*;
+use std::collections::HashSet;
 use NodeId;
+use WebOfTrust;
 
 /// A node in the `WoT` graph.
 #[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/wotb/lib.rs b/wotb/lib.rs
index 5169d7ca657780ab9bb48eab7e02f322c2f284d6..459355b995bed10684e87b6f6b204a4a7cd2f93b 100644
--- a/wotb/lib.rs
+++ b/wotb/lib.rs
@@ -27,9 +27,11 @@
 //! [js-tests]: https://github.com/duniter/wotb/blob/master/wotcpp/webOfTrust.cpp
 
 #![cfg_attr(feature = "strict", deny(warnings))]
-#![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
-        trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces,
-        unused_qualifications)]
+#![deny(
+    missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
+    trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces,
+    unused_qualifications
+)]
 
 extern crate bincode;
 extern crate byteorder;
@@ -47,9 +49,10 @@ pub use data::{NodeId, WebOfTrust};
 mod tests {
     use super::*;
     use data::*;
+    use operations::centrality::*;
     use operations::distance::*;
-    use operations::path::*;
     use operations::file::*;
+    use operations::path::*;
 
     /// Test translated from https://github.com/duniter/wotb/blob/master/tests/test.js
     ///
@@ -59,8 +62,9 @@ mod tests {
     where
         W: WebOfTrust + Sync,
     {
-        let path_finder = RustyPathFinder {};
+        let centralities_calculator = UlrikBrandesCentralityCalculator {};
         let distance_calculator = RustyDistanceCalculator {};
+        let path_finder = RustyPathFinder {};
         let mut wot = W::new(3);
 
         // should have an initial size of 0
@@ -561,8 +565,31 @@ mod tests {
             },)
         );
 
-        // Test centralities computation in g1_genesis wot
-        let wot_size = wot3.size();
+        // Test betweenness centralities computation in g1_genesis wot
+        let centralities = centralities_calculator.betweenness_centralities(&wot3);
+        assert_eq!(centralities.len(), 59);
+        assert_eq!(
+            centralities,
+            vec![
+                148, 30, 184, 11, 60, 51, 40, 115, 24, 140, 47, 69, 16, 34, 94, 126, 151, 0, 34,
+                133, 20, 103, 38, 144, 73, 523, 124, 23, 47, 17, 9, 64, 77, 281, 6, 105, 54, 0,
+                111, 21, 6, 2, 0, 1, 47, 59, 28, 236, 0, 0, 0, 0, 60, 6, 0, 1, 8, 33, 169,
+            ]
+        );
+
+        // Test stress centralities computation in g1_genesis wot
+        let stress_centralities = centralities_calculator.stress_centralities(&wot3);
+        assert_eq!(stress_centralities.len(), 59);
+        assert_eq!(
+            stress_centralities,
+            vec![
+                848, 240, 955, 80, 416, 203, 290, 645, 166, 908, 313, 231, 101, 202, 487, 769, 984,
+                0, 154, 534, 105, 697, 260, 700, 496, 1726, 711, 160, 217, 192, 89, 430, 636, 1276,
+                41, 420, 310, 0, 357, 125, 50, 15, 0, 12, 275, 170, 215, 1199, 0, 0, 0, 0, 201, 31,
+                0, 9, 55, 216, 865,
+            ]
+        );
+        /*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);
@@ -593,6 +620,6 @@ mod tests {
         for centrality in centralities {
             relative_centralities.push((centrality * 100_000 / oriented_couples_count) as usize);
         }
-        assert_eq!(relative_centralities.len(), 59);
+        assert_eq!(relative_centralities.len(), 59);*/
     }
 }
diff --git a/wotb/operations/centrality.rs b/wotb/operations/centrality.rs
new file mode 100644
index 0000000000000000000000000000000000000000..97ef9396600231d555b43c73243f519777f3bfa9
--- /dev/null
+++ b/wotb/operations/centrality.rs
@@ -0,0 +1,141 @@
+//  Copyright (C) 2017-2018  The Duniter Project Developers.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Provide a trait and implementations to find paths between nodes.
+
+use data::NodeId;
+use data::WebOfTrust;
+use std::collections::{HashMap, VecDeque};
+
+/// Find paths between 2 nodes of a `WebOfTrust`.
+pub trait CentralitiesCalculator<T: WebOfTrust> {
+    /// Compute betweenness centrality of all members.
+    fn betweenness_centralities(&self, wot: &T) -> Vec<u64>;
+    /// Compute stress centrality of all members.
+    fn stress_centralities(&self, wot: &T) -> Vec<u64>;
+}
+
+/// A new "rusty-er" implementation of `WoT` path finding.
+#[derive(Debug, Clone, Copy)]
+pub struct UlrikBrandesCentralityCalculator;
+
+impl<T: WebOfTrust> CentralitiesCalculator<T> for UlrikBrandesCentralityCalculator {
+    fn betweenness_centralities(&self, wot: &T) -> Vec<u64> {
+        let wot_size = wot.size();
+        let mut centralities = vec![0.0; wot_size];
+        let enabled_nodes = wot.get_enabled();
+
+        // The source of any path belongs to enabled_nodes
+        for s in enabled_nodes.clone() {
+            let mut stack: Vec<NodeId> = Vec::with_capacity(wot_size);
+            let mut paths: HashMap<NodeId, Vec<NodeId>> = HashMap::with_capacity(wot_size);
+            let mut sigma = vec![0.0; wot_size];
+            let mut d: Vec<isize> = vec![-1; wot_size];
+            let mut q: VecDeque<NodeId> = VecDeque::with_capacity(wot_size);
+
+            sigma[s.0] = 1.0;
+            d[s.0] = 0;
+            q.push_back(s);
+            while !q.is_empty() {
+                let v = q.pop_front().unwrap();
+                stack.push(v);
+                for w in wot.get_links_source(v).expect("v don't have any source !") {
+                    // w found for the first time ?
+                    if d[w.0] < 0 {
+                        q.push_back(w);
+                        d[w.0] = d[v.0] + 1;
+                    }
+                    // Shortest path to w via v
+                    if d[w.0] == d[v.0] + 1 {
+                        sigma[w.0] += sigma[v.0];
+                        paths.entry(w).or_insert_with(Vec::new).push(v);
+                    }
+                }
+            }
+            let mut delta = vec![0.0; wot_size];
+            // stack returns vertices in order of non-increasing distance from s
+            while !stack.is_empty() {
+                let w = stack.pop().unwrap();
+                if paths.contains_key(&w) {
+                    for v in paths.get(&w).expect("Not found w in p !") {
+                        if enabled_nodes.contains(&w) {
+                            delta[v.0] += (sigma[v.0] / sigma[w.0]) * (1.0 + delta[w.0]);
+                        } else {
+                            // If w not in enabled_nodes, no path can end at w
+                            delta[v.0] += (sigma[v.0] / sigma[w.0]) * delta[w.0];
+                        }
+                    }
+                }
+                if w != s {
+                    centralities[w.0] += delta[w.0];
+                }
+            }
+        }
+        centralities.into_iter().map(|c| c as u64).collect()
+    }
+    fn stress_centralities(&self, wot: &T) -> Vec<u64> {
+        let wot_size = wot.size();
+        let mut centralities = vec![0.0; wot_size];
+        let enabled_nodes = wot.get_enabled();
+
+        // The source of any path belongs to enabled_nodes
+        for s in enabled_nodes.clone() {
+            let mut stack: Vec<NodeId> = Vec::with_capacity(wot_size);
+            let mut paths: HashMap<NodeId, Vec<NodeId>> = HashMap::with_capacity(wot_size);
+            let mut sigma = vec![0.0; wot_size];
+            let mut d: Vec<isize> = vec![-1; wot_size];
+            let mut q: VecDeque<NodeId> = VecDeque::with_capacity(wot_size);
+
+            sigma[s.0] = 1.0;
+            d[s.0] = 0;
+            q.push_back(s);
+            while !q.is_empty() {
+                let v = q.pop_front().unwrap();
+                stack.push(v);
+                for w in wot.get_links_source(v).expect("v don't have any source !") {
+                    // w found for the first time ?
+                    if d[w.0] < 0 {
+                        q.push_back(w);
+                        d[w.0] = d[v.0] + 1;
+                    }
+                    // Shortest path to w via v
+                    if d[w.0] == d[v.0] + 1 {
+                        sigma[w.0] += sigma[v.0];
+                        paths.entry(w).or_insert_with(Vec::new).push(v);
+                    }
+                }
+            }
+            let mut delta = vec![0.0; wot_size];
+            // stack returns vertices in order of non-increasing distance from s
+            while !stack.is_empty() {
+                let w = stack.pop().unwrap();
+                if paths.contains_key(&w) {
+                    for v in paths.get(&w).expect("Not found w in p !") {
+                        if enabled_nodes.contains(&w) {
+                            delta[v.0] += sigma[v.0] * (1.0 + (delta[w.0] / sigma[w.0]));
+                        } else {
+                            // If w not in enabled_nodes, no path can end at w
+                            delta[v.0] += sigma[v.0] * (delta[w.0] / sigma[w.0]);
+                        }
+                    }
+                }
+                if w != s {
+                    centralities[w.0] += delta[w.0];
+                }
+            }
+        }
+        centralities.into_iter().map(|c| c as u64).collect()
+    }
+}
diff --git a/wotb/operations/distance.rs b/wotb/operations/distance.rs
index e097fe5bff7ee40be1c0ffaba6d915f44ff919b5..6f74bf1858834d65ffa40b169cdde634c4994bcf 100644
--- a/wotb/operations/distance.rs
+++ b/wotb/operations/distance.rs
@@ -15,10 +15,10 @@
 
 //! Provide a trait and implementations to compute distances.
 
-use std::collections::HashSet;
-use rayon::prelude::*;
-use data::WebOfTrust;
 use data::NodeId;
+use data::WebOfTrust;
+use rayon::prelude::*;
+use std::collections::HashSet;
 
 /// Paramters for `WoT` distance calculations
 #[derive(Debug, Copy, Clone, PartialEq)]
diff --git a/wotb/operations/file.rs b/wotb/operations/file.rs
index 7faba196f27be96d49217d1e74e8540c8682c79a..0f83673dbfa83962f210d8d96c34ee435efdcd2e 100644
--- a/wotb/operations/file.rs
+++ b/wotb/operations/file.rs
@@ -16,10 +16,10 @@
 //! Provide a trait and implementation to read and write `WebOfTrust` to disk.
 
 use data::NodeId;
-use std::io::prelude::*;
-use std::io;
 use std::fs;
 use std::fs::File;
+use std::io;
+use std::io::prelude::*;
 
 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
 
diff --git a/wotb/operations/mod.rs b/wotb/operations/mod.rs
index 2bd2782e2ec65ae636df61d6dde65cb4b055fccb..bc9564190043d15cecbbfc8c2ecdecd98dff0857 100644
--- a/wotb/operations/mod.rs
+++ b/wotb/operations/mod.rs
@@ -15,6 +15,7 @@
 
 //! Provide operation traits and implementations on `WebOfTrust` objects.
 
-pub mod path;
+pub mod centrality;
 pub mod distance;
 pub mod file;
+pub mod path;
diff --git a/wotb/operations/path.rs b/wotb/operations/path.rs
index 528283128702115dad6bf2d11440487209c50a5b..48690a0a3bfb9a0623d7cf9383e773c0f3e0dba2 100644
--- a/wotb/operations/path.rs
+++ b/wotb/operations/path.rs
@@ -15,9 +15,9 @@
 
 //! Provide a trait and implementations to find paths between nodes.
 
-use std::collections::HashSet;
 use data::NodeId;
 use data::WebOfTrust;
+use std::collections::HashSet;
 
 /// Find paths between 2 nodes of a `WebOfTrust`.
 pub trait PathFinder<T: WebOfTrust> {