diff --git a/Cargo.lock b/Cargo.lock
index 2c6ec61a329be276cee6a260aef19eedfb686425..e35bda0da815bc6202f9105ef1799f8f23d9448e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -33,7 +33,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "duniter-keys"
-version = "0.1.0"
+version = "0.2.0"
 dependencies = [
  "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/keys/Cargo.toml b/keys/Cargo.toml
index 6459b81cb250861febf4282e640e1b766d8671a7..3d6199a2c984a17f9d4ac8492a7e2f212f8908f8 100644
--- a/keys/Cargo.toml
+++ b/keys/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "duniter-keys"
-version = "0.1.0"
+version = "0.2.0"
 authors = ["nanocryk <nanocryk@duniter.org>"]
 description = "Manage cryptographic keys for the Duniter project."
 repository = "https://git.duniter.org/nodes/rust/duniter-rs"
diff --git a/keys/ed25519.rs b/keys/ed25519.rs
index bab6cb14d4bcf419fef453634329ba14a0fef9a2..8bb13a9108dcc9a44544c50a8b522ca3fc5c2b78 100644
--- a/keys/ed25519.rs
+++ b/keys/ed25519.rs
@@ -1,426 +1,397 @@
-//  Copyright (C) 2017  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 wrappers around ed25519 keys and signatures
-//!
-//! Key pairs can be generated with [`KeyPairGenerator`].
-//!
-//! [`KeyPairGenerator`]: struct.KeyPairGenerator.html
-
-use std::fmt::Display;
-use std::fmt::Error;
-use std::fmt::Formatter;
-use std::fmt::Debug;
-
-use base58::{ToBase58, FromBase58, FromBase58Error};
-use base64;
-use base64::DecodeError;
-use crypto;
-
-use super::BaseConvertionError;
-
-
-
-// ---------------------------- //
-// ----- struct Signature ----- //
-// ---------------------------- //
-
-/// Store a ed25519 signature.
-#[derive(Clone, Copy)]
-pub struct Signature(pub [u8; 64]);
-
-impl super::Signature for Signature {
-    fn from_base64(base64_data: &str) -> Result<Signature, BaseConvertionError> {
-        match base64::decode(base64_data) {
-            Ok(result) => {
-                if result.len() == 64 {
-                    let mut u8_array = [0; 64];
-
-                    u8_array[..64].clone_from_slice(&result[..64]);
-
-                    Ok(Signature(u8_array))
-                } else {
-                    Err(BaseConvertionError::InvalidKeyLendth(result.len(), 64))
-                }
-            }
-            Err(DecodeError::InvalidByte(pos, byte)) => {
-                Err(BaseConvertionError::InvalidCharacter(byte as char, pos))
-            }
-            Err(DecodeError::InvalidLength) => Err(
-                BaseConvertionError::InvalidBaseConverterLength(),
-            ),
-        }
-    }
-
-    fn to_base64(&self) -> String {
-        base64::encode(&self.0[..]) // need to take a slice for required trait `AsRef<[u8]>`
-    }
-}
-
-impl Display for Signature {
-    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
-        use super::Signature;
-
-        write!(f, "{}", self.to_base64())
-    }
-}
-
-impl Debug for Signature {
-    // Signature { 1eubHHb... }
-    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
-        write!(f, "Signature {{ {} }}", self)
-    }
-}
-
-impl PartialEq<Signature> for Signature {
-    fn eq(&self, other: &Signature) -> bool {
-        // No PartialEq for [u8;64], need to use 2 [u8;32]
-        self.0[0..32] == other.0[0..32] && self.0[32..64] == other.0[32..64]
-    }
-}
-
-impl Eq for Signature {}
-
-
-
-// ---------------------------- //
-// ----- struct PublicKey ----- //
-// ---------------------------- //
-
-/// Store a Ed25519 public key.
-///
-/// Can be generated with [`KeyPairGenerator`].
-///
-/// [`KeyPairGenerator`]: struct.KeyPairGenerator.html
-#[derive(Copy, Clone, PartialEq, Eq)]
-pub struct PublicKey(pub [u8; 32]);
-
-impl ToBase58 for PublicKey {
-    fn to_base58(&self) -> String {
-        self.0.to_base58()
-    }
-}
-
-impl Display for PublicKey {
-    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
-        write!(f, "{}", self.to_base58())
-    }
-}
-
-impl Debug for PublicKey {
-    // PublicKey { DNann1L... }
-    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
-        write!(f, "PublicKey {{ {} }}", self)
-    }
-}
-
-impl super::PublicKey for PublicKey {
-    type Signature = Signature;
-
-    fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> {
-        match base58_data.from_base58() {
-            Ok(result) => {
-                if result.len() == 32 {
-                    let mut u8_array = [0; 32];
-
-                    u8_array[..32].clone_from_slice(&result[..32]);
-
-                    Ok(PublicKey(u8_array))
-                } else {
-                    Err(BaseConvertionError::InvalidKeyLendth(result.len(), 32))
-                }
-            }
-            Err(FromBase58Error::InvalidBase58Character(character, pos)) => Err(
-                BaseConvertionError::InvalidCharacter(character, pos),
-            ),
-            Err(FromBase58Error::InvalidBase58Length) => Err(
-                BaseConvertionError::InvalidBaseConverterLength(),
-            ),
-        }
-    }
-
-    fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
-        crypto::ed25519::verify(message, &self.0, &signature.0)
-    }
-}
-
-
-
-// ----------------------------- //
-// ----- struct PrivateKey ----- //
-// ----------------------------- //
-
-/// Store a Ed25519 private key.
-///
-/// Can be generated with [`KeyPairGenerator`].
-///
-/// [`KeyPairGenerator`]: struct.KeyPairGenerator.html
-#[derive(Copy, Clone)]
-pub struct PrivateKey(pub [u8; 64]);
-
-impl ToBase58 for PrivateKey {
-    fn to_base58(&self) -> String {
-        self.0.to_base58()
-    }
-}
-
-impl Display for PrivateKey {
-    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
-        write!(f, "{}", self.to_base58())
-    }
-}
-
-impl Debug for PrivateKey {
-    // PrivateKey { 468Q1XtT... }
-    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
-        write!(f, "PrivateKey {{ {} }}", self)
-    }
-}
-
-impl PartialEq<PrivateKey> for PrivateKey {
-    fn eq(&self, other: &PrivateKey) -> bool {
-        // No PartialEq for [u8;64], need to use 2 [u8;32]
-        self.0[0..32] == other.0[0..32] && self.0[32..64] == other.0[32..64]
-    }
-}
-
-impl Eq for PrivateKey {}
-
-impl super::PrivateKey for PrivateKey {
-    type Signature = Signature;
-
-    fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> {
-        match base58_data.from_base58() {
-            Ok(result) => {
-                if result.len() == 64 {
-                    let mut u8_array = [0; 64];
-
-                    u8_array[..64].clone_from_slice(&result[..64]);
-
-                    Ok(PrivateKey(u8_array))
-                } else {
-                    Err(BaseConvertionError::InvalidKeyLendth(result.len(), 64))
-                }
-            }
-            Err(FromBase58Error::InvalidBase58Character(character, pos)) => Err(
-                BaseConvertionError::InvalidCharacter(character, pos),
-            ),
-            Err(FromBase58Error::InvalidBase58Length) => Err(
-                BaseConvertionError::InvalidBaseConverterLength(),
-            ),
-        }
-    }
-
-    /// Sign a message with this private key.
-    fn sign(&self, message: &[u8]) -> Self::Signature {
-        Signature(crypto::ed25519::signature(message, &self.0))
-    }
-}
-
-
-
-
-// ----------------------------------- //
-// ----- struct KeyPairGenerator ----- //
-// ----------------------------------- //
-
-/// Keypair generator with given parameters for `scrypt` keypair function.
-#[derive(Debug, Copy, Clone)]
-pub struct KeyPairGenerator {
-    /// The log2 of the Scrypt parameter `N`.
-    log_n: u8,
-    /// The Scrypt parameter `r`
-    r: u32,
-    /// The Scrypt parameter `p`
-    p: u32,
-}
-
-impl KeyPairGenerator {
-    /// Create a `KeyPairGenerator` with default arguments `(log_n: 12, r: 16, p: 1)`
-    pub fn with_default_parameters() -> KeyPairGenerator {
-        KeyPairGenerator {
-            log_n: 12,
-            r: 16,
-            p: 1,
-        }
-    }
-
-    /// Create a `KeyPairGenerator` with given arguments.
-    ///
-    /// # Arguments
-    ///
-    /// - log_n - The log2 of the Scrypt parameter N
-    /// - r - The Scrypt parameter r
-    /// - p - The Scrypt parameter p
-    pub fn with_parameters(log_n: u8, r: u32, p: u32) -> KeyPairGenerator {
-        KeyPairGenerator { log_n, r, p }
-    }
-
-    /// Create a keypair based on a given password and salt.
-    ///
-    /// The [`PublicKey`](struct.PublicKey.html) will be able to verify messaged signed with
-    /// the [`PrivateKey`](struct.PrivateKey.html).
-    pub fn generate(&self, password: &[u8], salt: &[u8]) -> (PrivateKey, PublicKey) {
-        let mut seed = [0u8; 32];
-        crypto::scrypt::scrypt(
-            password,
-            salt,
-            &crypto::scrypt::ScryptParams::new(self.log_n, self.r, self.p),
-            &mut seed,
-        );
-
-        let (private, public) = crypto::ed25519::keypair(&seed);
-        (PrivateKey(private), PublicKey(public))
-    }
-}
-
-
-
-// ---------------------- //
-// ----- UNIT TESTS ----- //
-// ---------------------- //
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use {Signature, PublicKey, PrivateKey};
-
-    #[test]
-    fn base58_private_key() {
-        let private58 = "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9r\
-        qnXuW3iAfZACm7";
-        let private_key = super::PrivateKey::from_base58(private58).unwrap();
-        let private_raw = private58.from_base58().unwrap();
-
-        for (key, raw) in private_key.0.iter().zip(private_raw.iter()) {
-            assert_eq!(key, raw);
-        }
-
-        assert_eq!(private_key.to_base58(), private58);
-        assert_eq!(
-            private_key,
-            super::PrivateKey::from_base58(private58).unwrap()
-        );
-
+//  Copyright (C) 2017  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 wrappers around ed25519 keys and signatures
+//!
+//! Key pairs can be generated with [`KeyPairGenerator`].
+//!
+//! [`KeyPairGenerator`]: struct.KeyPairGenerator.html
+
+use std::fmt::Display;
+use std::fmt::Error;
+use std::fmt::Formatter;
+use std::fmt::Debug;
+
+use base58::{FromBase58, FromBase58Error, ToBase58};
+use base64;
+use base64::DecodeError;
+use crypto;
+
+use super::BaseConvertionError;
+
+/// Store a ed25519 signature.
+#[derive(Clone, Copy)]
+pub struct Signature(pub [u8; 64]);
+
+impl super::Signature for Signature {
+    fn from_base64(base64_data: &str) -> Result<Signature, BaseConvertionError> {
+        match base64::decode(base64_data) {
+            Ok(result) => {
+                if result.len() == 64 {
+                    let mut u8_array = [0; 64];
+
+                    u8_array[..64].clone_from_slice(&result[..64]);
+
+                    Ok(Signature(u8_array))
+                } else {
+                    Err(BaseConvertionError::InvalidKeyLendth(result.len(), 64))
+                }
+            }
+            Err(DecodeError::InvalidByte(pos, byte)) => {
+                Err(BaseConvertionError::InvalidCharacter(byte as char, pos))
+            }
+            Err(DecodeError::InvalidLength) => {
+                Err(BaseConvertionError::InvalidBaseConverterLength())
+            }
+        }
+    }
+
+    fn to_base64(&self) -> String {
+        base64::encode(&self.0[..]) // need to take a slice for required trait `AsRef<[u8]>`
+    }
+}
+
+impl Display for Signature {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        use super::Signature;
+
+        write!(f, "{}", self.to_base64())
+    }
+}
+
+impl Debug for Signature {
+    // Signature { 1eubHHb... }
+    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        write!(f, "Signature {{ {} }}", self)
+    }
+}
+
+impl PartialEq<Signature> for Signature {
+    fn eq(&self, other: &Signature) -> bool {
+        // No PartialEq for [u8;64], need to use 2 [u8;32]
+        self.0[0..32] == other.0[0..32] && self.0[32..64] == other.0[32..64]
+    }
+}
+
+impl Eq for Signature {}
+
+/// Store a Ed25519 public key.
+///
+/// Can be generated with [`KeyPairGenerator`].
+///
+/// [`KeyPairGenerator`]: struct.KeyPairGenerator.html
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub struct PublicKey(pub [u8; 32]);
+
+impl ToBase58 for PublicKey {
+    fn to_base58(&self) -> String {
+        self.0.to_base58()
+    }
+}
+
+impl Display for PublicKey {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        write!(f, "{}", self.to_base58())
+    }
+}
+
+impl Debug for PublicKey {
+    // PublicKey { DNann1L... }
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        write!(f, "PublicKey {{ {} }}", self)
+    }
+}
+
+impl super::PublicKey for PublicKey {
+    type Signature = Signature;
+
+    fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> {
+        match base58_data.from_base58() {
+            Ok(result) => {
+                if result.len() == 32 {
+                    let mut u8_array = [0; 32];
+
+                    u8_array[..32].clone_from_slice(&result[..32]);
+
+                    Ok(PublicKey(u8_array))
+                } else {
+                    Err(BaseConvertionError::InvalidKeyLendth(result.len(), 32))
+                }
+            }
+            Err(FromBase58Error::InvalidBase58Character(character, pos)) => {
+                Err(BaseConvertionError::InvalidCharacter(character, pos))
+            }
+            Err(FromBase58Error::InvalidBase58Length) => {
+                Err(BaseConvertionError::InvalidBaseConverterLength())
+            }
+        }
+    }
+
+    fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
+        crypto::ed25519::verify(message, &self.0, &signature.0)
+    }
+}
+
+/// Store a Ed25519 private key.
+///
+/// Can be generated with [`KeyPairGenerator`].
+///
+/// [`KeyPairGenerator`]: struct.KeyPairGenerator.html
+#[derive(Copy, Clone)]
+pub struct PrivateKey(pub [u8; 64]);
+
+impl ToBase58 for PrivateKey {
+    fn to_base58(&self) -> String {
+        self.0.to_base58()
+    }
+}
+
+impl Display for PrivateKey {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        write!(f, "{}", self.to_base58())
+    }
+}
+
+impl Debug for PrivateKey {
+    // PrivateKey { 468Q1XtT... }
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        write!(f, "PrivateKey {{ {} }}", self)
+    }
+}
+
+impl PartialEq<PrivateKey> for PrivateKey {
+    fn eq(&self, other: &PrivateKey) -> bool {
+        // No PartialEq for [u8;64], need to use 2 [u8;32]
+        self.0[0..32] == other.0[0..32] && self.0[32..64] == other.0[32..64]
+    }
+}
+
+impl Eq for PrivateKey {}
+
+impl super::PrivateKey for PrivateKey {
+    type Signature = Signature;
+
+    fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> {
+        match base58_data.from_base58() {
+            Ok(result) => {
+                if result.len() == 64 {
+                    let mut u8_array = [0; 64];
+
+                    u8_array[..64].clone_from_slice(&result[..64]);
+
+                    Ok(PrivateKey(u8_array))
+                } else {
+                    Err(BaseConvertionError::InvalidKeyLendth(result.len(), 64))
+                }
+            }
+            Err(FromBase58Error::InvalidBase58Character(character, pos)) => {
+                Err(BaseConvertionError::InvalidCharacter(character, pos))
+            }
+            Err(FromBase58Error::InvalidBase58Length) => {
+                Err(BaseConvertionError::InvalidBaseConverterLength())
+            }
+        }
+    }
+
+    /// Sign a message with this private key.
+    fn sign(&self, message: &[u8]) -> Self::Signature {
+        Signature(crypto::ed25519::signature(message, &self.0))
+    }
+}
+
+/// Keypair generator with given parameters for `scrypt` keypair function.
+#[derive(Debug, Copy, Clone)]
+pub struct KeyPairGenerator {
+    /// The log2 of the Scrypt parameter `N`.
+    log_n: u8,
+    /// The Scrypt parameter `r`
+    r: u32,
+    /// The Scrypt parameter `p`
+    p: u32,
+}
+
+impl KeyPairGenerator {
+    /// Create a `KeyPairGenerator` with default arguments `(log_n: 12, r: 16, p: 1)`
+    pub fn with_default_parameters() -> KeyPairGenerator {
+        KeyPairGenerator {
+            log_n: 12,
+            r: 16,
+            p: 1,
+        }
+    }
+
+    /// Create a `KeyPairGenerator` with given arguments.
+    ///
+    /// # Arguments
+    ///
+    /// - log_n - The log2 of the Scrypt parameter N
+    /// - r - The Scrypt parameter r
+    /// - p - The Scrypt parameter p
+    pub fn with_parameters(log_n: u8, r: u32, p: u32) -> KeyPairGenerator {
+        KeyPairGenerator { log_n, r, p }
+    }
+
+    /// Create a keypair based on a given password and salt.
+    ///
+    /// The [`PublicKey`](struct.PublicKey.html) will be able to verify messaged signed with
+    /// the [`PrivateKey`](struct.PrivateKey.html).
+    pub fn generate(&self, password: &[u8], salt: &[u8]) -> (PrivateKey, PublicKey) {
+        let mut seed = [0u8; 32];
+        crypto::scrypt::scrypt(
+            password,
+            salt,
+            &crypto::scrypt::ScryptParams::new(self.log_n, self.r, self.p),
+            &mut seed,
+        );
+
+        let (private, public) = crypto::ed25519::keypair(&seed);
+        (PrivateKey(private), PublicKey(public))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use {PrivateKey, PublicKey, Signature};
+
+    #[test]
+    fn base58_private_key() {
+        let private58 =
+            "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9r\
+             qnXuW3iAfZACm7";
+        let private_key = super::PrivateKey::from_base58(private58).unwrap();
+        let private_raw = private58.from_base58().unwrap();
+
+        for (key, raw) in private_key.0.iter().zip(private_raw.iter()) {
+            assert_eq!(key, raw);
+        }
+
+        assert_eq!(private_key.to_base58(), private58);
+        assert_eq!(
+            private_key,
+            super::PrivateKey::from_base58(private58).unwrap()
+        );
+
         assert_eq!(
             super::PrivateKey::from_base58(
                 "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iA\
                 fZACm7djh",
             ).unwrap_err(),
             BaseConvertionError::InvalidKeyLendth(67, 64)
-        );
-        assert_eq!(
-            super::PrivateKey::from_base58(
-                "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9",
-            ).unwrap_err(),
-            BaseConvertionError::InvalidKeyLendth(53, 64)
-        );
-        assert_eq!(
-            super::PrivateKey::from_base58(
-                "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9<<",
-            ).unwrap_err(),
-            BaseConvertionError::InvalidCharacter('<', 73)
-        );
-    }
-
-    #[test]
-    fn base58_public_key() {
-        let public58 = "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV";
-        let public_key = super::PublicKey::from_base58(public58).unwrap();
-        let public_raw = public58.from_base58().unwrap();
-
-        for (key, raw) in public_key.0.iter().zip(public_raw.iter()) {
-            assert_eq!(key, raw);
-        }
-
-        assert_eq!(public_key.to_base58(), public58);
-        assert_eq!(public_key, super::PublicKey::from_base58(public58).unwrap());
-
-        assert_eq!(
-            super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLVdjq")
-                .unwrap_err(),
-            BaseConvertionError::InvalidKeyLendth(35, 32)
-        );
-        assert_eq!(
-            super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd").unwrap_err(),
-            BaseConvertionError::InvalidKeyLendth(31, 32)
-        );
-        assert_eq!(
-            super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd<<")
-                .unwrap_err(),
-            BaseConvertionError::InvalidCharacter('<', 42)
-        );
-    }
-
-    #[test]
-    fn base64_signature() {
-        let signature64 = "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FG\
-                          MMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==";
-        let signature = super::Signature::from_base64(signature64).unwrap();
-        let signature_raw = base64::decode(signature64).unwrap();
-
-        for (sig, raw) in signature.0.iter().zip(signature_raw.iter()) {
-            assert_eq!(sig, raw);
-        }
-
-        assert_eq!(
-            super::Signature::from_base64("YmhlaW9iaHNlcGlvaGVvaXNlcGl2ZXBvdm5pc2U=").unwrap_err(),
-            BaseConvertionError::InvalidKeyLendth(29, 64)
-        );
-        assert_eq!(
-            super::Signature::from_base64(
-                "YmhlaW9iaHNlcGlvaGVvaXNlcGl2ZXBvdm5pc2V2c2JlaW9idmVpb3Zqc\
-                2V2Z3BpaHNlamVwZ25qZXNqb2dwZWpnaW9zZXNkdnNic3JicmJyZGJyZGI=",
-            ).unwrap_err(),
-            BaseConvertionError::InvalidKeyLendth(86, 64)
-        );
-        assert_eq!(
-            super::Signature::from_base64(
-                "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMM\
-                mQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAgdha<<",
-            ).unwrap_err(),
-            BaseConvertionError::InvalidCharacter('<', 89)
-        );
-    }
-
-    #[test]
-    fn message_sign_verify() {
-        let pubkey = super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV")
-            .unwrap();
-
-        let prikey = super::PrivateKey::from_base58(
-            "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt\
-            5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
-        ).unwrap();
-
-        let expected_signature = super::Signature::from_base64(
-            "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FG\
-            MMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
-        ).unwrap();
-
+        );
+        assert_eq!(
+            super::PrivateKey::from_base58(
+                "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9",
+            ).unwrap_err(),
+            BaseConvertionError::InvalidKeyLendth(53, 64)
+        );
+        assert_eq!(
+            super::PrivateKey::from_base58(
+                "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9<<",
+            ).unwrap_err(),
+            BaseConvertionError::InvalidCharacter('<', 73)
+        );
+    }
+
+    #[test]
+    fn base58_public_key() {
+        let public58 = "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV";
+        let public_key = super::PublicKey::from_base58(public58).unwrap();
+        let public_raw = public58.from_base58().unwrap();
+
+        for (key, raw) in public_key.0.iter().zip(public_raw.iter()) {
+            assert_eq!(key, raw);
+        }
+
+        assert_eq!(public_key.to_base58(), public58);
+        assert_eq!(public_key, super::PublicKey::from_base58(public58).unwrap());
+
+        assert_eq!(
+            super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLVdjq")
+                .unwrap_err(),
+            BaseConvertionError::InvalidKeyLendth(35, 32)
+        );
+        assert_eq!(
+            super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd")
+                .unwrap_err(),
+            BaseConvertionError::InvalidKeyLendth(31, 32)
+        );
+        assert_eq!(
+            super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd<<")
+                .unwrap_err(),
+            BaseConvertionError::InvalidCharacter('<', 42)
+        );
+    }
+
+    #[test]
+    fn base64_signature() {
+        let signature64 = "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FG\
+                           MMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==";
+        let signature = super::Signature::from_base64(signature64).unwrap();
+        let signature_raw = base64::decode(signature64).unwrap();
+
+        for (sig, raw) in signature.0.iter().zip(signature_raw.iter()) {
+            assert_eq!(sig, raw);
+        }
+
+        assert_eq!(
+            super::Signature::from_base64("YmhlaW9iaHNlcGlvaGVvaXNlcGl2ZXBvdm5pc2U=").unwrap_err(),
+            BaseConvertionError::InvalidKeyLendth(29, 64)
+        );
+        assert_eq!(
+            super::Signature::from_base64(
+                "YmhlaW9iaHNlcGlvaGVvaXNlcGl2ZXBvdm5pc2V2c2JlaW9idmVpb3Zqc\
+                 2V2Z3BpaHNlamVwZ25qZXNqb2dwZWpnaW9zZXNkdnNic3JicmJyZGJyZGI=",
+            ).unwrap_err(),
+            BaseConvertionError::InvalidKeyLendth(86, 64)
+        );
+        assert_eq!(
+            super::Signature::from_base64(
+                "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMM\
+                 mQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAgdha<<",
+            ).unwrap_err(),
+            BaseConvertionError::InvalidCharacter('<', 89)
+        );
+    }
+
+    #[test]
+    fn message_sign_verify() {
+        let pubkey =
+            super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV").unwrap();
+
+        let prikey = super::PrivateKey::from_base58(
+            "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt\
+             5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
+        ).unwrap();
+
+        let expected_signature = super::Signature::from_base64(
+            "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FG\
+             MMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
+        ).unwrap();
+
         let message = "Version: 10
 Type: Identity
 Currency: duniter_unit_test_currency
 Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
 UniqueID: tic
 Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
-";
-
-        let sig = prikey.sign(message.as_bytes());
-
-        assert_eq!(sig, expected_signature);
-        assert!(pubkey.verify(message.as_bytes(), &sig));
-    }
-}
+";
+
+        let sig = prikey.sign(message.as_bytes());
+
+        assert_eq!(sig, expected_signature);
+        assert!(pubkey.verify(message.as_bytes(), &sig));
+    }
+}
diff --git a/keys/lib.rs b/keys/lib.rs
index 5f807abe5d3efaeb8cbd0b8e2cf84f37ab3c2d5e..49842a68658245ab861addd34c659bd00596a0ab 100644
--- a/keys/lib.rs
+++ b/keys/lib.rs
@@ -1,4 +1,4 @@
-//  Copyright (C) 2017  The Duniter Project Developers.
+//  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
@@ -46,12 +46,9 @@
 //! `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`
 //! with `=` as padding character.
 
