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

Feature/feat eth2 #36

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ members = [
"wallet/coin-bch",
"wallet/coin-filecoin",
"wallet/coin-btc-fork",
"wallet/coin-ethereum2",
]
1 change: 1 addition & 0 deletions api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ coin-tron = {path = "../wallet/coin-tron"}
coin-ckb = {path = "../wallet/coin-ckb"}
coin-bch = {path = "../wallet/coin-bch"}
coin-btc-fork = {path = "../wallet/coin-btc-fork"}
coin-ethereum2 = {path = "../wallet/coin-ethereum2"}

common = {path = "../common"}
coin-tezos = {path = "../wallet/coin-tezos"}
Expand Down
17 changes: 17 additions & 0 deletions api/src/ethereum2_address.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use crate::api::PubKeyResult;
use crate::error_handling::Result;
use crate::message_handler::encode_message;
use crate::PubKeyParam;
use coin_ethereum2::address::Eth2Address;
use prost::Message;

pub fn get_pub_key(param: &PubKeyParam) -> Result<Vec<u8>> {
let pub_key = Eth2Address::get_pub_key(&param.path)?;
let return_message = PubKeyResult {
path: param.path.to_owned(),
chain_type: param.chain_type.to_string(),
pub_key: pub_key,
derived_mode: "".to_string(),
};
encode_message(return_message)
}
13 changes: 13 additions & 0 deletions api/src/ethereum2_signer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use crate::error_handling::Result;
use crate::message_handler::encode_message;
use coin_ethereum2::eth2api::Eth2MsgSignInput;
use coin_ethereum2::transaction::Eth2Sign;
use coin_substrate::substrateapi::SubstrateRawTxIn;
use common::SignParam;
use prost::Message;

pub fn sign_eth2_message(data: &[u8], sign_param: &SignParam) -> Result<Vec<u8>> {
let sign_data: Eth2MsgSignInput = Eth2MsgSignInput::decode(data).expect("imkey_illegal_param");
let signed = Eth2Sign::msg_sign(sign_data, sign_param)?;
encode_message(signed)
}
3 changes: 3 additions & 0 deletions api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub mod device_manager;
pub mod eos_pubkey;
pub mod eos_signer;
pub mod error_handling;
pub mod ethereum2_address;
pub mod ethereum2_signer;
pub mod ethereum_address;
pub mod ethereum_signer;
pub mod filecoin_address;
Expand Down Expand Up @@ -150,6 +152,7 @@ pub unsafe extern "C" fn call_imkey_api(hex_str: *const c_char) -> *const c_char
"EOS" => eos_pubkey::get_eos_pubkey(&param),
"TEZOS" => tezos_address::get_pub_key(&param),
"COSMOS" => cosmos_address::get_cosmos_pub_key(&param),
"ETHEREUM2" => ethereum2_address::get_pub_key(&param),
_ => Err(format_err!("get_pub_key unsupported_chain")),
}
}),
Expand Down
36 changes: 36 additions & 0 deletions common/src/apdu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,42 @@ impl ImkApdu {
}
}

pub struct BlsApdu();

impl Default for BlsApdu {
fn default() -> Self {
BlsApdu()
}
}

impl BlsApdu {
pub fn sign(data: &[u8]) -> Vec<String> {
Apdu::prepare_sign(0x81, data.to_vec())
}
pub fn msg_sign(data: &[u8]) -> Vec<String> {
Apdu::prepare_sign(0x55, data.to_vec())
}

pub fn get_xpub(data: &[u8]) -> String {
if data.len() as u32 > LC_MAX {
panic!("data to long");
}
let mut apdu = ApduHeader::new(0x80, 0x82, 0x00, 0x00, data.len() as u8).to_array();
apdu.extend(data);
apdu.push(0x00); //Le
hex::encode(apdu)
}

pub fn register_address(name: &[u8], address: &[u8]) -> String {
let mut data: Vec<u8> = vec![];
data.push(address.len() as u8);
data.extend(address);
data.push(name.len() as u8);
data.extend(name);
Apdu::register_address(0x83, &data)
}
}

pub struct ApduCheck {}

