Merge pull request 'dubp/dewif-meta-data' (#13) from dubp/dewif-meta-data into master
Reviewed-on: #13
This commit is contained in:
commit
12d2f98672
|
@ -261,9 +261,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dup-crypto"
|
name = "dup-crypto"
|
||||||
version = "0.41.0"
|
version = "0.41.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38f6b6eb9f9a9e92e70515090be3733857966f2a635564f36e78af047e63a1bf"
|
checksum = "e69f621e9575ed2647fb67a9e8a8d8d5cc8d9281dec2fc848c7619a159501562"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
|
|
|
@ -10,7 +10,7 @@ crate-type = ["rlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
allo-isolate = "0.1.6"
|
allo-isolate = "0.1.6"
|
||||||
dup-crypto = { version = "0.41.0", features = ["bip32-ed25519", "dewif", "mnemonic", "mnemonic_french", "rand", "scrypt"] }
|
dup-crypto = { version = "0.41.1", features = ["bip32-ed25519", "dewif", "mnemonic", "mnemonic_french", "rand", "scrypt"] }
|
||||||
fast-threadpool = { version = "0.3.0", default-features = false }
|
fast-threadpool = { version = "0.3.0", default-features = false }
|
||||||
once_cell = { version = "1.3.1", default-features = false, features = ["std"] }
|
once_cell = { version = "1.3.1", default-features = false, features = ["std"] }
|
||||||
thiserror = "1.0.23"
|
thiserror = "1.0.23"
|
||||||
|
|
|
@ -19,14 +19,12 @@ pub mod classic;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub(super) fn change_secret_code(
|
pub(super) fn change_secret_code(
|
||||||
currency: &str,
|
|
||||||
dewif: &str,
|
dewif: &str,
|
||||||
old_secret_code: &str,
|
old_secret_code: &str,
|
||||||
member_wallet: bool,
|
member_wallet: bool,
|
||||||
secret_code_type: SecretCodeType,
|
secret_code_type: SecretCodeType,
|
||||||
system_memory: i64,
|
system_memory: i64,
|
||||||
) -> Result<Vec<String>, DubpError> {
|
) -> Result<Vec<String>, DubpError> {
|
||||||
let currency = parse_currency(currency)?;
|
|
||||||
let new_log_n = log_n(system_memory);
|
let new_log_n = log_n(system_memory);
|
||||||
let new_secret_code = gen_secret_code(member_wallet, secret_code_type, new_log_n)?;
|
let new_secret_code = gen_secret_code(member_wallet, secret_code_type, new_log_n)?;
|
||||||
|
|
||||||
|
@ -34,9 +32,7 @@ pub(super) fn change_secret_code(
|
||||||
dup_crypto::dewif::change_dewif_passphrase(dewif, old_secret_code, &new_secret_code)
|
dup_crypto::dewif::change_dewif_passphrase(dewif, old_secret_code, &new_secret_code)
|
||||||
.map_err(DubpError::DewifReadError)?;
|
.map_err(DubpError::DewifReadError)?;
|
||||||
|
|
||||||
let pubkey = get_pubkey(currency, &new_dewif, &new_secret_code)?;
|
Ok(vec![new_dewif, new_secret_code])
|
||||||
|
|
||||||
Ok(vec![new_dewif, new_secret_code, pubkey])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn gen_dewif(
|
pub(super) fn gen_dewif(
|
||||||
|
@ -56,28 +52,60 @@ pub(super) fn gen_dewif(
|
||||||
let log_n = log_n(system_memory);
|
let log_n = log_n(system_memory);
|
||||||
let secret_code = gen_secret_code(member_wallet, secret_code_type, log_n)?;
|
let secret_code = gen_secret_code(member_wallet, secret_code_type, log_n)?;
|
||||||
|
|
||||||
let (dewif, pubkey) = match wallet_type {
|
let dewif = match wallet_type {
|
||||||
WalletType::Bip32Ed25519 => {
|
WalletType::Bip32Ed25519 => {
|
||||||
let keypair = dup_crypto::keys::ed25519::bip32::KeyPair::from_seed(seed.clone());
|
let keypair = dup_crypto::keys::ed25519::bip32::KeyPair::from_seed(seed.clone());
|
||||||
let pubkey = keypair.public_key();
|
let pubkey = keypair.public_key();
|
||||||
let dewif = dup_crypto::dewif::write_dewif_v4_content(
|
dup_crypto::dewif::write_dewif_v4_content(currency, log_n, &secret_code, &pubkey, seed)
|
||||||
currency,
|
|
||||||
log_n,
|
|
||||||
&secret_code,
|
|
||||||
&pubkey,
|
|
||||||
seed,
|
|
||||||
);
|
|
||||||
(dewif, pubkey.to_base58())
|
|
||||||
}
|
}
|
||||||
WalletType::Ed25519 => {
|
WalletType::Ed25519 => {
|
||||||
let keypair = KeyPairFromSeed32Generator::generate(seed);
|
let keypair = KeyPairFromSeed32Generator::generate(seed);
|
||||||
let dewif =
|
dup_crypto::dewif::write_dewif_v3_content(currency, &keypair, log_n, &secret_code)
|
||||||
dup_crypto::dewif::write_dewif_v3_content(currency, &keypair, log_n, &secret_code);
|
|
||||||
(dewif, keypair.public_key().to_base58())
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vec![dewif, secret_code, pubkey])
|
Ok(vec![dewif, secret_code])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_dewif_meta(
|
||||||
|
dewif: &str,
|
||||||
|
member_wallet: bool,
|
||||||
|
secret_code_type: SecretCodeType,
|
||||||
|
) -> Result<Vec<String>, DubpError> {
|
||||||
|
let dup_crypto::dewif::DewifMeta {
|
||||||
|
currency,
|
||||||
|
log_n,
|
||||||
|
version,
|
||||||
|
} = dup_crypto::dewif::read_dewif_meta(dewif).map_err(DubpError::DewifReadError)?;
|
||||||
|
|
||||||
|
let secret_code_len =
|
||||||
|
crate::secret_code::compute_secret_code_len(member_wallet, secret_code_type, log_n)?;
|
||||||
|
|
||||||
|
Ok(vec![
|
||||||
|
currency.to_string(),
|
||||||
|
secret_code_len.to_string(),
|
||||||
|
version.to_string(),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_pubkey(
|
||||||
|
currency: Currency,
|
||||||
|
dewif: &str,
|
||||||
|
secret_code: &str,
|
||||||
|
) -> Result<String, DubpError> {
|
||||||
|
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
||||||
|
ExpectedCurrency::Specific(currency),
|
||||||
|
dewif,
|
||||||
|
&secret_code.to_ascii_uppercase(),
|
||||||
|
)
|
||||||
|
.map_err(DubpError::DewifReadError)?;
|
||||||
|
|
||||||
|
match keypairs.next() {
|
||||||
|
Some(KeyPairEnum::Ed25519(keypair)) => Ok(keypair.public_key().to_base58()),
|
||||||
|
Some(KeyPairEnum::Bip32Ed25519(_)) => Err(DubpError::GetMasterPubkeyOfHdWallet),
|
||||||
|
Some(_) => Err(DubpError::UnsupportedDewifVersion),
|
||||||
|
None => Err(DubpError::DewifReadError(DewifReadError::CorruptedContent)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_secret_code_len(
|
pub(super) fn get_secret_code_len(
|
||||||
|
@ -99,24 +127,6 @@ pub(super) fn get_secret_code_len(
|
||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_pubkey(
|
|
||||||
currency: Currency,
|
|
||||||
dewif: &str,
|
|
||||||
secret_code: &str,
|
|
||||||
) -> Result<String, DubpError> {
|
|
||||||
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
|
||||||
ExpectedCurrency::Specific(currency),
|
|
||||||
dewif,
|
|
||||||
&secret_code.to_ascii_uppercase(),
|
|
||||||
)
|
|
||||||
.map_err(DubpError::DewifReadError)?;
|
|
||||||
if let Some(keypair) = keypairs.next() {
|
|
||||||
Ok(keypair.public_key().to_base58())
|
|
||||||
} else {
|
|
||||||
Err(DubpError::DewifReadError(DewifReadError::CorruptedContent))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn log_n(system_memory: i64) -> u8 {
|
pub(crate) fn log_n(system_memory: i64) -> u8 {
|
||||||
if system_memory > 3_000_000_000 {
|
if system_memory > 3_000_000_000 {
|
||||||
15
|
15
|
||||||
|
|
|
@ -28,6 +28,8 @@ pub(crate) enum DubpError {
|
||||||
InvalidDerivationIndex(InvalidDerivationIndex),
|
InvalidDerivationIndex(InvalidDerivationIndex),
|
||||||
#[error("Digits secret code forbid for member wallet")]
|
#[error("Digits secret code forbid for member wallet")]
|
||||||
DigitsCodeForbidForMemberWallet,
|
DigitsCodeForbidForMemberWallet,
|
||||||
|
#[error("It is forbidden to retrieve the master public key of an HD wallet.")]
|
||||||
|
GetMasterPubkeyOfHdWallet,
|
||||||
#[error("this wallet is not an HD wallet")]
|
#[error("this wallet is not an HD wallet")]
|
||||||
NotHdWallet,
|
NotHdWallet,
|
||||||
#[error("this account index is not a transparent account index")]
|
#[error("this account index is not a transparent account index")]
|
||||||
|
@ -40,6 +42,8 @@ pub(crate) enum DubpError {
|
||||||
UnknownCurrencyName,
|
UnknownCurrencyName,
|
||||||
#[error("Unknown language")]
|
#[error("Unknown language")]
|
||||||
UnknownLanguage,
|
UnknownLanguage,
|
||||||
|
#[error("Unsupported DEWIF version")]
|
||||||
|
UnsupportedDewifVersion,
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Utf8Error(std::str::Utf8Error),
|
Utf8Error(std::str::Utf8Error),
|
||||||
#[error("Wrong language")]
|
#[error("Wrong language")]
|
||||||
|
|
|
@ -45,9 +45,8 @@ use thiserror::Error;
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn change_dewif_secret_code(
|
pub extern "C" fn change_dewif_secret_code(
|
||||||
port: i64,
|
port: i64,
|
||||||
currency: *const raw::c_char,
|
|
||||||
dewif: *const raw::c_char,
|
dewif: *const raw::c_char,
|
||||||
old_pin: *const raw::c_char,
|
old_secret_code: *const raw::c_char,
|
||||||
member_wallet: u32,
|
member_wallet: u32,
|
||||||
secret_code_type: u32,
|
secret_code_type: u32,
|
||||||
system_memory: i64,
|
system_memory: i64,
|
||||||
|
@ -55,25 +54,22 @@ pub extern "C" fn change_dewif_secret_code(
|
||||||
exec_async(
|
exec_async(
|
||||||
port,
|
port,
|
||||||
|| {
|
|| {
|
||||||
let currency = char_ptr_to_str(currency)?;
|
|
||||||
let dewif = char_ptr_to_str(dewif)?;
|
let dewif = char_ptr_to_str(dewif)?;
|
||||||
let old_pin = char_ptr_to_str(old_pin)?;
|
let old_secret_code = char_ptr_to_str(old_secret_code)?;
|
||||||
let member_wallet = member_wallet != 0;
|
let member_wallet = member_wallet != 0;
|
||||||
let secret_code_type = SecretCodeType::from(secret_code_type);
|
let secret_code_type = SecretCodeType::from(secret_code_type);
|
||||||
Ok((
|
Ok((
|
||||||
currency,
|
|
||||||
dewif,
|
dewif,
|
||||||
old_pin,
|
old_secret_code,
|
||||||
member_wallet,
|
member_wallet,
|
||||||
secret_code_type,
|
secret_code_type,
|
||||||
system_memory,
|
system_memory,
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|(currency, dewif, old_pin, member_wallet, secret_code_type, system_memory)| {
|
|(dewif, old_secret_code, member_wallet, secret_code_type, system_memory)| {
|
||||||
dewif::change_secret_code(
|
dewif::change_secret_code(
|
||||||
currency,
|
|
||||||
dewif,
|
dewif,
|
||||||
old_pin,
|
old_secret_code,
|
||||||
member_wallet,
|
member_wallet,
|
||||||
secret_code_type,
|
secret_code_type,
|
||||||
system_memory,
|
system_memory,
|
||||||
|
@ -180,6 +176,27 @@ pub extern "C" fn gen_mnemonic(port: i64, language: u32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
pub extern "C" fn get_dewif_meta(
|
||||||
|
port: i64,
|
||||||
|
dewif: *const raw::c_char,
|
||||||
|
member_wallet: u32,
|
||||||
|
secret_code_type: u32,
|
||||||
|
) {
|
||||||
|
exec_async(
|
||||||
|
port,
|
||||||
|
|| {
|
||||||
|
let dewif = char_ptr_to_str(dewif)?;
|
||||||
|
let member_wallet = member_wallet != 0;
|
||||||
|
let secret_code_type = SecretCodeType::from(secret_code_type);
|
||||||
|
Ok((dewif, member_wallet, secret_code_type))
|
||||||
|
},
|
||||||
|
|(dewif, member_wallet, secret_code_type)| {
|
||||||
|
dewif::get_dewif_meta(dewif, member_wallet, secret_code_type)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
pub extern "C" fn get_dewif_secret_code_len(
|
pub extern "C" fn get_dewif_secret_code_len(
|
||||||
dewif: *const raw::c_char,
|
dewif: *const raw::c_char,
|
||||||
member_wallet: u32,
|
member_wallet: u32,
|
||||||
|
|
|
@ -6,6 +6,29 @@ import "package:system_info/system_info.dart";
|
||||||
|
|
||||||
import 'ffi.dart' as native;
|
import 'ffi.dart' as native;
|
||||||
|
|
||||||
|
/// DEWIF meta data
|
||||||
|
class DewifMetaData {
|
||||||
|
/// Currency name
|
||||||
|
String currency;
|
||||||
|
|
||||||
|
/// Secret code length
|
||||||
|
int secretCodeLen;
|
||||||
|
|
||||||
|
/// DEWIF version
|
||||||
|
int version;
|
||||||
|
|
||||||
|
/// Wallet type
|
||||||
|
WalletType walletType;
|
||||||
|
|
||||||
|
DewifMetaData._(this.currency, this.secretCodeLen, this.version) {
|
||||||
|
if (version == 4) {
|
||||||
|
walletType = WalletType.bip32Ed25519;
|
||||||
|
} else {
|
||||||
|
walletType = WalletType.ed25519;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Language
|
/// Language
|
||||||
enum Language {
|
enum Language {
|
||||||
/// English
|
/// English
|
||||||
|
@ -23,10 +46,7 @@ class NewWallet {
|
||||||
/// Secret code
|
/// Secret code
|
||||||
String pin;
|
String pin;
|
||||||
|
|
||||||
/// Public key
|
NewWallet._(this.dewif, this.pin);
|
||||||
String publicKey;
|
|
||||||
|
|
||||||
NewWallet._(this.dewif, this.pin, this.publicKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Secret code type
|
/// Secret code type
|
||||||
|
@ -60,7 +80,6 @@ class DubpRust {
|
||||||
|
|
||||||
/// Change the secret code that encrypts the `dewif` keypair.
|
/// Change the secret code that encrypts the `dewif` keypair.
|
||||||
static Future<NewWallet> changeDewifPin({
|
static Future<NewWallet> changeDewifPin({
|
||||||
String currency = "g1",
|
|
||||||
String dewif,
|
String dewif,
|
||||||
String oldPin,
|
String oldPin,
|
||||||
SecretCodeType secretCodeType = SecretCodeType.letters,
|
SecretCodeType secretCodeType = SecretCodeType.letters,
|
||||||
|
@ -72,7 +91,6 @@ class DubpRust {
|
||||||
callback: _handleErrList);
|
callback: _handleErrList);
|
||||||
native.change_dewif_secret_code(
|
native.change_dewif_secret_code(
|
||||||
sendPort.nativePort,
|
sendPort.nativePort,
|
||||||
Utf8.toUtf8(currency),
|
|
||||||
Utf8.toUtf8(dewif),
|
Utf8.toUtf8(dewif),
|
||||||
Utf8.toUtf8(oldPin),
|
Utf8.toUtf8(oldPin),
|
||||||
0,
|
0,
|
||||||
|
@ -81,7 +99,7 @@ class DubpRust {
|
||||||
);
|
);
|
||||||
List<String> newWallet = await completer.future;
|
List<String> newWallet = await completer.future;
|
||||||
|
|
||||||
return Future.value(NewWallet._(newWallet[0], newWallet[1], newWallet[2]));
|
return Future.value(NewWallet._(newWallet[0], newWallet[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a random mnemonic
|
/// Generate a random mnemonic
|
||||||
|
@ -122,7 +140,7 @@ class DubpRust {
|
||||||
);
|
);
|
||||||
List<String> newWallet = await completer.future;
|
List<String> newWallet = await completer.future;
|
||||||
|
|
||||||
return Future.value(NewWallet._(newWallet[0], newWallet[1], newWallet[2]));
|
return Future.value(NewWallet._(newWallet[0], newWallet[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a wallet from a mnemonic phrase.
|
/// Generate a wallet from a mnemonic phrase.
|
||||||
|
@ -157,7 +175,7 @@ class DubpRust {
|
||||||
);
|
);
|
||||||
List<String> newWallet = await completer.future;
|
List<String> newWallet = await completer.future;
|
||||||
|
|
||||||
return Future.value(NewWallet._(newWallet[0], newWallet[1], newWallet[2]));
|
return Future.value(NewWallet._(newWallet[0], newWallet[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
//get_bip32_dewif_accounts_pubkeys
|
//get_bip32_dewif_accounts_pubkeys
|
||||||
|
@ -181,6 +199,21 @@ class DubpRust {
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get `dewif` keypair meta data.
|
||||||
|
static Future<DewifMetaData> getDewifMetaData(
|
||||||
|
{String dewif,
|
||||||
|
SecretCodeType secretCodeType = SecretCodeType.letters}) async {
|
||||||
|
final completer = Completer<List<String>>();
|
||||||
|
final sendPort = singleCompletePort<List<String>, List>(completer,
|
||||||
|
callback: _handleErrList);
|
||||||
|
native.get_dewif_meta(
|
||||||
|
sendPort.nativePort, Utf8.toUtf8(dewif), 0, secretCodeType.index);
|
||||||
|
List<String> dewifMetaData = await completer.future;
|
||||||
|
|
||||||
|
return Future.value(DewifMetaData._(dewifMetaData[0],
|
||||||
|
int.parse(dewifMetaData[1]), int.parse(dewifMetaData[2])));
|
||||||
|
}
|
||||||
|
|
||||||
/// Get public key (in base 58) of `dewif` keypair.
|
/// Get public key (in base 58) of `dewif` keypair.
|
||||||
static Future<String> getDewifPublicKey(
|
static Future<String> getDewifPublicKey(
|
||||||
{String currency = "g1", String dewif, String pin}) async {
|
{String currency = "g1", String dewif, String pin}) async {
|
||||||
|
|
Loading…
Reference in New Issue