-#![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 base58;
 extern crate base64;
@@ -64,10 +61,6 @@ use base58::ToBase58;
 
 pub mod ed25519;
 
-// ------------------------------------ //
-// ----- enum BaseConvertionError ----- //
-// ------------------------------------ //
-
 /// Errors enumeration for Base58/64 strings convertion.
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum BaseConvertionError {
@@ -79,11 +72,6 @@ pub enum BaseConvertionError {
     InvalidBaseConverterLength(),
 }
 
-
-// --------------------------- //
-// ----- trait Signature ----- //
-// --------------------------- //
-
 /// Store a cryptographic signature.
 ///
 /// A signature can be converted from/to Base64 format.
@@ -108,11 +96,6 @@ pub trait Signature: Clone + Display + Debug + PartialEq + Eq {
     fn to_base64(&self) -> String;
 }
 
-
-// ---------------------------- //
-// ----- struct PublicKey ----- //
-// ---------------------------- //
-
 /// Store a cryptographic public key.
 ///
 /// A `PublicKey` can be converted from/to Base64 format.
@@ -123,10 +106,8 @@ pub trait Signature: Clone + Display + Debug + PartialEq + Eq {
 ///
 /// [`PrivateKey`]: trait.PrivateKey.html
 pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
-    /// [`Signature`] type of associated cryptosystem.
-    ///
-    /// [`Signature`]: trait.Signature.html
-    type Signature;
+    /// Signature type of associated cryptosystem.
+    type Signature: Signature;
 
     /// Create a PublicKey from a Base58 string.
     ///
@@ -141,11 +122,6 @@ pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
     fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;
 }
 
-
-// ----------------------------- //
-// ----- struct PrivateKey ----- //
-// ----------------------------- //
-
 /// Store a cryptographic private key.
 ///
 /// A `PrivateKey` can be converted from/to Base58 format.
@@ -156,10 +132,8 @@ pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
 ///
 /// [`PublicKey`]: trait.PublicKey.html
 pub trait PrivateKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
-    /// [`Signature`] type of associated cryptosystem.
-    ///
-    /// [`Signature`]: trait.Signature.html
-    type Signature;
+    /// Signature type of associated cryptosystem.
+    type Signature: Signature;
 
     /// Create a PrivateKey from a Base58 string.
     ///