diff --git a/lib/crypto/src/bases/b58.rs b/lib/crypto/src/bases/b58.rs
index 592f2076830d8e61573ed339cf1552a684805508..f2193964c4989b40c9d3def9b936a9a1a8c7d682 100644
--- a/lib/crypto/src/bases/b58.rs
+++ b/lib/crypto/src/bases/b58.rs
@@ -24,7 +24,8 @@ pub trait ToBase58 {
 }
 
 /// Create an array of 32 bytes from a Base58 string.
-pub fn str_base58_to_32bytes(base58_data: &str) -> Result<[u8; 32], BaseConvertionError> {
+pub fn str_base58_to_32bytes(base58_data: &str) -> Result<([u8; 32], usize), BaseConvertionError> {
+    debug!("str_base58_to_32bytes({});", base58_data);
     match bs58::decode(base58_data).into_vec() {
         Ok(result) => {
             if result.len() == 32 {
@@ -32,7 +33,13 @@ pub fn str_base58_to_32bytes(base58_data: &str) -> Result<[u8; 32], BaseConverti
 
                 u8_array[..32].clone_from_slice(&result[..32]);
 
-                Ok(u8_array)
+                Ok((u8_array, 32))
+            } else if result.len() == 31 {
+                let mut u8_array = [0; 32];
+
+                u8_array[..31].clone_from_slice(&result[..31]);
+
+                Ok((u8_array, 31))
             } else {
                 Err(BaseConvertionError::InvalidLength {
                     expected: 32,
diff --git a/lib/crypto/src/keys/ed25519.rs b/lib/crypto/src/keys/ed25519.rs
index fa77c7b8d93d8318b30a264656037e93eeb485c1..a2ae5942a2e935000e4d4131a20941e88f9824dd 100644
--- a/lib/crypto/src/keys/ed25519.rs
+++ b/lib/crypto/src/keys/ed25519.rs
@@ -20,6 +20,7 @@
 //! [`KeyPairGenerator`]: struct.KeyPairGenerator.html
 
 use super::PublicKey as PublicKeyMethods;
+use super::{PubkeyFromBytesError, SigError};
 use crate::bases::b58::{bytes_to_str_base58, ToBase58};
 use crate::bases::*;
 use crate::seeds::Seed32;
@@ -28,13 +29,17 @@ use clear_on_drop::clear::Clear;
 use ring::signature::{Ed25519KeyPair as RingKeyPair, KeyPair, UnparsedPublicKey, ED25519};
 use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
 use serde::ser::{Serialize, SerializeTuple, Serializer};
+use std::convert::TryFrom;
 use std::fmt;
 use std::fmt::{Debug, Display, Formatter};
 use std::hash::{Hash, Hasher};
 use std::marker::PhantomData;
+use unwrap::unwrap;
 
-/// Size of a public key in bytes
+/// Maximal size of a public key in bytes
 pub static PUBKEY_SIZE_IN_BYTES: &usize = &32;
+/// Minimal size of a public key in bytes
+pub static PUBKEY_MIN_SIZE_IN_BYTES: &usize = &31;
 /// Size of a signature in bytes
 pub static SIG_SIZE_IN_BYTES: &usize = &64;
 
@@ -144,17 +149,55 @@ impl Eq for Signature {}
 ///
 /// [`KeyPairGenerator`]: struct.KeyPairGenerator.html
 #[derive(Copy, Clone, Deserialize, PartialEq, Eq, Hash, Serialize)]
-pub struct PublicKey(pub [u8; 32]);
+pub struct PublicKey {
+    datas: [u8; 32],
+    len: usize,
+}
+
+impl Default for PublicKey {
+    fn default() -> Self {
+        PublicKey {
+            datas: [0u8; 32],
+            len: 32,
+        }
+    }
+}
+
+impl AsRef<[u8]> for PublicKey {
+    fn as_ref(&self) -> &[u8] {
+        &self.datas[..self.len]
+    }
+}
+
+impl TryFrom<&[u8]> for PublicKey {
+    type Error = PubkeyFromBytesError;
+
+    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
+        if bytes.len() > *PUBKEY_SIZE_IN_BYTES || bytes.len() < *PUBKEY_MIN_SIZE_IN_BYTES {
+            Err(PubkeyFromBytesError::InvalidBytesLen {
+                expected: *PUBKEY_SIZE_IN_BYTES,
+                found: bytes.len(),
+            })
+        } else {
+            let mut u8_array = [0; 32];
+            u8_array[..bytes.len()].copy_from_slice(&bytes);
+            Ok(PublicKey {
+                datas: u8_array,
+                len: bytes.len(),
+            })
+        }
+    }
+}
 
 impl ToBase58 for PublicKey {
     fn to_base58(&self) -> String {
-        bytes_to_str_base58(&self.0[..])
+        bytes_to_str_base58(self.as_ref())
     }
 }
 
 impl Display for PublicKey {
     fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
-        write!(f, "{}", bytes_to_str_base58(&self.0[..]))
+        write!(f, "{}", bytes_to_str_base58(self.as_ref()))
     }
 }
 
@@ -165,22 +208,21 @@ impl Debug for PublicKey {
     }
 }
 
-use crate::keys::SigError;
-
 impl super::PublicKey for PublicKey {
     type Signature = Signature;
 
     #[inline]
     fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> {
-        Ok(PublicKey(b58::str_base58_to_32bytes(base58_data)?))
+        let (datas, len) = b58::str_base58_to_32bytes(base58_data)?;
+        Ok(PublicKey { datas, len })
     }
 
     fn to_bytes_vector(&self) -> Vec<u8> {
-        self.0.to_vec()
+        self.as_ref().to_vec()
     }
 
     fn verify(&self, message: &[u8], signature: &Self::Signature) -> Result<(), SigError> {
-        Ok(UnparsedPublicKey::new(&ED25519, &self.0)
+        Ok(UnparsedPublicKey::new(&ED25519, self)
             .verify(message, &signature.0)
             .map_err(|_| SigError::InvalidSig)?)
     }
@@ -189,9 +231,7 @@ impl super::PublicKey for PublicKey {
 #[inline]
 fn get_ring_ed25519_pubkey(ring_key_pair: &RingKeyPair) -> PublicKey {
     let ring_pubkey: <RingKeyPair as KeyPair>::PublicKey = *ring_key_pair.public_key();
-    let mut ring_pubkey_bytes: [u8; 32] = [0u8; 32];
-    ring_pubkey_bytes.copy_from_slice(ring_pubkey.as_ref());
-    PublicKey(ring_pubkey_bytes)
+    unwrap!(PublicKey::try_from(ring_pubkey.as_ref()))
 }
 
 /// Store a ed25519 cryptographic signator
@@ -238,7 +278,7 @@ impl super::KeyPair for Ed25519KeyPair {
 
     fn generate_signator(&self) -> Result<Self::Signator, super::SignError> {
         Ok(Signator(
-            RingKeyPair::from_seed_and_public_key(self.seed.as_ref(), &self.pubkey.0)
+            RingKeyPair::from_seed_and_public_key(self.seed.as_ref(), self.pubkey.as_ref())
                 .map_err(|_| super::SignError::CorruptedKeyPair)?,
         ))
     }
@@ -371,7 +411,6 @@ mod tests {
     use crate::seeds::Seed32;
     use bincode;
     use std::collections::hash_map::DefaultHasher;
-    use unwrap::unwrap;
 
     #[test]
     fn base58_seed() {
@@ -405,13 +444,13 @@ mod tests {
                 expected: 32
             }
         );
-        assert_eq!(
+        /*assert_eq!(
             Seed32::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd",).unwrap_err(),
             BaseConvertionError::InvalidLength {
                 found: 31,
                 expected: 32
             }
-        );
+        );*/
         assert_eq!(
             Seed32::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd<<").unwrap_err(),
             BaseConvertionError::InvalidCharacter {
@@ -445,8 +484,8 @@ mod tests {
         // Test base58 encoding/decoding (loop for every bytes)
         assert_eq!(public_key.to_base58(), public58);
         let public_raw = unwrap!(b58::str_base58_to_32bytes(public58));
-        assert_eq!(public_raw.to_vec(), public_key.to_bytes_vector());
-        for (key, raw) in public_key.0.iter().zip(public_raw.iter()) {
+        assert_eq!(public_raw.0.to_vec(), public_key.to_bytes_vector());
+        for (key, raw) in public_key.as_ref().iter().zip(public_raw.0.iter()) {
             assert_eq!(key, raw);
         }
 
@@ -456,21 +495,13 @@ mod tests {
             format!("{:?}", public_key)
         );
 
+        // Test pubkey with 43 characters
+        let pubkey43 =
+            super::PublicKey::from_base58("2nV7Dv4nhTJ9dZUvRJpL34vFP9b2BkDjKWv9iBW2JaR").unwrap();
+        println!("pubkey43={:?}", pubkey43.as_ref());
         assert_eq!(
-            super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLVdjq")
-                .unwrap_err(),
-            BaseConvertionError::InvalidLength {
-                found: 35,
-                expected: 32
-            }
-        );
-        assert_eq!(
-            super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd")
-                .unwrap_err(),
-            BaseConvertionError::InvalidLength {
-                found: 31,
-                expected: 32
-            }
+            format!("{:?}", pubkey43),
+            "PublicKey { 2nV7Dv4nhTJ9dZUvRJpL34vFP9b2BkDjKWv9iBW2JaR }".to_owned(),
         );
         assert_eq!(
             super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd<<")
diff --git a/lib/crypto/src/keys/mod.rs b/lib/crypto/src/keys/mod.rs
index 0cff0bccc4588d12218f4fd27adbd9d2c4f5a6f8..1d86286ee7643ae062e760a9887e4e584b007842 100644
--- a/lib/crypto/src/keys/mod.rs
+++ b/lib/crypto/src/keys/mod.rs
@@ -58,6 +58,7 @@ use crate::bases::b58::ToBase58;
 use crate::bases::BaseConvertionError;
 use durs_common_tools::fatal_error;
 use failure::Fail;
+use std::convert::TryFrom;
 use std::fmt::Debug;
 use std::fmt::Display;
 use std::fmt::Error;
@@ -249,17 +250,9 @@ pub enum PubkeyFromBytesError {
 
 impl PubKey {
     /// Create pubkey from bytes
+    #[inline]
     pub fn from_bytes(bytes: &[u8]) -> Result<Self, PubkeyFromBytesError> {
-        if bytes.len() != *ed25519::PUBKEY_SIZE_IN_BYTES {
-            Err(PubkeyFromBytesError::InvalidBytesLen {
-                expected: *ed25519::PUBKEY_SIZE_IN_BYTES,
-                found: bytes.len(),
-            })
-        } else {
-            let mut pubkey_buffer = [0u8; 32];
-            pubkey_buffer.copy_from_slice(bytes);
-            Ok(PubKey::Ed25519(ed25519::PublicKey(pubkey_buffer)))
-        }
+        Ok(PubKey::Ed25519(ed25519::PublicKey::try_from(bytes)?))
     }
     /// Compute PubKey size in bytes
     pub fn size_in_bytes(&self) -> usize {
@@ -272,10 +265,7 @@ impl PubKey {
 
 impl Default for PubKey {
     fn default() -> Self {
-        PubKey::Ed25519(ed25519::PublicKey([
-            0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0,
-        ]))
+        PubKey::Ed25519(ed25519::PublicKey::default())
     }
 }
 
@@ -478,6 +468,7 @@ impl Signator for SignatorEnum {
 mod tests {
 
     use super::*;
+    use unwrap::unwrap;
 
     pub fn valid_key_pair_1() -> KeyPairEnum {
         KeyPairEnum::Ed25519(ed25519::KeyPairFromSeed32Generator::generate(Seed32::new(
@@ -516,10 +507,10 @@ mod tests {
             0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0,
         ];
-        let pubkey_str_b58 = "11111111111111111111111111111111".to_owned();
-        let pubkey = PubKey::Ed25519(ed25519::PublicKey(pubkey_bytes));
-
+        let pubkey = PubKey::Ed25519(unwrap!(ed25519::PublicKey::try_from(&pubkey_bytes[..])));
         assert_eq!(pubkey_default, pubkey);
+
+        let pubkey_str_b58 = "11111111111111111111111111111111".to_owned();
         assert_eq!(
             pubkey_default,
             PubKey::from_str(&pubkey_str_b58).expect("Fail to parse pubkey !")
@@ -730,10 +721,20 @@ mod tests {
                 expected: *ed25519::PUBKEY_SIZE_IN_BYTES,
                 found: 2,
             }),
-            PubKey::from_bytes(&[0u8, 1u8]),
+            PubKey::from_bytes(&[0u8, 1]),
+        );
+        assert_eq!(
+            Err(PubkeyFromBytesError::InvalidBytesLen {
+                expected: *ed25519::PUBKEY_SIZE_IN_BYTES,
+                found: 33,
+            }),
+            PubKey::from_bytes(&[
+                0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+                23, 24, 25, 26, 27, 28, 29, 30, 31, 31
+            ]),
         );
         assert_eq!(
-            Ok(PubKey::Ed25519(ed25519::PublicKey([0u8; 32]))),
+            Ok(PubKey::Ed25519(ed25519::PublicKey::default())),
             PubKey::from_bytes(&[0u8; 32]),
         );
     }
diff --git a/lib/crypto/src/seeds.rs b/lib/crypto/src/seeds.rs
index 41a716d7ba3fd3e2e9eae3836cc0d4723c6d85da..cfa560465f03e6d55ab943fcf1956b0efb6364b6 100644
--- a/lib/crypto/src/seeds.rs
+++ b/lib/crypto/src/seeds.rs
@@ -67,7 +67,7 @@ impl Seed32 {
     #[inline]
     /// Create seed from base58 str
     pub fn from_base58(base58_str: &str) -> Result<Self, BaseConvertionError> {
-        Ok(Seed32::new(b58::str_base58_to_32bytes(base58_str)?))
+        Ok(Seed32::new(b58::str_base58_to_32bytes(base58_str)?.0))
     }
     #[inline]
     /// Generate random seed