impl ApduCheck {
Expand Down
6 changes: 4 additions & 2 deletions common/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub const VERSION: &str = "2.9.8";
pub const URL: &str = "https://imkey.online:1000/imkey";
// pub const URL: &str = "https://imkeyserver.com:10444/imkey";
// pub const URL: &str = "https://imkey.online:1000/imkey";
pub const URL: &str = "https://imkeyserver.com:10443/imkey";

pub const TSM_ACTION_SE_SECURE_CHECK: &str = "/seSecureCheck";
pub const TSM_ACTION_APP_DOWNLOAD: &str = "/appDownload";
Expand Down Expand Up @@ -29,6 +29,7 @@ pub const NERVOS_AID: &str = "695F6B315F636B62";
pub const TEZOS_AID: &str = "695F65645F78747A";
pub const BCH_AID: &str = "695F626368";
pub const LTC_AID: &str = "695F6C7463";
pub const ETH2_AID: &str = "695f65746832";

pub const BL_AID: &str = "D0426F6F746C6F61646572";

Expand All @@ -41,6 +42,7 @@ pub const NERVOS_PATH: &str = "m/44'/309'/0'/0/0";
pub const POLKADOT_PATH: &str = "m/44'/354'/0'/0'/0'";
pub const KUSAMA_PATH: &str = "m/44'/434'/0'/0'/0'";
pub const TRON_PATH: &str = "m/44'/195'/0'/0/0";
pub const ETH2_PATH: &str = "m/12381/3600/0/0";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确定前面的path不是harden 的是吧

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以看看https://eips.ethereum.org/EIPS/eip-2333 目前来看这个派生方案和bip32是不兼容的


pub const MAX_UTXO_NUMBER: usize = 252;
pub const EACH_ROUND_NUMBER: usize = 5;
Expand Down
2 changes: 2 additions & 0 deletions common/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,6 @@ pub enum CoinError {
InvalidVersion,
#[fail(display = "invalid addr length")]
InvalidAddrLength,
#[fail(display = "signature data too long")]
SignDataTooLong,
}
Empty file added device/src/bind_code.txt
Empty file.
4 changes: 4 additions & 0 deletions proto/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ fn main() {
// tcx-btc-fork
env::set_var("OUT_DIR", "../wallet/coin-btc-fork/src");
prost_build::compile_protos(&["src/btcfork.proto"], &["src/"]).unwrap();

// eth2
env::set_var("OUT_DIR", "../wallet/coin-ethereum2/src");
prost_build::compile_protos(&["src/eth2.proto"], &["src/"]).unwrap();
}

#[cfg(test)]
Expand Down
10 changes: 10 additions & 0 deletions proto/src/eth2.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
syntax = "proto3";
package eth2api;

message Eth2MsgSignInput {
string message = 1;
}

message Eth2MsgSignOutput {
string signature = 1;
}
1 change: 0 additions & 1 deletion rust-toolchain

This file was deleted.

16 changes: 16 additions & 0 deletions wallet/coin-ethereum2/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "coin-ethereum2"
version = "0.1.0"
authors = ["xiaoguang <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
common = {path = "../../common"}
device = {path = "../../device"}
transport = {path = "../../transport"}
failure = "0.1.6"
hex = "0.3.2"
prost = "0.6.1"
prost-types = "0.6.1"
74 changes: 74 additions & 0 deletions wallet/coin-ethereum2/src/address.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use crate::Result;

use common::apdu::{Apdu, ApduCheck, BlsApdu};
use common::constants::ETH2_AID;
use common::error::CoinError;
use common::path::check_path_validity;
use common::utility;
use common::utility::secp256k1_sign_verify;
use device::device_binding::KEY_MANAGER;
use hex;
use transport::message;
use transport::message::send_apdu;

#[derive(Debug)]
pub struct Eth2Address {}

impl Eth2Address {
pub fn get_pub_key(path: &str) -> Result<String> {
check_path_validity(path)?;

let select_apdu = Apdu::select_applet(ETH2_AID);
let select_response = message::send_apdu(select_apdu)?;
ApduCheck::check_response(&select_response)?;

let key_manager_obj = KEY_MANAGER.lock();
let bind_signature = utility::secp256k1_sign(&key_manager_obj.pri_key, &path.as_bytes())?;

let mut apdu_pack: Vec<u8> = vec![];
apdu_pack.push(0x00);
apdu_pack.push(bind_signature.len() as u8);
apdu_pack.extend(bind_signature.as_slice());
apdu_pack.push(0x01);
apdu_pack.push(path.as_bytes().len() as u8);
apdu_pack.extend(path.as_bytes());

//get public
let msg_pubkey = BlsApdu::get_xpub(&apdu_pack);
let res_msg_pubkey = send_apdu(msg_pubkey)?;
ApduCheck::check_response(&res_msg_pubkey)?;

let pubkey = &res_msg_pubkey[..96];
let sign_result = &res_msg_pubkey[96..res_msg_pubkey.len() - 4];

//se signature verify
let sign_verify_result = secp256k1_sign_verify(
&key_manager_obj.se_pub_key,
hex::decode(sign_result).unwrap().as_slice(),
hex::decode(pubkey).unwrap().as_slice(),
)?;
if !sign_verify_result {
return Err(CoinError::ImkeySignatureVerifyFail.into());
}

Ok(pubkey.to_string())
}
}

#[cfg(test)]
mod test {
use crate::address::Eth2Address;
use common::constants;
use device::device_binding::bind_test;

#[test]
fn test_get_pub_key() {
bind_test();

let uncomprs_pubkey = Eth2Address::get_pub_key(constants::ETH2_PATH).unwrap();
assert_eq!(
&uncomprs_pubkey,
"80CCA779CE5C8C183232518B3F7BF9D1A4AB8767589D320FE39A9379A674765A766FFC99FACC7D60F157F7E5F01E9D01"
);
}
}
10 changes: 10 additions & 0 deletions wallet/coin-ethereum2/src/eth2api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Eth2MsgSignInput {
#[prost(string, tag = "1")]
pub message: std::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Eth2MsgSignOutput {
#[prost(string, tag = "1")]
pub signature: std::string::String,
}
16 changes: 16 additions & 0 deletions wallet/coin-ethereum2/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pub mod address;
pub mod eth2api;
pub mod transaction;

#[macro_use]
extern crate failure;
use core::result;
pub type Result<T> = result::Result<T, failure::Error>;

#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
Loading