From c27ee25b4c814d7e595ae08d46faf2787fef81e9 Mon Sep 17 00:00:00 2001
From: librelois <elois@ifee.fr>
Date: Sun, 16 Sep 2018 15:24:06 +0200
Subject: [PATCH] [enh] WS2Pv2 : add human-readable format for peers v11 &
 heads v3

---
 Cargo.lock                                    |  17 +-
 Cargo.toml                                    |   1 -
 binarizer/Cargo.toml                          |  23 --
 binarizer/pubkey_box.rs                       |  91 -------
 binarizer/sig_box.rs                          |  90 -------
 binarizer/u16.rs                              |  48 ----
 binarizer/u32.rs                              |  48 ----
 .../lib.rs => crypto/keys/bin_signable.rs     |  77 ++----
 crypto/keys/mod.rs                            |   3 +-
 documents/Cargo.toml                          |   1 -
 documents/lib.rs                              |   5 +-
 network/Cargo.toml                            |   2 +-
 network/lib.rs                                |  20 +-
 network/network_endpoint.rs                   | 254 ++++++------------
 network/network_head_v3.rs                    | 117 +++++++-
 network/network_peer.rs                       |  59 +++-
 ws2p-messages/Cargo.toml                      |   1 -
 ws2p-messages/lib.rs                          |   3 +-
 ws2p-messages/v2/connect.rs                   | 120 ---------
 ws2p-messages/v2/mod.rs                       | 152 +----------
 ws2p-messages/v2/ok.rs                        |  86 ------
 ws2p-messages/v2/payload_container.rs         | 219 ---------------
 ws2p-messages/v2/req_responses.rs             |   1 -
 ws2p-messages/v2/requests.rs                  | 126 ---------
 ws2p-messages/v2/secret_flags.rs              | 110 --------
 ws2p-v1-legacy/Cargo.toml                     |   1 -
 ws2p-v1-legacy/lib.rs                         |   1 -
 ws2p/lib.rs                                   |   2 +-
 28 files changed, 294 insertions(+), 1384 deletions(-)
 delete mode 100644 binarizer/Cargo.toml
 delete mode 100644 binarizer/pubkey_box.rs
 delete mode 100644 binarizer/sig_box.rs
 delete mode 100644 binarizer/u16.rs
 delete mode 100644 binarizer/u32.rs
 rename binarizer/lib.rs => crypto/keys/bin_signable.rs (66%)

