diff --git a/blockchain/lib.rs b/blockchain/lib.rs
index c2ec0c3033278f4687e1bf4bc6cf350660756d49..e4be85fabceebdaf3142ab5eafa54779b917c7dd 100644
--- a/blockchain/lib.rs
+++ b/blockchain/lib.rs
@@ -50,7 +50,7 @@ use std::sync::mpsc;
 use std::time::{Duration, SystemTime, UNIX_EPOCH};
 
 use self::stack_up_block::try_stack_up_completed_block;
-use duniter_crypto::keys::ed25519;
+use duniter_crypto::keys::*;
 use duniter_dal::block::{DALBlock, WotEvent};
 use duniter_dal::constants::MAX_FORKS;
 use duniter_dal::dal_event::DALEvent;
@@ -141,7 +141,7 @@ impl BlockchainModule {
     /// Loading blockchain configuration
     pub fn load_blockchain_conf(
         conf: &DuniterConf,
-        _keys: RequiredKeysContent<ed25519::KeyPair>,
+        _keys: RequiredKeysContent,
         sync: bool,
     ) -> BlockchainModule {
         // Get db path
@@ -274,7 +274,7 @@ impl BlockchainModule {
         network_documents: &[NetworkDocument],
         current_blockstamp: &Blockstamp,
         forks: &mut Vec<ForkState>,
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
+        wotb_index: &HashMap<PubKey, NodeId>,
         wot: &W,
     ) -> (Blockstamp, Vec<WotEvent>) {
         let mut blockchain_documents = Vec::new();
@@ -352,7 +352,7 @@ impl BlockchainModule {
         blocks_in_box: &[Box<NetworkBlock>],
         current_blockstamp: &Blockstamp,
         forks: &[ForkState],
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
+        wotb_index: &HashMap<PubKey, NodeId>,
         wot: &W,
     ) -> (Blockstamp, Vec<ForkState>, Vec<WotEvent>) {
         debug!("BlockchainModule : receive_blocks()");
@@ -408,7 +408,7 @@ impl BlockchainModule {
     /*fn apply_local_block<W: WebOfTrust>(
         db: &sqlite::connexion,
         current_blockstamp: &Blockstamp,
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
+        wotb_index: &HashMap<PubKey, NodeId>,
         wot: &W,
     ) {
         for f in 1..10 {
@@ -420,7 +420,7 @@ impl BlockchainModule {
         block: &Block,
         current_blockstamp: &Blockstamp,
         forks: &mut Vec<ForkState>,
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
+        wotb_index: &HashMap<PubKey, NodeId>,
         wot: &W,
     ) -> (bool, Vec<ForkState>, Vec<WotEvent>) {
         let mut already_have_block = false;
@@ -562,7 +562,7 @@ impl BlockchainModule {
     pub fn try_stack_up_block<W: WebOfTrust + Sync>(
         &self,
         network_block: &NetworkBlock,
-        wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
+        wotb_index: &HashMap<PubKey, NodeId>,
         wot: &W,
         verif_level: SyncVerificationLevel,
     ) -> (bool, Vec<DBWriteRequest>, Vec<WotEvent>) {
@@ -585,8 +585,7 @@ impl BlockchainModule {
         let wot_path = duniter_conf::get_wot_path(self.conf_profile.clone(), &self.currency);
 
         // Get wotb index
-        let mut wotb_index: HashMap<ed25519::PublicKey, NodeId> =
-            DALIdentity::get_wotb_index(&self.db);
+        let mut wotb_index: HashMap<PubKey, NodeId> = DALIdentity::get_wotb_index(&self.db);
 
         // Open wot file
         let (mut wot, mut _wot_blockstamp) = duniter_dal::open_wot_file::<
@@ -852,7 +851,7 @@ impl BlockchainModule {
         wot_path: &PathBuf,
         current_blockstamp: &Blockstamp,
         wot: &mut W,
-        wotb_index: &mut HashMap<ed25519::PublicKey, NodeId>,
+        wotb_index: &mut HashMap<PubKey, NodeId>,
     ) {
         if !wot_events.is_empty() {
             for wot_event in wot_events {
diff --git a/blockchain/stack_up_block.rs b/blockchain/stack_up_block.rs
index 75ed957807597bb6b38d1ee7186d2fc3fbfe0de5..b3c327cdfcbbf1f717a5d0c70a26a4b4eeda2231 100644
--- a/blockchain/stack_up_block.rs
+++ b/blockchain/stack_up_block.rs
@@ -18,7 +18,7 @@ extern crate duniter_dal;
 extern crate duniter_documents;
 extern crate duniter_wotb;
 
-use duniter_crypto::keys::ed25519;
+use duniter_crypto::keys::*;
 use duniter_dal::block::{DALBlock, WotEvent};
 use duniter_dal::writers::requests::DBWriteRequest;
 use duniter_documents::blockchain::v10::documents::BlockDocument;
@@ -29,7 +29,7 @@ use std::collections::HashMap;
 
 pub fn try_stack_up_completed_block<W: WebOfTrust + Sync>(
     block: &BlockDocument,
-    wotb_index: &HashMap<ed25519::PublicKey, NodeId>,
+    wotb_index: &HashMap<PubKey, NodeId>,
     wot: &W,
 ) -> (bool, Vec<DBWriteRequest>, Vec<WotEvent>) {
     debug!(
@@ -39,7 +39,7 @@ pub fn try_stack_up_completed_block<W: WebOfTrust + Sync>(
     let mut db_requests = Vec::new();
     let mut wot_events = Vec::new();
     let mut wot_copy: W = wot.clone();
-    let mut wotb_index_copy: HashMap<ed25519::PublicKey, NodeId> = wotb_index.clone();
+    let mut wotb_index_copy: HashMap<PubKey, NodeId> = wotb_index.clone();
     let current_blockstamp = block.blockstamp();
     let mut identities = HashMap::with_capacity(block.identities.len());
     for identity in block.identities.clone() {
diff --git a/blockchain/sync.rs b/blockchain/sync.rs
index ab073cc99d23fc9b99535dd27a35b76a5ea7b597..a8f536dfa161b19b103832badb4844d147dde734 100644
--- a/blockchain/sync.rs
+++ b/blockchain/sync.rs
@@ -26,7 +26,7 @@ extern crate serde_json;
 extern crate sqlite;
 
 use self::pbr::ProgressBar;
-use duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_dal::parsers::identities::parse_compact_identity;
 use duniter_dal::parsers::transactions::parse_transaction;
 //use duniter_dal::writers::requests::DBWriteRequest;
@@ -47,7 +47,7 @@ use super::*;
 pub struct BlockHeader {
     pub number: BlockId,
     pub hash: BlockHash,
-    pub issuer: ed25519::PublicKey,
+    pub issuer: PubKey,
 }
 
 enum ParserWorkMess {
@@ -231,7 +231,7 @@ pub fn sync_ts(
     }
 
     // Get wotb index
-    let mut wotb_index: HashMap<ed25519::PublicKey, NodeId> =
+    let mut wotb_index: HashMap<PubKey, NodeId> =
         DALIdentity::get_wotb_index(&blockchain_module.db);
 
     // Start sync
@@ -358,8 +358,11 @@ pub fn parse_ts_block(row: &[sqlite::Value]) -> NetworkBlock {
             Hash::from_hex(row[0].as_string().expect("Fail to parse block hash"))
                 .expect("Fail to parse block hash (2)"),
         ),
-        issuer: PublicKey::from_base58(row[4].as_string().expect("Fail to parse block issuer"))
-            .expect("Failt to parse block issuer (2)"),
+        issuer: PubKey::Ed25519(
+            ed25519::PublicKey::from_base58(
+                row[4].as_string().expect("Fail to parse block issuer"),
+            ).expect("Failt to parse block issuer (2)"),
+        ),
     };
     let previous_header = if current_header.number.0 > 0 {
         Some(BlockHeader {
@@ -371,11 +374,13 @@ pub fn parse_ts_block(row: &[sqlite::Value]) -> NetworkBlock {
                         .expect("Fail to parse block previous hash"),
                 ).expect("Fail to parse block previous hash (2)"),
             ),
-            issuer: PublicKey::from_base58(
-                row[7]
-                    .as_string()
-                    .expect("Fail to parse previous block issuer"),
-            ).expect("Fail to parse previous block issuer (2)"),
+            issuer: PubKey::Ed25519(
+                ed25519::PublicKey::from_base58(
+                    row[7]
+                        .as_string()
+                        .expect("Fail to parse previous block issuer"),
+                ).expect("Fail to parse previous block issuer (2)"),
+            ),
         })
     } else {
         None
@@ -433,14 +438,14 @@ pub fn parse_ts_block(row: &[sqlite::Value]) -> NetworkBlock {
             .as_integer()
             .expect("Fail to parse issuers_frame_var") as isize,
         currency: String::from(currency),
-        issuers: vec![
-            PublicKey::from_base58(row[4].as_string().expect("Fail to parse issuer"))
+        issuers: vec![PubKey::Ed25519(
+            ed25519::PublicKey::from_base58(row[4].as_string().expect("Fail to parse issuer"))
                 .expect("Fail to parse issuer '2)"),
-        ],
-        signatures: vec![
-            Signature::from_base64(row[2].as_string().expect("Fail to parse signature"))
+        )],
+        signatures: vec![Sig::Ed25519(
+            ed25519::Signature::from_base64(row[2].as_string().expect("Fail to parse signature"))
                 .expect("Fail to parse signature (2)"),
-        ],
+        )],
         hash: Some(current_header.hash),
         parameters: None,
         previous_hash,
@@ -473,8 +478,11 @@ pub fn parse_ts_block(row: &[sqlite::Value]) -> NetworkBlock {
             .to_vec()
             .into_iter()
             .map(|e| {
-                PublicKey::from_base58(e.as_str().expect("Fail to parse excluded (4)"))
-                    .expect("Fail to parse excluded (5)")
+                PubKey::Ed25519(
+                    ed25519::PublicKey::from_base58(
+                        e.as_str().expect("Fail to parse excluded (4)"),
+                    ).expect("Fail to parse excluded (5)"),
+                )
             })
             .collect(),
         certifications: Vec::new(),
diff --git a/conf/lib.rs b/conf/lib.rs
index 5994cc80fa3148feeca9ad002ccf991752e534c4..4d35e68c90fee12d2a2129c68560533d1c87a6c3 100644
--- a/conf/lib.rs
+++ b/conf/lib.rs
@@ -30,7 +30,7 @@ extern crate duniter_crypto;
 extern crate duniter_module;
 extern crate rand;
 extern crate serde;
-use duniter_crypto::keys::{ed25519, KeyPair, PrivateKey, PublicKey};
+use duniter_crypto::keys::*;
 use duniter_module::{Currency, DuniterConf, DuniterConfV1, RequiredKeys, RequiredKeysContent};
 use rand::Rng;
 use serde::ser::{Serialize, SerializeStruct, Serializer};
@@ -49,9 +49,9 @@ pub static DEFAULT_CURRRENCY: &'static str = "g1";
 /// Keypairs filled in by the user (via a file or by direct entry in the terminal).
 pub struct DuniterKeyPairs {
     /// Keypair used by the node to sign its communications with other nodes. This keypair is mandatory, if it's not filled in, a random keypair is generated.
-    pub network_keypair: ed25519::KeyPair,
+    pub network_keypair: KeyPairEnum,
     /// Keypair used to sign the blocks forged by this node. If this keypair is'nt filled in, the node will not calculate blocks.
-    pub member_keypair: Option<ed25519::KeyPair>,
+    pub member_keypair: Option<KeyPairEnum>,
 }
 
 impl Serialize for DuniterKeyPairs {
@@ -65,7 +65,7 @@ impl Serialize for DuniterKeyPairs {
             String::from("")
         };
         let member_pub = if let Some(member_keypair) = self.member_keypair {
-            member_keypair.pubkey.to_string()
+            member_keypair.public_key().to_string()
         } else {
             String::from("")
         };
@@ -76,7 +76,7 @@ impl Serialize for DuniterKeyPairs {
         )?;
         state.serialize_field(
             "network_pub",
-            &self.network_keypair.pubkey.to_string().as_str(),
+            &self.network_keypair.public_key().to_string().as_str(),
         )?;
         state.serialize_field("member_sec", member_sec.as_str())?;
         state.serialize_field("member_pub", member_pub.as_str())?;
@@ -89,14 +89,14 @@ impl DuniterKeyPairs {
     pub fn get_required_keys_content(
         required_keys: RequiredKeys,
         keypairs: DuniterKeyPairs,
-    ) -> RequiredKeysContent<ed25519::KeyPair> {
+    ) -> RequiredKeysContent {
         match required_keys {
             RequiredKeys::MemberKeyPair() => {
                 RequiredKeysContent::MemberKeyPair(keypairs.member_keypair)
             }
             RequiredKeys::MemberPublicKey() => {
                 RequiredKeysContent::MemberPublicKey(if let Some(keys) = keypairs.member_keypair {
-                    Some(keys.pubkey)
+                    Some(keys.public_key())
                 } else {
                     None
                 })
@@ -105,7 +105,7 @@ impl DuniterKeyPairs {
                 RequiredKeysContent::NetworkKeyPair(keypairs.network_keypair)
             }
             RequiredKeys::NetworkPublicKey() => {
-                RequiredKeysContent::NetworkPublicKey(keypairs.network_keypair.pubkey)
+                RequiredKeysContent::NetworkPublicKey(keypairs.network_keypair.public_key())
             }
             RequiredKeys::None() => RequiredKeysContent::None(),
         }
@@ -116,10 +116,15 @@ fn _use_json_macro() -> serde_json::Value {
     json!({})
 }
 
-fn generate_random_keypair() -> ed25519::KeyPair {
+fn generate_random_keypair(algo: KeysAlgo) -> KeyPairEnum {
     let mut rng = rand::thread_rng();
-    let generator = ed25519::KeyPairFromSaltedPasswordGenerator::with_default_parameters();
-    generator.generate(&[rng.gen::<u8>(); 8], &[rng.gen::<u8>(); 8])
+    match algo {
+        KeysAlgo::Ed25519 => {
+            let generator = ed25519::KeyPairFromSaltedPasswordGenerator::with_default_parameters();
+            KeyPairEnum::Ed25519(generator.generate(&[rng.gen::<u8>(); 8], &[rng.gen::<u8>(); 8]))
+        }
+        KeysAlgo::Schnorr => panic!("Schnorr algo not yet supported !"),
+    }
 }
 
 fn generate_random_node_id() -> u32 {
@@ -209,12 +214,12 @@ pub fn load_conf_at_path(profile: &str, profile_path: &PathBuf) -> (DuniterConf,
                             .as_str()
                             .expect("Conf: Fail to parse keypairs file !");
                         DuniterKeyPairs {
-                            network_keypair: ed25519::KeyPair {
-                                privkey: PrivateKey::from_base58(network_sec)
+                            network_keypair: KeyPairEnum::Ed25519(ed25519::KeyPair {
+                                privkey: ed25519::PrivateKey::from_base58(network_sec)
                                     .expect("conf : keypairs file : fail to parse network_sec !"),
-                                pubkey: PublicKey::from_base58(network_pub)
+                                pubkey: ed25519::PublicKey::from_base58(network_pub)
                                     .expect("conf : keypairs file : fail to parse network_pub !"),
-                            },
+                            }),
                             member_keypair: None,
                         }
                     } else {
@@ -232,7 +237,7 @@ pub fn load_conf_at_path(profile: &str, profile_path: &PathBuf) -> (DuniterConf,
     } else {
         // Create keypairs file with random keypair
         let keypairs = DuniterKeyPairs {
-            network_keypair: generate_random_keypair(),
+            network_keypair: generate_random_keypair(KeysAlgo::Ed25519),
             member_keypair: None,
         };
         write_keypairs_file(&keypairs_path, &keypairs)
diff --git a/core/lib.rs b/core/lib.rs
index 4f421f519de988ab70d0b2e7a265e1bf58f8b356..8b16719c0f7ba3b10ad18ba3a84b5efa7873028e 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -42,7 +42,6 @@ use self::threadpool::ThreadPool;
 use clap::{App, ArgMatches};
 use duniter_blockchain::BlockchainModule;
 use duniter_conf::DuniterKeyPairs;
-use duniter_crypto::keys::ed25519;
 use duniter_message::DuniterMessage;
 use duniter_module::*;
 use log::Level;
@@ -199,7 +198,7 @@ impl DuniterCore {
         }
     }
     /// Plug a module
-    pub fn plug<M: DuniterModule<ed25519::KeyPair, DuniterMessage>>(&mut self) {
+    pub fn plug<M: DuniterModule<DuniterMessage>>(&mut self) {
         if self.start {
             // Start module in a new thread
             let soft_name_clone = &(*self.soft_name);
diff --git a/crypto/keys/ed25519.rs b/crypto/keys/ed25519.rs
index 9fe98d04b8ecb5c2f280bc4510a01e45977ce8dc..89fed477caccfd37462a97d47df7c4b28d60cb0b 100644
--- a/crypto/keys/ed25519.rs
+++ b/crypto/keys/ed25519.rs
@@ -233,7 +233,7 @@ impl super::PrivateKey for PrivateKey {
 }
 
 /// Store a ed25519 cryptographic key pair (`PublicKey` + `PrivateKey`)
-#[derive(Debug, Copy, Clone)]
+#[derive(Debug, Copy, Clone, Eq)]
 pub struct KeyPair {
     /// Store a Ed25519 public key.
     pub pubkey: PublicKey,
@@ -253,8 +253,6 @@ impl PartialEq<KeyPair> for KeyPair {
     }
 }
 
-impl Eq for KeyPair {}
-
 impl super::KeyPair for KeyPair {
     type Signature = Signature;
     type PublicKey = PublicKey;
diff --git a/crypto/keys/mod.rs b/crypto/keys/mod.rs
index d5e93c414ddf5be646de0fbbc2bbb924fddaaa2b..9adcceaa6f5451f29b04bd46ccf630515e7b5876 100644
--- a/crypto/keys/mod.rs
+++ b/crypto/keys/mod.rs
@@ -46,14 +46,33 @@
 //! `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`
 //! with `=` as padding character.
 
+extern crate serde;
+
+use self::serde::ser::{Serialize, Serializer};
+use base58::ToBase58;
 use std::fmt::Debug;
 use std::fmt::Display;
+use std::fmt::Error;
+use std::fmt::Formatter;
 use std::hash::Hash;
 
-use base58::ToBase58;
-
 pub mod ed25519;
 
+/// Cryptographic keys algorithms list
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum KeysAlgo {
+    /// Ed25519 algorithm
+    Ed25519 = 0,
+    /// Schnorr algorithm
+    Schnorr = 1,
+}
+
+/// Get the cryptographic algorithm.
+pub trait GetKeysAlgo: Clone + Debug + PartialEq + Eq {
+    /// Get the cryptographic algorithm.
+    fn algo(&self) -> KeysAlgo;
+}
+
 /// Errors enumeration for Base58/64 strings convertion.
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum BaseConvertionError {
@@ -65,7 +84,7 @@ pub enum BaseConvertionError {
     InvalidBaseConverterLength(),
 }
 
-/// Store a cryptographic signature.
+/// Define the operations that can be performed on a cryptographic signature.
 ///
 /// A signature can be converted from/to Base64 format.
 /// When converted back and forth the value should be the same.
@@ -89,7 +108,43 @@ pub trait Signature: Clone + Display + Debug + PartialEq + Eq + Hash {
     fn to_base64(&self) -> String;
 }
 
-/// Store a cryptographic public key.
+/// Store a cryptographic signature.
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+pub enum Sig {
+    /// Store a ed25519 Signature
+    Ed25519(ed25519::Signature),
+    /// Store a Schnorr Signature
+    Schnorr(),
+}
+
+impl Display for Sig {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        write!(f, "{}", self.to_base64())
+    }
+}
+
+impl GetKeysAlgo for Sig {
+    fn algo(&self) -> KeysAlgo {
+        match *self {
+            Sig::Ed25519(_) => KeysAlgo::Ed25519,
+            Sig::Schnorr() => KeysAlgo::Schnorr,
+        }
+    }
+}
+
+impl Signature for Sig {
+    fn from_base64(_base64_string: &str) -> Result<Self, BaseConvertionError> {
+        unimplemented!()
+    }
+    fn to_base64(&self) -> String {
+        match *self {
+            Sig::Ed25519(ed25519_sig) => ed25519_sig.to_base64(),
+            Sig::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+}
+
+/// Define the operations that can be performed on a cryptographic public key.
 ///
 /// A `PublicKey` can be converted from/to Base64 format.
 /// When converted back and forth the value should be the same.
@@ -115,7 +170,67 @@ pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + Hash + ToBase58
     fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;
 }
 
-/// Store a cryptographic private key.
+/// Store a cryptographic public key.
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+pub enum PubKey {
+    /// Store a ed25519 public key.
+    Ed25519(ed25519::PublicKey),
+    /// Store a Schnorr public key.
+    Schnorr(),
+}
+
+impl GetKeysAlgo for PubKey {
+    fn algo(&self) -> KeysAlgo {
+        match *self {
+            PubKey::Ed25519(_) => KeysAlgo::Ed25519,
+            PubKey::Schnorr() => KeysAlgo::Schnorr,
+        }
+    }
+}
+
+impl ToBase58 for PubKey {
+    fn to_base58(&self) -> String {
+        match *self {
+            PubKey::Ed25519(ed25519_pub) => ed25519_pub.to_base58(),
+            PubKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+}
+
+impl Display for PubKey {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        write!(f, "{}", self.to_base58())
+    }
+}
+
+impl Serialize for PubKey {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        serializer.serialize_str(&format!("{}", self))
+    }
+}
+
+impl PublicKey for PubKey {
+    type Signature = Sig;
+
+    fn from_base58(_base58_string: &str) -> Result<Self, BaseConvertionError> {
+        unimplemented!()
+    }
+    fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
+        match *self {
+            PubKey::Ed25519(ed25519_pubkey) => if let Sig::Ed25519(ed25519_sig) = signature {
+                ed25519_pubkey.verify(message, ed25519_sig)
+            } else {
+                panic!("Try to verify a signature with public key of a different algorithm !\nSignature={:?}\nPublickey={:?}", signature, self)
+            },
+            PubKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+}
+
+/// Define the operations that can be performed on a cryptographic private key.
 ///
 /// A `PrivateKey` can be converted from/to Base58 format.
 /// When converted back and forth the value should be the same.
@@ -141,7 +256,53 @@ pub trait PrivateKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
     fn sign(&self, message: &[u8]) -> Self::Signature;
 }
 
-/// Store a cryptographic key pair (`PublicKey` + `PrivateKey`)
+/// Store a cryptographic private key.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum PrivKey {
+    /// Store a ed25519 private key.
+    Ed25519(ed25519::PrivateKey),
+    /// Store a Schnorr private key.
+    Schnorr(),
+}
+
+impl GetKeysAlgo for PrivKey {
+    fn algo(&self) -> KeysAlgo {
+        match *self {
+            PrivKey::Ed25519(_) => KeysAlgo::Ed25519,
+            PrivKey::Schnorr() => KeysAlgo::Schnorr,
+        }
+    }
+}
+
+impl ToBase58 for PrivKey {
+    fn to_base58(&self) -> String {
+        match *self {
+            PrivKey::Ed25519(ed25519_privkey) => ed25519_privkey.to_base58(),
+            PrivKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+}
+
+impl Display for PrivKey {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        write!(f, "{}", self.to_base58())
+    }
+}
+
+impl PrivateKey for PrivKey {
+    type Signature = Sig;
+    fn from_base58(_base58_string: &str) -> Result<Self, BaseConvertionError> {
+        unimplemented!()
+    }
+    fn sign(&self, message: &[u8]) -> Self::Signature {
+        match *self {
+            PrivKey::Ed25519(ed25519_privkey) => Sig::Ed25519(ed25519_privkey.sign(message)),
+            PrivKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+}
+
+/// Define the operations that can be performed on a cryptographic key pair.
 pub trait KeyPair: Clone + Display + Debug + PartialEq + Eq {
     /// Signature type of associated cryptosystem.
     type Signature: Signature;
@@ -162,3 +323,69 @@ pub trait KeyPair: Clone + Display + Debug + PartialEq + Eq {
     /// Verify a signature with public key.
     fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;
 }
+
+/// Store a cryptographic key pair.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum KeyPairEnum {
+    /// Store a ed25519 key pair.
+    Ed25519(ed25519::KeyPair),
+    /// Store a Schnorr key pair.
+    Schnorr(),
+}
+
+impl GetKeysAlgo for KeyPairEnum {
+    fn algo(&self) -> KeysAlgo {
+        match *self {
+            KeyPairEnum::Ed25519(_) => KeysAlgo::Ed25519,
+            KeyPairEnum::Schnorr() => KeysAlgo::Schnorr,
+        }
+    }
+}
+
+impl Display for KeyPairEnum {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+        match *self {
+            KeyPairEnum::Ed25519(ed25519_keypair) => {
+                write!(f, "({}, hidden)", ed25519_keypair.pubkey.to_base58())
+            }
+            KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+}
+
+impl KeyPair for KeyPairEnum {
+    type Signature = Sig;
+    type PublicKey = PubKey;
+    type PrivateKey = PrivKey;
+
+    fn public_key(&self) -> Self::PublicKey {
+        match *self {
+            KeyPairEnum::Ed25519(ed25519_keypair) => PubKey::Ed25519(ed25519_keypair.public_key()),
+            KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+    fn private_key(&self) -> Self::PrivateKey {
+        match *self {
+            KeyPairEnum::Ed25519(ed25519_keypair) => {
+                PrivKey::Ed25519(ed25519_keypair.private_key())
+            }
+            KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+    fn verify(&self, message: &[u8], signature: &Sig) -> bool {
+        match *self {
+            KeyPairEnum::Ed25519(ed25519_keypair) => if let Sig::Ed25519(ed25519_sig) = signature {
+                ed25519_keypair.verify(message, ed25519_sig)
+            } else {
+                panic!("Try to verify a signature with key pair of a different algorithm !\nSignature={:?}\nKeyPair={:?}", signature, self)
+            },
+            KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+    fn sign(&self, message: &[u8]) -> Sig {
+        match *self {
+            KeyPairEnum::Ed25519(ed25519_keypair) => Sig::Ed25519(ed25519_keypair.sign(message)),
+            KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
+}
diff --git a/dal/block.rs b/dal/block.rs
index abdc73a16639fe2a76772b8891f35c1422ea34b7..d7a623bd15ffa29dd619acfc73b285e737384005 100644
--- a/dal/block.rs
+++ b/dal/block.rs
@@ -5,8 +5,7 @@ extern crate serde;
 extern crate serde_json;
 extern crate sqlite;
 
-use self::duniter_crypto::keys;
-use self::duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use self::duniter_crypto::keys::*;
 use self::duniter_documents::blockchain::v10::documents::identity::IdentityDocument;
 use self::duniter_documents::blockchain::v10::documents::membership::MembershipType;
 use self::duniter_documents::blockchain::v10::documents::BlockDocument;
@@ -55,8 +54,8 @@ pub fn blockstamp_to_timestamp(blockstamp: &Blockstamp, db: &DuniterDB) -> Optio
 
 #[derive(Debug, Copy, Clone)]
 pub enum WotEvent {
-    AddNode(ed25519::PublicKey, NodeId),
-    RemNode(ed25519::PublicKey),
+    AddNode(PubKey, NodeId),
+    RemNode(PubKey),
     AddLink(NodeId, NodeId),
     RemLink(NodeId, NodeId),
     EnableNode(NodeId),
@@ -282,7 +281,7 @@ impl DALBlock {
             let hashmap_identities = identities
                 .iter()
                 .map(|i| (i.issuers()[0], i.clone()))
-                .collect::<HashMap<ed25519::PublicKey, IdentityDocument>>();
+                .collect::<HashMap<PubKey, IdentityDocument>>();
             Some(DALBlock {
                 fork: row[0]
                     .as_integer()
@@ -340,20 +339,20 @@ impl DALBlock {
                         .as_string()
                         .expect("dal::get_block() : fail to parse currency !")
                         .to_string(),
-                    issuers: vec![
-                        PublicKey::from_base58(
+                    issuers: vec![PubKey::Ed25519(
+                        ed25519::PublicKey::from_base58(
                             row[16]
                                 .as_string()
                                 .expect("dal::get_block() : fail to parse issuer !"),
                         ).expect("dal::get_block() : fail to parse pubkey !"),
-                    ],
-                    signatures: vec![
-                        Signature::from_base64(
+                    )],
+                    signatures: vec![Sig::Ed25519(
+                        ed25519::Signature::from_base64(
                             row[17]
                                 .as_string()
                                 .expect("dal::get_block() : fail to parse signature !"),
                         ).expect("dal::get_block() : fail to parse signature (2) !"),
-                    ],
+                    )],
                     hash: Some(BlockHash(
                         Hash::from_hex(
                             row[18]
@@ -437,9 +436,9 @@ impl DALBlock {
         }
     }
 
-    pub fn get_current_frame(&self, db: &DuniterDB) -> HashMap<keys::ed25519::PublicKey, usize> {
+    pub fn get_current_frame(&self, db: &DuniterDB) -> HashMap<PubKey, usize> {
         let frame_begin = i64::from(self.block.number.0) - (self.block.issuers_frame as i64);
-        let mut current_frame: HashMap<keys::ed25519::PublicKey, usize> = HashMap::new();
+        let mut current_frame: HashMap<PubKey, usize> = HashMap::new();
         let mut cursor = db
             .0
             .prepare("SELECT issuer FROM blocks WHERE fork=0 AND number>=? LIMIT ?;")
@@ -457,19 +456,21 @@ impl DALBlock {
             .expect("get current frame blocks failure at step 3 !")
         {
             let current_frame_copy = current_frame.clone();
-            match current_frame_copy
-                .get(&PublicKey::from_base58(row[0].as_string().unwrap()).unwrap())
-            {
+            match current_frame_copy.get(&PubKey::Ed25519(
+                ed25519::PublicKey::from_base58(row[0].as_string().unwrap()).unwrap(),
+            )) {
                 Some(blocks_count) => {
-                    if let Some(new_blocks_count) = current_frame
-                        .get_mut(&PublicKey::from_base58(row[0].as_string().unwrap()).unwrap())
-                    {
+                    if let Some(new_blocks_count) = current_frame.get_mut(&PubKey::Ed25519(
+                        ed25519::PublicKey::from_base58(row[0].as_string().unwrap()).unwrap(),
+                    )) {
                         *new_blocks_count = *blocks_count + 1;
                     }
                 }
                 None => {
                     current_frame.insert(
-                        PublicKey::from_base58(row[0].as_string().unwrap()).unwrap(),
+                        PubKey::Ed25519(
+                            ed25519::PublicKey::from_base58(row[0].as_string().unwrap()).unwrap(),
+                        ),
                         0,
                     );
                 }
diff --git a/dal/dal_requests.rs b/dal/dal_requests.rs
index a16cb3ad6909cd6e9130f152ca324b0395aea49c..608de5e6422e8d9a29faaa1385faf17ae005092d 100644
--- a/dal/dal_requests.rs
+++ b/dal/dal_requests.rs
@@ -3,7 +3,7 @@ extern crate duniter_documents;
 extern crate duniter_module;
 extern crate serde;
 
-use self::duniter_crypto::keys::ed25519;
+use self::duniter_crypto::keys::*;
 use self::duniter_documents::blockchain::v10::documents::{
     BlockDocument, CertificationDocument, IdentityDocument, MembershipDocument, RevocationDocument,
 };
@@ -15,7 +15,7 @@ use std::collections::HashMap;
 pub enum DALReqPendings {
     AllPendingIdentyties(ModuleReqFullId, usize),
     AllPendingIdentytiesWithoutCerts(ModuleReqFullId, usize),
-    PendingWotDatasForPubkey(ModuleReqFullId, ed25519::PublicKey),
+    PendingWotDatasForPubkey(ModuleReqFullId, PubKey),
 }
 
 #[derive(Debug, Clone, PartialEq)]
@@ -23,7 +23,7 @@ pub enum DALReqBlockchain {
     CurrentBlock(ModuleReqFullId),
     BlockByNumber(ModuleReqFullId, u64),
     Chunk(ModuleReqFullId, u64, usize),
-    UIDs(Vec<ed25519::PublicKey>),
+    UIDs(Vec<PubKey>),
 }
 
 #[derive(Debug, Clone)]
@@ -53,7 +53,7 @@ pub enum DALResBlockchain {
     CurrentBlock(ModuleReqFullId, Box<BlockDocument>),
     BlockByNumber(ModuleReqFullId, Box<BlockDocument>),
     Chunk(ModuleReqFullId, Vec<BlockDocument>),
-    UIDs(HashMap<ed25519::PublicKey, Option<String>>),
+    UIDs(HashMap<PubKey, Option<String>>),
 }
 
 #[derive(Debug, Clone)]
diff --git a/dal/endpoint.rs b/dal/endpoint.rs
index 2bd5567ca2fa58578fdf66d4fe0b619aa41807b5..382b41dc507aaa8401f04b7c4c60d6965eeb7e5a 100644
--- a/dal/endpoint.rs
+++ b/dal/endpoint.rs
@@ -6,8 +6,7 @@ use std::time::Duration;
 
 use self::crypto::digest::Digest;
 use self::crypto::sha2::Sha256;
-use self::duniter_crypto::keys::PublicKey;
-use self::duniter_crypto::keys::ed25519::PublicKey as ed25519PublicKey;
+use self::duniter_crypto::keys::*;
 use super::DuniterDB;
 use super::WriteToDuniterDB;
 
@@ -57,7 +56,7 @@ pub struct DALEndpoint {
     pub hash_full_id: String,
     pub status: u32,
     pub node_id: u32,
-    pub pubkey: ed25519PublicKey,
+    pub pubkey: PubKey,
     pub api: DALEndpointApi,
     pub version: usize,
     pub endpoint: String,
@@ -68,7 +67,7 @@ impl DALEndpoint {
     pub fn new(
         status: u32,
         node_id: u32,
-        pubkey: ed25519PublicKey,
+        pubkey: PubKey,
         api: DALEndpointApi,
         version: usize,
         endpoint: String,
@@ -111,7 +110,7 @@ impl DALEndpoint {
                 hash_full_id: row[0].as_string().unwrap().to_string(),
                 status: row[1].as_integer().unwrap() as u32,
                 node_id: row[2].as_integer().unwrap() as u32,
-                pubkey: ed25519PublicKey::from_base58(row[3].as_string().unwrap()).unwrap(),
+                pubkey: PubKey::Ed25519(ed25519::PublicKey::from_base58(row[3].as_string().unwrap()).unwrap()),
                 api: DALEndpointApi::from(row[4].as_integer().unwrap() as u32),
                 version: row[5].as_integer().unwrap() as usize,
                 endpoint: row[6].as_string().unwrap().to_string(),
diff --git a/dal/identity.rs b/dal/identity.rs
index 39193d905fe6df37adb887f6b535f72750fde00e..dd0dd3442dd5468b2428bee682058f7f8eaa7b62 100644
--- a/dal/identity.rs
+++ b/dal/identity.rs
@@ -2,7 +2,7 @@ extern crate sqlite;
 
 use super::block::{blockstamp_to_timestamp, DALBlock};
 use super::DuniterDB;
-use duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::identity::IdentityDocumentBuilder;
 use duniter_documents::blockchain::v10::documents::IdentityDocument;
 use duniter_documents::blockchain::{Document, DocumentBuilder};
@@ -52,8 +52,8 @@ impl DALIdentity {
             .expect("Fail to exclude idty !");
     }
 
-    pub fn get_wotb_index(db: &DuniterDB) -> HashMap<ed25519::PublicKey, NodeId> {
-        let mut wotb_index: HashMap<ed25519::PublicKey, NodeId> = HashMap::new();
+    pub fn get_wotb_index(db: &DuniterDB) -> HashMap<PubKey, NodeId> {
+        let mut wotb_index: HashMap<PubKey, NodeId> = HashMap::new();
 
         let mut cursor = db
             .0
@@ -63,7 +63,9 @@ impl DALIdentity {
 
         while let Some(row) = cursor.next().unwrap() {
             wotb_index.insert(
-                PublicKey::from_base58(row[1].as_string().unwrap()).unwrap(),
+                PubKey::Ed25519(
+                    ed25519::PublicKey::from_base58(row[1].as_string().unwrap()).unwrap(),
+                ),
                 NodeId(row[0].as_integer().unwrap() as usize),
             );
         }
@@ -123,7 +125,7 @@ impl DALIdentity {
     pub fn renewal_identity(
         &mut self,
         db: &DuniterDB,
-        pubkey: &ed25519::PublicKey,
+        pubkey: &PubKey,
         renewal_blockstamp: &Blockstamp,
         renawal_timestamp: u64,
         revert: bool,
@@ -175,11 +177,7 @@ impl DALIdentity {
             .unwrap();
     }
 
-    pub fn get_identity(
-        currency: &str,
-        db: &DuniterDB,
-        pubkey: &ed25519::PublicKey,
-    ) -> Option<DALIdentity> {
+    pub fn get_identity(currency: &str, db: &DuniterDB, pubkey: &PubKey) -> Option<DALIdentity> {
         let mut cursor = db
             .0
             .prepare(
@@ -207,9 +205,11 @@ impl DALIdentity {
                 ).expect("DB Error : idty created_on invalid (2) !"),
                 issuer: &pubkey,
             };
-            let idty_sig = Signature::from_base64(
-                row[2].as_string().expect("get_identity: fail to parse sig"),
-            ).expect("get_identity: fail to parse sig (2)");
+            let idty_sig = Sig::Ed25519(
+                ed25519::Signature::from_base64(
+                    row[2].as_string().expect("get_identity: fail to parse sig"),
+                ).expect("get_identity: fail to parse sig (2)"),
+            );
             let idty_doc = idty_doc_builder.build_with_signature(vec![idty_sig]);
 
             let expired_on = match Blockstamp::from_string(
diff --git a/dal/lib.rs b/dal/lib.rs
index ee81c95b5d3f1ac0ffb00a26c63b4663fb556060..bdd108611c0e95b08f2ccc9eb935d05c0fad7d5a 100644
--- a/dal/lib.rs
+++ b/dal/lib.rs
@@ -44,7 +44,7 @@ pub mod parsers;
 pub mod tools;
 pub mod writers;
 
-use duniter_crypto::keys::{PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::BlockDocument;
 use duniter_documents::{BlockHash, BlockId, Blockstamp, Hash};
 use duniter_wotb::operations::file::FileFormater;
@@ -191,10 +191,12 @@ pub fn new_get_current_block(db: &DuniterDB) -> Option<BlockDocument> {
             issuers_frame: row[10].as_integer().expect("issuers_frame") as isize,
             issuers_frame_var: row[11].as_integer().expect("issuers_frame_var") as isize,
             currency: row[14].as_string().expect("currency").to_string(),
-            issuers: vec![PublicKey::from_base58(row[15].as_string().expect("issuer")).unwrap()],
-            signatures: vec![
-                Signature::from_base64(row[16].as_string().expect("signature")).unwrap(),
-            ],
+            issuers: vec![PubKey::Ed25519(
+                ed25519::PublicKey::from_base58(row[15].as_string().expect("issuer")).unwrap(),
+            )],
+            signatures: vec![Sig::Ed25519(
+                ed25519::Signature::from_base64(row[16].as_string().expect("signature")).unwrap(),
+            )],
             hash: Some(BlockHash(
                 Hash::from_hex(row[17].as_string().expect("hash")).unwrap(),
             )),
diff --git a/dal/parsers/blocks.rs b/dal/parsers/blocks.rs
index a98fc21cd83c9986b4581f205eef792486f29a6a..87712fdd9d902de8a8ffdbc90a9ac88fb037685c 100644
--- a/dal/parsers/blocks.rs
+++ b/dal/parsers/blocks.rs
@@ -7,7 +7,7 @@ use self::duniter_network::{NetworkBlock, NetworkBlockV10};
 use super::excluded::parse_exclusions_from_json_value;
 use super::identities::parse_compact_identity;
 use super::transactions::parse_transaction;
-use duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::membership::{
     MembershipDocument, MembershipType,
 };
@@ -28,10 +28,10 @@ fn parse_previous_hash(block_number: &BlockId, source: &serde_json::Value) -> Op
     }
 }
 
-fn parse_previous_issuer(source: &serde_json::Value) -> Option<ed25519::PublicKey> {
+fn parse_previous_issuer(source: &serde_json::Value) -> Option<PubKey> {
     match source.get("previousIssuer")?.as_str() {
-        Some(pubkey_str) => match PublicKey::from_base58(pubkey_str) {
-            Ok(pubkey) => Some(pubkey),
+        Some(pubkey_str) => match ed25519::PublicKey::from_base58(pubkey_str) {
+            Ok(pubkey) => Some(PubKey::Ed25519(pubkey)),
             Err(_) => None,
         },
         None => None,
@@ -61,12 +61,12 @@ fn parse_memberships(
 pub fn parse_json_block(source: &serde_json::Value) -> Option<NetworkBlock> {
     let number = BlockId(source.get("number")?.as_u64()? as u32);
     let currency = source.get("currency")?.as_str()?.to_string();
-    let issuer = match PublicKey::from_base58(source.get("issuer")?.as_str()?) {
-        Ok(pubkey) => pubkey,
+    let issuer = match ed25519::PublicKey::from_base58(source.get("issuer")?.as_str()?) {
+        Ok(pubkey) => PubKey::Ed25519(pubkey),
         Err(_) => return None,
     };
-    let sig = match Signature::from_base64(source.get("signature")?.as_str()?) {
-        Ok(sig) => sig,
+    let sig = match ed25519::Signature::from_base64(source.get("signature")?.as_str()?) {
+        Ok(sig) => Sig::Ed25519(sig),
         Err(_) => return None,
     };
     let hash = match Hash::from_hex(source.get("hash")?.as_str()?) {
diff --git a/dal/parsers/certifications.rs b/dal/parsers/certifications.rs
index 19ffba84056de64d42d3c2c82810d7dbd3374287..2b37e3f44325363c115da87b0887e89be4d92c34 100644
--- a/dal/parsers/certifications.rs
+++ b/dal/parsers/certifications.rs
@@ -5,7 +5,7 @@ extern crate sqlite;
 use super::super::block::DALBlock;
 use super::super::identity::DALIdentity;
 use super::super::DuniterDB;
-use duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::certification::{
     CertificationDocumentBuilder, CompactCertificationDocument,
 };
@@ -28,17 +28,23 @@ pub fn parse_certifications_into_compact(
             .collect();
         if certifications_datas.len() == 4 {
             certifications.push(TextDocumentFormat::Compact(CompactCertificationDocument {
-                issuer: PublicKey::from_base58(certifications_datas[0])
-                    .expect("Receive block in wrong format : fail to parse issuer !"),
-                target: PublicKey::from_base58(certifications_datas[1])
-                    .expect("Receive block in wrong format : fail to parse target !"),
+                issuer: PubKey::Ed25519(
+                    ed25519::PublicKey::from_base58(certifications_datas[0])
+                        .expect("Receive block in wrong format : fail to parse issuer !"),
+                ),
+                target: PubKey::Ed25519(
+                    ed25519::PublicKey::from_base58(certifications_datas[1])
+                        .expect("Receive block in wrong format : fail to parse target !"),
+                ),
                 block_number: BlockId(
                     certifications_datas[2]
                         .parse()
                         .expect("Receive block in wrong format : fail to parse block number !"),
                 ),
-                signature: Signature::from_base64(certifications_datas[3])
-                    .expect("Receive block in wrong format : fail to parse signature !"),
+                signature: Sig::Ed25519(
+                    ed25519::Signature::from_base64(certifications_datas[3])
+                        .expect("Receive block in wrong format : fail to parse signature !"),
+                ),
             }));
         }
     }
@@ -48,7 +54,7 @@ pub fn parse_certifications_into_compact(
 pub fn parse_certifications_from_json_value(
     currency: &str,
     db: &DuniterDB,
-    block_identities: &HashMap<ed25519::PublicKey, IdentityDocument>,
+    block_identities: &HashMap<PubKey, IdentityDocument>,
     array_certifications: &[serde_json::Value],
 ) -> Vec<TextDocumentFormat<CertificationDocument>> {
     let mut certifications: Vec<TextDocumentFormat<CertificationDocument>> = Vec::new();
@@ -59,8 +65,10 @@ pub fn parse_certifications_from_json_value(
             .split(':')
             .collect();
         if certification_datas.len() == 4 {
-            let target = PublicKey::from_base58(certification_datas[1])
-                .expect("Fail to parse cert target !");
+            let target = PubKey::Ed25519(
+                ed25519::PublicKey::from_base58(certification_datas[1])
+                    .expect("Fail to parse cert target !"),
+            );
             let target_idty_doc: IdentityDocument = match block_identities.get(&target) {
                 Some(idty_doc) => idty_doc.clone(),
                 None => {
@@ -77,8 +85,10 @@ pub fn parse_certifications_from_json_value(
             let cert_builder =
                 CertificationDocumentBuilder {
                     currency,
-                    issuer: &PublicKey::from_base58(certification_datas[0])
-                        .expect("Fail to parse cert issuer !"),
+                    issuer: &PubKey::Ed25519(
+                        ed25519::PublicKey::from_base58(certification_datas[0])
+                            .expect("Fail to parse cert issuer !"),
+                    ),
                     blockstamp: &Blockstamp {
                         id: cert_blockstamp_id,
                         hash: if cert_blockstamp_id == BlockId(0) {
@@ -97,8 +107,10 @@ pub fn parse_certifications_from_json_value(
                     identity_blockstamp: &target_idty_doc.blockstamp(),
                     identity_sig: &target_idty_doc.signatures()[0],
                 };
-            let cert_sig =
-                Signature::from_base64(certification_datas[3]).expect("Fail to parse cert sig !");
+            let cert_sig = Sig::Ed25519(
+                ed25519::Signature::from_base64(certification_datas[3])
+                    .expect("Fail to parse cert sig !"),
+            );
             certifications.push(TextDocumentFormat::Complete(
                 cert_builder.build_with_signature(vec![cert_sig]),
             ));
@@ -110,7 +122,7 @@ pub fn parse_certifications_from_json_value(
 pub fn parse_certifications(
     currency: &str,
     db: &DuniterDB,
-    block_identities: &HashMap<ed25519::PublicKey, IdentityDocument>,
+    block_identities: &HashMap<PubKey, IdentityDocument>,
     json_datas: &str,
 ) -> Option<Vec<TextDocumentFormat<CertificationDocument>>> {
     let raw_certifications: serde_json::Value =
diff --git a/dal/parsers/excluded.rs b/dal/parsers/excluded.rs
index 329261da4fe5a876d6d751945b53ef1d3bd8d505..645f3bc58321110ce66e05e0f08162f6c16d33c2 100644
--- a/dal/parsers/excluded.rs
+++ b/dal/parsers/excluded.rs
@@ -1,9 +1,10 @@
 extern crate serde;
 extern crate serde_json;
 
-use duniter_crypto::keys::{ed25519, PublicKey};
+use duniter_crypto::keys::ed25519;
+use duniter_crypto::keys::*;
 
-pub fn parse_exclusions(json_datas: &str) -> Option<Vec<ed25519::PublicKey>> {
+pub fn parse_exclusions(json_datas: &str) -> Option<Vec<PubKey>> {
     let raw_exclusions: serde_json::Value = serde_json::from_str(json_datas).unwrap();
 
     if raw_exclusions.is_array() {
@@ -15,12 +16,12 @@ pub fn parse_exclusions(json_datas: &str) -> Option<Vec<ed25519::PublicKey>> {
     }
 }
 
-pub fn parse_exclusions_from_json_value(
-    array_exclusions: &[serde_json::Value],
-) -> Vec<ed25519::PublicKey> {
-    let mut exclusions: Vec<ed25519::PublicKey> = Vec::new();
+pub fn parse_exclusions_from_json_value(array_exclusions: &[serde_json::Value]) -> Vec<PubKey> {
+    let mut exclusions: Vec<PubKey> = Vec::new();
     for exclusion in array_exclusions.iter() {
-        exclusions.push(PublicKey::from_base58(exclusion.as_str().unwrap()).unwrap());
+        exclusions.push(PubKey::Ed25519(
+            ed25519::PublicKey::from_base58(exclusion.as_str().unwrap()).unwrap(),
+        ));
     }
     exclusions
 }
diff --git a/dal/parsers/identities.rs b/dal/parsers/identities.rs
index 9791d4c0f5045d08ce499709ee79857c1676f6c2..4af0f43549472c9842a38bde1b49551826edd1bf 100644
--- a/dal/parsers/identities.rs
+++ b/dal/parsers/identities.rs
@@ -1,7 +1,7 @@
 extern crate serde_json;
 extern crate sqlite;
 
-use duniter_crypto::keys::{PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::identity::IdentityDocumentBuilder;
 use duniter_documents::blockchain::v10::documents::IdentityDocument;
 use duniter_documents::blockchain::DocumentBuilder;
@@ -39,11 +39,14 @@ pub fn parse_identities_from_json_value(
             if idty_datas.len() == 4 {
                 let idty_doc_builder = IdentityDocumentBuilder {
                     currency,
-                    issuer: &PublicKey::from_base58(idty_datas[0]).unwrap(),
+                    issuer: &PubKey::Ed25519(
+                        ed25519::PublicKey::from_base58(idty_datas[0]).unwrap(),
+                    ),
                     blockstamp: &Blockstamp::from_string(idty_datas[2]).unwrap(),
                     username: idty_datas[3],
                 };
-                let idty_sig = Signature::from_base64(idty_datas[1]).unwrap();
+                let idty_sig =
+                    Sig::Ed25519(ed25519::Signature::from_base64(idty_datas[1]).unwrap());
                 //memberships.push(membership_doc_builder.build_with_signature(vec![membership_sig]));
                 Ok(idty_doc_builder.build_with_signature(vec![idty_sig]))
             } else {
@@ -51,23 +54,6 @@ pub fn parse_identities_from_json_value(
             }
         })
         .collect()
-
-    /*for membership in array_memberships.iter() {
-        let membership_datas: Vec<&str> = membership.as_str().unwrap().split(':').collect();
-        if membership_datas.len() == 5 {
-            let membership_doc_builder = IdentityDocumentBuilder {
-                currency,
-                issuer: &PublicKey::from_base58(membership_datas[0]).unwrap(),
-                blockstamp: &Blockstamp::from_string(membership_datas[2]).unwrap(),
-                membership: membership_type,
-                identity_username: membership_datas[4],
-                identity_blockstamp: &Blockstamp::from_string(membership_datas[3]).unwrap(),
-            };
-            let membership_sig = Signature::from_base64(membership_datas[1]).unwrap();
-            memberships.push(membership_doc_builder.build_with_signature(vec![membership_sig]));
-        }
-    }
-    memberships*/
 }
 
 pub fn parse_compact_identity(
@@ -76,12 +62,12 @@ pub fn parse_compact_identity(
 ) -> Option<IdentityDocument> {
     if source.is_string() {
         let idty_elements: Vec<&str> = source.as_str().unwrap().split(':').collect();
-        let issuer = match PublicKey::from_base58(idty_elements[0]) {
-            Ok(pubkey) => pubkey,
+        let issuer = match ed25519::PublicKey::from_base58(idty_elements[0]) {
+            Ok(pubkey) => PubKey::Ed25519(pubkey),
             Err(_) => return None,
         };
-        let signature = match Signature::from_base64(idty_elements[1]) {
-            Ok(sig) => sig,
+        let signature = match ed25519::Signature::from_base64(idty_elements[1]) {
+            Ok(sig) => Sig::Ed25519(sig),
             Err(_) => return None,
         };
         let blockstamp = match Blockstamp::from_string(idty_elements[2]) {
diff --git a/dal/parsers/memberships.rs b/dal/parsers/memberships.rs
index 8db1a052ec09720219c62fefef64f77f6529444a..27229024b110948d74f0029d2602f780338c8aa0 100644
--- a/dal/parsers/memberships.rs
+++ b/dal/parsers/memberships.rs
@@ -1,7 +1,7 @@
 extern crate serde_json;
 extern crate sqlite;
 
-use duniter_crypto::keys::{PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::membership::{
     MembershipDocumentBuilder, MembershipType,
 };
@@ -50,13 +50,16 @@ pub fn parse_memberships_from_json_value(
             if membership_datas.len() == 5 {
                 let membership_doc_builder = MembershipDocumentBuilder {
                     currency,
-                    issuer: &PublicKey::from_base58(membership_datas[0]).unwrap(),
+                    issuer: &PubKey::Ed25519(
+                        ed25519::PublicKey::from_base58(membership_datas[0]).unwrap(),
+                    ),
                     blockstamp: &Blockstamp::from_string(membership_datas[2]).unwrap(),
                     membership: membership_type,
                     identity_username: membership_datas[4],
                     identity_blockstamp: &Blockstamp::from_string(membership_datas[3]).unwrap(),
                 };
-                let membership_sig = Signature::from_base64(membership_datas[1]).unwrap();
+                let membership_sig =
+                    Sig::Ed25519(ed25519::Signature::from_base64(membership_datas[1]).unwrap());
                 Ok(membership_doc_builder.build_with_signature(vec![membership_sig]))
             } else {
                 Err(MembershipParseError::WrongFormat())
diff --git a/dal/parsers/mod.rs b/dal/parsers/mod.rs
index 49a98a57d01502f01c3412b2cbd6e5643ef8e049..34b7772097b5d7ef26f8ba97b15beae677d663e7 100644
--- a/dal/parsers/mod.rs
+++ b/dal/parsers/mod.rs
@@ -9,7 +9,7 @@ pub mod transactions;
 #[cfg(test)]
 mod tests {
     use super::transactions::*;
-    use duniter_crypto::keys::{PublicKey, Signature};
+    use duniter_crypto::keys::*;
     use duniter_documents::blockchain::v10::documents::transaction::*;
     use duniter_documents::blockchain::DocumentBuilder;
     use duniter_documents::Blockstamp;
@@ -47,9 +47,10 @@ mod tests {
                 "112533-000002150F2E805E604D9B31212D079570AAD8D3A4D8BB75F2C15A94A345B6B1",
             ).unwrap(),
             locktime: &0,
-            issuers: &vec![
-                PublicKey::from_base58("51EFVNZwpfmTXU7BSLpeh3PZFgfdmm5hq5MzCDopdH2").unwrap(),
-            ],
+            issuers: &vec![PubKey::Ed25519(
+                ed25519::PublicKey::from_base58("51EFVNZwpfmTXU7BSLpeh3PZFgfdmm5hq5MzCDopdH2")
+                    .unwrap(),
+            )],
             inputs: &vec![
                 TransactionInput::parse_from_str(
                     "1000:0:D:51EFVNZwpfmTXU7BSLpeh3PZFgfdmm5hq5MzCDopdH2:46496",
@@ -66,7 +67,7 @@ mod tests {
 
         assert_eq!(
             parse_transaction("g1", &tx_json).expect("Fail to parse transaction !"),
-            tx_builder.build_with_signature(vec![Signature::from_base64("5olrjFylTCsVq8I5Yr7FpXeviynICyvIwe1yG5N0RJF+VZb+bCFBnLAMpmMCU2qzUvK7z41UXOrMRybXiLa2Dw==").unwrap()])
+            tx_builder.build_with_signature(vec![Sig::Ed25519(ed25519::Signature::from_base64("5olrjFylTCsVq8I5Yr7FpXeviynICyvIwe1yG5N0RJF+VZb+bCFBnLAMpmMCU2qzUvK7z41UXOrMRybXiLa2Dw==").unwrap())])
         );
     }
 
@@ -104,9 +105,10 @@ mod tests {
                 "58-00005B9167EBA1E32C6EAD42AE7F72D8F14B765D3C9E47D233B553D47C5AEE0C",
             ).unwrap(),
             locktime: &0,
-            issuers: &vec![
-                PublicKey::from_base58("FVUFRrk1K5TQGsY7PRLwqHgdHRoHrwb1hcucp4C2N5tD").unwrap(),
-            ],
+            issuers: &vec![PubKey::Ed25519(
+                ed25519::PublicKey::from_base58("FVUFRrk1K5TQGsY7PRLwqHgdHRoHrwb1hcucp4C2N5tD")
+                    .unwrap(),
+            )],
             inputs: &vec![
                 TransactionInput::parse_from_str(
                     "1000:0:D:FVUFRrk1K5TQGsY7PRLwqHgdHRoHrwb1hcucp4C2N5tD:1",
@@ -126,7 +128,7 @@ mod tests {
 
         assert_eq!(
             parse_transaction("g1", &tx_json).expect("Fail to parse transaction !"),
-            tx_builder.build_with_signature(vec![Signature::from_base64("VWbvsiybM4L2X5+o+6lIiuKNw5KrD1yGZqmV+lHtA28XoRUFzochSIgfoUqBsTAaYEHY45vSX917LDXudTEzBg==").unwrap()])
+            tx_builder.build_with_signature(vec![Sig::Ed25519(ed25519::Signature::from_base64("VWbvsiybM4L2X5+o+6lIiuKNw5KrD1yGZqmV+lHtA28XoRUFzochSIgfoUqBsTAaYEHY45vSX917LDXudTEzBg==").unwrap())])
         );
     }
 }
diff --git a/dal/parsers/revoked.rs b/dal/parsers/revoked.rs
index 75ab8c8e988674342927f8078328748d00e80f38..fec4ca70bb6a1a82aacb3f467229efe7204ebf8b 100644
--- a/dal/parsers/revoked.rs
+++ b/dal/parsers/revoked.rs
@@ -1,6 +1,6 @@
 extern crate serde_json;
 
-use duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::revocation::{
     CompactRevocationDocument, RevocationDocumentBuilder,
 };
@@ -26,10 +26,14 @@ pub fn parse_revocations_into_compact(
             .collect();
         if revocations_datas.len() == 2 {
             revocations.push(TextDocumentFormat::Compact(CompactRevocationDocument {
-                issuer: PublicKey::from_base58(revocations_datas[0])
-                    .expect("Receive block in wrong format !"),
-                signature: Signature::from_base64(revocations_datas[1])
-                    .expect("Receive block in wrong format !"),
+                issuer: PubKey::Ed25519(
+                    ed25519::PublicKey::from_base58(revocations_datas[0])
+                        .expect("Receive block in wrong format !"),
+                ),
+                signature: Sig::Ed25519(
+                    ed25519::Signature::from_base64(revocations_datas[1])
+                        .expect("Receive block in wrong format !"),
+                ),
             }));
         }
     }
@@ -39,7 +43,7 @@ pub fn parse_revocations_into_compact(
 pub fn parse_revocations(
     currency: &str,
     db: &DuniterDB,
-    block_identities: &HashMap<ed25519::PublicKey, IdentityDocument>,
+    block_identities: &HashMap<PubKey, IdentityDocument>,
     json_datas: &str,
 ) -> Option<Vec<TextDocumentFormat<RevocationDocument>>> {
     let raw_revocations: serde_json::Value = serde_json::from_str(json_datas).unwrap();
@@ -59,15 +63,15 @@ pub fn parse_revocations(
 pub fn parse_revocations_from_json_value(
     currency: &str,
     db: &DuniterDB,
-    block_identities: &HashMap<ed25519::PublicKey, IdentityDocument>,
+    block_identities: &HashMap<PubKey, IdentityDocument>,
     array_revocations: &[serde_json::Value],
 ) -> Vec<TextDocumentFormat<RevocationDocument>> {
     let mut revocations: Vec<TextDocumentFormat<RevocationDocument>> = Vec::new();
     for revocation in array_revocations.iter() {
         let revocations_datas: Vec<&str> = revocation.as_str().unwrap().split(':').collect();
         if revocations_datas.len() == 2 {
-            let idty_pubkey: ed25519::PublicKey =
-                PublicKey::from_base58(revocations_datas[0]).unwrap();
+            let idty_pubkey =
+                PubKey::Ed25519(ed25519::PublicKey::from_base58(revocations_datas[0]).unwrap());
             let idty_doc: IdentityDocument = match block_identities.get(&idty_pubkey) {
                 Some(idty_doc) => idty_doc.clone(),
                 None => {
@@ -82,7 +86,8 @@ pub fn parse_revocations_from_json_value(
                 identity_blockstamp: &idty_doc.blockstamp(),
                 identity_sig: &idty_doc.signatures()[0],
             };
-            let revoc_sig = Signature::from_base64(revocations_datas[1]).unwrap();
+            let revoc_sig =
+                Sig::Ed25519(ed25519::Signature::from_base64(revocations_datas[1]).unwrap());
             revocations.push(TextDocumentFormat::Complete(
                 revoc_doc_builder.build_with_signature(vec![revoc_sig]),
             ));
diff --git a/dal/parsers/transactions.rs b/dal/parsers/transactions.rs
index 75146df4b1f32e6b842c6024616c1dd35dfbcb3d..e4b21fa4b0b46bd9d23acd91d391745569f3e111 100644
--- a/dal/parsers/transactions.rs
+++ b/dal/parsers/transactions.rs
@@ -1,7 +1,7 @@
 extern crate serde;
 extern crate serde_json;
 
-use duniter_crypto::keys::{PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::transaction::{
     TransactionDocument, TransactionDocumentBuilder, TransactionInput, TransactionInputUnlocks,
     TransactionOutput,
@@ -48,10 +48,10 @@ pub fn parse_compact_transactions(
             let mut line = 2;
             let mut issuers = Vec::new();
             for _ in 0..issuers_count {
-                issuers.push(
-                    PublicKey::from_base58(transaction_lines[line])
+                issuers.push(PubKey::Ed25519(
+                    ed25519::PublicKey::from_base58(transaction_lines[line])
                         .expect("Fail to parse tx issuer !"),
-                );
+                ));
                 line += 1;
             }
             let mut inputs = Vec::new();
@@ -85,10 +85,10 @@ pub fn parse_compact_transactions(
             }
             let mut signatures = Vec::new();
             for _ in 0..issuers_count {
-                signatures.push(
-                    Signature::from_base64(transaction_lines[line])
+                signatures.push(Sig::Ed25519(
+                    ed25519::Signature::from_base64(transaction_lines[line])
                         .expect("Fail to parse tx signature !"),
-                );
+                ));
                 line += 1;
             }
             let tx_doc_builder = TransactionDocumentBuilder {
@@ -124,8 +124,8 @@ pub fn parse_transaction(
     let issuers_array = source.get("issuers")?.as_array()?;
     let mut issuers = Vec::with_capacity(issuers_array.len());
     for issuer in issuers_array {
-        match PublicKey::from_base58(issuer.as_str()?) {
-            Ok(pubkey) => issuers.push(pubkey),
+        match ed25519::PublicKey::from_base58(issuer.as_str()?) {
+            Ok(pubkey) => issuers.push(PubKey::Ed25519(pubkey)),
             Err(_) => {
                 return None;
             }
@@ -165,8 +165,8 @@ pub fn parse_transaction(
     let signatures_array = source.get("signatures")?.as_array()?;
     let mut signatures = Vec::with_capacity(signatures_array.len());
     for signature in signatures_array {
-        match Signature::from_base64(signature.as_str()?) {
-            Ok(signature) => signatures.push(signature),
+        match ed25519::Signature::from_base64(signature.as_str()?) {
+            Ok(signature) => signatures.push(Sig::Ed25519(signature)),
             Err(_) => {
                 return None;
             }
@@ -208,9 +208,10 @@ Merci pour la calligraphie ;) de Liam$\
                 "112533-000002150F2E805E604D9B31212D079570AAD8D3A4D8BB75F2C15A94A345B6B1",
             ).unwrap(),
             locktime: &0,
-            issuers: &vec![
-                PublicKey::from_base58("51EFVNZwpfmTXU7BSLpeh3PZFgfdmm5hq5MzCDopdH2").unwrap(),
-            ],
+            issuers: &vec![PubKey::Ed25519(
+                ed25519::PublicKey::from_base58("51EFVNZwpfmTXU7BSLpeh3PZFgfdmm5hq5MzCDopdH2")
+                    .unwrap(),
+            )],
             inputs: &vec![
                 TransactionInput::parse_from_str(
                     "1000:0:D:51EFVNZwpfmTXU7BSLpeh3PZFgfdmm5hq5MzCDopdH2:46496",
@@ -227,7 +228,7 @@ Merci pour la calligraphie ;) de Liam$\
 
         assert_eq!(
             parse_compact_transactions("g1", compact_txs).expect("Fail to parse compact transactions !"),
-            vec![tx_builder.build_with_signature(vec![Signature::from_base64("5olrjFylTCsVq8I5Yr7FpXeviynICyvIwe1yG5N0RJF+VZb+bCFBnLAMpmMCU2qzUvK7z41UXOrMRybXiLa2Dw==").unwrap()])]
+            vec![tx_builder.build_with_signature(vec![Sig::Ed25519(ed25519::Signature::from_base64("5olrjFylTCsVq8I5Yr7FpXeviynICyvIwe1yG5N0RJF+VZb+bCFBnLAMpmMCU2qzUvK7z41UXOrMRybXiLa2Dw==").unwrap())])]
         );
     }
 }
diff --git a/dal/writers/certification.rs b/dal/writers/certification.rs
index f42aac963315b1df527bdc8413db065f0a961921..f175de0f681a0b4a1272ebb14eb5748102b2acf3 100644
--- a/dal/writers/certification.rs
+++ b/dal/writers/certification.rs
@@ -3,7 +3,7 @@ extern crate serde_json;
 extern crate sqlite;
 
 use super::super::DuniterDB;
-use duniter_crypto::keys::ed25519;
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::certification::CompactCertificationDocument;
 use duniter_documents::Blockstamp;
 
@@ -44,7 +44,7 @@ pub fn write_certification(
         .expect("Fail to execute INSERT certification !");
 }
 
-pub fn remove_certification(from: ed25519::PublicKey, to: ed25519::PublicKey, db: &DuniterDB) {
+pub fn remove_certification(from: PubKey, to: PubKey, db: &DuniterDB) {
     db.0
         .execute(format!(
             "DELETE FROM certifications WHERE pubkey_from={} AND pubkey_to={}",
diff --git a/dal/writers/requests.rs b/dal/writers/requests.rs
index 3edb71eeefe58308885e88668f05a976a0e57a4a..13a909a5976b7f084835668bdcfa625497422139 100644
--- a/dal/writers/requests.rs
+++ b/dal/writers/requests.rs
@@ -5,7 +5,7 @@ extern crate serde;
 extern crate serde_json;
 extern crate sqlite;
 
-use self::duniter_crypto::keys::ed25519;
+use self::duniter_crypto::keys::PubKey;
 use self::duniter_documents::blockchain::v10::documents::certification::CompactCertificationDocument;
 use self::duniter_documents::blockchain::v10::documents::identity::IdentityDocument;
 use self::duniter_documents::Blockstamp;
@@ -21,7 +21,7 @@ pub enum DBWriteRequest {
     /// Newcomer
     CreateIdentity(NodeId, Blockstamp, u64, Box<IdentityDocument>),
     /// Active
-    RenewalIdentity(ed25519::PublicKey, Blockstamp, u64),
+    RenewalIdentity(PubKey, Blockstamp, u64),
     /// Excluded
     ExcludeIdentity(NodeId, Blockstamp, u64),
     /// Revoked
diff --git a/documents/blockchain/mod.rs b/documents/blockchain/mod.rs
index ff070ebabeaab0aa48fb8feec7057bde65684026..4ddea4f316c2dcbec5c72265242e2da8d3e1bdfd 100644
--- a/documents/blockchain/mod.rs
+++ b/documents/blockchain/mod.rs
@@ -143,18 +143,18 @@ pub trait DocumentParser<S, D, E> {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use duniter_crypto::keys::{ed25519, Signature};
+    use duniter_crypto::keys::*;
 
     // simple text document for signature testing
     #[derive(Debug, Clone)]
     struct PlainTextDocument {
         pub text: &'static str,
-        pub issuers: Vec<ed25519::PublicKey>,
-        pub signatures: Vec<ed25519::Signature>,
+        pub issuers: Vec<PubKey>,
+        pub signatures: Vec<Sig>,
     }
 
     impl Document for PlainTextDocument {
-        type PublicKey = ed25519::PublicKey;
+        type PublicKey = PubKey;
         type CurrencyType = str;
 
         fn version(&self) -> u16 {
@@ -169,11 +169,11 @@ mod tests {
             unimplemented!()
         }
 
-        fn issuers(&self) -> &Vec<ed25519::PublicKey> {
+        fn issuers(&self) -> &Vec<PubKey> {
             &self.issuers
         }
 
-        fn signatures(&self) -> &Vec<ed25519::Signature> {
+        fn signatures(&self) -> &Vec<Sig> {
             &self.signatures
         }
 
@@ -193,24 +193,30 @@ Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
 ";
 
         // good pair
-        let issuer1 = ed25519::PublicKey::from_base58(
-            "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV",
-        ).unwrap();
-
-        let sig1 = ed25519::Signature::from_base64(
-            "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMM\
-             mQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
-        ).unwrap();
+        let issuer1 = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV")
+                .unwrap(),
+        );
+
+        let sig1 = Sig::Ed25519(
+            ed25519::Signature::from_base64(
+                "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMM\
+                 mQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
+            ).unwrap(),
+        );
 
         // incorrect pair
-        let issuer2 = ed25519::PublicKey::from_base58(
-            "DNann1Lh55eZMEDXeYt32bzHbA3NJR46DeQYCS2qQdLV",
-        ).unwrap();
-
-        let sig2 = ed25519::Signature::from_base64(
-            "1eubHHbuNfilHHH0G2bI30iZzebQ2cQ1PC7uPAw08FGMM\
-             mQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
-        ).unwrap();
+        let issuer2 = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt32bzHbA3NJR46DeQYCS2qQdLV")
+                .unwrap(),
+        );
+
+        let sig2 = Sig::Ed25519(
+            ed25519::Signature::from_base64(
+                "1eubHHbuNfilHHH0G2bI30iZzebQ2cQ1PC7uPAw08FGMM\
+                 mQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
+            ).unwrap(),
+        );
 
         {
             let doc = PlainTextDocument {
diff --git a/documents/blockchain/v10/documents/block.rs b/documents/blockchain/v10/documents/block.rs
index 1b51c4689331f4b1bbf849d348a3ef7428577222..8201f50d6ead3be019eb6717ccfc51fe26117676 100644
--- a/documents/blockchain/v10/documents/block.rs
+++ b/documents/blockchain/v10/documents/block.rs
@@ -17,7 +17,7 @@
 
 use crypto::digest::Digest;
 use crypto::sha2::Sha256;
-use duniter_crypto::keys::{ed25519, PrivateKey};
+use duniter_crypto::keys::*;
 
 use blockchain::v10::documents::certification::CertificationDocument;
 use blockchain::v10::documents::identity::IdentityDocument;
@@ -105,10 +105,10 @@ pub struct BlockDocument {
     /// Currency.
     pub currency: String,
     /// Document issuer (there should be only one).
-    pub issuers: Vec<ed25519::PublicKey>,
+    pub issuers: Vec<PubKey>,
     /// Document signature (there should be only one).
     /// This vector is empty, when the block is generated but the proof of work has not yet started
-    pub signatures: Vec<ed25519::Signature>,
+    pub signatures: Vec<Sig>,
     /// The hash is None, when the block is generated but the proof of work has not yet started
     pub hash: Option<BlockHash>,
     /// Currency parameters (only in genesis block)
@@ -116,7 +116,7 @@ pub struct BlockDocument {
     /// Hash of the previous block
     pub previous_hash: Hash,
     /// Issuer of the previous block
-    pub previous_issuer: Option<ed25519::PublicKey>,
+    pub previous_issuer: Option<PubKey>,
     /// Hash of the deterministic content of the block
     pub inner_hash: Option<Hash>,
     /// Amount of new dividend created at this block, None if no dividend is created at this block
@@ -132,7 +132,7 @@ pub struct BlockDocument {
     /// Revokeds
     pub revoked: Vec<TextDocumentFormat<RevocationDocument>>,
     /// Excludeds
-    pub excluded: Vec<ed25519::PublicKey>,
+    pub excluded: Vec<PubKey>,
     /// Certifications
     pub certifications: Vec<TextDocumentFormat<CertificationDocument>>,
     /// Transactions
@@ -159,7 +159,7 @@ impl BlockDocument {
         );
     }
     /// Sign block
-    pub fn sign(&mut self, privkey: ed25519::PrivateKey) {
+    pub fn sign(&mut self, privkey: PrivKey) {
         self.signatures = vec![privkey.sign(self.inner_hash_and_nonce_str.as_bytes())];
     }
     /// Compute hash
@@ -280,7 +280,7 @@ Transactions:{transactions}
 }
 
 impl Document for BlockDocument {
-    type PublicKey = ed25519::PublicKey;
+    type PublicKey = PubKey;
     type CurrencyType = str;
 
     fn version(&self) -> u16 {
@@ -298,11 +298,11 @@ impl Document for BlockDocument {
         }
     }
 
-    fn issuers(&self) -> &Vec<ed25519::PublicKey> {
+    fn issuers(&self) -> &Vec<PubKey> {
         &self.issuers
     }
 
-    fn signatures(&self) -> &Vec<ed25519::Signature> {
+    fn signatures(&self) -> &Vec<Sig> {
         &self.signatures
     }
 
@@ -345,7 +345,6 @@ mod tests {
     use super::*;
     use blockchain::v10::documents::V10DocumentParser;
     use blockchain::{Document, DocumentParser, VerificationResult};
-    use duniter_crypto::keys::{PublicKey, Signature};
     use std::ops::Deref;
 
     #[test]
@@ -363,12 +362,12 @@ mod tests {
             issuers_frame: 201,
             issuers_frame_var: 5,
             currency: String::from("g1"),
-            issuers: vec![ed25519::PublicKey::from_base58("2sZF6j2PkxBDNAqUde7Dgo5x3crkerZpQ4rBqqJGn8QT").unwrap()],
-            signatures: vec![ed25519::Signature::from_base64("FsRxB+NOiL+8zTr2d3B2j2KBItDuCa0KjFMF6hXmdQzfqXAs9g3m7DlGgYLcqzqe6JXjx/Lyzqze1HBR4cS0Aw==").unwrap()],
+            issuers: vec![PubKey::Ed25519(ed25519::PublicKey::from_base58("2sZF6j2PkxBDNAqUde7Dgo5x3crkerZpQ4rBqqJGn8QT").unwrap())],
+            signatures: vec![Sig::Ed25519(ed25519::Signature::from_base64("FsRxB+NOiL+8zTr2d3B2j2KBItDuCa0KjFMF6hXmdQzfqXAs9g3m7DlGgYLcqzqe6JXjx/Lyzqze1HBR4cS0Aw==").unwrap())],
             hash: None,
             parameters: None,
             previous_hash: Hash::from_hex("0000001F8AACF6764135F3E5D0D4E8358A3CBE537A4BF71152A00CC442EFD136").expect("fail to parse previous_hash"),
-            previous_issuer: Some(ed25519::PublicKey::from_base58("38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE").unwrap()),
+            previous_issuer: Some(PubKey::Ed25519(ed25519::PublicKey::from_base58("38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE").unwrap())),
             inner_hash: None,
             dividend: None,
             identities: Vec::new(),
@@ -498,12 +497,12 @@ a9PHPuSfw7jW8FRQHXFsGi/bnLjbtDnTYvEVgUC9u0WlR7GVofa+Xb+l5iy6NwuEXiwvueAkf08wPVY8
             issuers_frame: 211,
             issuers_frame_var: 0,
             currency: String::from("g1"),
-            issuers: vec![ed25519::PublicKey::from_base58("DA4PYtXdvQqk1nCaprXH52iMsK5Ahxs1nRWbWKLhpVkQ").unwrap()],
-            signatures: vec![ed25519::Signature::from_base64("92id58VmkhgVNee4LDqBGSm8u/ooHzAD67JM6fhAE/CV8LCz7XrMF1DvRl+eRpmlaVkp6I+Iy8gmZ1WUM5C8BA==").unwrap()],
+            issuers: vec![PubKey::Ed25519(ed25519::PublicKey::from_base58("DA4PYtXdvQqk1nCaprXH52iMsK5Ahxs1nRWbWKLhpVkQ").unwrap())],
+            signatures: vec![Sig::Ed25519(ed25519::Signature::from_base64("92id58VmkhgVNee4LDqBGSm8u/ooHzAD67JM6fhAE/CV8LCz7XrMF1DvRl+eRpmlaVkp6I+Iy8gmZ1WUM5C8BA==").unwrap())],
             hash: None,
             parameters: None,
             previous_hash: Hash::from_hex("000001144968D0C3516BE6225E4662F182E28956AF46DD7FB228E3D0F9413FEB").expect("fail to parse previous_hash"),
-            previous_issuer: Some(ed25519::PublicKey::from_base58("D3krfq6J9AmfpKnS3gQVYoy7NzGCc61vokteTS8LJ4YH").unwrap()),
+            previous_issuer: Some(PubKey::Ed25519(ed25519::PublicKey::from_base58("D3krfq6J9AmfpKnS3gQVYoy7NzGCc61vokteTS8LJ4YH").unwrap())),
             inner_hash: None,
             dividend: None,
             identities: Vec::new(),
diff --git a/documents/blockchain/v10/documents/certification.rs b/documents/blockchain/v10/documents/certification.rs
index 842591838c7eb796bb28cfc5a76bd2e816fffffc..67ff2e877741aa672cde5fffb3df11b39779160e 100644
--- a/documents/blockchain/v10/documents/certification.rs
+++ b/documents/blockchain/v10/documents/certification.rs
@@ -18,7 +18,7 @@
 extern crate serde;
 
 use self::serde::ser::{Serialize, Serializer};
-use duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use duniter_crypto::keys::*;
 use regex::Regex;
 
 use blockchain::v10::documents::*;
@@ -36,13 +36,13 @@ lazy_static! {
 /// Wrap an Compact Revocation document (in block content)
 pub struct CompactCertificationDocument {
     /// Issuer
-    pub issuer: ed25519::PublicKey,
+    pub issuer: PubKey,
     /// Target
-    pub target: ed25519::PublicKey,
+    pub target: PubKey,
     /// Blockstamp
     pub block_number: BlockId,
     /// Signature
-    pub signature: ed25519::Signature,
+    pub signature: Sig,
 }
 
 impl CompactTextDocument for CompactCertificationDocument {
@@ -70,19 +70,19 @@ pub struct CertificationDocument {
     /// Name of the currency.
     currency: String,
     /// Document issuer (there should be only one).
-    issuers: Vec<ed25519::PublicKey>,
+    issuers: Vec<PubKey>,
     /// issuer of target identity.
-    target: ed25519::PublicKey,
+    target: PubKey,
     /// Username of target identity
     identity_username: String,
     /// Target Identity document blockstamp.
     identity_blockstamp: Blockstamp,
     /// Target Identity document signature.
-    identity_sig: ed25519::Signature,
+    identity_sig: Sig,
     /// Blockstamp
     blockstamp: Blockstamp,
     /// Document signature (there should be only one).
-    signatures: Vec<ed25519::Signature>,
+    signatures: Vec<Sig>,
 }
 
 impl CertificationDocument {
@@ -92,18 +92,18 @@ impl CertificationDocument {
     }
 
     /// Pubkey of source identity
-    pub fn source(&self) -> &ed25519::PublicKey {
+    pub fn source(&self) -> &PubKey {
         &self.issuers[0]
     }
 
     /// Pubkey of target identity
-    pub fn target(&self) -> &ed25519::PublicKey {
+    pub fn target(&self) -> &PubKey {
         &self.target
     }
 }
 
 impl Document for CertificationDocument {
-    type PublicKey = ed25519::PublicKey;
+    type PublicKey = PubKey;
     type CurrencyType = str;
 
     fn version(&self) -> u16 {
@@ -118,11 +118,11 @@ impl Document for CertificationDocument {
         self.blockstamp
     }
 
-    fn issuers(&self) -> &Vec<ed25519::PublicKey> {
+    fn issuers(&self) -> &Vec<PubKey> {
         &self.issuers
     }
 
-    fn signatures(&self) -> &Vec<ed25519::Signature> {
+    fn signatures(&self) -> &Vec<Sig> {
         &self.signatures
     }
 
@@ -169,25 +169,21 @@ pub struct CertificationDocumentBuilder<'a> {
     /// Document currency.
     pub currency: &'a str,
     /// Certification issuer (=source).
-    pub issuer: &'a ed25519::PublicKey,
+    pub issuer: &'a PubKey,
     /// Reference blockstamp.
     pub blockstamp: &'a Blockstamp,
     /// Pubkey of target identity.
-    pub target: &'a ed25519::PublicKey,
+    pub target: &'a PubKey,
     /// 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,
+    pub identity_sig: &'a Sig,
 }
 
 impl<'a> CertificationDocumentBuilder<'a> {
-    fn build_with_text_and_sigs(
-        self,
-        text: String,
-        signatures: Vec<ed25519::Signature>,
-    ) -> CertificationDocument {
+    fn build_with_text_and_sigs(self, text: String, signatures: Vec<Sig>) -> CertificationDocument {
         CertificationDocument {
             text,
             currency: self.currency.to_string(),
@@ -204,13 +200,13 @@ impl<'a> CertificationDocumentBuilder<'a> {
 
 impl<'a> DocumentBuilder for CertificationDocumentBuilder<'a> {
     type Document = CertificationDocument;
-    type PrivateKey = ed25519::PrivateKey;
+    type PrivateKey = PrivKey;
 
-    fn build_with_signature(&self, signatures: Vec<ed25519::Signature>) -> CertificationDocument {
+    fn build_with_signature(&self, signatures: Vec<Sig>) -> CertificationDocument {
         self.build_with_text_and_sigs(self.generate_text(), signatures)
     }
 
-    fn build_and_sign(&self, private_keys: Vec<ed25519::PrivateKey>) -> CertificationDocument {
+    fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> CertificationDocument {
         let (text, signatures) = self.build_signed_text(private_keys);
         self.build_with_text_and_sigs(text, signatures)
     }
@@ -249,7 +245,7 @@ impl StandardTextDocumentParser for CertificationDocumentParser {
         doc: &str,
         body: &str,
         currency: &str,
-        signatures: Vec<ed25519::Signature>,
+        signatures: Vec<Sig>,
     ) -> Result<V10Document, V10DocumentParsingError> {
         if let Some(caps) = CERTIFICATION_REGEX.captures(body) {
             let issuer = &caps["issuer"];
@@ -261,11 +257,11 @@ impl StandardTextDocumentParser for CertificationDocumentParser {
 
             // Regex match so should not fail.
             // TODO : Test it anyway
-            let issuer = ed25519::PublicKey::from_base58(issuer).unwrap();
-            let target = ed25519::PublicKey::from_base58(target).unwrap();
+            let issuer = PubKey::Ed25519(ed25519::PublicKey::from_base58(issuer).unwrap());
+            let target = PubKey::Ed25519(ed25519::PublicKey::from_base58(target).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();
+            let identity_sig = Sig::Ed25519(ed25519::Signature::from_base64(identity_sig).unwrap());
             let blockstamp = Blockstamp::from_string(blockstamp).unwrap();
 
             Ok(V10Document::Certification(Box::new(
@@ -297,29 +293,31 @@ mod tests {
 
     #[test]
     fn generate_real_document() {
-        let pubkey = ed25519::PublicKey::from_base58(
-            "4tNQ7d9pj2Da5wUVoW9mFn7JjuPoowF977au8DdhEjVR",
-        ).unwrap();
+        let pubkey = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("4tNQ7d9pj2Da5wUVoW9mFn7JjuPoowF977au8DdhEjVR")
+                .unwrap(),
+        );
 
-        let prikey = ed25519::PrivateKey::from_base58(
+        let prikey = PrivKey::Ed25519(ed25519::PrivateKey::from_base58(
             "3XGWuuU1dQ7zaYPzE76ATfY71STzRkbT3t4DE1bSjMhYje81XdJFeXVG9uMPi3oDeRTosT2dmBAFH8VydrAUWXRZ",
-        ).unwrap();
+        ).unwrap());
 
-        let sig = ed25519::Signature::from_base64(
+        let sig = Sig::Ed25519(ed25519::Signature::from_base64(
             "qfR6zqT1oJbqIsppOi64gC9yTtxb6g6XA9RYpulkq9ehMvqg2VYVigCbR0yVpqKFsnYiQTrnjgFuFRSJCJDfCw==",
-        ).unwrap();
+        ).unwrap());
 
-        let target = ed25519::PublicKey::from_base58(
-            "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV",
-        ).unwrap();
+        let target = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV")
+                .unwrap(),
+        );
 
         let identity_blockstamp = Blockstamp::from_string(
             "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
         ).unwrap();
 
-        let identity_sig = ed25519::Signature::from_base64(
+        let identity_sig = Sig::Ed25519(ed25519::Signature::from_base64(
             "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
-        ).unwrap();
+        ).unwrap());
 
         let blockstamp = Blockstamp::from_string(
             "36-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B865",
@@ -382,9 +380,9 @@ CertTimestamp: 167884-0001DFCA28002A8C96575E53B8CEF8317453A7B0BA255542CCF0EC8AB5
 
         let currency = "g1-test";
 
-        let signatures = vec![Signature::from_base64(
+        let signatures = vec![Sig::Ed25519(ed25519::Signature::from_base64(
 "wqZxPEGxLrHGv8VdEIfUGvUcf+tDdNTMXjLzVRCQ4UhlhDRahOMjfcbP7byNYr5OfIl83S1MBxF7VJgu8YasCA=="
-        ).unwrap(),];
+        ).unwrap())];
 
         let doc =
             CertificationDocumentParser::parse_standard(doc, body, currency, signatures).unwrap();
diff --git a/documents/blockchain/v10/documents/identity.rs b/documents/blockchain/v10/documents/identity.rs
index 40bd02bb3c7dc5c1c7d52938028b8f25e14998e0..310b3adc113adb3e0e3330dc2a4b4be4f51b1643 100644
--- a/documents/blockchain/v10/documents/identity.rs
+++ b/documents/blockchain/v10/documents/identity.rs
@@ -18,7 +18,7 @@
 extern crate serde;
 
 use self::serde::ser::{Serialize, Serializer};
-use duniter_crypto::keys::{ed25519, PublicKey};
+use duniter_crypto::keys::*;
 use regex::Regex;
 
 use blockchain::v10::documents::*;
@@ -49,9 +49,9 @@ pub struct IdentityDocument {
     /// Blockstamp
     blockstamp: Blockstamp,
     /// Document issuer (there should be only one).
-    issuers: Vec<ed25519::PublicKey>,
+    issuers: Vec<PubKey>,
     /// Document signature (there should be only one).
-    signatures: Vec<ed25519::Signature>,
+    signatures: Vec<Sig>,
 }
 
 impl IdentityDocument {
@@ -62,7 +62,7 @@ impl IdentityDocument {
 }
 
 impl Document for IdentityDocument {
-    type PublicKey = ed25519::PublicKey;
+    type PublicKey = PubKey;
     type CurrencyType = str;
 
     fn version(&self) -> u16 {
@@ -77,11 +77,11 @@ impl Document for IdentityDocument {
         self.blockstamp
     }
 
-    fn issuers(&self) -> &Vec<ed25519::PublicKey> {
+    fn issuers(&self) -> &Vec<PubKey> {
         &self.issuers
     }
 
-    fn signatures(&self) -> &Vec<ed25519::Signature> {
+    fn signatures(&self) -> &Vec<Sig> {
         &self.signatures
     }
 
@@ -139,15 +139,11 @@ pub struct IdentityDocumentBuilder<'a> {
     /// Reference blockstamp.
     pub blockstamp: &'a Blockstamp,
     /// Document/identity issuer.
-    pub issuer: &'a ed25519::PublicKey,
+    pub issuer: &'a PubKey,
 }
 
 impl<'a> IdentityDocumentBuilder<'a> {
-    fn build_with_text_and_sigs(
-        self,
-        text: String,
-        signatures: Vec<ed25519::Signature>,
-    ) -> IdentityDocument {
+    fn build_with_text_and_sigs(self, text: String, signatures: Vec<Sig>) -> IdentityDocument {
         IdentityDocument {
             text,
             currency: self.currency.to_string(),
@@ -161,13 +157,13 @@ impl<'a> IdentityDocumentBuilder<'a> {
 
 impl<'a> DocumentBuilder for IdentityDocumentBuilder<'a> {
     type Document = IdentityDocument;
-    type PrivateKey = ed25519::PrivateKey;
+    type PrivateKey = PrivKey;
 
-    fn build_with_signature(&self, signatures: Vec<ed25519::Signature>) -> IdentityDocument {
+    fn build_with_signature(&self, signatures: Vec<Sig>) -> IdentityDocument {
         self.build_with_text_and_sigs(self.generate_text(), signatures)
     }
 
-    fn build_and_sign(&self, private_keys: Vec<ed25519::PrivateKey>) -> IdentityDocument {
+    fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> IdentityDocument {
         let (text, signatures) = self.build_signed_text(private_keys);
         self.build_with_text_and_sigs(text, signatures)
     }
@@ -200,7 +196,7 @@ impl StandardTextDocumentParser for IdentityDocumentParser {
         doc: &str,
         body: &str,
         currency: &str,
-        signatures: Vec<ed25519::Signature>,
+        signatures: Vec<Sig>,
     ) -> Result<V10Document, V10DocumentParsingError> {
         if let Some(caps) = IDENTITY_REGEX.captures(body) {
             let issuer = &caps["issuer"];
@@ -209,7 +205,7 @@ impl StandardTextDocumentParser for IdentityDocumentParser {
 
             // Regex match so should not fail.
             // TODO : Test it anyway
-            let issuer = ed25519::PublicKey::from_base58(issuer).unwrap();
+            let issuer = PubKey::Ed25519(ed25519::PublicKey::from_base58(issuer).unwrap());
             let blockstamp = Blockstamp::from_string(blockstamp).unwrap();
 
             Ok(V10Document::Identity(IdentityDocument {
@@ -236,19 +232,24 @@ mod tests {
 
     #[test]
     fn generate_real_document() {
-        let pubkey = ed25519::PublicKey::from_base58(
-            "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV",
-        ).unwrap();
+        let pubkey = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV")
+                .unwrap(),
+        );
 
-        let prikey = ed25519::PrivateKey::from_base58(
-            "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\
-             iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
-        ).unwrap();
+        let prikey = PrivKey::Ed25519(
+            ed25519::PrivateKey::from_base58(
+                "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\
+                 iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
+            ).unwrap(),
+        );
 
-        let sig = ed25519::Signature::from_base64(
-            "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGM\
-             MmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
-        ).unwrap();
+        let sig = Sig::Ed25519(
+            ed25519::Signature::from_base64(
+                "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGM\
+                 MmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
+            ).unwrap(),
+        );
 
         let block = Blockstamp::from_string(
             "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
@@ -298,9 +299,9 @@ Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
 
         let currency = "duniter_unit_test_currency";
 
-        let signatures = vec![Signature::from_base64(
+        let signatures = vec![Sig::Ed25519(ed25519::Signature::from_base64(
 "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg=="
-        ).unwrap(),];
+        ).unwrap())];
 
         let doc = IdentityDocumentParser::parse_standard(doc, body, currency, signatures).unwrap();
         if let V10Document::Identity(doc) = doc {
diff --git a/documents/blockchain/v10/documents/membership.rs b/documents/blockchain/v10/documents/membership.rs
index 2e313601e9f938d431ba33800582234a9ab15382..414ebf815cc94dc83c042a442e8ab649d8f2cdb7 100644
--- a/documents/blockchain/v10/documents/membership.rs
+++ b/documents/blockchain/v10/documents/membership.rs
@@ -18,7 +18,7 @@
 extern crate serde;
 
 use self::serde::ser::{Serialize, Serializer};
-use duniter_crypto::keys::{ed25519, PublicKey};
+use duniter_crypto::keys::*;
 use regex::Regex;
 
 use blockchain::v10::documents::*;
@@ -57,7 +57,7 @@ pub struct MembershipDocument {
     /// Name of the currency.
     currency: String,
     /// Document issuer (there should be only one).
-    issuers: Vec<ed25519::PublicKey>,
+    issuers: Vec<PubKey>,
     /// Blockstamp
     blockstamp: Blockstamp,
     /// Membership message.
@@ -67,7 +67,7 @@ pub struct MembershipDocument {
     /// Identity document blockstamp.
     identity_blockstamp: Blockstamp,
     /// Document signature (there should be only one).
-    signatures: Vec<ed25519::Signature>,
+    signatures: Vec<Sig>,
 }
 
 impl MembershipDocument {
@@ -83,7 +83,7 @@ impl MembershipDocument {
 }
 
 impl Document for MembershipDocument {
-    type PublicKey = ed25519::PublicKey;
+    type PublicKey = PubKey;
     type CurrencyType = str;
 
     fn version(&self) -> u16 {
@@ -98,11 +98,11 @@ impl Document for MembershipDocument {
         self.blockstamp
     }
 
-    fn issuers(&self) -> &Vec<ed25519::PublicKey> {
+    fn issuers(&self) -> &Vec<PubKey> {
         &self.issuers
     }
 
-    fn signatures(&self) -> &Vec<ed25519::Signature> {
+    fn signatures(&self) -> &Vec<Sig> {
         &self.signatures
     }
 
@@ -157,7 +157,7 @@ pub struct MembershipDocumentBuilder<'a> {
     /// Document currency.
     pub currency: &'a str,
     /// Document/identity issuer.
-    pub issuer: &'a ed25519::PublicKey,
+    pub issuer: &'a PubKey,
     /// Reference blockstamp.
     pub blockstamp: &'a Blockstamp,
     /// Membership message.
@@ -169,11 +169,7 @@ pub struct MembershipDocumentBuilder<'a> {
 }
 
 impl<'a> MembershipDocumentBuilder<'a> {
-    fn build_with_text_and_sigs(
-        self,
-        text: String,
-        signatures: Vec<ed25519::Signature>,
-    ) -> MembershipDocument {
+    fn build_with_text_and_sigs(self, text: String, signatures: Vec<Sig>) -> MembershipDocument {
         MembershipDocument {
             text,
             currency: self.currency.to_string(),
@@ -189,13 +185,13 @@ impl<'a> MembershipDocumentBuilder<'a> {
 
 impl<'a> DocumentBuilder for MembershipDocumentBuilder<'a> {
     type Document = MembershipDocument;
-    type PrivateKey = ed25519::PrivateKey;
+    type PrivateKey = PrivKey;
 
-    fn build_with_signature(&self, signatures: Vec<ed25519::Signature>) -> MembershipDocument {
+    fn build_with_signature(&self, signatures: Vec<Sig>) -> MembershipDocument {
         self.build_with_text_and_sigs(self.generate_text(), signatures)
     }
 
-    fn build_and_sign(&self, private_keys: Vec<ed25519::PrivateKey>) -> MembershipDocument {
+    fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> MembershipDocument {
         let (text, signatures) = self.build_signed_text(private_keys);
         self.build_with_text_and_sigs(text, signatures)
     }
@@ -235,7 +231,7 @@ impl StandardTextDocumentParser for MembershipDocumentParser {
         doc: &str,
         body: &str,
         currency: &str,
-        signatures: Vec<ed25519::Signature>,
+        signatures: Vec<Sig>,
     ) -> Result<V10Document, V10DocumentParsingError> {
         if let Some(caps) = MEMBERSHIP_REGEX.captures(body) {
             let issuer = &caps["issuer"];
@@ -247,7 +243,7 @@ impl StandardTextDocumentParser for MembershipDocumentParser {
 
             // Regex match so should not fail.
             // TODO : Test it anyway
-            let issuer = ed25519::PublicKey::from_base58(issuer).unwrap();
+            let issuer = PubKey::Ed25519(ed25519::PublicKey::from_base58(issuer).unwrap());
             let blockstamp = Blockstamp::from_string(blockstamp).unwrap();
             let membership = match membership {
                 "IN" => MembershipType::In(),
@@ -283,19 +279,24 @@ mod tests {
 
     #[test]
     fn generate_real_document() {
-        let pubkey = ed25519::PublicKey::from_base58(
-            "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV",
-        ).unwrap();
+        let pubkey = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV")
+                .unwrap(),
+        );
 
-        let prikey = ed25519::PrivateKey::from_base58(
-            "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\
-             iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
-        ).unwrap();
+        let prikey = PrivKey::Ed25519(
+            ed25519::PrivateKey::from_base58(
+                "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\
+                 iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
+            ).unwrap(),
+        );
 
-        let sig = ed25519::Signature::from_base64(
-            "s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkEl\
-             AyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw==",
-        ).unwrap();
+        let sig = Sig::Ed25519(
+            ed25519::Signature::from_base64(
+                "s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkEl\
+                 AyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw==",
+            ).unwrap(),
+        );
 
         let block = Blockstamp::from_string(
             "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
@@ -353,9 +354,9 @@ CertTS: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
 
         let currency = "duniter_unit_test_currency";
 
-        let signatures = vec![Signature::from_base64(
+        let signatures = vec![Sig::Ed25519(ed25519::Signature::from_base64(
 "s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkElAyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw=="
-        ).unwrap(),];
+        ).unwrap())];
 
         let doc =
             MembershipDocumentParser::parse_standard(doc, body, currency, signatures).unwrap();
diff --git a/documents/blockchain/v10/documents/mod.rs b/documents/blockchain/v10/documents/mod.rs
index 495190dd55e0d22a5e671b0c16f1cc8e6e0f2405..091d60fc2bd200d8c80d39f16bab7ca283170dad 100644
--- a/documents/blockchain/v10/documents/mod.rs
+++ b/documents/blockchain/v10/documents/mod.rs
@@ -21,7 +21,7 @@ use self::crypto::digest::Digest;
 
 use blockchain::v10::documents::identity::IdentityDocumentParser;
 use blockchain::{Document, DocumentBuilder, DocumentParser};
-use duniter_crypto::keys::{ed25519, Signature};
+use duniter_crypto::keys::*;
 use regex::Regex;
 
 pub mod block;
@@ -119,7 +119,7 @@ impl<D: TextDocument> CompactTextDocument for TextDocumentFormat<D> {
 }
 
 /// Trait for a V10 document.
-pub trait TextDocument: Document<PublicKey = ed25519::PublicKey, CurrencyType = str> {
+pub trait TextDocument: Document<PublicKey = PubKey, CurrencyType = str> {
     /// Type of associated compact document.
     type CompactTextDocument_: CompactTextDocument;
 
@@ -172,12 +172,7 @@ pub trait TextDocumentBuilder: DocumentBuilder {
     ///
     /// - Text without signatures
     /// - Signatures
-    fn build_signed_text(
-        &self,
-        private_keys: Vec<ed25519::PrivateKey>,
-    ) -> (String, Vec<ed25519::Signature>) {
-        use duniter_crypto::keys::PrivateKey;
-
+    fn build_signed_text(&self, private_keys: Vec<PrivKey>) -> (String, Vec<Sig>) {
         let text = self.generate_text();
 
         let signatures: Vec<_> = {
@@ -213,7 +208,7 @@ pub struct V10DocumentParts {
     /// Currency
     pub currency: String,
     /// Signatures
-    pub signatures: Vec<ed25519::Signature>,
+    pub signatures: Vec<Sig>,
 }
 
 trait StandardTextDocumentParser {
@@ -221,7 +216,7 @@ trait StandardTextDocumentParser {
         doc: &str,
         body: &str,
         currency: &str,
-        signatures: Vec<ed25519::Signature>,
+        signatures: Vec<Sig>,
     ) -> Result<V10Document, V10DocumentParsingError>;
 }
 
@@ -238,7 +233,7 @@ impl<'a> DocumentParser<&'a str, V10Document, V10DocumentParsingError> for V10Do
             let body = &caps["body"];
             let sigs = SIGNATURES_REGEX
                 .captures_iter(&caps["sigs"])
-                .map(|capture| ed25519::Signature::from_base64(&capture[0]).unwrap())
+                .map(|capture| Sig::Ed25519(ed25519::Signature::from_base64(&capture[0]).unwrap()))
                 .collect::<Vec<_>>();
 
             // TODO : Improve error handling of Signature::from_base64 failure
diff --git a/documents/blockchain/v10/documents/revocation.rs b/documents/blockchain/v10/documents/revocation.rs
index d40d97046fe03fb391ae42598985aa8c143ffcde..f8d3877b58b28d644561175a5e711deefe492f44 100644
--- a/documents/blockchain/v10/documents/revocation.rs
+++ b/documents/blockchain/v10/documents/revocation.rs
@@ -18,7 +18,7 @@
 extern crate serde;
 
 use self::serde::ser::{Serialize, Serializer};
-use duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use duniter_crypto::keys::*;
 use regex::Regex;
 
 use blockchain::v10::documents::*;
@@ -38,9 +38,9 @@ lazy_static! {
 /// Wrap an Compact Revocation document (in block content)
 pub struct CompactRevocationDocument {
     /// Issuer
-    pub issuer: ed25519::PublicKey,
+    pub issuer: PubKey,
     /// Signature
-    pub signature: ed25519::Signature,
+    pub signature: Sig,
 }
 
 impl CompactTextDocument for CompactRevocationDocument {
@@ -66,15 +66,15 @@ pub struct RevocationDocument {
     /// Name of the currency.
     currency: String,
     /// Document issuer (there should be only one).
-    issuers: Vec<ed25519::PublicKey>,
+    issuers: Vec<PubKey>,
     /// Username of target identity
     identity_username: String,
     /// Target Identity document blockstamp.
     identity_blockstamp: Blockstamp,
     /// Target Identity document signature.
-    identity_sig: ed25519::Signature,
+    identity_sig: Sig,
     /// Document signature (there should be only one).
-    signatures: Vec<ed25519::Signature>,
+    signatures: Vec<Sig>,
 }
 
 impl RevocationDocument {
@@ -85,7 +85,7 @@ impl RevocationDocument {
 }
 
 impl Document for RevocationDocument {
-    type PublicKey = ed25519::PublicKey;
+    type PublicKey = PubKey;
     type CurrencyType = str;
 
     fn version(&self) -> u16 {
@@ -100,11 +100,11 @@ impl Document for RevocationDocument {
         unimplemented!()
     }
 
-    fn issuers(&self) -> &Vec<ed25519::PublicKey> {
+    fn issuers(&self) -> &Vec<PubKey> {
         &self.issuers
     }
 
-    fn signatures(&self) -> &Vec<ed25519::Signature> {
+    fn signatures(&self) -> &Vec<Sig> {
         &self.signatures
     }
 
@@ -149,21 +149,17 @@ pub struct RevocationDocumentBuilder<'a> {
     /// Document currency.
     pub currency: &'a str,
     /// Revocation issuer.
-    pub issuer: &'a ed25519::PublicKey,
+    pub issuer: &'a PubKey,
     /// 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,
+    pub identity_sig: &'a Sig,
 }
 
 impl<'a> RevocationDocumentBuilder<'a> {
-    fn build_with_text_and_sigs(
-        self,
-        text: String,
-        signatures: Vec<ed25519::Signature>,
-    ) -> RevocationDocument {
+    fn build_with_text_and_sigs(self, text: String, signatures: Vec<Sig>) -> RevocationDocument {
         RevocationDocument {
             text,
             currency: self.currency.to_string(),
@@ -178,13 +174,13 @@ impl<'a> RevocationDocumentBuilder<'a> {
 
 impl<'a> DocumentBuilder for RevocationDocumentBuilder<'a> {
     type Document = RevocationDocument;
-    type PrivateKey = ed25519::PrivateKey;
+    type PrivateKey = PrivKey;
 
-    fn build_with_signature(&self, signatures: Vec<ed25519::Signature>) -> RevocationDocument {
+    fn build_with_signature(&self, signatures: Vec<Sig>) -> RevocationDocument {
         self.build_with_text_and_sigs(self.generate_text(), signatures)
     }
 
-    fn build_and_sign(&self, private_keys: Vec<ed25519::PrivateKey>) -> RevocationDocument {
+    fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> RevocationDocument {
         let (text, signatures) = self.build_signed_text(private_keys);
         self.build_with_text_and_sigs(text, signatures)
     }
@@ -219,7 +215,7 @@ impl StandardTextDocumentParser for RevocationDocumentParser {
         doc: &str,
         body: &str,
         currency: &str,
-        signatures: Vec<ed25519::Signature>,
+        signatures: Vec<Sig>,
     ) -> Result<V10Document, V10DocumentParsingError> {
         if let Some(caps) = REVOCATION_REGEX.captures(body) {
             let issuer = &caps["issuer"];
@@ -229,10 +225,10 @@ impl StandardTextDocumentParser for RevocationDocumentParser {
 
             // Regex match so should not fail.
             // TODO : Test it anyway
-            let issuer = ed25519::PublicKey::from_base58(issuer).unwrap();
+            let issuer = PubKey::Ed25519(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();
+            let identity_sig = Sig::Ed25519(Signature::from_base64(identity_sig).unwrap());
 
             Ok(V10Document::Revocation(Box::new(RevocationDocument {
                 text: doc.to_owned(),
@@ -259,26 +255,29 @@ mod tests {
 
     #[test]
     fn generate_real_document() {
-        let pubkey = ed25519::PublicKey::from_base58(
-            "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV",
-        ).unwrap();
+        let pubkey = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV")
+                .unwrap(),
+        );
 
-        let prikey = ed25519::PrivateKey::from_base58(
-            "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\
-             iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
-        ).unwrap();
+        let prikey = PrivKey::Ed25519(
+            ed25519::PrivateKey::from_base58(
+                "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\
+                 iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
+            ).unwrap(),
+        );
 
-        let sig = ed25519::Signature::from_base64(
+        let sig = Sig::Ed25519(ed25519::Signature::from_base64(
             "XXOgI++6qpY9O31ml/FcfbXCE6aixIrgkT5jL7kBle3YOMr+8wrp7Rt+z9hDVjrNfYX2gpeJsuMNfG4T/fzVDQ==",
-        ).unwrap();
+        ).unwrap());
 
         let identity_blockstamp = Blockstamp::from_string(
             "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
         ).unwrap();
 
-        let identity_sig = ed25519::Signature::from_base64(
+        let identity_sig = Sig::Ed25519(ed25519::Signature::from_base64(
             "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
-        ).unwrap();
+        ).unwrap());
 
         let builder = RevocationDocumentBuilder {
             currency: "g1",
@@ -329,9 +328,9 @@ IdtySignature: 1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnex
 
         let currency = "g1";
 
-        let signatures = vec![Signature::from_base64(
+        let signatures = vec![Sig::Ed25519(ed25519::Signature::from_base64(
 "XXOgI++6qpY9O31ml/FcfbXCE6aixIrgkT5jL7kBle3YOMr+8wrp7Rt+z9hDVjrNfYX2gpeJsuMNfG4T/fzVDQ=="
-        ).unwrap(),];
+        ).unwrap())];
 
         let doc =
             RevocationDocumentParser::parse_standard(doc, body, currency, signatures).unwrap();
diff --git a/documents/blockchain/v10/documents/transaction.rs b/documents/blockchain/v10/documents/transaction.rs
index 992640c8a6ce937f77e9e703803fa1791f6a8835..5a3483bcdc0727574745673768dd631d17456f67 100644
--- a/documents/blockchain/v10/documents/transaction.rs
+++ b/documents/blockchain/v10/documents/transaction.rs
@@ -19,7 +19,7 @@ extern crate serde;
 
 use std::ops::Deref;
 
-use duniter_crypto::keys::{ed25519, PublicKey};
+use duniter_crypto::keys::*;
 use regex::Regex;
 use regex::RegexBuilder;
 
@@ -62,7 +62,7 @@ lazy_static! {
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum TransactionInput {
     /// Universal Dividend Input
-    D(isize, usize, ed25519::PublicKey, u64),
+    D(isize, usize, PubKey, u64),
     /// Previous Transaction Input
     T(isize, usize, String, usize),
 }
@@ -91,12 +91,14 @@ impl TransactionInput {
             Ok(TransactionInput::D(
                 amount.parse().expect("fail to parse input amount !"),
                 base.parse().expect("fail to parse input base !"),
-                ed25519::PublicKey::from_base58(pubkey).expect("fail to parse input pubkey !"),
+                PubKey::Ed25519(
+                    ed25519::PublicKey::from_base58(pubkey).expect("fail to parse input pubkey !"),
+                ),
                 block_number
                     .parse()
                     .expect("fail to parse input block_number !"),
             ))
-        //Ok(TransactionInput::D(10, 0, PublicKey::from_base58("FD9wujR7KABw88RyKEGBYRLz8PA6jzVCbcBAsrBXBqSa").unwrap(), 0))
+        //Ok(TransactionInput::D(10, 0, PubKey::Ed25519(ed25519::PublicKey::from_base58("FD9wujR7KABw88RyKEGBYRLz8PA6jzVCbcBAsrBXBqSa").unwrap(), 0)))
         } else if let Some(caps) = T_INPUT_REGEX.captures(source) {
             let amount = &caps["amount"];
             let base = &caps["base"];
@@ -205,7 +207,7 @@ impl TransactionInputUnlocks {
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum TransactionOutputCondition {
     /// The consumption of funds will require a valid signature of the specified key
-    Sig(ed25519::PublicKey),
+    Sig(PubKey),
     /// The consumption of funds will require to provide a code with the hash indicated
     Xhx(String),
     /// Funds may not be consumed until the blockchain reaches the timestamp indicated.
@@ -228,10 +230,10 @@ impl ToString for TransactionOutputCondition {
 impl TransactionOutputCondition {
     fn parse_from_str(source: &str) -> Result<TransactionOutputCondition, V10DocumentParsingError> {
         if let Some(caps) = OUTPUT_COND_SIG_REGEX.captures(source) {
-            Ok(TransactionOutputCondition::Sig(
+            Ok(TransactionOutputCondition::Sig(PubKey::Ed25519(
                 ed25519::PublicKey::from_base58(&caps["pubkey"])
                     .expect("fail to parse SIG TransactionOutputCondition"),
-            ))
+            )))
         } else if let Some(caps) = OUTPUT_COND_XHX_REGEX.captures(source) {
             Ok(TransactionOutputCondition::Xhx(String::from(&caps["hash"])))
         } else if let Some(caps) = OUTPUT_COND_CLTV_REGEX.captures(source) {
@@ -397,7 +399,7 @@ pub struct TransactionDocument {
     /// Locktime
     locktime: u64,
     /// Document issuer (there should be only one).
-    issuers: Vec<ed25519::PublicKey>,
+    issuers: Vec<PubKey>,
     /// Transaction inputs.
     inputs: Vec<TransactionInput>,
     /// Inputs unlocks.
@@ -407,11 +409,11 @@ pub struct TransactionDocument {
     /// Transaction comment
     comment: String,
     /// Document signature (there should be only one).
-    signatures: Vec<ed25519::Signature>,
+    signatures: Vec<Sig>,
 }
 
 impl Document for TransactionDocument {
-    type PublicKey = ed25519::PublicKey;
+    type PublicKey = PubKey;
     type CurrencyType = str;
 
     fn version(&self) -> u16 {
@@ -426,11 +428,11 @@ impl Document for TransactionDocument {
         self.blockstamp
     }
 
-    fn issuers(&self) -> &Vec<ed25519::PublicKey> {
+    fn issuers(&self) -> &Vec<PubKey> {
         &self.issuers
     }
 
-    fn signatures(&self) -> &Vec<ed25519::Signature> {
+    fn signatures(&self) -> &Vec<Sig> {
         &self.signatures
     }
 
@@ -530,7 +532,7 @@ pub struct TransactionDocumentBuilder<'a> {
     /// Locktime
     pub locktime: &'a u64,
     /// Transaction Document issuers.
-    pub issuers: &'a Vec<ed25519::PublicKey>,
+    pub issuers: &'a Vec<PubKey>,
     /// Transaction inputs.
     pub inputs: &'a Vec<TransactionInput>,
     /// Inputs unlocks.
@@ -542,11 +544,7 @@ pub struct TransactionDocumentBuilder<'a> {
 }
 
 impl<'a> TransactionDocumentBuilder<'a> {
-    fn build_with_text_and_sigs(
-        self,
-        text: String,
-        signatures: Vec<ed25519::Signature>,
-    ) -> TransactionDocument {
+    fn build_with_text_and_sigs(self, text: String, signatures: Vec<Sig>) -> TransactionDocument {
         TransactionDocument {
             text,
             currency: self.currency.to_string(),
@@ -564,13 +562,13 @@ impl<'a> TransactionDocumentBuilder<'a> {
 
 impl<'a> DocumentBuilder for TransactionDocumentBuilder<'a> {
     type Document = TransactionDocument;
-    type PrivateKey = ed25519::PrivateKey;
+    type PrivateKey = PrivKey;
 
-    fn build_with_signature(&self, signatures: Vec<ed25519::Signature>) -> TransactionDocument {
+    fn build_with_signature(&self, signatures: Vec<Sig>) -> TransactionDocument {
         self.build_with_text_and_sigs(self.generate_text(), signatures)
     }
 
-    fn build_and_sign(&self, private_keys: Vec<ed25519::PrivateKey>) -> TransactionDocument {
+    fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> TransactionDocument {
         let (text, signatures) = self.build_signed_text(private_keys);
         self.build_with_text_and_sigs(text, signatures)
     }
@@ -627,7 +625,7 @@ impl StandardTextDocumentParser for TransactionDocumentParser {
         doc: &str,
         body: &str,
         currency: &str,
-        signatures: Vec<ed25519::Signature>,
+        signatures: Vec<Sig>,
     ) -> Result<V10Document, V10DocumentParsingError> {
         let tx_regex: Regex = RegexBuilder::new(&TRANSACTION_REGEX_BUILDER)
             .size_limit(**TRANSACTION_REGEX_SIZE)
@@ -645,9 +643,9 @@ impl StandardTextDocumentParser for TransactionDocumentParser {
 
             let mut issuers = Vec::new();
             for caps in ISSUER_REGEX.captures_iter(issuers_str) {
-                issuers.push(
+                issuers.push(PubKey::Ed25519(
                     ed25519::PublicKey::from_base58(&caps["issuer"]).expect("fail to parse issuer"),
-                );
+                ));
             }
             let inputs_array: Vec<&str> = inputs.split('\n').collect();
             let mut inputs = Vec::new();
@@ -695,22 +693,24 @@ impl StandardTextDocumentParser for TransactionDocumentParser {
 mod tests {
     use super::*;
     use blockchain::{Document, VerificationResult};
-    use duniter_crypto::keys::{PrivateKey, PublicKey, Signature};
 
     #[test]
     fn generate_real_document() {
-        let pubkey = ed25519::PublicKey::from_base58(
-            "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV",
-        ).unwrap();
+        let pubkey = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV")
+                .unwrap(),
+        );
 
-        let prikey = ed25519::PrivateKey::from_base58(
-            "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\
-             iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
-        ).unwrap();
+        let prikey = PrivKey::Ed25519(
+            ed25519::PrivateKey::from_base58(
+                "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\
+                 iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
+            ).unwrap(),
+        );
 
-        let sig = ed25519::Signature::from_base64(
+        let sig = Sig::Ed25519(ed25519::Signature::from_base64(
             "pRQeKlzCsvPNmYAAkEP5jPPQO1RwrtFMRfCajEfkkrG0UQE0DhoTkxG3Zs2JFmvAFLw67pn1V5NQ08zsSfJkBg==",
-        ).unwrap();
+        ).unwrap());
 
         let block = Blockstamp::from_string(
             "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
@@ -850,15 +850,15 @@ Comment: -----@@@----- (why not this comment?)
         let currency = "duniter_unit_test_currency";
 
         let signatures = vec![
-            Signature::from_base64(
+            Sig::Ed25519(ed25519::Signature::from_base64(
 "kL59C1izKjcRN429AlKdshwhWbasvyL7sthI757zm1DfZTdTIctDWlKbYeG/tS7QyAgI3gcfrTHPhu1E1lKCBw=="
-        ).expect("fail to parse test signature"),
-            Signature::from_base64(
+        ).expect("fail to parse test signature")),
+            Sig::Ed25519(ed25519::Signature::from_base64(
 "e3LpgB2RZ/E/BCxPJsn+TDDyxGYzrIsMyDt//KhJCjIQD6pNUxr5M5jrq2OwQZgwmz91YcmoQ2XRQAUDpe4BAw=="
-            ).expect("fail to parse test signature"),
-            Signature::from_base64(
+            ).expect("fail to parse test signature")),
+            Sig::Ed25519(ed25519::Signature::from_base64(
 "w69bYgiQxDmCReB0Dugt9BstXlAKnwJkKCdWvCeZ9KnUCv0FJys6klzYk/O/b9t74tYhWZSX0bhETWHiwfpWBw=="
-            ).expect("fail to parse test signature"),
+            ).expect("fail to parse test signature")),
         ];
 
         let doc = TransactionDocumentParser::parse_standard(doc, body, currency, signatures)
diff --git a/message/lib.rs b/message/lib.rs
index b0d3068ed2fc2ff89e6e3c48c4aa4be36f6fa95a..03539027ee88412e5a8af143d0864e425c7ef59a 100644
--- a/message/lib.rs
+++ b/message/lib.rs
@@ -33,7 +33,7 @@ extern crate serde_json;
 
 use std::sync::mpsc;
 
-use duniter_crypto::keys::ed25519;
+use duniter_crypto::keys::Sig;
 use duniter_dal::dal_event::DALEvent;
 use duniter_dal::dal_requests::{DALRequest, DALResponse};
 use duniter_documents::blockchain::BlockchainProtocol;
@@ -65,7 +65,7 @@ pub enum DuniterMessage {
     /// Request to the pow module
     ProverRequest(BlockId, Hash),
     /// Pow module response
-    ProverResponse(BlockId, ed25519::Signature, u64),
+    ProverResponse(BlockId, Sig, u64),
     /// Client API event
     ReceiveDocsFromClient(Vec<BlockchainProtocol>),
     /// Stop signal
diff --git a/module/lib.rs b/module/lib.rs
index 75640b34d81fc9b912b0e5a2f77947954434cd9a..a75136830777356f024887772dff63f1fff6e54c 100644
--- a/module/lib.rs
+++ b/module/lib.rs
@@ -27,7 +27,7 @@ extern crate duniter_crypto;
 extern crate serde;
 extern crate serde_json;
 
-use duniter_crypto::keys::KeyPair;
+use duniter_crypto::keys::{KeyPair, KeyPairEnum};
 use serde::ser::{Serialize, SerializeStruct, Serializer};
 use std::fmt::Debug;
 use std::sync::mpsc;
@@ -225,17 +225,17 @@ pub enum RequiredKeys {
     None(),
 }
 
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
 /// Contains the keys the module needs
-pub enum RequiredKeysContent<K: KeyPair> {
+pub enum RequiredKeysContent {
     /// Contains the member keypair (private key included).
-    MemberKeyPair(Option<K>),
+    MemberKeyPair(Option<KeyPairEnum>),
     /// Contains the member public key.
-    MemberPublicKey(Option<K::PublicKey>),
+    MemberPublicKey(Option<<KeyPairEnum as KeyPair>::PublicKey>),
     /// Contains the network keypair (private key included).
-    NetworkKeyPair(K),
+    NetworkKeyPair(KeyPairEnum),
     /// Contains the network public key.
-    NetworkPublicKey(K::PublicKey),
+    NetworkPublicKey(<KeyPairEnum as KeyPair>::PublicKey),
     /// Does not contain any keys
     None(),
 }
@@ -252,7 +252,7 @@ pub enum ModulePriority {
 }
 
 /// All Duniter-rs modules must implement this trait.
-pub trait DuniterModule<K: KeyPair, M: ModuleMessage> {
+pub trait DuniterModule<M: ModuleMessage> {
     /// Returns the module identifier
     fn id() -> ModuleId;
     /// Returns the module priority
@@ -265,7 +265,7 @@ pub trait DuniterModule<K: KeyPair, M: ModuleMessage> {
     fn start(
         soft_name: &str,
         soft_version: &str,
-        keys: RequiredKeysContent<K>,
+        keys: RequiredKeysContent,
         conf: &DuniterConf,
         module_conf: &serde_json::Value,
         main_sender: mpsc::Sender<RooterThreadMessage<M>>,
diff --git a/network/lib.rs b/network/lib.rs
index 9b477cb2a3549deb248f757ccf3bf7ea1d621eca..8130c8e90fd4a81849cf8e0a63d5750b0c56e1fe 100644
--- a/network/lib.rs
+++ b/network/lib.rs
@@ -40,7 +40,7 @@ use self::network_head::NetworkHead;
 use self::network_peer::NetworkPeer;
 use crypto::digest::Digest;
 use crypto::sha2::Sha256;
-use duniter_crypto::keys::{ed25519, PublicKey};
+use duniter_crypto::keys::*;
 use duniter_documents::blockchain::v10::documents::{
     BlockDocument, CertificationDocument, IdentityDocument, MembershipDocument, RevocationDocument,
     TransactionDocument,
@@ -75,13 +75,16 @@ impl<'a> From<&'a str> for NodeUUID {
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 /// Complete identifier of a duniter node.
-pub struct NodeFullId(pub NodeUUID, pub ed25519::PublicKey);
+pub struct NodeFullId(pub NodeUUID, pub PubKey);
 
 impl Default for NodeFullId {
     fn default() -> NodeFullId {
         NodeFullId(
             NodeUUID::default(),
-            PublicKey::from_base58("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA").unwrap(),
+            PubKey::Ed25519(
+                ed25519::PublicKey::from_base58("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
+                    .unwrap(),
+            ),
         )
     }
 }
@@ -290,8 +293,10 @@ mod tests {
 
     #[test]
     fn parse_endpoint() {
-        let issuer =
-            PublicKey::from_base58("D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx").unwrap();
+        let issuer = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx")
+                .unwrap(),
+        );
         let node_id = NodeUUID(u32::from_str_radix("c1c39a0a", 16).unwrap());
         let full_id = NodeFullId(node_id, issuer);
         assert_eq!(
@@ -314,8 +319,10 @@ mod tests {
 
     #[test]
     fn parse_endpoint2() {
-        let issuer =
-            PublicKey::from_base58("5gJYnQp8v7bWwk7EWRoL8vCLof1r3y9c6VDdnGSM1GLv").unwrap();
+        let issuer = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("5gJYnQp8v7bWwk7EWRoL8vCLof1r3y9c6VDdnGSM1GLv")
+                .unwrap(),
+        );
         let node_id = NodeUUID(u32::from_str_radix("cb06a19b", 16).unwrap());
         let full_id = NodeFullId(node_id, issuer);
         assert_eq!(
diff --git a/network/network_endpoint.rs b/network/network_endpoint.rs
index 53e3ae82947ebecdfca1c757d1164e39096e9498..759088e1df601bfefc22737fabca266131eba354 100644
--- a/network/network_endpoint.rs
+++ b/network/network_endpoint.rs
@@ -25,7 +25,7 @@ extern crate serde_json;
 
 use self::regex::Regex;
 use super::{NodeFullId, NodeUUID};
-use duniter_crypto::keys::ed25519;
+use duniter_crypto::keys::PubKey;
 use duniter_documents::Hash;
 
 lazy_static! {
@@ -50,7 +50,7 @@ pub struct NetworkEndpointV1 {
     /// Node unique identifier
     pub node_id: Option<NodeUUID>,
     /// Public key of the node declaring this endpoint
-    pub issuer: ed25519::PublicKey,
+    pub issuer: PubKey,
     /// NodeFullID hash
     pub hash_full_id: Option<Hash>,
     /// hostname
@@ -101,7 +101,7 @@ impl NetworkEndpoint {
         }
     }
     /// Accessors providing node public key
-    pub fn pubkey(&self) -> ed25519::PublicKey {
+    pub fn pubkey(&self) -> PubKey {
         match *self {
             NetworkEndpoint::V1(ref ep) => ep.issuer,
             _ => panic!("Endpoint version is not supported !"),
@@ -177,7 +177,7 @@ impl NetworkEndpoint {
     /// Parse Endpoint from rax format
     pub fn parse_from_raw(
         raw_endpoint: &str,
-        issuer: ed25519::PublicKey,
+        issuer: PubKey,
         status: u32,
         last_check: u64,
     ) -> Option<NetworkEndpoint> {
diff --git a/network/network_head.rs b/network/network_head.rs
index 3e248386dd0528e25d7aef123a4ac9c62eb3f220..efd2dad5ade55ede0b08e1312223e62741856af9 100644
--- a/network/network_head.rs
+++ b/network/network_head.rs
@@ -20,7 +20,7 @@ extern crate duniter_documents;
 extern crate serde_json;
 
 use super::{NodeFullId, NodeUUID};
-use duniter_crypto::keys::{ed25519, PublicKey, Signature};
+use duniter_crypto::keys::*;
 use duniter_documents::Blockstamp;
 use std::cmp::Ordering;
 use std::collections::HashMap;
@@ -34,7 +34,7 @@ pub struct NetworkHeadMessageV2 {
     /// Head version
     pub version: usize,
     /// Head pubkey
-    pub pubkey: ed25519::PublicKey,
+    pub pubkey: PubKey,
     /// Head blockstamp
     pub blockstamp: Blockstamp,
     /// Head node id
@@ -151,11 +151,11 @@ impl NetworkHeadMessage {
     /// Parse head from string
     fn from_str(source: &str) -> Option<NetworkHeadMessage> {
         let source_array: Vec<&str> = source.split(':').collect();
-        if let Ok(pubkey) = PublicKey::from_base58(&source_array[3].to_string()) {
+        if let Ok(pubkey) = ed25519::PublicKey::from_base58(&source_array[3].to_string()) {
             Some(NetworkHeadMessage::V2(NetworkHeadMessageV2 {
                 api: source_array[0].to_string(),
                 version: source_array[2].parse().unwrap(),
-                pubkey,
+                pubkey: PubKey::Ed25519(pubkey),
                 blockstamp: Blockstamp::from_string(source_array[4]).unwrap(),
                 node_uuid: NodeUUID(u32::from_str_radix(source_array[5], 16).unwrap()),
                 software: source_array[6].to_string(),
@@ -191,7 +191,7 @@ impl NetworkHeadMessage {
         }
     }
     /// Get head issuer public key
-    fn _pubkey(&self) -> ed25519::PublicKey {
+    fn _pubkey(&self) -> PubKey {
         match *self {
             NetworkHeadMessage::V2(ref head_message_v2) => head_message_v2.pubkey,
             _ => panic!("This HEAD version is not supported !"),
@@ -244,11 +244,11 @@ pub struct NetworkHeadV2 {
     /// Head V1 Message
     pub message: NetworkHeadMessage,
     /// signature of V1 Message
-    pub sig: ed25519::Signature,
+    pub sig: Sig,
     /// Head V2 Message
     pub message_v2: NetworkHeadMessage,
     /// signature of V2 Message
-    pub sig_v2: ed25519::Signature,
+    pub sig_v2: Sig,
     /// Head step
     pub step: u32,
     /// Head issuer uid
@@ -327,7 +327,7 @@ impl NetworkHead {
         }
     }
     /// Get pubkey of head issuer
-    pub fn pubkey(&self) -> ed25519::PublicKey {
+    pub fn pubkey(&self) -> PubKey {
         match *self {
             NetworkHead::V2(ref head_v2) => match head_v2.message_v2 {
                 NetworkHeadMessage::V2(ref head_message_v2) => head_message_v2.pubkey,
@@ -361,10 +361,11 @@ impl NetworkHead {
     pub fn verify(&self) -> bool {
         match *self {
             NetworkHead::V2(ref head_v2) => {
-                let pubkey: ed25519::PublicKey =
-                    PublicKey::from_base58(&self.pubkey().to_string()).unwrap();
-                pubkey.verify(head_v2.message.to_string().as_bytes(), &head_v2.sig)
-                    && pubkey.verify(head_v2.message_v2.to_string().as_bytes(), &head_v2.sig_v2)
+                self.pubkey()
+                    .verify(head_v2.message.to_string().as_bytes(), &head_v2.sig)
+                    && self
+                        .pubkey()
+                        .verify(head_v2.message_v2.to_string().as_bytes(), &head_v2.sig_v2)
             }
             _ => panic!("This HEAD version is not supported !"),
         }
@@ -409,11 +410,16 @@ impl NetworkHead {
         match message {
             NetworkHeadMessage::V2(_) => Some(NetworkHead::V2(Box::new(NetworkHeadV2 {
                 message,
-                sig: Signature::from_base64(source.get("sig")?.as_str().unwrap()).unwrap(),
+                sig: Sig::Ed25519(
+                    ed25519::Signature::from_base64(source.get("sig")?.as_str().unwrap()).unwrap(),
+                ),
                 message_v2: NetworkHeadMessage::from_str(
                     source.get("messageV2")?.as_str().unwrap(),
                 )?,
-                sig_v2: Signature::from_base64(source.get("sigV2")?.as_str().unwrap()).unwrap(),
+                sig_v2: Sig::Ed25519(
+                    ed25519::Signature::from_base64(source.get("sigV2")?.as_str().unwrap())
+                        .unwrap(),
+                ),
                 step: source.get("step")?.as_u64().unwrap() as u32,
                 uid: None,
             }))),
diff --git a/network/network_peer.rs b/network/network_peer.rs
index 5efe5ed188f3e4e939ac08ffdc67eb681c3d97b7..c2eb4d33e6e51fab1d85334a173247f37268044b 100644
--- a/network/network_peer.rs
+++ b/network/network_peer.rs
@@ -23,7 +23,7 @@ extern crate serde;
 extern crate serde_json;
 
 use super::network_endpoint::NetworkEndpoint;
-use duniter_crypto::keys::ed25519;
+use duniter_crypto::keys::*;
 use duniter_documents::Blockstamp;
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -32,7 +32,7 @@ pub struct NetworkPeerV10 {
     /// Peer card Blockstamp
     pub blockstamp: Blockstamp,
     /// Peer card issuer
-    pub issuer: ed25519::PublicKey,
+    pub issuer: PubKey,
     /// Peer card endpoints list
     pub endpoints: Vec<NetworkEndpoint>,
 }
@@ -62,7 +62,7 @@ impl NetworkPeer {
         }
     }
     /// Get peer card issuer
-    pub fn issuer(&self) -> ed25519::PublicKey {
+    pub fn issuer(&self) -> PubKey {
         match *self {
             NetworkPeer::V10(ref peer_v10) => peer_v10.issuer,
             _ => panic!("Peer version is not supported !"),
diff --git a/tui/lib.rs b/tui/lib.rs
index a3d54cca706665d11c6411dddd98158dd5a85acb..17d8b21e3fa57e3581dfd3f521e8ceb77624a610 100644
--- a/tui/lib.rs
+++ b/tui/lib.rs
@@ -36,7 +36,6 @@ extern crate duniter_network;
 extern crate serde_json;
 extern crate termion;
 
-use duniter_crypto::keys::ed25519;
 use duniter_dal::dal_event::DALEvent;
 use duniter_message::DuniterMessage;
 use duniter_module::*;
@@ -348,7 +347,7 @@ impl Default for TuiModule {
     }
 }
 
-impl DuniterModule<ed25519::KeyPair, DuniterMessage> for TuiModule {
+impl DuniterModule<DuniterMessage> for TuiModule {
     fn id() -> ModuleId {
         ModuleId::Str("tui")
     }
@@ -364,7 +363,7 @@ impl DuniterModule<ed25519::KeyPair, DuniterMessage> for TuiModule {
     fn start(
         _soft_name: &str,
         _soft_version: &str,
-        _keys: RequiredKeysContent<ed25519::KeyPair>,
+        _keys: RequiredKeysContent,
         _conf: &DuniterConf,
         module_conf: &serde_json::Value,
         main_sender: mpsc::Sender<RooterThreadMessage<DuniterMessage>>,
diff --git a/ws2p/ack_message.rs b/ws2p/ack_message.rs
index 07d4b4a2233e57f41cbf7a635194bb7846b54a7a..23ba4fd2ad023a2b24deb4179c53bfb68ad40e06 100644
--- a/ws2p/ack_message.rs
+++ b/ws2p/ack_message.rs
@@ -4,15 +4,14 @@ extern crate serde_json;
 
 use self::serde::ser::{Serialize, SerializeStruct, Serializer};
 use super::WS2PMessage;
-use duniter_crypto::keys::ed25519::PublicKey as ed25519PublicKey;
-use duniter_crypto::keys::PublicKey;
+use duniter_crypto::keys::*;
 
 #[derive(Debug, Clone)]
 pub struct WS2PAckMessageV1 {
     pub currency: String,
-    pub pubkey: ed25519PublicKey,
+    pub pubkey: PubKey,
     pub challenge: String,
-    pub signature: Option<duniter_crypto::keys::ed25519::Signature>,
+    pub signature: Option<Sig>,
 }
 
 impl WS2PMessage for WS2PAckMessageV1 {
@@ -25,9 +24,10 @@ impl WS2PMessage for WS2PAckMessageV1 {
             Some(signature) => signature.as_str().unwrap().to_string(),
             None => return None,
         };
-        let pubkey: ed25519PublicKey = ed25519PublicKey::from_base58(&pubkey).unwrap();
-        let signature: Option<duniter_crypto::keys::ed25519::Signature> =
-            Some(duniter_crypto::keys::Signature::from_base64(&signature).unwrap());
+        let pubkey = PubKey::Ed25519(ed25519::PublicKey::from_base58(&pubkey).unwrap());
+        let signature: Option<Sig> = Some(Sig::Ed25519(
+            ed25519::Signature::from_base64(&signature).unwrap(),
+        ));
         Some(WS2PAckMessageV1 {
             currency,
             pubkey,
diff --git a/ws2p/connect_message.rs b/ws2p/connect_message.rs
index 4b048143a38d8dd22d88dbcb95abb4989d893ea4..30bb53daf3bcbe3f1e4be1d2cbd9aa8407931f21 100644
--- a/ws2p/connect_message.rs
+++ b/ws2p/connect_message.rs
@@ -4,15 +4,14 @@ extern crate serde_json;
 
 use self::serde::ser::{Serialize, SerializeStruct, Serializer};
 use super::WS2PMessage;
-use duniter_crypto::keys::ed25519::PublicKey as ed25519PublicKey;
-use duniter_crypto::keys::PublicKey;
+use duniter_crypto::keys::*;
 
 #[derive(Debug, Clone)]
 pub struct WS2PConnectMessageV1 {
     pub currency: String,
-    pub pubkey: ed25519PublicKey,
+    pub pubkey: PubKey,
     pub challenge: String,
-    pub signature: Option<duniter_crypto::keys::ed25519::Signature>,
+    pub signature: Option<Sig>,
 }
 
 impl WS2PMessage for WS2PConnectMessageV1 {
@@ -29,9 +28,10 @@ impl WS2PMessage for WS2PConnectMessageV1 {
             Some(signature) => signature.as_str().unwrap().to_string(),
             None => return None,
         };
-        let pubkey: ed25519PublicKey = ed25519PublicKey::from_base58(&pubkey).unwrap();
-        let signature: Option<duniter_crypto::keys::ed25519::Signature> =
-            Some(duniter_crypto::keys::Signature::from_base64(&signature).unwrap());
+        let pubkey = PubKey::Ed25519(ed25519::PublicKey::from_base58(&pubkey).unwrap());
+        let signature = Some(Sig::Ed25519(
+            ed25519::Signature::from_base64(&signature).unwrap(),
+        ));
         Some(WS2PConnectMessageV1 {
             currency,
             pubkey,
@@ -49,21 +49,6 @@ impl WS2PMessage for WS2PConnectMessageV1 {
         self.pubkey
             .verify(self.to_raw().as_bytes(), &self.signature.unwrap())
     }
-    /*fn parse_and_verify(v: serde_json::Value, currency: String) -> bool {
-        let pubkey = match v.get("pub") {
-            Some(pubkey) => pubkey.as_str().unwrap().to_string(),
-            None => return false,
-        };
-        let challenge = match v.get("pub") {
-            Some(challenge) => challenge.as_str().unwrap().to_string(),
-            None => return false,
-        };
-        let signature  = match v.get("pub") {
-            Some(signature) => signature.as_str().unwrap().to_string(),
-            None => return false,
-        };
-        ed25519PublicKey::from_base58(&pubkey).unwrap().verify(format!("WS2P:CONNECT:{}:{}:{}", currency, pubkey, challenge),&duniter_keys::Signature::from_base64(&signature).unwrap())
-    }*/
 }
 
 impl Serialize for WS2PConnectMessageV1 {
diff --git a/ws2p/lib.rs b/ws2p/lib.rs
index 2376fcba1c2da2ef8fb63586d4334fc0062eda77..c4dffa53f807810445890dcb8adabf07bb7aee30 100644
--- a/ws2p/lib.rs
+++ b/ws2p/lib.rs
@@ -51,8 +51,7 @@ use std::sync::mpsc;
 use std::thread;
 use std::time::{Duration, SystemTime, UNIX_EPOCH};
 
-use duniter_crypto::keys::ed25519::Signature;
-use duniter_crypto::keys::{ed25519, KeyPair, PrivateKey, PublicKey};
+use duniter_crypto::keys::*;
 use duniter_dal::dal_event::DALEvent;
 use duniter_dal::dal_requests::{DALReqBlockchain, DALRequest, DALResBlockchain, DALResponse};
 use duniter_dal::parsers::blocks::parse_json_block;
@@ -129,7 +128,7 @@ pub struct WS2PModule {}
 pub struct WS2PModuleDatas {
     pub followers: Vec<mpsc::Sender<DuniterMessage>>,
     pub currency: Option<String>,
-    pub key_pair: Option<ed25519::KeyPair>,
+    pub key_pair: Option<KeyPairEnum>,
     pub conf: Option<WS2PConf>,
     pub main_thread_channel: (
         mpsc::Sender<WS2PThreadSignal>,
@@ -142,7 +141,7 @@ pub struct WS2PModuleDatas {
     pub requests_awaiting_response: HashMap<ModuleReqId, (NetworkRequest, NodeFullId, SystemTime)>,
     pub heads_cache: HashMap<NodeFullId, NetworkHead>,
     pub my_head: Option<NetworkHead>,
-    pub uids_cache: HashMap<ed25519::PublicKey, String>,
+    pub uids_cache: HashMap<PubKey, String>,
 }
 
 #[derive(Debug)]
@@ -154,7 +153,7 @@ pub enum WS2PThreadSignal {
 pub trait WS2PMessage: Sized {
     fn parse(v: &serde_json::Value, currency: String) -> Option<Self>;
     fn to_raw(&self) -> String;
-    fn sign(&self, key_pair: ed25519::KeyPair) -> Signature {
+    fn sign(&self, key_pair: KeyPairEnum) -> Sig {
         key_pair.sign(self.to_raw().as_bytes())
     }
     fn verify(&self) -> bool;
@@ -187,7 +186,7 @@ impl Default for WS2PModule {
     }
 }
 
-impl DuniterModule<ed25519::KeyPair, DuniterMessage> for WS2PModule {
+impl DuniterModule<DuniterMessage> for WS2PModule {
     fn id() -> ModuleId {
         ModuleId::Str("ws2p")
     }
@@ -208,7 +207,7 @@ impl DuniterModule<ed25519::KeyPair, DuniterMessage> for WS2PModule {
     fn start(
         soft_name: &str,
         soft_version: &str,
-        keys: RequiredKeysContent<ed25519::KeyPair>,
+        keys: RequiredKeysContent,
         duniter_conf: &DuniterConf,
         module_conf: &serde_json::Value,
         rooter_sender: mpsc::Sender<RooterThreadMessage<DuniterMessage>>,
@@ -927,13 +926,13 @@ impl WS2PModuleDatas {
                 let array_peers = peers.as_array().expect("Conf: Fail to parse conf file !");
                 for peer in array_peers {
                     let pubkey = match peer.get("pubkey") {
-                        Some(pubkey) => {
-                            PublicKey::from_base58(
+                        Some(pubkey) => PubKey::Ed25519(
+                            ed25519::PublicKey::from_base58(
                                 pubkey
                                     .as_str()
                                     .expect("WS2PConf Error : fail to parse sync endpoint pubkey"),
-                            ).expect("WS2PConf Error : fail to parse sync endpoint pubkey")
-                        }
+                            ).expect("WS2PConf Error : fail to parse sync endpoint pubkey"),
+                        ),
                         None => panic!(
                             "Fail to load ws2p conf : \
                              WrongFormat : not found pubkey field !"
@@ -999,7 +998,7 @@ impl WS2PModuleDatas {
         }
     }
     pub fn generate_my_head(
-        network_keypair: &ed25519::KeyPair,
+        network_keypair: &KeyPairEnum,
         conf: &WS2PConf,
         soft_name: &str,
         soft_version: &str,
@@ -1009,7 +1008,7 @@ impl WS2PModuleDatas {
         let message = NetworkHeadMessage::V2(NetworkHeadMessageV2 {
             api: String::from("WS2POCA"),
             version: 1,
-            pubkey: network_keypair.pubkey,
+            pubkey: network_keypair.public_key(),
             blockstamp: *my_current_blockstamp,
             node_uuid: conf.node_id,
             software: String::from(soft_name),
@@ -1021,7 +1020,7 @@ impl WS2PModuleDatas {
         let message_v2 = NetworkHeadMessage::V2(NetworkHeadMessageV2 {
             api: String::from("WS2POCA"),
             version: 2,
-            pubkey: network_keypair.pubkey,
+            pubkey: network_keypair.public_key(),
             blockstamp: *my_current_blockstamp,
             node_uuid: conf.node_id,
             software: String::from(soft_name),
@@ -1032,10 +1031,12 @@ impl WS2PModuleDatas {
         });
         NetworkHead::V2(Box::new(NetworkHeadV2 {
             message: message.clone(),
-            sig: network_keypair.privkey.sign(message.to_string().as_bytes()),
+            sig: network_keypair
+                .private_key()
+                .sign(message.to_string().as_bytes()),
             message_v2: message_v2.clone(),
             sig_v2: network_keypair
-                .privkey
+                .private_key()
                 .sign(message_v2.to_string().as_bytes()),
             step: 0,
             uid: my_uid,
@@ -1436,7 +1437,7 @@ impl WS2PModuleDatas {
         // Create CONNECT Message
         let mut connect_message = WS2PConnectMessageV1 {
             currency: self.currency.clone().unwrap(),
-            pubkey: self.key_pair.unwrap().pubkey,
+            pubkey: self.key_pair.unwrap().public_key(),
             challenge: conn_meta_datas.challenge.clone(),
             signature: None,
         };
@@ -1676,8 +1677,8 @@ mod tests {
     extern crate duniter_module;
     extern crate duniter_network;
 
-    use self::duniter_crypto::keys::ed25519;
     use self::duniter_crypto::keys::PublicKey;
+    use self::duniter_crypto::keys::*;
     use self::duniter_dal::parsers::blocks::parse_json_block;
     use self::duniter_documents::blockchain::v10::documents::BlockDocument;
     use self::duniter_module::DuniterModule;
@@ -1864,8 +1865,10 @@ mod tests {
 
         let mut endpoint = NetworkEndpoint::parse_from_raw(
             "WS2P cb06a19b g1.imirhil.fr 53012 /",
-            ed25519::PublicKey::from_base58("5gJYnQp8v7bWwk7EWRoL8vCLof1r3y9c6VDdnGSM1GLv")
-                .unwrap(),
+            PubKey::Ed25519(
+                ed25519::PublicKey::from_base58("5gJYnQp8v7bWwk7EWRoL8vCLof1r3y9c6VDdnGSM1GLv")
+                    .unwrap(),
+            ),
             1,
             current_time.as_secs(),
         ).expect("Failt to parse test endpoint !");
diff --git a/ws2p/ok_message.rs b/ws2p/ok_message.rs
index 9572c822c9761930a622a9cf0eca9ceff631acc4..e0c5c54ac30b5c1899044420d589714acfa086b1 100644
--- a/ws2p/ok_message.rs
+++ b/ws2p/ok_message.rs
@@ -4,15 +4,14 @@ extern crate serde_json;
 
 use self::serde::ser::{Serialize, SerializeStruct, Serializer};
 use super::WS2PMessage;
-use duniter_crypto::keys::ed25519::PublicKey as ed25519PublicKey;
-use duniter_crypto::keys::PublicKey;
+use duniter_crypto::keys::*;
 
 #[derive(Debug, Clone)]
 pub struct WS2POkMessageV1 {
     pub currency: String,
-    pub pubkey: ed25519PublicKey,
+    pub pubkey: PubKey,
     pub challenge: String,
-    pub signature: Option<duniter_crypto::keys::ed25519::Signature>,
+    pub signature: Option<Sig>,
 }
 
 impl WS2PMessage for WS2POkMessageV1 {
@@ -24,13 +23,14 @@ impl WS2PMessage for WS2POkMessageV1 {
                 .to_string(),
             None => return None,
         };
-        let pubkey: ed25519PublicKey = ed25519PublicKey::from_base58(
-            "969qRJs8KhsnkyzqarpL4RKZGMdVKNbZgu8fhsigM7Lj",
-        ).expect("fail to create default pubkey !");
-        let signature: Option<duniter_crypto::keys::ed25519::Signature> = Some(
+        let pubkey: PubKey = PubKey::Ed25519(
+            ed25519::PublicKey::from_base58("969qRJs8KhsnkyzqarpL4RKZGMdVKNbZgu8fhsigM7Lj")
+                .expect("fail to create default pubkey !"),
+        );
+        let signature: Option<Sig> = Some(Sig::Ed25519(
             duniter_crypto::keys::Signature::from_base64(&signature)
                 .expect("fail to parse signature of OK message !"),
-        );
+        ));
         Some(WS2POkMessageV1 {
             currency,
             pubkey,
diff --git a/ws2p/test.db b/ws2p/test.db
index e14c9a19404e0e792e709cf7079a7e068f3cfb13..8959a44d9e3c611a28067504c61ee857cbf47dfb 100644
Binary files a/ws2p/test.db and b/ws2p/test.db differ
diff --git a/ws2p/ws2p_connection.rs b/ws2p/ws2p_connection.rs
index cad367e93a8b85eaf569f59b14822eb9cb909f08..6305b29d4a26cd70275739a89d98b23af97ca689 100644
--- a/ws2p/ws2p_connection.rs
+++ b/ws2p/ws2p_connection.rs
@@ -1,8 +1,7 @@
 extern crate serde_json;
 extern crate websocket;
 
-use duniter_crypto::keys::ed25519;
-use duniter_crypto::keys::PublicKey;
+use duniter_crypto::keys::*;
 use duniter_dal::parsers::blocks::parse_json_block;
 use duniter_module::ModuleReqId;
 use duniter_network::network_endpoint::{NetworkEndpoint, NetworkEndpointApi};
@@ -122,7 +121,7 @@ pub enum WS2PCloseConnectionReason {
 pub struct WS2PConnectionMetaData {
     pub state: WS2PConnectionState,
     pub remote_uuid: Option<NodeUUID>,
-    pub remote_pubkey: Option<ed25519::PublicKey>,
+    pub remote_pubkey: Option<PubKey>,
     pub challenge: String,
     pub remote_challenge: String,
     pub current_blockstamp: Option<(u32, String)>,
@@ -132,7 +131,7 @@ pub struct WS2PConnectionMetaData {
 pub struct WS2PDatasForListeningThread {
     pub conn_meta_datas: WS2PConnectionMetaData,
     pub currency: String,
-    pub key_pair: ed25519::KeyPair,
+    pub key_pair: KeyPairEnum,
 }
 
 impl WS2PConnectionMetaData {
@@ -159,7 +158,7 @@ impl WS2PConnectionMetaData {
     pub fn parse_and_check_incoming_message(
         &mut self,
         currency: &str,
-        key_pair: ed25519::KeyPair,
+        key_pair: KeyPairEnum,
         m: &serde_json::Value,
     ) -> WS2PConnectionMessagePayload {
         if let Some(s) = m.get("auth") {
@@ -176,7 +175,7 @@ impl WS2PConnectionMetaData {
                                     self.remote_challenge = message.challenge.clone();
                                     let mut response = WS2PAckMessageV1 {
                                         currency: currency.to_string(),
-                                        pubkey: key_pair.pubkey,
+                                        pubkey: key_pair.public_key(),
                                         challenge: self.remote_challenge.clone(),
                                         signature: None,
                                     };
@@ -209,7 +208,7 @@ impl WS2PConnectionMetaData {
                             };
                             let mut response = WS2POkMessageV1 {
                                 currency: currency.to_string(),
-                                pubkey: key_pair.pubkey,
+                                pubkey: key_pair.public_key(),
                                 challenge: self.challenge.to_string(),
                                 signature: None,
                             };
@@ -359,8 +358,9 @@ impl WS2PConnectionMetaData {
     ) -> WS2PConnectionMessagePayload {
         match body.get("peer") {
             Some(peer) => match peer.get("pubkey") {
-                Some(raw_pubkey) => match PublicKey::from_base58(raw_pubkey.as_str().unwrap_or(""))
-                {
+                Some(raw_pubkey) => match ed25519::PublicKey::from_base58(
+                    raw_pubkey.as_str().unwrap_or(""),
+                ) {
                     Ok(pubkey) => {
                         let mut ws2p_endpoints: Vec<NetworkEndpoint> = Vec::new();
                         match peer.get("endpoints") {
@@ -369,7 +369,7 @@ impl WS2PConnectionMetaData {
                                     for endpoint in array_endpoints {
                                         if let Some(ep) = NetworkEndpoint::parse_from_raw(
                                             endpoint.as_str().unwrap_or(""),
-                                            pubkey,
+                                            PubKey::Ed25519(pubkey),
                                             0,
                                             0,
                                         ) {
diff --git a/ws2p/ws2p_db.rs b/ws2p/ws2p_db.rs
index ea6b9c41a3fbdf8cf962a8cbd93660d501ce8756..5ffad9a7d8627903ef91d41e5c503b987a38cdc8 100644
--- a/ws2p/ws2p_db.rs
+++ b/ws2p/ws2p_db.rs
@@ -7,7 +7,7 @@ extern crate serde_json;
 extern crate sqlite;
 extern crate websocket;
 
-use duniter_crypto::keys::{ed25519, PublicKey};
+use duniter_crypto::keys::*;
 use duniter_network::network_endpoint::{NetworkEndpoint, NetworkEndpointApi};
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -70,7 +70,8 @@ pub fn get_endpoints_for_api(
         .expect("get_endpoints_for_api() : Error in cursor.next()")
     {
         let raw_ep = row[6].as_string().unwrap().to_string();
-        let ep_issuer = ed25519::PublicKey::from_base58(row[3].as_string().unwrap()).unwrap();
+        let ep_issuer =
+            PubKey::Ed25519(ed25519::PublicKey::from_base58(row[3].as_string().unwrap()).unwrap());
         let mut ep = match NetworkEndpoint::parse_from_raw(
             &raw_ep,
             ep_issuer,