diff --git a/documents/blockchain/v10/documents/certification.rs b/documents/blockchain/v10/documents/certification.rs
index 68e9cc14be9b27a1180976b00f075eabf95f1e8e..4a30de9ffc535274781562e2caaf0157abf66d12 100644
--- a/documents/blockchain/v10/documents/certification.rs
+++ b/documents/blockchain/v10/documents/certification.rs
@@ -173,7 +173,7 @@ impl<'a> TextDocumentBuilder for CertificationDocumentBuilder<'a> {
     fn generate_text(&self) -> String {
         format!(
             "Version: 10
-Type: Membership
+Type: Certification
 Currency: {currency}
 Issuer: {issuer}
 IdtyIssuer: {target}
@@ -259,7 +259,7 @@ mod tests {
         ).unwrap();
 
         let sig = ed25519::Signature::from_base64(
-            "xNhaCa+HgrQh/2koZ3a7PGku8h+NXIp7YxFcLYzS/YLwNA4lNXOks8hAIX4QyPy7hTUWPlhcQNdq74exXm5pCw==",
+            "qfR6zqT1oJbqIsppOi64gC9yTtxb6g6XA9RYpulkq9ehMvqg2VYVigCbR0yVpqKFsnYiQTrnjgFuFRSJCJDfCw==",
         ).unwrap();
 
         let target = ed25519::PublicKey::from_base58(
diff --git a/documents/blockchain/v10/documents/mod.rs b/documents/blockchain/v10/documents/mod.rs
index 4e38bccacb0bc09e7b46444c932fb339229e44aa..4c0d6f38c23b3763c4f9e716afd37f71589258df 100644
--- a/documents/blockchain/v10/documents/mod.rs
+++ b/documents/blockchain/v10/documents/mod.rs
@@ -23,11 +23,13 @@ use blockchain::v10::documents::identity::IdentityDocumentParser;
 pub mod identity;
 pub mod membership;
 pub mod certification;
+pub mod revocation;
 
 pub use blockchain::v10::documents::identity::{IdentityDocument, IdentityDocumentBuilder};
 pub use blockchain::v10::documents::membership::{MembershipDocument, MembershipDocumentParser};
 pub use blockchain::v10::documents::certification::{CertificationDocument,
                                                     CertificationDocumentParser};
+pub use blockchain::v10::documents::revocation::{RevocationDocument, RevocationDocumentParser};
 
 // Use of lazy_static so the regex is only compiled at first use.
 lazy_static! {
@@ -62,7 +64,7 @@ pub enum V10Document {
     Certification(Box<CertificationDocument>),
 
     /// Revocation document.
-    Revocation(),
+    Revocation(Box<RevocationDocument>),
 }
 
 /// Trait for a V10 document.
diff --git a/documents/blockchain/v10/documents/revocation.rs b/documents/blockchain/v10/documents/revocation.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0de185e224eb5ead27a35afa2315b3f4c1b90150
--- /dev/null
+++ b/documents/blockchain/v10/documents/revocation.rs
@@ -0,0 +1,302 @@
+//  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/>.
+
+//! Wrappers around Revocation documents.
+
+use duniter_crypto::keys::{PublicKey, Signature, ed25519};
+use regex::Regex;
+
+use Blockstamp;
+use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
+use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder,
+                                 V10Document, V10DocumentParsingError};
+
+lazy_static! {
+    static ref REVOCATION_REGEX: Regex = Regex::new(
+        "^Issuer: (?P<issuer>[1-9A-Za-z][^OIl]{43,44})\n\
+         IdtyUniqueID: (?P<idty_uid>[[:alnum:]_-]+)\n\
+         IdtyTimestamp: (?P<idty_blockstamp>[0-9]+-[0-9A-F]{64})\n\
+         IdtySignature: (?P<idty_sig>(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?)\n$"
+    ).unwrap();
+}
+
+/// Wrap an Revocation document.
+///
+/// Must be created by parsing a text document or using a builder.
+#[derive(Debug, Clone)]
+pub struct RevocationDocument {
+    /// Document as text.
+    ///
+    /// Is used to check signatures, and other values mut be extracted from it.
+    text: String,
+
+    /// Name of the currency.
+    currency: String,
+    /// Document issuer (there should be only one).
+    issuers: Vec<ed25519::PublicKey>,
+    /// Username of target identity
+    identity_username: String,
+    /// Target Identity document blockstamp.
+    identity_blockstamp: Blockstamp,
+    /// Target Identity document signature.
+    identity_sig: ed25519::Signature,
+    /// Document signature (there should be only one).
+    signatures: Vec<ed25519::Signature>,
+}
+
+impl RevocationDocument {
+    /// Username of target identity
+    pub fn identity_username(&self) -> &str {
+        &self.identity_username
+    }
+}
+
+impl Document for RevocationDocument {
+    type PublicKey = ed25519::PublicKey;
+    type CurrencyType = str;
+
+    fn version(&self) -> u16 {
+        10
+    }
+
+    fn currency(&self) -> &str {
+        &self.currency
+    }
+
+    fn issuers(&self) -> &Vec<ed25519::PublicKey> {
+        &self.issuers
+    }
+
+    fn signatures(&self) -> &Vec<ed25519::Signature> {
+        &self.signatures
+    }
+
+    fn as_bytes(&self) -> &[u8] {
+        self.as_text().as_bytes()
+    }
+}
+
+impl TextDocument for RevocationDocument {
+    fn as_text(&self) -> &str {
+        &self.text
+    }
+}
+
+impl IntoSpecializedDocument<BlockchainProtocol> for RevocationDocument {
+    fn into_specialized(self) -> BlockchainProtocol {
+        BlockchainProtocol::V10(V10Document::Revocation(Box::new(self)))
+    }
+}
+
+/// Revocation document builder.
+#[derive(Debug, Copy, Clone)]
+pub struct RevocationDocumentBuilder<'a> {
+    /// Document currency.
+    pub currency: &'a str,
+    /// Revocation issuer.
+    pub issuer: &'a ed25519::PublicKey,
+    /// Username of target Identity.
+    pub identity_username: &'a str,
+    /// Blockstamp of target Identity.
+    pub identity_blockstamp: &'a Blockstamp,
+    /// Signature of target Identity.
+    pub identity_sig: &'a ed25519::Signature,
+}
+
+impl<'a> RevocationDocumentBuilder<'a> {
+    fn build_with_text_and_sigs(
+        self,
+        text: String,
+        signatures: Vec<ed25519::Signature>,
+    ) -> RevocationDocument {
+        RevocationDocument {
+            text,
+            currency: self.currency.to_string(),
+            issuers: vec![*self.issuer],
+            identity_username: self.identity_username.to_string(),
+            identity_blockstamp: *self.identity_blockstamp,
+            identity_sig: *self.identity_sig,
+            signatures,
+        }
+    }
+}
+
+impl<'a> DocumentBuilder for RevocationDocumentBuilder<'a> {
+    type Document = RevocationDocument;
+    type PrivateKey = ed25519::PrivateKey;
+
+    fn build_with_signature(&self, signatures: Vec<ed25519::Signature>) -> RevocationDocument {
+        self.build_with_text_and_sigs(self.generate_text(), signatures)
+    }
+
+    fn build_and_sign(&self, private_keys: Vec<ed25519::PrivateKey>) -> RevocationDocument {
+        let (text, signatures) = self.build_signed_text(private_keys);
+        self.build_with_text_and_sigs(text, signatures)
+    }
+}
+
+impl<'a> TextDocumentBuilder for RevocationDocumentBuilder<'a> {
+    fn generate_text(&self) -> String {
+        format!(
+            "Version: 10
+Type: Revocation
+Currency: {currency}
+Issuer: {issuer}
+IdtyUniqueID: {idty_uid}
+IdtyTimestamp: {idty_blockstamp}
+IdtySignature: {idty_sig}
+",
+            currency = self.currency,
+            issuer = self.issuer,
+            idty_uid = self.identity_username,
+            idty_blockstamp = self.identity_blockstamp,
+            idty_sig = self.identity_sig,
+        )
+    }
+}
+
+/// Revocation document parser
+#[derive(Debug, Clone, Copy)]
+pub struct RevocationDocumentParser;
+
+impl StandardTextDocumentParser for RevocationDocumentParser {
+    fn parse_standard(
+        doc: &str,
+        body: &str,
+        currency: &str,
+        signatures: Vec<ed25519::Signature>,
+    ) -> Result<V10Document, V10DocumentParsingError> {
+        if let Some(caps) = REVOCATION_REGEX.captures(body) {
+            let issuer = &caps["issuer"];
+            let identity_username = &caps["idty_uid"];
+            let identity_blockstamp = &caps["idty_blockstamp"];
+            let identity_sig = &caps["idty_sig"];
+
+            // Regex match so should not fail.
+            // TODO : Test it anyway
+            let issuer = ed25519::PublicKey::from_base58(issuer).unwrap();
+            let identity_username = String::from(identity_username);
+            let identity_blockstamp = Blockstamp::from_string(identity_blockstamp).unwrap();
+            let identity_sig = ed25519::Signature::from_base64(identity_sig).unwrap();
+
+            Ok(V10Document::Revocation(Box::new(RevocationDocument {
+                text: doc.to_owned(),
+                issuers: vec![issuer],
+                currency: currency.to_owned(),
+                identity_username,
+                identity_blockstamp,
+                identity_sig,
+                signatures,
+            })))
+        } else {
+            Err(V10DocumentParsingError::InvalidInnerFormat(
+                "Revocation".to_string(),
+            ))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use duniter_crypto::keys::{PrivateKey, PublicKey, Signature};
+    use blockchain::VerificationResult;
+
+    #[test]
+    fn generate_real_document() {
+        let pubkey = ed25519::PublicKey::from_base58(
+            "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV",
+        ).unwrap();
+
+        let prikey = ed25519::PrivateKey::from_base58(
+            "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\
+             iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
+        ).unwrap();
+
+        let sig = ed25519::Signature::from_base64(
+            "XXOgI++6qpY9O31ml/FcfbXCE6aixIrgkT5jL7kBle3YOMr+8wrp7Rt+z9hDVjrNfYX2gpeJsuMNfG4T/fzVDQ==",
+        ).unwrap();
+
+        let identity_blockstamp = Blockstamp::from_string(
+            "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
+        ).unwrap();
+
+        let identity_sig = ed25519::Signature::from_base64(
+            "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
+        ).unwrap();
+
+        let builder = RevocationDocumentBuilder {
+            currency: "g1",
+            issuer: &pubkey,
+            identity_username: "tic",
+            identity_blockstamp: &identity_blockstamp,
+            identity_sig: &identity_sig,
+        };
+
+        assert_eq!(
+            builder.build_with_signature(vec![sig]).verify_signatures(),
+            VerificationResult::Valid()
+        );
+
+        assert_eq!(
+            builder.build_and_sign(vec![prikey]).verify_signatures(),
+            VerificationResult::Valid()
+        );
+    }
+
+    #[test]
+    fn revocation_standard_regex() {
+        assert!(REVOCATION_REGEX.is_match(
+            "Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
+IdtyUniqueID: tic
+IdtyTimestamp: 98221-000000575AC04F5164F7A307CDB766139EA47DD249E4A2444F292BC8AAB408B3
+IdtySignature: DjeipIeb/RF0tpVCnVnuw6mH1iLJHIsDfPGLR90Twy3PeoaDz6Yzhc/UjLWqHCi5Y6wYajV0dNg4jQRUneVBCQ==
+"
+        ));
+    }
+
+    #[test]
+    fn revocation_document() {
+        let doc = "Version: 10
+Type: Revocation
+Currency: g1
+Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
+IdtyUniqueID: tic
+IdtyTimestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
+IdtySignature: 1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==
+";
+
+        let body = "Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
+IdtyUniqueID: tic
+IdtyTimestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
+IdtySignature: 1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==
+";
+
+        let currency = "g1";
+
+        let signatures = vec![Signature::from_base64(
+"XXOgI++6qpY9O31ml/FcfbXCE6aixIrgkT5jL7kBle3YOMr+8wrp7Rt+z9hDVjrNfYX2gpeJsuMNfG4T/fzVDQ=="
+        ).unwrap(),];
+
+        let doc =
+            RevocationDocumentParser::parse_standard(doc, body, currency, signatures).unwrap();
+        if let V10Document::Revocation(doc) = doc {
+            println!("Doc : {:?}", doc);
+            assert_eq!(doc.verify_signatures(), VerificationResult::Valid())
+        } else {
+            panic!("Wrong document type");
+        }
+    }
+}