diff --git a/Cargo.lock b/Cargo.lock
index 4732f9f8..d36ea327 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -291,7 +291,6 @@ dependencies = [
  "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "duniter-crypto 0.2.0-a0.1",
- "dup-binarizer 0.1.0-a0.1",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -329,12 +328,12 @@ dependencies = [
 name = "duniter-network"
 version = "0.1.0-a0.1"
 dependencies = [
+ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "duniter-crypto 0.2.0-a0.1",
  "duniter-documents 0.8.0-a0.1",
  "duniter-module 0.1.0-a0.1",
- "dup-binarizer 0.1.0-a0.1",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -373,18 +372,6 @@ dependencies = [
  "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "dup-binarizer"
-version = "0.1.0-a0.1"
-dependencies = [
- "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "duniter-crypto 0.2.0-a0.1",
- "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "durs"
 version = "0.1.0-a0.1"
@@ -419,7 +406,6 @@ dependencies = [
  "duniter-crypto 0.2.0-a0.1",
  "duniter-documents 0.8.0-a0.1",
  "duniter-network 0.1.0-a0.1",
- "dup-binarizer 0.1.0-a0.1",
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -442,7 +428,6 @@ dependencies = [
  "duniter-module 0.1.0-a0.1",
  "duniter-network 0.1.0-a0.1",
  "duniter-wotb 0.8.0-a0.7",
- "dup-binarizer 0.1.0-a0.1",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 6d25b833..8e8d7b43 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,7 +20,6 @@ strict = []
 
 [workspace]
 members = [
-    "binarizer",
     "blockchain",
     "conf",
     "core",
diff --git a/binarizer/Cargo.toml b/binarizer/Cargo.toml
deleted file mode 100644
index 6e4f00e1..00000000
--- a/binarizer/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-name = "dup-binarizer"
-version = "0.1.0-a0.1"
-authors = ["librelois <elois@duniter.org>"]
-description = "Binarizer for Dividend Universel Protocol."
-license = "AGPL-3.0"
-
-[lib]
-path = "lib.rs"
-
-[dependencies]
-bincode = "1.0.1"
-byteorder = "1.2.3"
-duniter-crypto = { path = "../crypto" }
-rust-crypto = "0.2.*"
-serde = "1.0.78"
-
-[dev-dependencies]
-pretty_assertions = "0.5.1"
-
-[features]
-# Treat warnings as a build error.
-strict = []
\ No newline at end of file
diff --git a/binarizer/pubkey_box.rs b/binarizer/pubkey_box.rs
deleted file mode 100644
index 3edde2f7..00000000
--- a/binarizer/pubkey_box.rs
+++ /dev/null
@@ -1,91 +0,0 @@
-//  Copyright (C) 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/>.
-
-//! Defined all aspects of the inter-node network that concern all modules and are therefore independent of one implementation or another of this network layer.
-
-use duniter_crypto::keys::*;
-use u16::*;
-
-/// Total size of Ed25519 PubkeyBox
-pub static ED25519_PUBKEY_BOX_SIZE: &'static usize = &33;
-
-/// ReadPubkeyBoxError
-#[derive(Debug)]
-pub enum ReadPubkeyBoxError {
-    /// IoError
-    IoError(::std::io::Error),
-    /// TooShort
-    TooShort(),
-    /// TooLong
-    TooLong(),
-    /// AlgoNotSupported
-    AlgoNotSupported(),
-}
-
-impl From<::std::io::Error> for ReadPubkeyBoxError {
-    fn from(e: ::std::io::Error) -> Self {
-        ReadPubkeyBoxError::IoError(e)
-    }
-}
-
-/// WritePubkeyBoxError
-#[derive(Debug)]
-pub enum WritePubkeyBoxError {
-    /// IoError
-    IoError(::std::io::Error),
-    /// AlgoNotSupported
-    AlgoNotSupported(),
-}
-
-impl From<::std::io::Error> for WritePubkeyBoxError {
-    fn from(e: ::std::io::Error) -> Self {
-        WritePubkeyBoxError::IoError(e)
-    }
-}
-
-/// Read pubkey_box
-pub fn read_pubkey_box(datas: &[u8]) -> Result<(PubKey, u8), ReadPubkeyBoxError> {
-    if !datas.is_empty() {
-        match datas[0] {
-            0x00 => {
-                if datas.len() < *ED25519_PUBKEY_BOX_SIZE {
-                    Err(ReadPubkeyBoxError::TooShort())
-                } else if datas.len() > *ED25519_PUBKEY_BOX_SIZE {
-                    Err(ReadPubkeyBoxError::TooLong())
-                } else {
-                    let mut pubkey_bytes: [u8; 32] = [0u8; 32];
-                    pubkey_bytes.copy_from_slice(&datas[1..(*ED25519_PUBKEY_BOX_SIZE)]);
-                    Ok((PubKey::Ed25519(ed25519::PublicKey(pubkey_bytes)), 0x00))
-                }
-            }
-            _ => Err(ReadPubkeyBoxError::AlgoNotSupported()),
-        }
-    } else {
-        Err(ReadPubkeyBoxError::TooShort())
-    }
-}
-
-/// Write pubkey_box
-pub fn write_pubkey_box(buffer: &mut Vec<u8>, pubkey: PubKey) -> Result<(), WritePubkeyBoxError> {
-    match pubkey {
-        PubKey::Ed25519(ed25519_pubkey) => {
-            write_u16_be(buffer, *ED25519_PUBKEY_BOX_SIZE as u16)?;
-            buffer.push(0x00);
-            buffer.extend_from_slice(&ed25519_pubkey.0);
-            Ok(())
-        }
-        _ => Err(WritePubkeyBoxError::AlgoNotSupported()),
-    }
-}
diff --git a/binarizer/sig_box.rs b/binarizer/sig_box.rs
deleted file mode 100644
index 92f2bfb2..00000000
--- a/binarizer/sig_box.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-//  Copyright (C) 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/>.
-
-//! Defined all aspects of the inter-node network that concern all modules and are therefore independent of one implementation or another of this network layer.
-
-use duniter_crypto::keys::*;
-use u16::*;
-
-/// Total size of Ed25519 SigBox
-pub static ED25519_SIG_BOX_SIZE: &'static usize = &64;
-
-/// ReadSigBoxError
-#[derive(Debug)]
-pub enum ReadSigBoxError {
-    /// IoError
-    IoError(::std::io::Error),
-    /// TooShort
-    TooShort(),
-    /// TooLong
-    TooLong(),
-    /// AlgoNotSupported
-    AlgoNotSupported(),
-}
-
-impl From<::std::io::Error> for ReadSigBoxError {
-    fn from(e: ::std::io::Error) -> Self {
-        ReadSigBoxError::IoError(e)
-    }
-}
-
-/// WriteSigBoxError
-#[derive(Debug)]
-pub enum WriteSigBoxError {
-    /// IoError
-    IoError(::std::io::Error),
-    /// AlgoNotSupported
-    AlgoNotSupported(),
-}
-
-impl From<::std::io::Error> for WriteSigBoxError {
-    fn from(e: ::std::io::Error) -> Self {
-        WriteSigBoxError::IoError(e)
-    }
-}
-
-/// Read sig_box
-pub fn read_sig_box(datas: &[u8], algo: u8) -> Result<Sig, ReadSigBoxError> {
-    if !datas.is_empty() {
-        match algo {
-            0x00 => {
-                if datas.len() < *ED25519_SIG_BOX_SIZE {
-                    Err(ReadSigBoxError::TooShort())
-                } else if datas.len() > *ED25519_SIG_BOX_SIZE {
-                    Err(ReadSigBoxError::TooLong())
-                } else {
-                    let mut sig_bytes: [u8; 64] = [0u8; 64];
-                    sig_bytes.copy_from_slice(&datas[0..(*ED25519_SIG_BOX_SIZE)]);
-                    Ok(Sig::Ed25519(ed25519::Signature(sig_bytes)))
-                }
-            }
-            _ => Err(ReadSigBoxError::AlgoNotSupported()),
-        }
-    } else {
-        Err(ReadSigBoxError::TooShort())
-    }
-}
-
-/// Write sig_box
-pub fn write_sig_box(buffer: &mut Vec<u8>, sig: Sig) -> Result<(), WriteSigBoxError> {
-    match sig {
-        Sig::Ed25519(ed25519_sig) => {
-            write_u16_be(buffer, *ED25519_SIG_BOX_SIZE as u16)?;
-            buffer.extend_from_slice(&ed25519_sig.0);
-            Ok(())
-        }
-        _ => Err(WriteSigBoxError::AlgoNotSupported()),
-    }
-}
diff --git a/binarizer/u16.rs b/binarizer/u16.rs
deleted file mode 100644
index 9ce15877..00000000
--- a/binarizer/u16.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-//  Copyright (C) 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/>.
-
-//! Defined all aspects of the inter-node network that concern all modules and are therefore independent of one implementation or another of this network layer.
-
-use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
-use std::io::Cursor;
-use std::mem;
-
-/// Read u16 in big endian
-pub fn read_u16_be(datas: &[u8]) -> Result<u16, ::std::io::Error> {
-    let mut bytes = Cursor::new(datas.to_vec());
-    Ok(bytes.read_u16::<BigEndian>()?)
-}
-
-/// Read u16 in little endian
-pub fn read_u16_le(datas: &[u8]) -> Result<u16, ::std::io::Error> {
-    let mut bytes = Cursor::new(datas.to_vec());
-    Ok(bytes.read_u16::<LittleEndian>()?)
-}
-
-/// Write u16 in big endian
-pub fn write_u16_be(buffer: &mut Vec<u8>, number: u16) -> Result<(), ::std::io::Error> {
-    let mut buffer2 = [0u8; mem::size_of::<u16>()];
-    buffer2.as_mut().write_u16::<BigEndian>(number)?;
-    buffer.extend_from_slice(&buffer2);
-    Ok(())
-}
-
-/// Write u16 in little endian
-pub fn write_u16_le(buffer: &mut Vec<u8>, number: u16) -> Result<(), ::std::io::Error> {
-    let mut buffer2 = [0u8; mem::size_of::<u16>()];
-    buffer2.as_mut().write_u16::<LittleEndian>(number)?;
-    buffer.extend_from_slice(&buffer2);
-    Ok(())
-}
diff --git a/binarizer/u32.rs b/binarizer/u32.rs
deleted file mode 100644
index 1788304f..00000000
--- a/binarizer/u32.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-//  Copyright (C) 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/>.
-
-//! Defined all aspects of the inter-node network that concern all modules and are therefore independent of one implementation or another of this network layer.
-
-use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
-use std::io::Cursor;
-use std::mem;
-
-/// Read u32 in big endian
-pub fn read_u32_be(datas: &[u8]) -> Result<u32, ::std::io::Error> {
-    let mut bytes = Cursor::new(datas.to_vec());
-    Ok(bytes.read_u32::<BigEndian>()?)
-}
-
-/// Read u32 in little endian
-pub fn read_u32_le(datas: &[u8]) -> Result<u32, ::std::io::Error> {
-    let mut bytes = Cursor::new(datas.to_vec());
-    Ok(bytes.read_u32::<LittleEndian>()?)
-}
-
-/// Write u32 in big endian
-pub fn write_u32_be(buffer: &mut Vec<u8>, number: u32) -> Result<(), ::std::io::Error> {
-    let mut buffer2 = [0u8; mem::size_of::<u32>()];
-    buffer2.as_mut().write_u32::<BigEndian>(number)?;
-    buffer.extend_from_slice(&buffer2);
-    Ok(())
-}
-
-/// Write u32 in little endian
-pub fn write_u32_le(buffer: &mut Vec<u8>, number: u32) -> Result<(), ::std::io::Error> {
-    let mut buffer2 = [0u8; mem::size_of::<u32>()];
-    buffer2.as_mut().write_u32::<LittleEndian>(number)?;
-    buffer.extend_from_slice(&buffer2);
-    Ok(())
-}
diff --git a/binarizer/lib.rs b/crypto/keys/bin_signable.rs
similarity index 66%
rename from binarizer/lib.rs
rename to crypto/keys/bin_signable.rs
index 899e3143..3c572131 100644
--- a/binarizer/lib.rs
+++ b/crypto/keys/bin_signable.rs
@@ -1,4 +1,4 @@
-//  Copyright (C) 2018  The Duniter Project Developers.
+//  Copyright (C) 2018  The Durs 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
@@ -13,56 +13,17 @@
 // 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/>.
 
-//! Defined all aspects of the inter-node network that concern all modules and are therefore independent of one implementation or another of this network layer.
+//! Generic code for signing data in binary format
 
-#![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
-)]
-
-//#[cfg(test)]
-//#[macro_use]
-//extern crate pretty_assertions;
-
-extern crate bincode;
-extern crate byteorder;
-extern crate crypto;
-extern crate duniter_crypto;
-extern crate serde;
-
-pub mod pubkey_box;
-pub mod sig_box;
-pub mod u16;
-pub mod u32;
-
-use bincode::serialize;
-use duniter_crypto::hashs::*;
-use duniter_crypto::keys::*;
+use super::*;
+use bincode;
+use hashs::Hash;
 use serde::{Deserialize, Serialize};
 
-/// BinMessage := Message in binary format.
-pub trait BinMessage: Sized {
-    /// ReadBytesError
-    type ReadBytesError;
-    /// Create Self from bytes slice
-    fn from_bytes(&[u8]) -> Result<Self, Self::ReadBytesError>;
-    /// Convert Self to bytes vector
-    fn to_bytes_vector(&self) -> Vec<u8>;
-}
-
-/// Signatureable bin message
-pub trait BinMessageSignable<'de>: Serialize + Deserialize<'de> {
+/// Signatureable in binary format
+pub trait BinSignable<'de>: Serialize + Deserialize<'de> {
     /// Return message issuer pubkey
-    fn issuer_pubkey(&self) -> PubKey {
-        PubKey::default()
-    }
+    fn issuer_pubkey(&self) -> PubKey;
     /// Return true if message store is hash
     fn store_hash(&self) -> bool {
         false
@@ -74,19 +35,19 @@ pub trait BinMessageSignable<'de>: Serialize + Deserialize<'de> {
     /// Change hash (redefine ly by messages with hash field)
     fn set_hash(&mut self, _hash: Hash) {}
     /// Return message signature
-    fn signature(&self) -> Option<Sig> {
-        None
-    }
-    /// Store signature
+    fn signature(&self) -> Option<Sig>;
+    /// Change signature
     fn set_signature(&mut self, _signature: Sig);
     /// Compute hash
     fn compute_hash(&self) -> Result<(Hash, Vec<u8>), bincode::Error> {
-        let mut bin_msg = serialize(&self)?;
-        bin_msg.pop(); // Delete sig: None
+        let mut bin_msg = bincode::serialize(&self)?;
+        let sig_size = bincode::serialized_size(&self.signature())?;
+        let bin_msg_len = bin_msg.len();
+        bin_msg.truncate(bin_msg_len - (sig_size as usize));
         if self.store_hash() {
             bin_msg.pop(); // Delete hash: None
         }
-        // Compute hash
+        // Compute hash of binary datas without signature
         let hash = Hash::compute(&bin_msg);
         Ok((hash, bin_msg))
     }
@@ -105,11 +66,12 @@ pub trait BinMessageSignable<'de>: Serialize + Deserialize<'de> {
                     self.set_signature(sig);
                     if self.hash().is_some() {
                         bin_msg.extend_from_slice(
-                            &serialize(&Some(hash)).expect("Fail to binarize hash !"),
+                            &bincode::serialize(&Some(hash)).expect("Fail to binarize hash !"),
                         );
                     }
-                    bin_msg
-                        .extend_from_slice(&serialize(&Some(sig)).expect("Fail to binarize sig !"));
+                    bin_msg.extend_from_slice(
+                        &bincode::serialize(&Some(sig)).expect("Fail to binarize sig !"),
+                    );
                     Ok(bin_msg)
                 }
                 _ => Err(SignError::WrongAlgo()),
@@ -128,6 +90,7 @@ pub trait BinMessageSignable<'de>: Serialize + Deserialize<'de> {
                         } else {
                             self.compute_hash()?
                         };
+                        println!("DEBUG: verified hash={:?}", hash.0);
                         if pubkey.verify(&hash.0, &sig) {
                             Ok(())
                         } else {
diff --git a/crypto/keys/mod.rs b/crypto/keys/mod.rs
index 5f07e568..b110b95e 100644
--- a/crypto/keys/mod.rs
+++ b/crypto/keys/mod.rs
@@ -56,10 +56,11 @@ use std::fmt::Error;
 use std::fmt::Formatter;
 use std::hash::Hash;
 
+pub mod bin_signable;
 pub mod ed25519;
 
 /// Cryptographic keys algorithms list
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
 pub enum KeysAlgo {
     /// Ed25519 algorithm
     Ed25519 = 0,
diff --git a/documents/Cargo.toml b/documents/Cargo.toml
index efc02dee..0f6fd6ff 100644
--- a/documents/Cargo.toml
+++ b/documents/Cargo.toml
@@ -22,7 +22,6 @@ regex = "1.0.*"
 rust-crypto = "0.2.*"
 serde = "1.0.*"
 serde_derive = "1.0.*"
-dup-binarizer = { path = "../binarizer" }
 
 [features]
 # Treat warnings as a build error.
diff --git a/documents/lib.rs b/documents/lib.rs
index b7577984..e36b3412 100644
--- a/documents/lib.rs
+++ b/documents/lib.rs
@@ -38,7 +38,6 @@ extern crate base64;
 extern crate byteorder;
 extern crate crypto;
 extern crate duniter_crypto;
-extern crate dup_binarizer;
 extern crate linked_hash_map;
 extern crate regex;
 extern crate serde;
@@ -46,7 +45,6 @@ extern crate serde;
 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
 use currencies_codes::*;
 use duniter_crypto::hashs::Hash;
-use dup_binarizer::BinMessage;
 use std::cmp::Ordering;
 use std::fmt::{Debug, Display, Error, Formatter};
 use std::io::Cursor;
@@ -240,6 +238,7 @@ impl From<::std::io::Error> for ReadBytesBlockstampError {
     }
 }
 
+/*
 impl BinMessage for Blockstamp {
     type ReadBytesError = ReadBytesBlockstampError;
     fn from_bytes(bytes: &[u8]) -> Result<Self, Self::ReadBytesError> {
@@ -272,7 +271,7 @@ impl BinMessage for Blockstamp {
         bytes.extend(self.hash.0.to_bytes_vector());
         bytes
     }
-}
+}*/
 
 impl Blockstamp {
     /// Create a `BlockUId` from a text.
diff --git a/network/Cargo.toml b/network/Cargo.toml
index cbf48989..f31e48bf 100644
--- a/network/Cargo.toml
+++ b/network/Cargo.toml
@@ -9,11 +9,11 @@ license = "AGPL-3.0"
 path = "lib.rs"
 
 [dependencies]
+base58 = "0.1.*"
 byteorder = "1.2.3"
 duniter-crypto = { path = "../crypto" }
 duniter-documents = { path = "../documents" }
 duniter-module = { path = "../module" }
-dup-binarizer = { path = "../binarizer" }
 lazy_static = "1.0.*"
 regex = "1.0.*"
 rust-crypto = "0.2.*"
diff --git a/network/lib.rs b/network/lib.rs
index 4feb04e9..90eef259 100644
--- a/network/lib.rs
+++ b/network/lib.rs
@@ -30,18 +30,18 @@
 
 #[macro_use]
 extern crate lazy_static;
-//#[cfg(test)]
-//#[macro_use]
-//extern crate pretty_assertions;
+#[cfg(test)]
+#[macro_use]
+extern crate pretty_assertions;
 #[macro_use]
 extern crate serde_derive;
 
+extern crate base58;
 extern crate byteorder;
 extern crate crypto;
 extern crate duniter_crypto;
 extern crate duniter_documents;
 extern crate duniter_module;
-extern crate dup_binarizer;
 extern crate serde;
 extern crate serde_json;
 
@@ -62,16 +62,13 @@ use duniter_documents::blockchain::v10::documents::{
 use duniter_documents::blockchain::Document;
 use duniter_documents::{BlockHash, BlockId, Blockstamp};
 use duniter_module::*;
+use network_endpoint::ApiFeatures;
 use network_head::NetworkHead;
 use network_peer::PeerCard;
 use std::fmt::{Debug, Display, Error, Formatter};
 use std::ops::Deref;
 use std::sync::mpsc;
 
-#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
-/// ApiFeatures
-pub struct ApiFeatures(pub Vec<u8>);
-
 /// ApiModule
 pub trait ApiModule<DC: DuniterConf, M: ModuleMessage>: DuniterModule<DC, M> {
     /// Parsing error
@@ -354,6 +351,13 @@ mod tests {
     use super::network_endpoint::*;
     use super::*;
 
+    pub fn keypair1() -> ed25519::KeyPair {
+        ed25519::KeyPairFromSaltedPasswordGenerator::with_default_parameters().generate(
+            "JhxtHB7UcsDbA9wMSyMKXUzBZUQvqVyB32KwzS9SWoLkjrUhHV".as_bytes(),
+            "JhxtHB7UcsDbA9wMSyMKXUzBZUQvqVyB32KwzS9SWoLkjrUhHV_".as_bytes(),
+        )
+    }
+
     #[test]
     fn parse_endpoint() {
         let issuer = PubKey::Ed25519(
diff --git a/network/network_endpoint.rs b/network/network_endpoint.rs
index 5342e306..e33a864b 100644
--- a/network/network_endpoint.rs
+++ b/network/network_endpoint.rs
@@ -28,7 +28,7 @@ use duniter_crypto::keys::PubKey;
 use std::net::{AddrParseError, Ipv4Addr, Ipv6Addr};
 use std::num::ParseIntError;
 use std::str::FromStr;
-use {ApiFeatures, NodeFullId, NodeId};
+use {NodeFullId, NodeId};
 
 /// Total size of all fixed size fields of an EndpointV2
 pub static ENDPOINTV2_FIXED_SIZE: &'static usize = &9;
@@ -37,6 +37,40 @@ pub static MAX_NETWORK_FEATURES_COUNT: &'static usize = &2040;
 /// Maximum number of api features
 pub static MAX_API_FEATURES_COUNT: &'static usize = &2040;
 
+#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
+/// ApiFeatures
+pub struct ApiFeatures(pub Vec<u8>);
+
+impl ApiFeatures {
+    fn to_string_for_api(&self, api: &NetworkEndpointApi) -> String {
+        match api.0.as_str() {
+            "WS2P" => {
+                let mut af_count = 0;
+                let def = if self.0[0] | 0b_1111_1110 == 255u8 {
+                    af_count += 1;
+                    " DEF"
+                } else {
+                    ""
+                };
+                let low = if self.0[0] | 0b_1111_1101 == 255u8 {
+                    af_count += 1;
+                    " LOW"
+                } else {
+                    ""
+                };
+                let abf = if self.0[0] | 0b_1111_1011 == 255u8 {
+                    af_count += 1;
+                    " ABF"
+                } else {
+                    ""
+                };
+                format!("{}{}{}{}", af_count, def, low, abf)
+            }
+            _ => String::from(""),
+        }
+    }
+}
+
 lazy_static! {
     #[derive(Debug)]
     /// Regex match all endpoint in V1 format (works for all api)
@@ -148,6 +182,18 @@ pub struct EndpointEnumV1 {
 /// Network features
 pub struct EndpointV2NetworkFeatures(pub Vec<u8>);
 
+impl ToString for EndpointV2NetworkFeatures {
+    fn to_string(&self) -> String {
+        if self.tls() {
+            String::from("1 TLS")
+        } else if self.tor() {
+            String::from("1 TOR")
+        } else {
+            String::from("")
+        }
+    }
+}
+
 impl EndpointV2NetworkFeatures {
     /// Parse network features from utf8 string's array
     pub fn from_str_array(
@@ -229,6 +275,43 @@ pub struct EndpointV2 {
     pub path: Option<String>,
 }
 
+impl ToString for EndpointV2 {
+    fn to_string(&self) -> String {
+        let host: String = if let Some(ref host) = self.host {
+            format!("{} ", host)
+        } else {
+            String::from("")
+        };
+        let ip4: String = if let Some(ip4) = self.ip_v4 {
+            format!("{} ", ip4.to_string())
+        } else {
+            String::from("")
+        };
+        let ip6: String = if let Some(ip6) = self.ip_v6 {
+            format!("[{}] ", ip6.to_string())
+        } else {
+            String::from("")
+        };
+        let path: &str = if let Some(ref path) = self.path {
+            path
+        } else {
+            ""
+        };
+        format!(
+            "{api} {version} {nf} {af} {port} {host}{ip4}{ip6}{path}",
+            api = self.api.0,
+            version = self.api_version,
+            nf = self.network_features.to_string(),
+            af = self.api_features.to_string_for_api(&self.api),
+            port = self.port,
+            host = host,
+            ip4 = ip4,
+            ip6 = ip6,
+            path = path,
+        )
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
 /// Size informations of Endpoint v2
 pub struct EndpointV2Size {
@@ -270,170 +353,6 @@ impl EndpointV2Size {
     }
 }
 
-/*
-impl BinMessage for EndpointV2 {
-    type ReadBytesError = EndpointReadBytesError;
-
-    fn to_bytes_vector(&self) -> Vec<u8> {
-        let endpoint_size = self.compute_endpoint_size();
-        let mut binary_endpoint = Vec::with_capacity(endpoint_size.total_size());
-        binary_endpoint.push(endpoint_size.api_size);
-        binary_endpoint.push(endpoint_size.host_size);
-        binary_endpoint.push(endpoint_size.path_size);
-        binary_endpoint.append(&mut self.api.to_bytes_vector());
-        // api_version
-        let mut buffer = [0u8; mem::size_of::<u16>()];
-        buffer
-            .as_mut()
-            .write_u16::<BigEndian>(self.api_version)
-            .expect("Unable to write");
-        binary_endpoint.extend_from_slice(&buffer);
-        // nf_size
-        binary_endpoint.push(endpoint_size.nf_size);
-        // network_features
-        binary_endpoint.extend_from_slice(&self.network_features.to_bytes_slice());
-        binary_endpoint.push(endpoint_size.af_size);
-        binary_endpoint.append(&mut self.api_features.0.clone());
-        if let Some(ip_v4) = self.ip_v4 {
-            binary_endpoint.extend_from_slice(&ip_v4.octets());
-        }
-        if let Some(ip_v6) = self.ip_v6 {
-            binary_endpoint.extend_from_slice(&ip_v6.octets());
-        }
-        if let Some(ref host) = self.host {
-            binary_endpoint.extend_from_slice(host.as_bytes());
-        }
-        // port
-        let mut buffer = [0u8; mem::size_of::<u16>()];
-        buffer
-            .as_mut()
-            .write_u16::<BigEndian>(self.port)
-            .expect("Unable to write");
-        binary_endpoint.extend_from_slice(&buffer);
-        // path
-        if let Some(ref path) = self.path {
-            binary_endpoint.extend_from_slice(path.as_bytes());
-        }
-        binary_endpoint
-    }
-    /// Create endpoint from bytes vector
-    fn from_bytes(binary_ep: &[u8]) -> Result<EndpointV2, EndpointReadBytesError> {
-        if binary_ep.len() < *ENDPOINTV2_FIXED_SIZE {
-            return Err(EndpointReadBytesError::TooShort());
-        }
-        let api_size = binary_ep[0] as usize;
-        let host_size = binary_ep[1] as usize;
-        let path_size = binary_ep[2] as usize;
-        if binary_ep.len() < (*ENDPOINTV2_FIXED_SIZE + api_size + host_size + path_size) {
-            return Err(EndpointReadBytesError::TooShort());
-        }
-        let mut index: usize = 3;
-        // read api
-        let api_datas = if api_size == 0 {
-            index += 1;
-            &binary_ep[index - 1..index]
-        } else {
-            index += api_size;
-            &binary_ep[index - api_size..index]
-        };
-        let api = NetworkEndpointApi::api_from_bytes(api_size, api_datas)?;
-        // read api_version
-        let mut api_version_bytes = Cursor::new(binary_ep[index..index + 2].to_vec());
-        index += 2;
-        let api_version = api_version_bytes.read_u16::<BigEndian>()?;
-        // read nf_size
-        let nf_size = binary_ep[index] as usize;
-        index += 1;
-        if binary_ep.len() < index + nf_size + 1 {
-            return Err(EndpointReadBytesError::TooShort());
-        }
-        // read network_features
-        let network_features =
-            EndpointV2NetworkFeatures(binary_ep[index..index + nf_size].to_vec());
-        index += nf_size;
-        // read af_size
-        let af_size = binary_ep[index] as usize;
-        index += 1;
-        if binary_ep.len() < index + af_size + 1 {
-            return Err(EndpointReadBytesError::TooShort());
-        }
-        // read api_features
-        let api_features = ApiFeatures(binary_ep[index..index + nf_size].to_vec());
-        index += af_size;
-        // read ip_v4
-        let ip_v4 = network_features.ip_v4();
-        if binary_ep.len() < index + 4 && ip_v4 {
-            return Err(EndpointReadBytesError::TooShort());
-        }
-        let ip_v4 = if ip_v4 {
-            index += 4;
-            Some(Ipv4Addr::new(
-                binary_ep[index - 4],
-                binary_ep[index - 3],
-                binary_ep[index - 2],
-                binary_ep[index - 1],
-            ))
-        } else {
-            None
-        };
-        // read ip_v6
-        let ip_v6 = network_features.ip_v6();
-        if binary_ep.len() < index + 16 && ip_v6 {
-            return Err(EndpointReadBytesError::TooShort());
-        }
-        let ip_v6 = if ip_v6 {
-            index += 16;
-            let mut ip_v6_datas: [u8; 16] = [0u8; 16];
-            ip_v6_datas.copy_from_slice(&binary_ep[index - 16..index]);
-            Some(Ipv6Addr::from(ip_v6_datas))
-        } else {
-            None
-        };
-        // read host
-        if binary_ep.len() < index + host_size + 2 {
-            return Err(EndpointReadBytesError::TooShort());
-        }
-        let host = if host_size > 0 {
-            index += host_size;
-            Some(String::from_utf8(
-                binary_ep[index - host_size..index].to_vec(),
-            )?)
-        } else {
-            None
-        };
-        // read port
-        let mut port_bytes = Cursor::new((&binary_ep[index..index + 2]).to_vec());
-        index += 2;
-        let port = port_bytes.read_u16::<BigEndian>()?;
-        // read path
-        if binary_ep.len() < index + path_size {
-            return Err(EndpointReadBytesError::TooShort());
-        } else if binary_ep.len() > index + path_size {
-            return Err(EndpointReadBytesError::TooLong());
-        }
-        let path = if path_size > 0 {
-            Some(String::from_utf8(
-                binary_ep[index..index + path_size].to_vec(),
-            )?)
-        } else {
-            None
-        };
-        Ok(EndpointV2 {
-            api,
-            api_version,
-            network_features,
-            api_features,
-            ip_v4,
-            ip_v6,
-            host,
-            port,
-            path,
-            status: 0,
-            last_check: 0,
-        })
-    }
-}*/
-
 impl EndpointV2 {
     /// Generate endpoint url
     pub fn get_url(&self, get_protocol: bool, supported_ip_v6: bool) -> Option<String> {
@@ -710,7 +629,7 @@ impl ToString for EndpointEnum {
     fn to_string(&self) -> String {
         match *self {
             EndpointEnum::V1(ref ep) => ep.raw_endpoint.clone(),
-            EndpointEnum::V2(ref _ep) => panic!("Endpoint version is not supported !"),
+            EndpointEnum::V2(ref ep) => ep.to_string(),
         }
     }
 }
@@ -869,7 +788,8 @@ mod tests {
         let binary_endpoint = serialize(&endpoint).expect("Fail to serialize endpoint !");
         let endpoint2: EndpointV2 =
             deserialize(&binary_endpoint).expect("Fail to deserialize endpoint !");
-        assert_eq!(endpoint, endpoint2,)
+        assert_eq!(endpoint, endpoint2,);
+        assert_eq!(str_endpoint, endpoint.to_string());
     }
 
     #[test]
diff --git a/network/network_head_v3.rs b/network/network_head_v3.rs
index e10fa158..99ac157f 100644
--- a/network/network_head_v3.rs
+++ b/network/network_head_v3.rs
@@ -15,8 +15,11 @@
 
 //! Module defining the format of network heads v3 and how to handle them.
 
+use base58::ToBase58;
+use duniter_crypto::keys::bin_signable::BinSignable;
 use duniter_crypto::keys::*;
 use duniter_documents::Blockstamp;
+use serde_json;
 use std::cmp::Ordering;
 use NodeId;
 
@@ -41,12 +44,36 @@ impl Ord for NetworkHeadV3Container {
     }
 }
 
+impl NetworkHeadV3Container {
+    /// Convert to JSON String
+    pub fn to_json_head(&self) -> Result<String, serde_json::Error> {
+        Ok(serde_json::to_string_pretty(&JsonHeadV3 {
+            api_outgoing_conf: self.body.api_outgoing_conf,
+            api_incoming_conf: self.body.api_incoming_conf,
+            free_mirror_rooms: self.body.free_mirror_rooms,
+            low_priority_rooms: self.body.low_priority_rooms,
+            node_id: self.body.node_id,
+            algorithm: self.body.pubkey.algo(),
+            pubkey: self.body.pubkey.to_base58(),
+            blockstamp: self.body.blockstamp.to_string(),
+            software: &self.body.software,
+            soft_version: &self.body.soft_version,
+            signature: if let Some(sig) = self.body.signature {
+                Some(sig.to_base64())
+            } else {
+                None
+            },
+            step: self.step,
+        })?)
+    }
+}
+
 #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
 /// Head V3
 pub struct NetworkHeadV3 {
-    ///
+    /// WS2P Private configuration
     pub api_outgoing_conf: u8,
-    ///
+    /// WS2P Public configuration
     pub api_incoming_conf: u8,
     /// Issuer node free mirror rooms
     pub free_mirror_rooms: u8,
@@ -77,3 +104,89 @@ impl Ord for NetworkHeadV3 {
         self.blockstamp.cmp(&other.blockstamp)
     }
 }
+
+impl<'de> BinSignable<'de> for NetworkHeadV3 {
+    fn issuer_pubkey(&self) -> PubKey {
+        self.pubkey
+    }
+    fn signature(&self) -> Option<Sig> {
+        self.signature
+    }
+    fn set_signature(&mut self, signature: Sig) {
+        self.signature = Some(signature);
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
+/// Head V3 for json serializer
+pub struct JsonHeadV3<'a> {
+    /// WS2P Private configuration
+    pub api_outgoing_conf: u8,
+    /// WS2P Public configuration
+    pub api_incoming_conf: u8,
+    /// Issuer node free mirror rooms
+    pub free_mirror_rooms: u8,
+    /// Issuer node free "low priority" rooms
+    pub low_priority_rooms: u8,
+    /// Issuer node id
+    pub node_id: NodeId,
+    /// Issuer key algorithm
+    pub algorithm: KeysAlgo,
+    /// Issuer pubkey
+    pub pubkey: String,
+    /// Head blockstamp
+    pub blockstamp: String,
+    /// Issuer node software
+    pub software: &'a str,
+    /// Issuer node soft version
+    pub soft_version: &'a str,
+    /// Issuer signature
+    pub signature: Option<String>,
+    /// Head step
+    pub step: u8,
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use duniter_crypto::keys::bin_signable::BinSignable;
+    use tests::bincode::deserialize;
+    use tests::keypair1;
+
+    #[test]
+    fn head_v3_sign_and_verify() {
+        let mut head_v3 = NetworkHeadV3Container {
+            step: 0,
+            body: NetworkHeadV3 {
+                api_outgoing_conf: 0u8,
+                api_incoming_conf: 0u8,
+                free_mirror_rooms: 0u8,
+                low_priority_rooms: 0u8,
+                node_id: NodeId(0),
+                pubkey: PubKey::Ed25519(keypair1().public_key()),
+                blockstamp: Blockstamp::from_string(
+                    "50-000005B1CEB4EC5245EF7E33101A330A1C9A358EC45A25FC13F78BB58C9E7370",
+                ).unwrap(),
+                software: String::from("durs"),
+                soft_version: String::from("0.1.0-a0.1"),
+                signature: None,
+            },
+        };
+        // Sign
+        let sign_result = head_v3
+            .body
+            .sign(PrivKey::Ed25519(keypair1().private_key()));
+        if let Ok(head_v3_body_bytes) = sign_result {
+            let deser_head_v3_body: NetworkHeadV3 =
+                deserialize(&head_v3_body_bytes).expect("Fail to deserialize PeerCardV11 !");
+            assert_eq!(head_v3.body, deser_head_v3_body,)
+        } else {
+            panic!("failt to sign head v3 : {:?}", sign_result.err().unwrap())
+        }
+        // Verify signature
+        head_v3.body.verify().expect("HEADv3 : Invalid signature !");
+        //let json_head_v3 = head_v3.to_json_head().expect("Fail to serialize HEAD v3 !");
+        //println!("{}", json_head_v3);
+        //panic!();
+    }
+}
diff --git a/network/network_peer.rs b/network/network_peer.rs
index ff1da05c..8a62a434 100644
--- a/network/network_peer.rs
+++ b/network/network_peer.rs
@@ -21,9 +21,10 @@ extern crate duniter_documents;
 extern crate duniter_module;
 extern crate serde;
 
+use base58::ToBase58;
+use duniter_crypto::keys::bin_signable::BinSignable;
 use duniter_crypto::keys::*;
 use duniter_documents::{Blockstamp, CurrencyName};
-use dup_binarizer::*;
 use network_endpoint::*;
 use *;
 
@@ -55,7 +56,48 @@ pub struct PeerCardV11 {
     pub sig: Option<Sig>,
 }
 
-impl<'de> BinMessageSignable<'de> for PeerCardV11 {
+#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
+/// Peer card V11 for JSON Serializer
+pub struct JsonPeerCardV11<'a> {
+    /// PeerCard version
+    pub version: usize,
+    /// Currency Name
+    pub currency_name: &'a str,
+    /// Issuer node id
+    pub node_id: NodeId,
+    /// Issuer pubkey alogirithm
+    pub algorithm: KeysAlgo,
+    /// Issuer pubkey
+    pub pubkey: String,
+    /// Peer card creation blockstamp
+    pub blockstamp: String,
+    /// Endpoints
+    pub endpoints: Vec<String>,
+    /// Signature
+    pub signature: Option<String>,
+}
+
+impl PeerCardV11 {
+    /// Convert to JSON String
+    pub fn to_json_peer(&self) -> Result<String, serde_json::Error> {
+        Ok(serde_json::to_string_pretty(&JsonPeerCardV11 {
+            version: 11,
+            currency_name: &self.currency_name.0,
+            node_id: self.node_id,
+            algorithm: self.issuer.algo(),
+            pubkey: self.issuer.to_base58(),
+            blockstamp: self.blockstamp.to_string(),
+            endpoints: self.endpoints.iter().map(|ep| ep.to_string()).collect(),
+            signature: if let Some(sig) = self.sig {
+                Some(sig.to_base64())
+            } else {
+                None
+            },
+        })?)
+    }
+}
+
+impl<'de> BinSignable<'de> for PeerCardV11 {
     fn issuer_pubkey(&self) -> PubKey {
         self.issuer
     }
@@ -114,13 +156,8 @@ mod tests {
     use std::net::Ipv4Addr;
     use std::str::FromStr;
     use tests::bincode::deserialize;
+    use tests::keypair1;
 
-    fn keypair1() -> ed25519::KeyPair {
-        ed25519::KeyPairFromSaltedPasswordGenerator::with_default_parameters().generate(
-            "JhxtHB7UcsDbA9wMSyMKXUzBZUQvqVyB32KwzS9SWoLkjrUhHV".as_bytes(),
-            "JhxtHB7UcsDbA9wMSyMKXUzBZUQvqVyB32KwzS9SWoLkjrUhHV_".as_bytes(),
-        )
-    }
     fn create_endpoint_v2() -> EndpointV2 {
         EndpointV2 {
             api: NetworkEndpointApi(String::from("WS2P")),
@@ -149,7 +186,7 @@ mod tests {
     }
 
     #[test]
-    fn test_convert_peer_card_v11_into_bytes_vector() {
+    fn peer_card_v11_sign_and_verify() {
         let keypair1 = keypair1();
         let mut peer_card_v11 = PeerCardV11 {
             currency_name: CurrencyName(String::from("g1")),
@@ -173,5 +210,9 @@ mod tests {
         } else {
             panic!("failt to sign peer card : {:?}", sign_result.err().unwrap())
         }
+        // Verify signature
+        peer_card_v11
+            .verify()
+            .expect("Fail to verify PeerCardV11 !");
     }
 }
diff --git a/ws2p-messages/Cargo.toml b/ws2p-messages/Cargo.toml
index 4ef01740..aa6532d0 100644
--- a/ws2p-messages/Cargo.toml
+++ b/ws2p-messages/Cargo.toml
@@ -14,7 +14,6 @@ byteorder = "1.2.3"
 duniter-crypto = { path = "../crypto" }
 duniter-documents = { path = "../documents" }
 duniter-network = { path = "../network" }
-dup-binarizer = { path = "../binarizer" }
 log = "0.4.*"
 regex = "0.2.*"
 rust-crypto = "0.2.*"
diff --git a/ws2p-messages/lib.rs b/ws2p-messages/lib.rs
index cfca4c06..e7e0e9c6 100644
--- a/ws2p-messages/lib.rs
+++ b/ws2p-messages/lib.rs
@@ -39,7 +39,6 @@ extern crate byteorder;
 extern crate duniter_crypto;
 extern crate duniter_documents;
 extern crate duniter_network;
-extern crate dup_binarizer;
 
 /// WS2Pv2 Messages
 pub mod v2;
@@ -57,13 +56,13 @@ pub enum WS2PMessage {
 mod tests {
     use bincode;
     use bincode::{deserialize, serialize};
+    use duniter_crypto::keys::bin_signable::BinSignable;
     use duniter_crypto::keys::*;
     use duniter_documents::blockchain::v10::documents::certification::*;
     use duniter_documents::{Blockstamp, CurrencyName};
     use duniter_network::network_endpoint::*;
     use duniter_network::network_peer::*;
     use duniter_network::*;
-    use dup_binarizer::BinMessageSignable;
     use std::net::Ipv4Addr;
     use std::str::FromStr;
     use v2::payload_container::WS2Pv0MessagePayload;
diff --git a/ws2p-messages/v2/connect.rs b/ws2p-messages/v2/connect.rs
index 1b55bd7a..3ed23827 100644
--- a/ws2p-messages/v2/connect.rs
+++ b/ws2p-messages/v2/connect.rs
@@ -82,126 +82,6 @@ impl Default for WS2Pv2ConnectMsg {
     }
 }
 
-/*
-impl BinMessage for WS2Pv2ConnectMsg {
-    type ReadBytesError = WS2Pv0MsgPayloadContentParseError;
-    fn from_bytes(datas: &[u8]) -> Result<Self, Self::ReadBytesError> {
-        if datas.len() < *CONNECT_MSG_MIN_SIZE {
-            return Err(WS2Pv0MsgPayloadContentParseError::TooShort(
-                "Insufficient size (<CONNECT_MSG_MIN_SIZE).",
-            ));
-        }
-        let mut index = 0;
-        // read challenge
-        let mut challenge_datas: [u8; 32] = [0u8; 32];
-        challenge_datas.copy_from_slice(&datas[0..32]);
-        let challenge = Hash(challenge_datas);
-        index += 32;
-        // read af_size
-        let af_size = datas[index] as usize;
-        index += 1;
-        // read api_features
-        let api_features = WS2PFeatures(datas[index..index + af_size].to_vec());
-        index += af_size;
-        // read flags_size
-        let flags_size = datas[index] as usize;
-        index += 1;
-        // read flags_queries
-        let flags_queries = WS2PConnectFlags(datas[index..index + flags_size].to_vec());
-        index += flags_size;
-        // read peer_card
-        let peer_card = if datas.len() > index + 2 {
-            let peer_card_size = u16::read_u16_be(&datas[index..index + 2])? as usize;
-            index += 2 + peer_card_size;
-            if peer_card_size > 0 {
-                if datas.len() < index {
-                    return Err(WS2Pv0MsgPayloadContentParseError::TooShort("peer_card"));
-                }
-                Some(PeerCardV11::from_bytes(
-                    &datas[index - peer_card_size..index],
-                )?)
-            } else {
-                None
-            }
-        } else if datas.len() == index {
-            None
-        } else {
-            return Err(WS2Pv0MsgPayloadContentParseError::TooShort(
-                "peer_card_size",
-            ));
-        };
-        // read chunkstamp
-        let chunkstamp = if datas.len() == index + Blockstamp::SIZE_IN_BYTES {
-            Some(Blockstamp::from_bytes(&datas[index..])?)
-        } else if datas.len() == index {
-            None
-        } else {
-            return Err(WS2Pv0MsgPayloadContentParseError::WrongSize("chunkstamp"));
-        };
-        Ok(WS2Pv2ConnectMsg {
-            challenge,
-            api_features,
-            flags_queries,
-            peer_card,
-            chunkstamp,
-        })
-    }
-    fn to_bytes_vector(&self) -> Vec<u8> {
-        // Binarize peer_card
-        let bin_peer_card = if let Some(ref peer_card) = self.peer_card {
-            peer_card.to_bytes_vector()
-        } else {
-            vec![0u8, 0u8] // peer_card_size = 0
-        };
-        // Binarize bin_chunkstamp
-        let bin_chunkstamp = if let Some(ref chunkstamp) = self.chunkstamp {
-            chunkstamp.to_bytes_vector()
-        } else {
-            vec![]
-        };
-        // Compute msg_bin_size and allocate buffer
-        let af_size = if self.api_features.is_empty() {
-            0
-        } else {
-            self.api_features.0.len()
-        };
-        let flags_size = if self.flags_queries.is_empty() {
-            0
-        } else {
-            self.flags_queries.0.len()
-        };
-        let msg_bin_size = CONNECT_MSG_MIN_SIZE
-            + af_size
-            + flags_size
-            + bin_peer_card.len()
-            + bin_chunkstamp.len();
-        let mut buffer = Vec::with_capacity(msg_bin_size);
-        // Write challenge
-        buffer.extend_from_slice(&self.challenge.0);
-        // Write af_size
-        buffer.push(af_size as u8);
-        // Write api_features
-        if !self.api_features.is_empty() {
-            buffer.extend(&self.api_features.0);
-        }
-        // Write flags_size
-        buffer.push(flags_size as u8);
-        // Write flags_queries
-        if !self.flags_queries.is_empty() {
-            buffer.extend(&self.flags_queries.0);
-        }
-        // Write peer_card
-        if !bin_peer_card.is_empty() {
-            buffer.extend(&bin_peer_card);
-        }
-        // Write chunkstamp
-        if !bin_chunkstamp.is_empty() {
-            buffer.extend(&bin_chunkstamp);
-        }
-        buffer
-    }
-}*/
-
 #[cfg(test)]
 mod tests {
     use super::super::*;
diff --git a/ws2p-messages/v2/mod.rs b/ws2p-messages/v2/mod.rs
index 8642ca2e..8562ef37 100644
--- a/ws2p-messages/v2/mod.rs
+++ b/ws2p-messages/v2/mod.rs
@@ -29,10 +29,10 @@ pub mod requests;
 pub mod secret_flags;
 
 use duniter_crypto::hashs::Hash;
+use duniter_crypto::keys::bin_signable::BinSignable;
 use duniter_crypto::keys::*;
 use duniter_documents::CurrencyName;
 use duniter_network::NodeId;
-use dup_binarizer::*;
 use v2::payload_container::*;
 
 /// WS2P v2 message metadata size
@@ -60,7 +60,7 @@ impl WS2Pv0Message {
     pub const WS2P_VERSION: u16 = 0;
 }
 
-impl<'de> BinMessageSignable<'de> for WS2Pv0Message {
+impl<'de> BinSignable<'de> for WS2Pv0Message {
     fn issuer_pubkey(&self) -> PubKey {
         self.issuer_pubkey
     }
@@ -81,154 +81,6 @@ impl<'de> BinMessageSignable<'de> for WS2Pv0Message {
     }
 }
 
-/*impl BinMessage for WS2Pv0Message {
-    type ReadBytesError = WS2Pv0MessageReadBytesError;
-    fn from_bytes(binary_msg: &[u8]) -> Result<WS2Pv0Message, WS2Pv0MessageReadBytesError> {
-        let mut index = 0;
-        // read currency_code
-        let mut currency_code_bytes = Cursor::new(binary_msg[index..index + 2].to_vec());
-        index += 2;
-        let currency_code = CurrencyName::from_u16(currency_code_bytes.read_u16::<BigEndian>()?)?;
-        // read ws2p_version
-        let mut ws2p_version_bytes = Cursor::new(binary_msg[index..index + 2].to_vec());
-        index += 2;
-        let ws2p_version = ws2p_version_bytes.read_u16::<BigEndian>()?;
-        match ws2p_version {
-            2u16 => {
-                // read issuer_node_id
-                let mut node_id_bytes = Cursor::new(binary_msg[index..index + 4].to_vec());
-                index += 4;
-                let issuer_node_id = NodeId(node_id_bytes.read_u32::<BigEndian>()?);
-                // read issuer_size
-                let issuer_size = u16::read_u16_be(&binary_msg[index..index + 2])? as usize;
-                index += 2;
-                // read issuer_pubkey
-                let (issuer_pubkey, key_algo) = if binary_msg.len() > index + issuer_size {
-                    index += issuer_size;
-                    pubkey_box::read_pubkey_box(&binary_msg[index - issuer_size..index])?
-                } else {
-                    return Err(WS2Pv0MessageReadBytesError::TooShort(String::from(
-                        "issuer",
-                    )));
-                };
-                // read payload_size
-                let payload_size = if binary_msg.len() > index + 8 {
-                    let mut payload_size_bytes =
-                        Cursor::new(binary_msg[index + 4..index + 8].to_vec());
-                    payload_size_bytes.read_u32::<BigEndian>()? as usize
-                } else {
-                    return Err(WS2Pv0MessageReadBytesError::TooShort(String::from(
-                        "payload_size",
-                    )));
-                };
-                // read payload
-                let payload = if binary_msg.len() > index + payload_size + 8 {
-                    index += payload_size + 8;
-                    WS2Pv0MessagePayload::from_bytes(
-                        &binary_msg[index - (payload_size + 8)..index],
-                    )?
-                } else {
-                    return Err(WS2Pv0MessageReadBytesError::TooShort(String::from(
-                        "payload",
-                    )));
-                };
-                // read message_hash
-                let message_hash = if binary_msg.len() >= index + 32 {
-                    let mut hash_datas: [u8; 32] = [0u8; 32];
-                    index += 32;
-                    hash_datas.copy_from_slice(&binary_msg[index - 32..index]);
-                    Some(Hash(hash_datas))
-                } else if binary_msg.len() == index {
-                    None
-                } else {
-                    return Err(WS2Pv0MessageReadBytesError::TooShort(String::from(
-                        "message_hash",
-                    )));
-                };
-                // read signature_size
-                let signature_size = if binary_msg.len() > index + 2 {
-                    index += 2;
-                    u16::read_u16_be(&binary_msg[index - 2..index])? as usize
-                } else {
-                    return Err(WS2Pv0MessageReadBytesError::TooShort(String::from(
-                        "signature_size",
-                    )));
-                };
-                // read signature
-                let signature = if binary_msg.len() > index + signature_size {
-                    return Err(WS2Pv0MessageReadBytesError::TooLong());
-                } else if binary_msg.len() == index + signature_size {
-                    index += signature_size;
-                    Some(sig_box::read_sig_box(
-                        &binary_msg[index - signature_size..index],
-                        key_algo,
-                    )?)
-                } else if binary_msg.len() > index {
-                    return Err(WS2Pv0MessageReadBytesError::TooLong());
-                } else if binary_msg.len() == index {
-                    None
-                } else {
-                    return Err(WS2Pv0MessageReadBytesError::TooShort(String::from("end")));
-                };
-                Ok(WS2Pv0Message {
-                    currency_code,
-                    issuer_node_id,
-                    issuer_pubkey,
-                    payload,
-                    message_hash,
-                    signature,
-                })
-            }
-            0u16 | 1u16 => Err(WS2Pv0MessageReadBytesError::TooEarlyVersion()),
-            _ => Err(WS2Pv0MessageReadBytesError::VersionNotYetSupported()),
-        }
-    }
-    fn to_bytes_vector(&self) -> Vec<u8> {
-        // Binarize payload (message_type + elements_count + payload_size + payload)
-        let bin_payload = self.payload.to_bytes_vector();
-        let payload_size = bin_payload.len() - *WS2P_V2_MESSAGE_PAYLOAD_METADATA_SIZE;
-        let msg_size = *WS2P_V2_MESSAGE_METADATA_SIZE + payload_size as usize;
-        let mut bytes_vector = Vec::with_capacity(msg_size);
-        // currency_code
-        bytes_vector.extend_from_slice(
-            &self
-                .currency_code
-                .to_bytes()
-                .expect("Fatal Error : Try to binarize WS2Pv2 message with UnknowCurrencyName !"),
-        );
-        // ws2p_version
-        let mut buffer = [0u8; mem::size_of::<u16>()];
-        buffer
-            .as_mut()
-            .write_u16::<BigEndian>(WS2Pv0Message::WS2P_VERSION)
-            .expect("Unable to write");
-        bytes_vector.extend_from_slice(&buffer);
-        // Write issuer_node_id
-        let mut buffer = [0u8; mem::size_of::<u32>()];
-        buffer
-            .as_mut()
-            .write_u32::<BigEndian>(self.issuer_node_id.0)
-            .expect("Unable to write");
-        bytes_vector.extend_from_slice(&buffer);
-        // Write issuer_pubey
-        pubkey_box::write_pubkey_box(&mut bytes_vector, self.issuer_pubkey)
-            .expect("Fail to binarize peer.issuer !");
-        // Write payload : message_type + elements_count + payload_size + payload_content
-        bytes_vector.extend(bin_payload);
-        // Write message_hash
-        if let Some(message_hash) = self.message_hash {
-            bytes_vector.extend(message_hash.to_bytes_vector());
-        }
-        // Write signature
-        if let Some(signature) = self.signature {
-            sig_box::write_sig_box(&mut bytes_vector, signature)
-                .expect("Fail to binarize msg.sig !");
-        }
-
-        bytes_vector
-    }
-}*/
-
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/ws2p-messages/v2/ok.rs b/ws2p-messages/v2/ok.rs
index 8471dde8..e442e373 100644
--- a/ws2p-messages/v2/ok.rs
+++ b/ws2p-messages/v2/ok.rs
@@ -35,49 +35,6 @@ impl Default for WS2Pv2OkMsg {
     }
 }
 
-/*
-impl BinMessage for WS2Pv2OkMsg {
-    type ReadBytesError = WS2Pv0MsgPayloadContentParseError;
-    fn from_bytes(datas: &[u8]) -> Result<Self, Self::ReadBytesError> {
-        match datas.len() {
-            0 => Ok(WS2Pv2OkMsg::default()),
-            1 => Err(WS2Pv0MsgPayloadContentParseError::TooShort(
-                "Size of WS2Pv2OkMsg cannot be 1",
-            )),
-            2 => Ok(WS2Pv2OkMsg {
-                prefix: NonZeroU16::new(u16::read_u16_be(&datas)?),
-                sync_target: None,
-            }),
-            _ => Ok(WS2Pv2OkMsg {
-                prefix: NonZeroU16::new(u16::read_u16_be(&datas[0..2])?),
-                sync_target: Some(WS2Pv2SyncTarget::from_bytes(&datas[2..])?),
-            }),
-        }
-    }
-    fn to_bytes_vector(&self) -> Vec<u8> {
-        if let Some(ref sync_target) = self.sync_target {
-            let sync_target_bytes = sync_target.to_bytes_vector();
-            let mut ok_msg_bytes = Vec::with_capacity(2 + sync_target_bytes.len());
-            if let Some(prefix) = self.prefix {
-                u16::write_u16_be(&mut ok_msg_bytes, prefix.get())
-                    .expect("Fail to write prefix in WS2Pv2OkMsg !");
-            } else {
-                u16::write_u16_be(&mut ok_msg_bytes, 0)
-                    .expect("Fail to write prefix in WS2Pv2OkMsg !");
-            }
-            ok_msg_bytes.extend(sync_target_bytes);
-            ok_msg_bytes
-        } else if let Some(prefix) = self.prefix {
-            let mut ok_msg_bytes = Vec::with_capacity(2);
-            u16::write_u16_be(&mut ok_msg_bytes, prefix.get())
-                .expect("Fail to write prefix in WS2Pv2OkMsg !");
-            ok_msg_bytes
-        } else {
-            vec![]
-        }
-    }
-}*/
-
 #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
 /// WS2Pv2SyncTarget
 pub struct WS2Pv2SyncTarget {
@@ -87,49 +44,6 @@ pub struct WS2Pv2SyncTarget {
     pub chunks_hash: Vec<Hash>,
 }
 
-/*
-impl BinMessage for WS2Pv2SyncTarget {
-    type ReadBytesError = WS2Pv0MsgPayloadContentParseError;
-    fn from_bytes(datas: &[u8]) -> Result<Self, Self::ReadBytesError> {
-        // target_blockstamp
-        let target_blockstamp = if datas.len() < (Blockstamp::SIZE_IN_BYTES + 2) {
-            return Err(WS2Pv0MsgPayloadContentParseError::TooShort("blockstamp"));
-        } else {
-            Blockstamp::from_bytes(&datas[0..Blockstamp::SIZE_IN_BYTES])?
-        };
-        // chunks_hash_count
-        let mut index = Blockstamp::SIZE_IN_BYTES + 2;
-        let chunks_hash_count = u16::read_u16_be(&datas[index - 2..index])? as usize;
-        let chunks_hash = if datas.len() < (index + (chunks_hash_count * Hash::SIZE_IN_BYTES)) {
-            return Err(WS2Pv0MsgPayloadContentParseError::TooShort("chunks_hash"));
-        } else {
-            let mut chunks_hash = Vec::with_capacity(chunks_hash_count);
-            for _ in 0..chunks_hash_count {
-                let mut hash_bytes: [u8; 32] = [0u8; 32];
-                hash_bytes.copy_from_slice(&datas[index..index + Hash::SIZE_IN_BYTES]);
-                chunks_hash.push(Hash(hash_bytes));
-                index += Hash::SIZE_IN_BYTES;
-            }
-            chunks_hash
-        };
-        Ok(WS2Pv2SyncTarget {
-            target_blockstamp,
-            chunks_hash,
-        })
-    }
-    fn to_bytes_vector(&self) -> Vec<u8> {
-        let chunks_hash_size = self.chunks_hash.len() * Hash::SIZE_IN_BYTES;
-        let mut bytes = Vec::with_capacity(Blockstamp::SIZE_IN_BYTES + 2 + chunks_hash_size);
-        bytes.extend(self.target_blockstamp.to_bytes_vector());
-        u16::write_u16_be(&mut bytes, self.chunks_hash.len() as u16)
-            .expect("Fail to write chunks_hash_count in WS2Pv2SyncTarget !");
-        for hash in &self.chunks_hash {
-            bytes.extend_from_slice(&hash.0);
-        }
-        bytes
-    }
-}*/
-
 #[cfg(test)]
 mod tests {
     use super::super::*;
diff --git a/ws2p-messages/v2/payload_container.rs b/ws2p-messages/v2/payload_container.rs
index 6826dda8..9ff1dec5 100644
--- a/ws2p-messages/v2/payload_container.rs
+++ b/ws2p-messages/v2/payload_container.rs
@@ -66,222 +66,3 @@ pub enum WS2Pv0MessagePayload {
     /// PENDING_TXS Message
     PendingTxs(Vec<TransactionDocument>),
 }
-
-/*
-impl BinMessage for WS2Pv0MessagePayload {
-    type ReadBytesError = WS2Pv0MessagePayloadReadBytesError;
-
-    fn from_bytes(
-        payload: &[u8],
-    ) -> Result<WS2Pv0MessagePayload, WS2Pv0MessagePayloadReadBytesError> {
-        // read payload_size
-        let payload_size = if payload.len() >= 8 {
-            let mut payload_size_bytes = Cursor::new(payload[4..8].to_vec());
-            payload_size_bytes.read_u32::<BigEndian>()? as usize
-        } else {
-            return Err(WS2Pv0MessagePayloadReadBytesError::TooShort(String::from(
-                "payload_size",
-            )));
-        };
-        // Check size of bytes vector
-        if payload.len() > 8 + payload_size {
-            return Err(WS2Pv0MessagePayloadReadBytesError::TooLong());
-        } else if payload.len() < 8 + payload_size {
-            return Err(WS2Pv0MessagePayloadReadBytesError::TooShort(String::from(
-                "payload_content",
-            )));
-        }
-        // Read message_type
-        let mut message_type_bytes = Cursor::new(payload[0..2].to_vec());
-        let message_type = message_type_bytes.read_u16::<BigEndian>()?;
-        // Read elements_count
-        let mut elements_count_bytes = Cursor::new(payload[2..4].to_vec());
-        let elements_count = elements_count_bytes.read_u16::<BigEndian>()? as usize;
-        // Read payload_content
-        match message_type {
-            0x0000 => {
-                if elements_count == 0 {
-                    Ok(WS2Pv0MessagePayload::Connect(Box::new(
-                        WS2Pv2ConnectMsg::from_bytes(&payload[8..])?,
-                    )))
-                } else {
-                    Err(WS2Pv0MessagePayloadReadBytesError::WrongElementsCount())
-                }
-            }
-            0x0001 => {
-                if elements_count == 0 {
-                    let mut hash_bytes = [0u8; 32];
-                    hash_bytes.copy_from_slice(&payload[8..40]);
-                    Ok(WS2Pv0MessagePayload::Ack(Hash(hash_bytes)))
-                } else {
-                    Err(WS2Pv0MessagePayloadReadBytesError::WrongElementsCount())
-                }
-            }
-            0x0002 => {
-                if elements_count == 0 {
-                    Ok(WS2Pv0MessagePayload::SecretFlags(
-                        WS2Pv2SecretFlagsMsg::from_bytes(&payload[8..])?,
-                    ))
-                } else {
-                    Err(WS2Pv0MessagePayloadReadBytesError::WrongElementsCount())
-                }
-            }
-            0x0003 => {
-                if elements_count == 0 {
-                    Ok(WS2Pv0MessagePayload::Ok(WS2Pv2OkMsg::from_bytes(
-                        &payload[8..],
-                    )?))
-                } else {
-                    Err(WS2Pv0MessagePayloadReadBytesError::WrongElementsCount())
-                }
-            }
-            0x0010 => {
-                if elements_count == 0 {
-                    Ok(WS2Pv0MessagePayload::Request(WS2Pv2Request::from_bytes(
-                        &payload[8..],
-                    )?))
-                } else {
-                    Err(WS2Pv0MessagePayloadReadBytesError::WrongElementsCount())
-                }
-            }
-            0x0011 => {
-                if elements_count == 0 {
-                    Ok(WS2Pv0MessagePayload::ReqRes(WS2Pv2ReqRes::from_bytes(
-                        &payload[8..],
-                    )?))
-                } else {
-                    Err(WS2Pv0MessagePayloadReadBytesError::WrongElementsCount())
-                }
-            }
-            0x0100 => {
-                let mut peers = Vec::with_capacity(elements_count);
-                let peers_bytes = &payload[8..];
-                let mut index = 0;
-                for _ in 0..elements_count {
-                    // Read peer_size
-                    index += 2;
-                    if peers_bytes.len() < index {
-                        return Err(WS2Pv0MessagePayloadReadBytesError::TooShort(String::from(
-                            "peer_size",
-                        )));
-                    }
-                    let mut peer_size_bytes = Cursor::new(peers_bytes[index - 2..index].to_vec());
-                    let peer_size = peer_size_bytes.read_u16::<BigEndian>()? as usize;
-                    // Read
-                    index += peer_size;
-                    if peers_bytes.len() < index {
-                        return Err(WS2Pv0MessagePayloadReadBytesError::TooShort(String::from(
-                            "peer_content",
-                        )));
-                    }
-                    let peer = PeerCardV11::from_bytes(&peers_bytes[index - peer_size..index])?;
-                    // Add peer
-                    peers.push(peer);
-                }
-                if peers_bytes.len() > index {
-                    Err(WS2Pv0MessagePayloadReadBytesError::TooLong())
-                } else {
-                    Ok(WS2Pv0MessagePayload::Peers(peers))
-                }
-            }
-            _ => Err(WS2Pv0MessagePayloadReadBytesError::UnknowMsgType()),
-        }
-    }
-    fn to_bytes_vector(&self) -> Vec<u8> {
-        let bin_payload_container = match *self {
-            WS2Pv0MessagePayload::Connect(ref connect_msg) => {
-                WS2Pv0MessageBinPayload {
-                    message_type: 0x0000,
-                    elements_count: 0,
-                    payload_content: connect_msg.to_bytes_vector(),
-                }
-            }
-            WS2Pv0MessagePayload::Ack(ref hash) => {
-                WS2Pv0MessageBinPayload {
-                    message_type: 0x0001,
-                    elements_count: 0,
-                    payload_content: hash.0.to_vec(),
-                }
-            }
-            WS2Pv0MessagePayload::SecretFlags(ref secret_flags_msg) => {
-                WS2Pv0MessageBinPayload {
-                    message_type: 0x0002,
-                    elements_count: 0,
-                    payload_content: secret_flags_msg.to_bytes_vector(),
-                }
-            }
-            WS2Pv0MessagePayload::Ok(ref ok_msg) => {
-                WS2Pv0MessageBinPayload {
-                    message_type: 0x0003,
-                    elements_count: 0,
-                    payload_content: ok_msg.to_bytes_vector(),
-                }
-            }
-            WS2Pv0MessagePayload::Request(ref request_msg) => {
-                WS2Pv0MessageBinPayload {
-                    message_type: 0x0010,
-                    elements_count: 0,
-                    payload_content: request_msg.to_bytes_vector(),
-                }
-            }
-            WS2Pv0MessagePayload::ReqRes(ref req_res_msg) => {
-                WS2Pv0MessageBinPayload {
-                    message_type: 0x0011,
-                    elements_count: 0,
-                    payload_content: req_res_msg.to_bytes_vector(),
-                }
-            }
-            WS2Pv0MessagePayload::Peers(ref peers) => {
-                // Get elements_count
-                let elements_count = peers.len() as u16;
-                // Binarize peers
-                let mut bin_peers = vec![];
-                for peer in peers.clone() {
-                    bin_peers.push(peer.to_bytes_vector());
-                }
-                // Compute payload_content_size
-                let payload_size = bin_peers.iter().map(|bin_peer| bin_peer.len()).sum();
-                let mut payload_content = Vec::with_capacity(payload_size);
-                // Write payload_content
-                for bin_peer in bin_peers {
-                    payload_content.extend(bin_peer);
-                }
-                WS2Pv0MessageBinPayload {
-                    message_type: 0x0100,
-                    elements_count,
-                    payload_content,
-                }
-            }
-            //_ => vec![],
-        };
-        // Create bin_payload buffer
-        let mut bin_payload = Vec::with_capacity(
-            bin_payload_container.payload_content.len() + *WS2P_V2_MESSAGE_PAYLOAD_METADATA_SIZE,
-        );
-        // Write message_type
-        let mut buffer = [0u8; mem::size_of::<u16>()];
-        buffer
-            .as_mut()
-            .write_u16::<BigEndian>(bin_payload_container.message_type)
-            .expect("Unable to write");
-        bin_payload.extend_from_slice(&buffer);
-        // Write elements_count
-        let mut buffer = [0u8; mem::size_of::<u16>()];
-        buffer
-            .as_mut()
-            .write_u16::<BigEndian>(bin_payload_container.elements_count)
-            .expect("Unable to write");
-        bin_payload.extend_from_slice(&buffer);
-        // Write payload_size
-        let mut buffer = [0u8; mem::size_of::<u32>()];
-        buffer
-            .as_mut()
-            .write_u32::<BigEndian>(bin_payload_container.payload_content.len() as u32)
-            .expect("Unable to write");
-        bin_payload.extend_from_slice(&buffer);
-        // Write payload_content
-        bin_payload.extend(bin_payload_container.payload_content);
-        // Return bin_payload
-        bin_payload
-    }
-}*/
diff --git a/ws2p-messages/v2/req_responses.rs b/ws2p-messages/v2/req_responses.rs
index dae5aedd..0a46a21d 100644
--- a/ws2p-messages/v2/req_responses.rs
+++ b/ws2p-messages/v2/req_responses.rs
@@ -19,7 +19,6 @@ use duniter_documents::blockchain::v10::documents::identity::CompactIdentityDocu
 use duniter_documents::blockchain::v10::documents::membership::CompactPoolMembershipDoc;
 use duniter_documents::blockchain::v10::documents::BlockDocument;
 use duniter_documents::Blockstamp;
-use dup_binarizer::*;
 use std::str;
 
 /// WS2Pv2 request response
diff --git a/ws2p-messages/v2/requests.rs b/ws2p-messages/v2/requests.rs
index ef6ccfdb..3290ceaa 100644
--- a/ws2p-messages/v2/requests.rs
+++ b/ws2p-messages/v2/requests.rs
@@ -14,7 +14,6 @@
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 use duniter_documents::{BlockId, Blockstamp};
-use dup_binarizer::*;
 
 /// WS2Pv2Request
 #[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
@@ -71,131 +70,6 @@ impl WS2Pv2RequestBody {
     }
 }
 
-/*
-impl BinMessage for WS2Pv2Request {
-    type ReadBytesError = WS2Pv2RequestParseError;
-    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::ReadBytesError> {
-        if bytes.len() >= 4 {
-            let id = u32::read_u32_be(&bytes[0..4])?;
-            let body = WS2Pv2RequestBody::from_bytes(&bytes[4..])?;
-            Ok(WS2Pv2Request { id, body })
-        } else {
-            Err(WS2Pv2RequestParseError::TooShort("id"))
-        }
-    }
-    fn to_bytes_vector(&self) -> Vec<u8> {
-        let mut buffer = Vec::with_capacity(self.size_in_bytes());
-        u32::write_u32_be(&mut buffer, self.id).expect("Fail to binarize WS2pv2Request !");
-        buffer.append(&mut self.body.to_bytes_vector());
-        buffer
-    }
-}*/
-
-/*
-impl BinMessage for WS2Pv2RequestBody {
-    type ReadBytesError = WS2Pv2RequestParseError;
-    fn from_bytes(bytes: &[u8]) -> Result<Self, Self::ReadBytesError> {
-        if bytes.is_empty() {
-            return Err(WS2Pv2RequestParseError::TooShort("empty"));
-        }
-        match bytes[0] {
-            0x00 => if bytes.len() == 1 {
-                Ok(WS2Pv2RequestBody::None)
-            } else {
-                Err(WS2Pv2RequestParseError::WrongSize(
-                    "None request with params",
-                ))
-            },
-            0x01 => if bytes.len() == 1 {
-                Ok(WS2Pv2RequestBody::Current)
-            } else {
-                Err(WS2Pv2RequestParseError::WrongSize(
-                    "Current request with params",
-                ))
-            },
-            0x02 => {
-                if bytes.len() == 7 {
-                    Ok(WS2Pv2RequestBody::BlocksHashs(
-                        BlockId(u32::read_u32_be(&bytes[1..=5])?),
-                        u16::read_u16_be(&bytes[5..7])?,
-                    ))
-                } else {
-                    Err(WS2Pv2RequestParseError::WrongSize(
-                        "BlocksHashs request with wrong size",
-                    ))
-                }
-            }
-            0x03 => {
-                if bytes.len() == 7 {
-                    Ok(WS2Pv2RequestBody::Chunk(
-                        BlockId(u32::read_u32_be(&bytes[1..=4])?),
-                        u16::read_u16_be(&bytes[5..7])?,
-                    ))
-                } else {
-                    Err(WS2Pv2RequestParseError::WrongSize(
-                        "Chunk request with wrong size",
-                    ))
-                }
-            }
-            0x04 => {
-                if bytes.len() == 37 {
-                    Ok(WS2Pv2RequestBody::ChunkByHash(Blockstamp::from_bytes(
-                        &bytes[1..],
-                    )?))
-                } else {
-                    Err(WS2Pv2RequestParseError::WrongSize(
-                        "ChunkByHash request with wrong size",
-                    ))
-                }
-            }
-            0x05 => {
-                if bytes.len() == 4 {
-                    Ok(WS2Pv2RequestBody::WotPool(
-                        u16::read_u16_be(&bytes[1..=2])?,
-                        bytes[3],
-                    ))
-                } else {
-                    Err(WS2Pv2RequestParseError::WrongSize(
-                        "WotPool request with wrong size",
-                    ))
-                }
-            }
-            _ => Err(WS2Pv2RequestParseError::UnknowRequestType()),
-        }
-    }
-    fn to_bytes_vector(&self) -> Vec<u8> {
-        let mut buffer = Vec::with_capacity(self.size_in_bytes());
-        match *self {
-            WS2Pv2RequestBody::None => {
-                buffer.push(0x00);
-            }
-            WS2Pv2RequestBody::Current => {
-                buffer.push(0x01);
-            }
-            WS2Pv2RequestBody::BlocksHashs(param1, param2) => {
-                buffer.push(0x02);
-                u32::write_u32_be(&mut buffer, param1.0).expect("Fail to binarize WS2pv2Request !");
-                u16::write_u16_be(&mut buffer, param2).expect("Fail to binarize WS2pv2Request !");
-            }
-            WS2Pv2RequestBody::Chunk(param1, param2) => {
-                buffer.push(0x03);
-                u32::write_u32_be(&mut buffer, param1.0).expect("Fail to binarize WS2pv2Request !");
-                u16::write_u16_be(&mut buffer, param2).expect("Fail to binarize WS2pv2Request !");
-            }
-            WS2Pv2RequestBody::ChunkByHash(param1) => {
-                buffer.push(0x04);
-                buffer.append(&mut param1.to_bytes_vector());
-            }
-            WS2Pv2RequestBody::WotPool(param1, param2) => {
-                buffer.push(0x05);
-                u16::write_u16_be(&mut buffer, param1).expect("Fail to binarize WS2pv2Request !");
-                buffer.push(param2);
-            }
-        }
-        buffer
-    }
-}*/
-
 #[cfg(test)]
 mod tests {
     use super::super::*;
diff --git a/ws2p-messages/v2/secret_flags.rs b/ws2p-messages/v2/secret_flags.rs
index 82537a58..ac4b3400 100644
--- a/ws2p-messages/v2/secret_flags.rs
+++ b/ws2p-messages/v2/secret_flags.rs
@@ -64,116 +64,6 @@ impl Default for WS2Pv2SecretFlagsMsg {
     }
 }
 
-/*
-impl BinMessage for WS2Pv2SecretFlagsMsg {
-    type ReadBytesError = WS2Pv0MsgPayloadContentParseError;
-    fn from_bytes(datas: &[u8]) -> Result<Self, Self::ReadBytesError> {
-        // Read flags_size
-        if datas.is_empty() {
-            return Err(WS2Pv0MsgPayloadContentParseError::TooShort("Empty datas !"));
-        }
-        let mut index = 0;
-        let flags_size = datas[0] as usize;
-        index += 1;
-        // Read secret_flags
-        if datas.len() < flags_size + index {
-            return Err(WS2Pv0MsgPayloadContentParseError::TooShort("secret_flags"));
-        }
-        let secret_flags = WS2Pv2SecretFlags(datas[index..index + flags_size].to_vec());
-        index += flags_size;
-        // Read member_pubkey
-        let (member_pubkey, key_algo) = if secret_flags.member_pubkey() {
-            if datas.len() < index + 2 {
-                return Err(WS2Pv0MsgPayloadContentParseError::TooShort(
-                    "member_pubkey: pubkey_box size",
-                ));
-            }
-            // Read pubkey_box size
-            let pubkey_box_size = u16::read_u16_be(&datas[index..index + 2])? as usize;
-            index += 2;
-            if datas.len() < index + pubkey_box_size {
-                return Err(WS2Pv0MsgPayloadContentParseError::TooShort(
-                    "member_pubkey: pubkey_box",
-                ));
-            }
-            // Read pubkey_box
-            index += pubkey_box_size;
-            let (member_pubkey, key_algo) =
-                pubkey_box::read_pubkey_box(&datas[index - pubkey_box_size..index])?;
-            (Some(member_pubkey), key_algo)
-        } else {
-            (None, 0u8)
-        };
-        // Read member_proof
-        let member_proof = if member_pubkey.is_some() && secret_flags.member_proof() {
-            if datas.len() < index + 2 {
-                return Err(WS2Pv0MsgPayloadContentParseError::TooShort(
-                    "member_proof: sig_box size",
-                ));
-            }
-            // Read sig_box size
-            let sig_box_size = u16::read_u16_be(&datas[index..index + 2])? as usize;
-            index += 2;
-            if datas.len() < index + sig_box_size {
-                return Err(WS2Pv0MsgPayloadContentParseError::TooShort(
-                    "member_proof: sig_box",
-                ));
-            }
-            // Read sig_box
-            index += sig_box_size;
-            Some(sig_box::read_sig_box(
-                &datas[index - sig_box_size..index],
-                key_algo,
-            )?)
-        } else {
-            None
-        };
-        Ok(WS2Pv2SecretFlagsMsg {
-            secret_flags,
-            member_pubkey,
-            member_proof,
-        })
-    }
-    fn to_bytes_vector(&self) -> Vec<u8> {
-        // Compute buffer size
-        let secret_flags_size = if !self.secret_flags.is_empty() {
-            self.secret_flags.0.len()
-        } else {
-            0
-        };
-        let member_pubkey_size = if let Some(ref member_pubkey) = self.member_pubkey {
-            member_pubkey.size_in_bytes()
-        } else {
-            0
-        };
-        let member_proof_size = if let Some(ref member_proof) = self.member_proof {
-            member_proof.size_in_bytes()
-        } else {
-            0
-        };
-        let buffer_size = 1 + secret_flags_size + member_pubkey_size + member_proof_size;
-        // Allocate buffer
-        let mut buffer = Vec::with_capacity(buffer_size);
-        // Write secret_flags_size
-        buffer.push(secret_flags_size as u8);
-        // Write secret_flags
-        if secret_flags_size > 0 {
-            buffer.append(&mut self.secret_flags.0.clone());
-        }
-        // Write member_pubkey
-        if let Some(ref member_pubkey) = self.member_pubkey {
-            pubkey_box::write_pubkey_box(&mut buffer, *member_pubkey)
-                .expect("WS2Pv2SecretFlagsMsg : fail to binarize member_pubkey !");
-        };
-        // Write member_proof
-        if let Some(ref member_proof) = self.member_proof {
-            sig_box::write_sig_box(&mut buffer, *member_proof)
-                .expect("WS2Pv2SecretFlagsMsg : fail  to binarize member_proof !");
-        };
-        buffer
-    }
-}*/
-
 #[cfg(test)]
 mod tests {
     use super::super::*;
diff --git a/ws2p-v1-legacy/Cargo.toml b/ws2p-v1-legacy/Cargo.toml
index d75a0ef7..b8c41471 100644
--- a/ws2p-v1-legacy/Cargo.toml
+++ b/ws2p-v1-legacy/Cargo.toml
@@ -18,7 +18,6 @@ duniter-message =  { path = "../message" }
 duniter-module = { path = "../module" }
 duniter-network = { path = "../network" }
 duniter-wotb = { path = "../wotb" }
-dup-binarizer = { path = "../binarizer" }
 lazy_static = "1.0.*"
 log = "0.4.*"
 rand = "0.4.*"
diff --git a/ws2p-v1-legacy/lib.rs b/ws2p-v1-legacy/lib.rs
index bcd7238f..e9fc2140 100644
--- a/ws2p-v1-legacy/lib.rs
+++ b/ws2p-v1-legacy/lib.rs
@@ -45,7 +45,6 @@ extern crate duniter_documents;
 extern crate duniter_message;
 extern crate duniter_module;
 extern crate duniter_network;
-extern crate dup_binarizer;
 extern crate rand;
 extern crate sqlite;
 extern crate ws;
diff --git a/ws2p/lib.rs b/ws2p/lib.rs
index ec1772b0..14796e5e 100644
--- a/ws2p/lib.rs
+++ b/ws2p/lib.rs
@@ -46,7 +46,7 @@ use duniter_conf::DuRsConf;
 use duniter_crypto::keys::*;
 use duniter_message::DuniterMessage;
 use duniter_module::*;
-use duniter_network::network_endpoint::EndpointEnum;
+use duniter_network::network_endpoint::*;
 use duniter_network::*;
 use std::sync::mpsc;
 
-- 
GitLab