diff --git a/Cargo.lock b/Cargo.lock index 2c6ad0e..70861c7 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 58d56c9..1b138b3 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 a7905e3..2186fcc 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, 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, 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 0000000..b5d649b --- /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 . + +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 e0280e0..7530a96 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 765427d..b9148e0 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 { - let mnemonic = Mnemonic::new(MnemonicType::Words12, u32_to_language(language)?) - .map_err(|_| DubpError::RandErr)?; +pub(super) fn gen_mnemonic(language: Language) -> Result { + 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 { - 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 { + 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 f9581e4..4b29dca 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 { 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 e2f1d2e..6332ea3 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>(); final sendPort = singleCompletePort, List>(completer, callback: _handleErrList); @@ -77,6 +80,7 @@ class DubpRust { Utf8.toUtf8(oldPin), 0, secretCodeType.index, + ram, ); List 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>(); final sendPort = singleCompletePort, List>(completer, callback: _handleErrList); @@ -106,13 +113,27 @@ class DubpRust { Utf8.toUtf8(mnemonic), 0, secretCodeType.index, + ram, ); List 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 getLegacyPublicKey({String password, String salt}) { + final completer = Completer(); + final sendPort = + singleCompletePort(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 getDewifPublicKey( {String currency = "g1", String dewif, String pin}) async { final completer = Completer(); @@ -145,6 +166,21 @@ class DubpRust { return completer.future; } + /// Sign the message `message` with legacy wallet (password + salt) + static Future signLegacy( + {String password, String salt, String message}) { + final completer = Completer(); + final sendPort = + singleCompletePort(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 37fe020..c5f7973 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 e640dce..bfc6dfa 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 299602e..a5cb3cb 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: