diff --git a/Cargo.lock b/Cargo.lock
index 2c6ad0e9d86f50b912ee93e6cd2c9b6a1a7a8171..70861c7e7ba61de9347538756d7bbc014ee47f84 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -261,9 +261,9 @@ dependencies = [
 
 [[package]]
 name = "dup-crypto"
-version = "0.36.0"
+version = "0.38.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ed9887f92b29910736ad29f5631abcbd8fc6b2bd2dd5510dc1edd32b0265d04"
+checksum = "3b1f8913ba1b77dbbf419c2aeabc566ccca5e77385b6738bb408cd9a9e7bbb86"
 dependencies = [
  "aes",
  "arrayvec",
diff --git a/native/dubp_rs/Cargo.toml b/native/dubp_rs/Cargo.toml
index 58d56c9965f15e322c2c35dce7e4d43f7fdec7ae..1b138b39c27e59be7d89cb3cbb9fc230ef572d17 100644
--- a/native/dubp_rs/Cargo.toml
+++ b/native/dubp_rs/Cargo.toml
@@ -10,7 +10,7 @@ crate-type = ["rlib"]
 
 [dependencies]
 allo-isolate = "0.1.6"
-dup-crypto = { version = "0.36.0", features = ["dewif", "mnemonic", "mnemonic_french", "rand", "scrypt"] }
+dup-crypto = { version = "0.38.0", features = ["dewif", "mnemonic", "mnemonic_french", "rand", "scrypt"] }
 fast-threadpool = { version = "0.3.0", default-features = false }
 once_cell = { version = "1.3.1", default-features = false, features = ["std"] }
 thiserror = "1.0.23"
diff --git a/native/dubp_rs/src/dewif.rs b/native/dubp_rs/src/dewif.rs
index a7905e38e2b4118c65c4b7d4884861334014ef46..2186fcc56fdae68d5cf222fbdfcde97aae7581a0 100644
--- a/native/dubp_rs/src/dewif.rs
+++ b/native/dubp_rs/src/dewif.rs
@@ -21,6 +21,7 @@ pub(super) fn change_secret_code(
     old_secret_code: &str,
     member_wallet: bool,
     secret_code_type: SecretCodeType,
+    system_memory: i64,
 ) -> Result<Vec<String>, DubpError> {
     let currency = parse_currency(currency)?;
     let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
@@ -30,9 +31,11 @@ pub(super) fn change_secret_code(
     )
     .map_err(DubpError::DewifReadError)?;
     if let Some(KeyPairEnum::Ed25519(keypair)) = keypairs.next() {
-        let new_secret_code = gen_secret_code(member_wallet, secret_code_type)?;
+        let log_n = log_n(system_memory);
+        let new_secret_code = gen_secret_code(member_wallet, secret_code_type, log_n)?;
 
-        let dewif = dup_crypto::dewif::write_dewif_v1_content(currency, &keypair, &new_secret_code);
+        let dewif =
+            dup_crypto::dewif::write_dewif_v3_content(currency, &keypair, log_n, &new_secret_code);
         let pubkey = keypair.public_key().to_base58();
         Ok(vec![dewif, new_secret_code, pubkey])
     } else {
@@ -46,6 +49,7 @@ pub(super) fn gen_dewif(
     mnemonic: &str,
     member_wallet: bool,
     secret_code_type: SecretCodeType,
+    system_memory: i64,
 ) -> Result<Vec<String>, DubpError> {
     let currency = parse_currency(currency)?;
     let mnemonic =
@@ -53,8 +57,9 @@ pub(super) fn gen_dewif(
     let seed = dup_crypto::mnemonic::mnemonic_to_seed(&mnemonic);
     let keypair = KeyPairFromSeed32Generator::generate(seed);
 
-    let secret_code = gen_secret_code(member_wallet, secret_code_type)?;
-    let dewif = dup_crypto::dewif::write_dewif_v1_content(currency, &keypair, &secret_code);
+    let log_n = log_n(system_memory);
+    let secret_code = gen_secret_code(member_wallet, secret_code_type, log_n)?;
+    let dewif = dup_crypto::dewif::write_dewif_v3_content(currency, &keypair, log_n, &secret_code);
     let pubkey = keypair.public_key().to_base58();
     Ok(vec![dewif, secret_code, pubkey])
 }
@@ -111,3 +116,11 @@ pub(super) fn sign_several(
         Err(DubpError::DewifReadError(DewifReadError::CorruptedContent))
     }
 }
+
+fn log_n(system_memory: i64) -> u8 {
+    if system_memory > 3_000_000_000 {
+        15
+    } else {
+        12
+    }
+}
diff --git a/native/dubp_rs/src/legacy.rs b/native/dubp_rs/src/legacy.rs
new file mode 100644
index 0000000000000000000000000000000000000000..b5d649bcd1c05bda385df8cf5c6c5f9a3d6fdea1
--- /dev/null
+++ b/native/dubp_rs/src/legacy.rs
@@ -0,0 +1,32 @@
+//  Copyright (C) 2020  Éloïs SANCHEZ.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+use crate::*;
+use dup_crypto::keys::ed25519::{KeyPairFromSaltedPasswordGenerator, SaltedPassword};
+
+pub(super) fn get_pubkey(salt: &str, password: &str) -> String {
+    KeyPairFromSaltedPasswordGenerator::with_default_parameters()
+        .generate(SaltedPassword::new(salt.to_owned(), password.to_owned()))
+        .public_key()
+        .to_base58()
+}
+
+pub(super) fn sign(salt: &str, password: &str, msg: &str) -> String {
+    KeyPairFromSaltedPasswordGenerator::with_default_parameters()
+        .generate(SaltedPassword::new(salt.to_owned(), password.to_owned()))
+        .generate_signator()
+        .sign(msg.as_bytes())
+        .to_base64()
+}
diff --git a/native/dubp_rs/src/lib.rs b/native/dubp_rs/src/lib.rs
index e0280e0d318073c39c40aa6912489400cede8d09..7530a96568f5a79438d28c8ffd9e6082310e1548 100644
--- a/native/dubp_rs/src/lib.rs
+++ b/native/dubp_rs/src/lib.rs
@@ -19,6 +19,7 @@ mod r#async;
 mod dewif;
 mod error;
 mod inputs;
+mod legacy;
 mod mnemonic;
 mod secret_code;
 
@@ -49,6 +50,7 @@ pub extern "C" fn change_dewif_secret_code(
     old_pin: *const raw::c_char,
     member_wallet: u32,
     secret_code_type: u32,
+    system_memory: i64,
 ) {
     exec_async(
         port,
@@ -58,10 +60,24 @@ pub extern "C" fn change_dewif_secret_code(
             let old_pin = char_ptr_to_str(old_pin)?;
             let member_wallet = member_wallet != 0;
             let secret_code_type = SecretCodeType::from(secret_code_type);
-            Ok((currency, dewif, old_pin, member_wallet, secret_code_type))
+            Ok((
+                currency,
+                dewif,
+                old_pin,
+                member_wallet,
+                secret_code_type,
+                system_memory,
+            ))
         },
-        |(currency, dewif, old_pin, member_wallet, secret_code_type)| {
-            dewif::change_secret_code(currency, dewif, old_pin, member_wallet, secret_code_type)
+        |(currency, dewif, old_pin, member_wallet, secret_code_type, system_memory)| {
+            dewif::change_secret_code(
+                currency,
+                dewif,
+                old_pin,
+                member_wallet,
+                secret_code_type,
+                system_memory,
+            )
         },
     )
 }
@@ -74,6 +90,7 @@ pub extern "C" fn gen_dewif(
     mnemonic: *const raw::c_char,
     member_wallet: u32,
     secret_code_type: u32,
+    system_memory: i64,
 ) {
     exec_async(
         port,
@@ -89,15 +106,17 @@ pub extern "C" fn gen_dewif(
                 mnemonic,
                 member_wallet,
                 secret_code_type,
+                system_memory,
             ))
         },
-        |(currency, language, mnemonic, member_wallet, secret_code_type)| {
+        |(currency, language, mnemonic, member_wallet, secret_code_type, system_memory)| {
             dewif::gen_dewif(
                 currency,
                 language,
                 mnemonic,
                 member_wallet,
                 secret_code_type,
+                system_memory,
             )
         },
     )
@@ -105,7 +124,7 @@ pub extern "C" fn gen_dewif(
 
 #[no_mangle]
 pub extern "C" fn gen_mnemonic(port: i64, language: u32) {
-    Isolate::new(port).post(DartRes::from(mnemonic::gen_mnemonic(language)));
+    exec_async(port, || u32_to_language(language), mnemonic::gen_mnemonic)
 }
 
 #[no_mangle]
@@ -127,6 +146,23 @@ pub extern "C" fn get_dewif_pubkey(
     )
 }
 
+#[no_mangle]
+pub extern "C" fn get_legacy_pubkey(
+    port: i64,
+    salt: *const raw::c_char,
+    password: *const raw::c_char,
+) {
+    exec_async(
+        port,
+        || {
+            let salt = char_ptr_to_str(salt)?;
+            let password = char_ptr_to_str(password)?;
+            Ok((salt, password))
+        },
+        |(salt, password)| Ok::<_, DubpError>(legacy::get_pubkey(salt, password)),
+    )
+}
+
 #[no_mangle]
 pub extern "C" fn mnemonic_to_pubkey(
     port: i64,
@@ -136,6 +172,7 @@ pub extern "C" fn mnemonic_to_pubkey(
     exec_async(
         port,
         || {
+            let language = u32_to_language(language)?;
             let mnemonic_phrase = char_ptr_to_str(mnemonic_phrase)?;
             Ok((language, mnemonic_phrase))
         },
@@ -164,6 +201,25 @@ pub extern "C" fn sign(
     )
 }
 
+#[no_mangle]
+pub extern "C" fn sign_legacy(
+    port: i64,
+    salt: *const raw::c_char,
+    password: *const raw::c_char,
+    msg: *const raw::c_char,
+) {
+    exec_async(
+        port,
+        || {
+            let salt = char_ptr_to_str(salt)?;
+            let password = char_ptr_to_str(password)?;
+            let msg = char_ptr_to_str(msg)?;
+            Ok((salt, password, msg))
+        },
+        |(salt, password, msg)| Ok::<_, DubpError>(legacy::sign(salt, password, msg)),
+    )
+}
+
 #[no_mangle]
 pub extern "C" fn sign_several(
     port: i64,
diff --git a/native/dubp_rs/src/mnemonic.rs b/native/dubp_rs/src/mnemonic.rs
index 765427dde2477d365e7b028310eb512a08744cf1..b9148e0f6a1dfdd8b63f874437cd92cefd833471 100644
--- a/native/dubp_rs/src/mnemonic.rs
+++ b/native/dubp_rs/src/mnemonic.rs
@@ -15,15 +15,15 @@
 
 use crate::*;
 
-pub(super) fn gen_mnemonic(language: u32) -> Result<String, DubpError> {
-    let mnemonic = Mnemonic::new(MnemonicType::Words12, u32_to_language(language)?)
-        .map_err(|_| DubpError::RandErr)?;
+pub(super) fn gen_mnemonic(language: Language) -> Result<String, DubpError> {
+    let mnemonic =
+        Mnemonic::new(MnemonicType::Words12, language).map_err(|_| DubpError::RandErr)?;
     Ok(mnemonic.phrase().to_owned())
 }
 
-pub(super) fn mnemonic_to_pubkey(language: u32, mnemonic: &str) -> Result<String, DubpError> {
-    let mnemonic = Mnemonic::from_phrase(mnemonic, u32_to_language(language)?)
-        .map_err(|_| DubpError::WrongLanguage)?;
+pub(super) fn mnemonic_to_pubkey(language: Language, mnemonic: &str) -> Result<String, DubpError> {
+    let mnemonic =
+        Mnemonic::from_phrase(mnemonic, language).map_err(|_| DubpError::WrongLanguage)?;
     let seed = dup_crypto::mnemonic::mnemonic_to_seed(&mnemonic);
     let keypair = KeyPairFromSeed32Generator::generate(seed);
     Ok(keypair.public_key().to_base58())
diff --git a/native/dubp_rs/src/secret_code.rs b/native/dubp_rs/src/secret_code.rs
index f9581e441684934f652c8e3d081921f28c3b25a7..4b29dca7fda2a1569bcdf3941f8ef7c953a0a232 100644
--- a/native/dubp_rs/src/secret_code.rs
+++ b/native/dubp_rs/src/secret_code.rs
@@ -18,11 +18,14 @@ use crate::*;
 pub(crate) fn gen_secret_code(
     member_wallet: bool,
     secret_code_type: SecretCodeType,
+    log_n: u8,
 ) -> Result<String, DubpError> {
     match secret_code_type {
         SecretCodeType::Digits => {
             if member_wallet {
                 Err(DubpError::DigitsCodeForbidForMemberWallet)
+            } else if log_n >= 15 {
+                gen_random_digits(7)
             } else {
                 gen_random_digits(8)
             }
@@ -30,6 +33,8 @@ pub(crate) fn gen_secret_code(
         SecretCodeType::Letters => {
             if member_wallet {
                 gen_random_letters(10)
+            } else if log_n >= 15 {
+                gen_random_letters(5)
             } else {
                 gen_random_letters(6)
             }
diff --git a/packages/dubp_rs/lib/dubp.dart b/packages/dubp_rs/lib/dubp.dart
index e2f1d2e3050edca2220e2621c3768f3e110fbbd9..6332ea36d979be45d210f7a59fc212b627820cb1 100644
--- a/packages/dubp_rs/lib/dubp.dart
+++ b/packages/dubp_rs/lib/dubp.dart
@@ -2,6 +2,7 @@ import 'dart:async';
 import 'dart:ffi';
 import 'package:ffi/ffi.dart';
 import 'package:isolate/ports.dart';
+import "package:system_info/system_info.dart";
 
 import 'ffi.dart' as native;
 
@@ -45,7 +46,7 @@ class DubpRust {
   /// Must be called only once at the start of your application.
   static void setup() {
     native.store_dart_post_cobject(NativeApi.postCObject);
-    print("Dubp Setup Done");
+    print("DUBP_RS Setup Done");
   }
 
   /// Generate a random mnemonic
@@ -67,6 +68,8 @@ class DubpRust {
     String oldPin,
     SecretCodeType secretCodeType = SecretCodeType.letters,
   }) async {
+    int ram = SysInfo.getTotalPhysicalMemory();
+
     final completer = Completer<List<String>>();
     final sendPort = singleCompletePort<List<String>, List>(completer,
         callback: _handleErrList);
@@ -77,6 +80,7 @@ class DubpRust {
       Utf8.toUtf8(oldPin),
       0,
       secretCodeType.index,
+      ram,
     );
     List<String> newWallet = await completer.future;
 
@@ -96,6 +100,9 @@ class DubpRust {
     String mnemonic,
     SecretCodeType secretCodeType = SecretCodeType.letters,
   }) async {
+    int ram = SysInfo.getTotalPhysicalMemory();
+    print('ram=$ram');
+
     final completer = Completer<List<String>>();
     final sendPort = singleCompletePort<List<String>, List>(completer,
         callback: _handleErrList);
@@ -106,13 +113,27 @@ class DubpRust {
       Utf8.toUtf8(mnemonic),
       0,
       secretCodeType.index,
+      ram,
     );
     List<String> newWallet = await completer.future;
 
     return Future.value(NewWallet._(newWallet[0], newWallet[1], newWallet[2]));
   }
 
-  /// Get pulblic key (in base 58) of `dewif` keypair.
+  /// Get public key (in base 58) of legacy wallet (password + salt)
+  static Future<String> getLegacyPublicKey({String password, String salt}) {
+    final completer = Completer<String>();
+    final sendPort =
+        singleCompletePort<String, String>(completer, callback: _handleErr);
+    native.get_legacy_pubkey(
+      sendPort.nativePort,
+      Utf8.toUtf8(password),
+      Utf8.toUtf8(salt),
+    );
+    return completer.future;
+  }
+
+  /// Get public key (in base 58) of `dewif` keypair.
   static Future<String> getDewifPublicKey(
       {String currency = "g1", String dewif, String pin}) async {
     final completer = Completer<String>();
@@ -145,6 +166,21 @@ class DubpRust {
     return completer.future;
   }
 
+  /// Sign the message `message` with legacy wallet (password + salt)
+  static Future<String> signLegacy(
+      {String password, String salt, String message}) {
+    final completer = Completer<String>();
+    final sendPort =
+        singleCompletePort<String, String>(completer, callback: _handleErr);
+    native.sign_legacy(
+      sendPort.nativePort,
+      Utf8.toUtf8(password),
+      Utf8.toUtf8(salt),
+      Utf8.toUtf8(message),
+    );
+    return completer.future;
+  }
+
   /// Sign several messages `messages` with `dewif` keypair encryted in DEWIF
   /// format.
   ///
diff --git a/packages/dubp_rs/pubspec.lock b/packages/dubp_rs/pubspec.lock
index 37fe0206ac586384d95cb0e4b3f94322e23c8597..c5f7973f416a48e5f6057da9ebcc40ef1c5330d7 100644
--- a/packages/dubp_rs/pubspec.lock
+++ b/packages/dubp_rs/pubspec.lock
@@ -64,6 +64,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "0.1.3"
+  file_utils:
+    dependency: transitive
+    description:
+      name: file_utils
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.1.4"
   flutter:
     dependency: "direct main"
     description: flutter
@@ -74,6 +81,13 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  globbing:
+    dependency: transitive
+    description:
+      name: globbing
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.1"
   isolate:
     dependency: "direct main"
     description:
@@ -135,6 +149,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "1.1.0-nullsafety.1"
+  system_info:
+    dependency: "direct main"
+    description:
+      name: system_info
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.1.3"
   term_glyph:
     dependency: transitive
     description:
diff --git a/packages/dubp_rs/pubspec.yaml b/packages/dubp_rs/pubspec.yaml
index e640dcec83fbd052661b7b3e81b66355cc989f51..bfc6dfad3ee90de37c5ab18834448ab124aaa2c4 100644
--- a/packages/dubp_rs/pubspec.yaml
+++ b/packages/dubp_rs/pubspec.yaml
@@ -11,6 +11,7 @@ dependencies:
     sdk: flutter
   ffi: ^0.1.3
   isolate: ^2.0.3
+  system_info: ^0.1.3
 
 dev_dependencies:
   effective_dart: ^1.0.0
diff --git a/pubspec.lock b/pubspec.lock
index 299602e9febb6585a84fc26272c3b5bc9fbc94a0..a5cb3cb79de774d2de51286b14b82e673f7fd09a 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -134,6 +134,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "5.2.1"
+  file_utils:
+    dependency: transitive
+    description:
+      name: file_utils
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.1.4"
   flutter:
     dependency: "direct main"
     description: flutter
@@ -163,6 +170,13 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  globbing:
+    dependency: transitive
+    description:
+      name: globbing
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.1"
   gql:
     dependency: transitive
     description: