diff --git a/src/components/finutils/src/bins/fn.rs b/src/components/finutils/src/bins/fn.rs index dd0b8b3eb..1002fda1d 100644 --- a/src/components/finutils/src/bins/fn.rs +++ b/src/components/finutils/src/bins/fn.rs @@ -304,6 +304,10 @@ fn run() -> Result<()> { } else { common::setup(sa, om, tp).c(d!())?; } + } else if let Some(m) = matches.subcommand_matches("sign") { + let sk = m.value_of("sk"); + let msg = m.value_of("message"); + common::sign(sk.c(d!())?, msg.c(d!())?).c(d!())?; } else if let Some(m) = matches.subcommand_matches("transfer") { let f = match m.value_of("from-seckey") { Some(path) => { diff --git a/src/components/finutils/src/bins/fn.yml b/src/components/finutils/src/bins/fn.yml index 008be37cf..ba6dabb2a 100644 --- a/src/components/finutils/src/bins/fn.yml +++ b/src/components/finutils/src/bins/fn.yml @@ -39,6 +39,23 @@ subcommands: long: validator-key takes_value: true value_name: Path + - sign: + about: Sign message + args: + - sk: + help: secret key in hex + short: s + long: secret-key + takes_value: true + value_name: SecretKey + required: true + - message: + help: the message string + short: m + long: message + takes_value: true + value_name: Message + required: true - stake: about: Stake tokens (i.e. bond tokens) from a Findora account to a Validator args: diff --git a/src/components/finutils/src/common/mod.rs b/src/components/finutils/src/common/mod.rs index b256ac5aa..baa6373aa 100644 --- a/src/components/finutils/src/common/mod.rs +++ b/src/components/finutils/src/common/mod.rs @@ -6,7 +6,9 @@ //! This module is the library part of FN. //! +use sha3::{Digest, Keccak256}; use std::str::FromStr; +use zei::serialization::ZeiFromToBytes; #[cfg(not(target_arch = "wasm32"))] pub mod dev; @@ -169,6 +171,32 @@ pub fn stake( utils::send_tx(&tx).c(d!()) } +/// Sign message using ed25519 +/// Secret Key +/// Message +pub fn sign(secret_key: &str, message: &str) -> Result<()> { + let pair = + XfrSecretKey::zei_from_bytes(hex::decode(secret_key).c(d!())?.as_slice())? + .into_keypair(); + + let msg_bytes = message.as_bytes(); + let d = Keccak256::digest(msg_bytes); + + let sig = pair.get_sk_ref().sign(d.as_slice(), pair.get_pk_ref()); + + let pk_hex = hex::encode(pair.get_pk_ref().zei_to_bytes()); + let msg_hex = hex::encode(d.as_slice()); + let sig_hex = hex::encode(sig.zei_to_bytes()); + + println!("message: 0x{}", hex::encode(msg_bytes)); + println!("message hash: 0x{}", msg_hex); + println!("public key: 0x{}", pk_hex); + println!("signature: 0x{}", sig_hex); + println!("data: 0x{}{}{}", pk_hex, msg_hex, sig_hex); + + Ok(()) +} + /// Append more FRA token to the specified tendermint node pub fn stake_append( amount: &str,