use rand::rngs::OsRng; use rust_util::XResult; use serde::{Deserialize, Serialize}; use secp256k1::{Secp256k1, SecretKey, key::PublicKey}; use sha2::Sha256; use ripemd160::Ripemd160; use digest::{ Input, FixedOutput }; use std::str::FromStr; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct JsonKeyPair { pub tag: Option, pub identity: String, pub pri_key: String, pub pub_key: String, } impl JsonKeyPair { pub fn from(pri_key: SecretKey, pub_key: PublicKey, tag: Option) -> Self { JsonKeyPair { tag, identity: make_btc_address(&pub_key), pri_key: format!("{}", pri_key), pub_key: format!("{}", pub_key), } } pub fn to_json(&self) -> XResult { serde_json::to_string_pretty(self).map_err(|e| e.into()) } pub fn from_json(json: &str) -> XResult { serde_json::from_str(json).map_err(|e| e.into()) } pub fn to_key_pair(&self) -> XResult<(SecretKey, PublicKey)> { let pri_key = SecretKey::from_str(&self.pri_key)?; let pub_key = PublicKey::from_str(&self.pub_key)?; Ok((pri_key, pub_key)) } } pub fn make_key_pair() -> (SecretKey, PublicKey) { let secp = Secp256k1::new(); let mut rng = OsRng::new().expect("OsRng"); let (secret_key, public_key) = secp.generate_keypair(&mut rng); (secret_key, public_key) } pub fn make_btc_address(public_key: &PublicKey) -> String { let public_key_bytes = public_key.serialize_uncompressed().to_vec(); let riphemd160_sha256_pub_key = calc_ripemd160(&calc_sha256(&public_key_bytes)); let mut btc_addr = Vec::::with_capacity(25); btc_addr.push(0x00 as u8); btc_addr.extend_from_slice(&riphemd160_sha256_pub_key); let checksum = &calc_sha256(&calc_sha256(&btc_addr))[0..4]; btc_addr.extend_from_slice(checksum); bs58::encode(&btc_addr).into_string() } #[inline] pub fn calc_sha256(i: &[u8]) -> Vec { calc_hash(Sha256::default(), i) } #[inline] fn calc_ripemd160(i: &[u8]) -> Vec { calc_hash(Ripemd160::default(), i) } #[inline] fn calc_hash(mut hasher: T, i: &[u8]) -> Vec where T: Input + FixedOutput { hasher.input(&i); hasher.fixed_result().to_vec() }