diff --git a/Cargo.lock b/Cargo.lock index 8ffe513c7e389617a435ec33f97e3ce0321abbd6..d7a684373e7d3483c38cca2404083b1d8ec4e34b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -268,9 +268,9 @@ dependencies = [ [[package]] name = "dup-crypto" -version = "0.45.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58a3b88cbd886b092a7e6c58608d87744706e0fc66a48eaf452c297e5aac3802" +checksum = "97b1ebfa9edbb53cd4434f01877fcd74fb2416b93a217754d2daecbeecad67eb" dependencies = [ "aes", "arrayvec", diff --git a/native/dubp_rs/Cargo.toml b/native/dubp_rs/Cargo.toml index b27959de42dbb73aa4e2424b297bb730708bb2fe..05ba6373a8515d25ee82f183d08e814bd3c09051 100644 --- a/native/dubp_rs/Cargo.toml +++ b/native/dubp_rs/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["rlib"] [dependencies] allo-isolate = "0.1.6" -dup-crypto = { version = "0.45.0", features = ["bip32-ed25519", "dewif", "mnemonic", "mnemonic_french", "scrypt"] } +dup-crypto = { version = "0.46.0", features = ["bip32-ed25519", "dewif", "mnemonic", "mnemonic_french", "scrypt"] } fast-threadpool = { version = "0.3.0", default-features = false } once_cell = { version = "1.3.1", default-features = false, features = ["std"] } parking_lot = "0.11.1" diff --git a/native/dubp_rs/src/error.rs b/native/dubp_rs/src/error.rs index 29a48bceafeed2b3764a050a18868c3d50e5a1e3..0448156b88475f5f5425d62d3dff5e38c71de190 100644 --- a/native/dubp_rs/src/error.rs +++ b/native/dubp_rs/src/error.rs @@ -31,6 +31,8 @@ pub(crate) enum DubpError { #[error("{0}")] InvalidAccountIndex(InvalidAccountIndex), #[error("{0}")] + InvalidPubkey(PublicKeyFromStrErr), + #[error("{0}")] InvalidU31(U31Error), #[error("Invalid secret code type")] InvalidSecretCodeType, diff --git a/native/dubp_rs/src/lib.rs b/native/dubp_rs/src/lib.rs index 92b8091205d2b9b696dae193f1cf4ef180948611..37cd38e97acb62090a0b7654b1949a0bed2f4866 100644 --- a/native/dubp_rs/src/lib.rs +++ b/native/dubp_rs/src/lib.rs @@ -21,6 +21,7 @@ mod error; mod inputs; mod legacy; mod mnemonic; +mod pubkey; mod secret_code; use crate::error::{DartRes, DubpError}; @@ -35,8 +36,8 @@ use dup_crypto::{ ed25519::bip32::{ ChainCode, InvalidAccountIndex, KeyPair, PrivateDerivationPath, PublicKeyWithChainCode, }, - ed25519::{KeyPairFromSeed32Generator, PublicKey}, - KeyPair as _, KeyPairEnum, Signator as _, Signature as _, + ed25519::{KeyPairFromSeed32Generator, PublicKey, PublicKeyFromStrErr}, + KeyPair as _, KeyPairEnum, PublicKey as _, Signator as _, Signature as _, }, mnemonic::{Language, Mnemonic, MnemonicType}, utils::{U31Error, U31}, @@ -83,6 +84,20 @@ pub extern "C" fn change_dewif_secret_code( ) } +#[no_mangle] +pub extern "C" fn check_pubkey(port: i64, pubkey: *const raw::c_char) { + exec_async(port, || Ok(char_ptr_to_str(pubkey)?), pubkey::check_pubkey) +} + +#[no_mangle] +pub extern "C" fn compute_checksum(port: i64, pubkey: *const raw::c_char) { + exec_async( + port, + || Ok(char_ptr_to_str(pubkey)?), + pubkey::compute_checksum, + ) +} + #[no_mangle] pub extern "C" fn gen_dewif( port: i64, diff --git a/native/dubp_rs/src/pubkey.rs b/native/dubp_rs/src/pubkey.rs new file mode 100644 index 0000000000000000000000000000000000000000..6c338258f462a8c1ebd75cbf6c211050d4d623d4 --- /dev/null +++ b/native/dubp_rs/src/pubkey.rs @@ -0,0 +1,27 @@ +// 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::*; + +pub(crate) fn check_pubkey(pubkey: &str) -> Result<(), DubpError> { + PublicKey::from_base58_with_checksum_opt(pubkey).map_err(DubpError::InvalidPubkey)?; + Ok(()) +} + +pub(crate) fn compute_checksum(pubkey: &str) -> Result<String, DubpError> { + Ok(PublicKey::from_base58(pubkey) + .map_err(|e| DubpError::InvalidPubkey(PublicKeyFromStrErr::BaseConversionError(e)))? + .checksum()) +} diff --git a/packages/dubp_rs/lib/dubp.dart b/packages/dubp_rs/lib/dubp.dart index 94382c7fb63a8620aaf72b6c0000675393d59490..a1f903df707087c66ea865cd71a52867a472df08 100644 --- a/packages/dubp_rs/lib/dubp.dart +++ b/packages/dubp_rs/lib/dubp.dart @@ -102,6 +102,30 @@ class DubpRust { return Future.value(NewWallet._(newWallet[0], newWallet[1])); } + /// Check validity of a base58 public key with its checksum + static Future<void> checkPublicKey({String pubkey}) { + final completer = Completer<void>(); + final sendPort = + singleCompletePort<void, String>(completer, callback: _handleErrVoid); + native.check_pubkey( + sendPort.nativePort, + Utf8.toUtf8(pubkey), + ); + return completer.future; + } + + /// Compute public key checksum + static Future<String> computeChecksum({String pubkey}) { + final completer = Completer<String>(); + final sendPort = + singleCompletePort<String, String>(completer, callback: _handleErr); + native.compute_checksum( + sendPort.nativePort, + Utf8.toUtf8(pubkey), + ); + return completer.future; + } + /// Generate a random mnemonic static Future<String> genMnemonic({Language language = Language.english}) { final completer = Completer<String>();