diff --git a/Cargo.lock b/Cargo.lock index 70861c7..a28e4d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -222,9 +222,9 @@ dependencies = [ [[package]] name = "cryptoxide" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da24927b5b899890bcb29205436c957b7892ec3a3fbffce81d710b9611e77778" +checksum = "f2824e117f942b77e942b14162316711d66f07d14b0f37a44fa4b4cad592b8fa" [[package]] name = "dart-bindgen" @@ -261,9 +261,9 @@ dependencies = [ [[package]] name = "dup-crypto" -version = "0.38.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b1f8913ba1b77dbbf419c2aeabc566ccca5e77385b6738bb408cd9a9e7bbb86" +checksum = "ba9cba3d83bf946b9e2d3b444f98df563d6ffefa94579bdfc6f06b158cd872a9" dependencies = [ "aes", "arrayvec", @@ -272,6 +272,7 @@ dependencies = [ "bs58", "byteorder", "cryptoxide", + "ed25519-bip32", "getrandom", "once_cell", "ring", @@ -282,6 +283,15 @@ dependencies = [ ] [[package]] +name = "ed25519-bip32" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8827180a2b511141fbe49141e50b31a8d542465e0fb572f81f36feea2addfe92" +dependencies = [ + "cryptoxide", +] + +[[package]] name = "fast-threadpool" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 81a6dfc..90c3171 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,7 @@ members = ["native/dubp_rs"] [profile.release] lto = true codegen-units = 1 -debug = true \ No newline at end of file +debug = true + +[patch.crates-io] +#dup-crypto = { path = "/home/elois/dev/duniter/libs/dubp-rs-libs/crypto" } diff --git a/native/dubp_rs/Cargo.toml b/native/dubp_rs/Cargo.toml index 1b138b3..5d104fa 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.38.0", features = ["dewif", "mnemonic", "mnemonic_french", "rand", "scrypt"] } +dup-crypto = { version = "0.40.0", features = ["bip32-ed25519", "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 80fa7ba..70e2562 100644 --- a/native/dubp_rs/src/dewif.rs +++ b/native/dubp_rs/src/dewif.rs @@ -64,6 +64,21 @@ pub(super) fn gen_dewif( Ok(vec![dewif, secret_code, pubkey]) } +pub(super) fn get_secret_code_len( + currency: Currency, + dewif: &str, + member_wallet: bool, + secret_code_type: SecretCodeType, +) -> Result { + let log_n = dup_crypto::dewif::read_dewif_log_n(ExpectedCurrency::Specific(currency), dewif) + .map_err(DubpError::DewifReadError)?; + + Ok( + crate::secret_code::compute_secret_code_len(member_wallet, secret_code_type, log_n)? + .to_string(), + ) +} + pub(super) fn get_pubkey(currency: Currency, dewif: &str, pin: &str) -> Result { let mut keypairs = dup_crypto::dewif::read_dewif_file_content( ExpectedCurrency::Specific(currency), diff --git a/native/dubp_rs/src/inputs.rs b/native/dubp_rs/src/inputs.rs index 7959580..557e0c4 100644 --- a/native/dubp_rs/src/inputs.rs +++ b/native/dubp_rs/src/inputs.rs @@ -15,6 +15,7 @@ use crate::*; +#[derive(Clone, Copy, Debug)] pub(crate) enum SecretCodeType { Digits, Letters, diff --git a/native/dubp_rs/src/lib.rs b/native/dubp_rs/src/lib.rs index 91a2811..172cab2 100644 --- a/native/dubp_rs/src/lib.rs +++ b/native/dubp_rs/src/lib.rs @@ -168,6 +168,29 @@ pub extern "C" fn gen_mnemonic(port: i64, language: u32) { } #[no_mangle] +pub extern "C" fn get_dewif_secret_code_len( + port: i64, + currency: *const raw::c_char, + dewif: *const raw::c_char, + member_wallet: u32, + secret_code_type: u32, +) { + exec_async( + port, + || { + let currency = parse_currency(char_ptr_to_str(currency)?)?; + let dewif = char_ptr_to_str(dewif)?; + let member_wallet = member_wallet != 0; + let secret_code_type = SecretCodeType::from(secret_code_type); + Ok((currency, dewif, member_wallet, secret_code_type)) + }, + |(currency, dewif, member_wallet, secret_code_type)| { + dewif::get_secret_code_len(currency, dewif, member_wallet, secret_code_type) + }, + ) +} + +#[no_mangle] pub extern "C" fn get_dewif_pubkey( port: i64, currency: *const raw::c_char, diff --git a/native/dubp_rs/src/secret_code.rs b/native/dubp_rs/src/secret_code.rs index 4b29dca..3666705 100644 --- a/native/dubp_rs/src/secret_code.rs +++ b/native/dubp_rs/src/secret_code.rs @@ -15,33 +15,45 @@ use crate::*; -pub(crate) fn gen_secret_code( +pub(crate) fn compute_secret_code_len( member_wallet: bool, secret_code_type: SecretCodeType, log_n: u8, -) -> Result { +) -> Result { match secret_code_type { SecretCodeType::Digits => { if member_wallet { Err(DubpError::DigitsCodeForbidForMemberWallet) } else if log_n >= 15 { - gen_random_digits(7) + Ok(7) } else { - gen_random_digits(8) + Ok(8) } } SecretCodeType::Letters => { if member_wallet { - gen_random_letters(10) + Ok(10) } else if log_n >= 15 { - gen_random_letters(5) + Ok(5) } else { - gen_random_letters(6) + Ok(6) } } } } +pub(crate) fn gen_secret_code( + member_wallet: bool, + secret_code_type: SecretCodeType, + log_n: u8, +) -> Result { + let secret_code_len = compute_secret_code_len(member_wallet, secret_code_type, log_n)?; + match secret_code_type { + SecretCodeType::Digits => gen_random_digits(secret_code_len), + SecretCodeType::Letters => gen_random_letters(secret_code_len), + } +} + fn gen_random_digits(n: usize) -> Result { let mut digits_string = dup_crypto::rand::gen_u32() .map_err(|_| DubpError::RandErr)? diff --git a/packages/dubp_rs/lib/dubp.dart b/packages/dubp_rs/lib/dubp.dart index 7aa5c26..4d246e6 100644 --- a/packages/dubp_rs/lib/dubp.dart +++ b/packages/dubp_rs/lib/dubp.dart @@ -116,7 +116,6 @@ class DubpRust { return Future.value(NewWallet._(newWallet[0], newWallet[1], newWallet[2])); } - /// Generate a wallet from a mnemonic phrase. /// /// If the mnemonic is not in English, you must indicate the language of @@ -165,6 +164,24 @@ class DubpRust { return completer.future; } + /// Get secret code length of `dewif` keypair. + static Future getDewifSecretCodeLen( + {String currency = "g1", + String dewif, + SecretCodeType secretCodeType = SecretCodeType.letters}) async { + final completer = Completer(); + final sendPort = + singleCompletePort(completer, callback: _handleErrInt); + native.get_dewif_secret_code_len( + sendPort.nativePort, + Utf8.toUtf8(currency), + Utf8.toUtf8(dewif), + 0, + secretCodeType.index, + ); + return completer.future; + } + /// Get public key (in base 58) of legacy wallet (password + salt) /// /// This deprecated method must be used only for compatibility purpose ! @@ -271,4 +288,14 @@ class DubpRust { return arr; } } + + static int _handleErrInt(String res) { + if (res.startsWith('DUBP_RS_ERROR: ')) { + final error = res; + print(error); + throw error; + } else { + return int.parse(res); + } + } }