diff --git a/Cargo.lock b/Cargo.lock
index 57ecf4604f7e365b05db6b611245454874183268..9648b789bb4d65f41aacf4c31367e66662587faa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -94,7 +94,7 @@ dependencies = [
 
 [[package]]
 name = "duniter-documents"
-version = "0.4.1"
+version = "0.5.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/crypto/keys/ed25519.rs b/crypto/keys/ed25519.rs
index 1d3e50a046d647391b6b47980802eef5fd8daaf3..2ed603663b048770633b8277ba1749993c151705 100644
--- a/crypto/keys/ed25519.rs
+++ b/crypto/keys/ed25519.rs
@@ -19,10 +19,12 @@
 //!
 //! [`KeyPairGenerator`]: struct.KeyPairGenerator.html
 
+use std::collections::hash_map::DefaultHasher;
 use std::fmt::Display;
 use std::fmt::Error;
 use std::fmt::Formatter;
 use std::fmt::Debug;
+use std::hash::{Hash, Hasher};
 
 use base58::{FromBase58, FromBase58Error, ToBase58};
 use base64;
@@ -35,6 +37,13 @@ use super::{BaseConvertionError, PrivateKey as PrivateKeyMethods, PublicKey as P
 #[derive(Clone, Copy)]
 pub struct Signature(pub [u8; 64]);
 
+impl Hash for Signature {
+    fn hash<H: Hasher>(&self, _state: &mut H) {
+        let mut hasher = DefaultHasher::new();
+        Hash::hash_slice(&self.0, &mut hasher);
+    }
+}
+
 impl super::Signature for Signature {
     fn from_base64(base64_data: &str) -> Result<Signature, BaseConvertionError> {
         match base64::decode(base64_data) {
diff --git a/documents/Cargo.toml b/documents/Cargo.toml
index 94f4ac9cf7f9933e3ae5c2dd7e1266b96d7ecc22..2a42d7fd9d4e01bde39d80f0f12c663078a1707c 100644
--- a/documents/Cargo.toml
+++ b/documents/Cargo.toml
@@ -1,8 +1,8 @@
 [package]
 name = "duniter-documents"
-version = "0.4.1"
+version = "0.5.0"
 authors = ["nanocryk <nanocryk@duniter.org>", "elois <elois@ifee.fr>"]
-description = "Implements the Duniter Protocol"
+description = "Handles Duniter documents"
 repository = "https://git.duniter.org/nodes/rust/duniter-rs"
 readme = "README.md"
 keywords = ["duniter", "blockchain", "cryptocurrency", "document"]
diff --git a/documents/README.md b/documents/README.md
index d9a912991098f9ad2a437a6c3b666bf8b4fe9eea..6191c3d031f0586268323ddfa27f4339aa3f2eae 100644
--- a/documents/README.md
+++ b/documents/README.md
@@ -1,10 +1,10 @@
-# protocol
+# Documents
 
-`protocol` is a crate implementing the [Duniter] Protocol in [version 10][version10].
+`documents` is a crate implementing the [Duniter] Documents Protocol in [version 10][version10].
 
 [Duniter]: https://duniter.org/en/
 [version10]: https://git.duniter.org/nodes/typescript/duniter/blob/master/doc/Protocol.md
 
 ## How to use it
 
-You can add `duniter-keys` as a `cargo` dependency in your Rust project.
+You can add `duniter-documents` as a `cargo` dependency in your Rust project.
diff --git a/documents/blockchain/mod.rs b/documents/blockchain/mod.rs
index 5f997b0c9fd18f8dfc1443f8ca304c22a9c1d42f..97e35dd8508f605dc7c3ae697acdfc26e652e42b 100644
--- a/documents/blockchain/mod.rs
+++ b/documents/blockchain/mod.rs
@@ -25,7 +25,7 @@ pub mod v10;
 #[derive(Debug)]
 pub enum BlockchainProtocol {
     /// Version 10.
-    V10(v10::documents::V10Document),
+    V10(Box<v10::documents::V10Document>),
     /// Version 11. (not done yet, but defined for tests)
     V11(),
 }
diff --git a/documents/blockchain/v10/documents/certification.rs b/documents/blockchain/v10/documents/certification.rs
index 4a30de9ffc535274781562e2caaf0157abf66d12..d4de8631c1078f587aba3679dbe8328c294b82ac 100644
--- a/documents/blockchain/v10/documents/certification.rs
+++ b/documents/blockchain/v10/documents/certification.rs
@@ -112,7 +112,7 @@ impl TextDocument for CertificationDocument {
 
 impl IntoSpecializedDocument<BlockchainProtocol> for CertificationDocument {
     fn into_specialized(self) -> BlockchainProtocol {
-        BlockchainProtocol::V10(V10Document::Certification(Box::new(self)))
+        BlockchainProtocol::V10(Box::new(V10Document::Certification(Box::new(self))))
     }
 }
 
diff --git a/documents/blockchain/v10/documents/identity.rs b/documents/blockchain/v10/documents/identity.rs
index 05762ee565f2683e3c4e2a1cd091d4a1bc46b63d..ac7622ec78cb27ce47dfb36c28668dd7f2980b35 100644
--- a/documents/blockchain/v10/documents/identity.rs
+++ b/documents/blockchain/v10/documents/identity.rs
@@ -32,7 +32,7 @@ lazy_static! {
 /// Wrap an Identity document.
 ///
 /// Must be created by parsing a text document or using a builder.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Hash)]
 pub struct IdentityDocument {
     /// Document as text.
     ///
@@ -92,7 +92,7 @@ impl TextDocument for IdentityDocument {
 
 impl IntoSpecializedDocument<BlockchainProtocol> for IdentityDocument {
     fn into_specialized(self) -> BlockchainProtocol {
-        BlockchainProtocol::V10(V10Document::Identity(self))
+        BlockchainProtocol::V10(Box::new(V10Document::Identity(self)))
     }
 }
 
diff --git a/documents/blockchain/v10/documents/membership.rs b/documents/blockchain/v10/documents/membership.rs
index fb1d2d12baeea41c74f4da7ee029f99a7399a1f7..0fab5443d53f047616407afbc153dc491c60289d 100644
--- a/documents/blockchain/v10/documents/membership.rs
+++ b/documents/blockchain/v10/documents/membership.rs
@@ -34,7 +34,7 @@ lazy_static! {
 }
 
 /// Type of a Membership.
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq, Hash)]
 pub enum MembershipType {
     /// The member wishes to opt-in.
     In(),
@@ -45,7 +45,7 @@ pub enum MembershipType {
 /// Wrap an Membership document.
 ///
 /// Must be created by parsing a text document or using a builder.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Hash)]
 pub struct MembershipDocument {
     /// Document as text.
     ///
@@ -113,7 +113,7 @@ impl TextDocument for MembershipDocument {
 
 impl IntoSpecializedDocument<BlockchainProtocol> for MembershipDocument {
     fn into_specialized(self) -> BlockchainProtocol {
-        BlockchainProtocol::V10(V10Document::Membership(self))
+        BlockchainProtocol::V10(Box::new(V10Document::Membership(self)))
     }
 }
 
diff --git a/documents/blockchain/v10/documents/revocation.rs b/documents/blockchain/v10/documents/revocation.rs
index 0de185e224eb5ead27a35afa2315b3f4c1b90150..6b7538b9c472913d74821518400a7ce985e9e077 100644
--- a/documents/blockchain/v10/documents/revocation.rs
+++ b/documents/blockchain/v10/documents/revocation.rs
@@ -96,7 +96,7 @@ impl TextDocument for RevocationDocument {
 
 impl IntoSpecializedDocument<BlockchainProtocol> for RevocationDocument {
     fn into_specialized(self) -> BlockchainProtocol {
-        BlockchainProtocol::V10(V10Document::Revocation(Box::new(self)))
+        BlockchainProtocol::V10(Box::new(V10Document::Revocation(Box::new(self))))
     }
 }
 
diff --git a/documents/lib.rs b/documents/lib.rs
index e3d8b38171011e2329eb1d41623b99ffae96bbcc..d445c12f94a8f699c25d279c25c11b8896cf7a30 100644
--- a/documents/lib.rs
+++ b/documents/lib.rs
@@ -36,7 +36,7 @@ use duniter_crypto::keys::BaseConvertionError;
 pub mod blockchain;
 
 /// A block Id.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct BlockId(pub u32);
 
 impl Display for BlockId {
@@ -48,7 +48,7 @@ impl Display for BlockId {
 /// A hash wrapper.
 ///
 /// A hash is often provided as string composed of 64 hexadecimal character (0 to 9 then A to F).
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Hash(pub [u8; 32]);
 
 impl Display for Hash {
@@ -110,7 +110,7 @@ impl Hash {
 }
 
 /// Wrapper of a block hash.
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct BlockHash(Hash);
 
 impl Display for BlockHash {
@@ -148,7 +148,7 @@ pub enum BlockUIdParseError {
 ///
 /// [`BlockId`]: struct.BlockId.html
 /// [`BlockHash`]: struct.BlockHash.html
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Blockstamp {
     /// Block Id.
     pub id: BlockId,