Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add human readable public key #734

Draft
wants to merge 5 commits into
base: develop-ready
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/components/wasm/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ use {
open_blind_asset_record as open_bar, AssetRecordType,
AssetRecordType::NonConfidentialAmount_NonConfidentialAssetType,
},
sig::{XfrKeyPair, XfrPublicKey, XfrSecretKey},
sig::{KeyType, XfrKeyPair, XfrPublicKey, XfrSecretKey},
structs::{
AssetRecordTemplate, AssetType as NoahAssetType, XfrBody,
ASSET_TYPE_LENGTH,
Expand Down Expand Up @@ -1826,6 +1826,12 @@ use ring::pbkdf2;
use std::num::NonZeroU32;
use std::str;

#[wasm_bindgen]
/// Returns human-readable encoded representation of an XfrPublicKey.
pub fn public_key_to_human(key: &XfrPublicKey) -> String {
wallet::public_key_to_human(key)
}

#[wasm_bindgen]
/// Returns bech32 encoded representation of an XfrPublicKey.
pub fn public_key_to_bech32(key: &XfrPublicKey) -> String {
Expand Down Expand Up @@ -1940,6 +1946,20 @@ pub fn create_keypair_from_secret(sk_str: String) -> Result<XfrKeyPair, JsValue>
Ok(sk.into_keypair())
}

#[wasm_bindgen]
#[allow(missing_docs)]
pub fn create_keypair_from_secret_secp256k1(
sk_str: String,
) -> Result<XfrKeyPair, JsValue> {
let mut bytes = vec![KeyType::Secp256k1.to_byte()];
bytes.extend(hex::decode(&sk_str).c(d!()).map_err(error_to_jsvalue)?);
let sk = XfrSecretKey::noah_from_bytes(&bytes)
.c(d!())
.map_err(error_to_jsvalue)?;

Ok(sk.into_keypair())
}

#[wasm_bindgen]
#[allow(missing_docs)]
pub fn get_pk_from_keypair(kp: &XfrKeyPair) -> XfrPublicKey {
Expand Down
1 change: 1 addition & 0 deletions src/libs/globutils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ ed25519-dalek-bip32 = { git = "https://github.com/FindoraNetwork/ed25519-dalek-b
tracing = "0.1.13"
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
bs58 = "0.4"
sha3 = "0.10"

[dev-dependencies]
rand_chacha = "0.3"
Expand Down
45 changes: 38 additions & 7 deletions src/libs/globutils/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ use bech32::{self, FromBase32, ToBase32};
use bip0039::{Count, Language, Mnemonic};
use ed25519_dalek_bip32::{DerivationPath, ExtendedSecretKey};
use noah::anon_xfr::structs::Nullifier;
use noah::xfr::sig::XfrPublicKeyInner;
use noah::{
anon_xfr::{
keys::{AXfrKeyPair, AXfrPubKey},
structs::Commitment,
},
xfr::sig::{XfrKeyPair, XfrPublicKey, XfrSecretKey},
xfr::sig::{KeyType, XfrKeyPair, XfrPublicKey, XfrSecretKey},
};
use noah_algebra::serialization::NoahFromToBytes;
use noah_crypto::basic::hybrid_encryption::{XPublicKey, XSecretKey};
use ruc::*;
use sha3::{Digest, Keccak256};

/// Randomly generate a 12words-length mnemonic.
#[inline(always)]
Expand Down Expand Up @@ -313,17 +315,46 @@ pub fn nullifier_to_base58(n: &Nullifier) -> String {
bs58::encode(&Nullifier::noah_to_bytes(n)).into_string()
}

/// Convert a XfrPublicKey to human-readable address
#[inline(always)]
pub fn public_key_to_human(key: &XfrPublicKey) -> String {
match key.inner() {
XfrPublicKeyInner::Ed25519(_) | XfrPublicKeyInner::Secp256k1(_) => {
public_key_to_bech32(key)
}
XfrPublicKeyInner::Address(bytes) => {
// checksum encode
let hex = hex::encode(bytes);

let mut hasher = Keccak256::new();
hasher.update(hex.as_bytes());
let hash = hasher.finalize();
let check_hash = hex::encode(hash);

let mut res = String::from("0x");
for (index, byte) in hex[..40].chars().enumerate() {
if check_hash.chars().nth(index).unwrap().to_digit(16).unwrap() > 7 {
res += &byte.to_uppercase().to_string();
} else {
res += &byte.to_string();
}
}
res
}
}
}

/// Convert a XfrPublicKey to bech32 human-readable address
#[inline(always)]
pub fn public_key_to_bech32(key: &XfrPublicKey) -> String {
let bytes = &XfrPublicKey::noah_to_bytes(key);
match bytes[0] {
0u8 => bech32enc_fra(<&[u8; 32]>::try_from(&bytes[1..33]).unwrap()),
1u8 => bech32enc_eth(<&[u8; 33]>::try_from(&bytes[1..34]).unwrap()),
2u8 => {
panic!("public key not supported")
let keytype = KeyType::from_byte(bytes[0]);
match keytype {
KeyType::Ed25519 => bech32enc_fra(<&[u8; 32]>::try_from(&bytes[1..33]).unwrap()),
KeyType::Secp256k1 => {
bech32enc_eth(<&[u8; 33]>::try_from(&bytes[1..34]).unwrap())
}
_ => {
KeyType::Address => {
panic!("public key not supported")
}
}
Expand Down