Updated ethkey to the latest version
This commit is contained in:
parent
bf6308312e
commit
074311d95b
@ -21,7 +21,8 @@ Usage:
|
|||||||
ethkey generate prefix <prefix> <iterations> [options]
|
ethkey generate prefix <prefix> <iterations> [options]
|
||||||
ethkey generate brain <seed> [options]
|
ethkey generate brain <seed> [options]
|
||||||
ethkey sign <secret> <message>
|
ethkey sign <secret> <message>
|
||||||
ethkey verify <public> <signature> <message>
|
ethkey verify public <public> <signature> <message>
|
||||||
|
ethkey verify address <address> <signature> <message>
|
||||||
ethkey [-h | --help]
|
ethkey [-h | --help]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
@ -126,15 +127,32 @@ c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8
|
|||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
#### `verify <public> <signature> <message>`
|
#### `verify public <public> <signature> <message>`
|
||||||
*Verify the signature.*
|
*Verify the signature.*
|
||||||
|
|
||||||
- `<secret>` - ethereum public, 64 bytes long
|
- `<public>` - ethereum public, 64 bytes long
|
||||||
- `<signature>` - message signature, 65 bytes long
|
- `<signature>` - message signature, 65 bytes long
|
||||||
- `<message>` - message, 32 bytes long
|
- `<message>` - message, 32 bytes long
|
||||||
|
|
||||||
```
|
```
|
||||||
ethkey verify 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200 bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987
|
ethkey verify public 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200 bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
true
|
||||||
|
```
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
#### `verify address <address> <signature> <message>`
|
||||||
|
*Verify the signature.*
|
||||||
|
|
||||||
|
- `<address>` - ethereum address, 20 bytes long
|
||||||
|
- `<signature>` - message signature, 65 bytes long
|
||||||
|
- `<message>` - message, 32 bytes long
|
||||||
|
|
||||||
|
```
|
||||||
|
ethkey verify address 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200 bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -7,7 +7,7 @@ use std::{env, fmt, process};
|
|||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
use rustc_serialize::hex::{FromHex, FromHexError};
|
use rustc_serialize::hex::{FromHex, FromHexError};
|
||||||
use ethkey::{KeyPair, Random, Brain, Prefix, Error as EthkeyError, Generator, Secret, Message, Public, Signature, sign, verify};
|
use ethkey::{KeyPair, Random, Brain, Prefix, Error as EthkeyError, Generator, Secret, Message, Public, Signature, Address, sign, verify_public, verify_address};
|
||||||
|
|
||||||
pub const USAGE: &'static str = r#"
|
pub const USAGE: &'static str = r#"
|
||||||
Ethereum keys generator.
|
Ethereum keys generator.
|
||||||
@ -19,7 +19,8 @@ Usage:
|
|||||||
ethkey generate prefix <prefix> <iterations> [options]
|
ethkey generate prefix <prefix> <iterations> [options]
|
||||||
ethkey generate brain <seed> [options]
|
ethkey generate brain <seed> [options]
|
||||||
ethkey sign <secret> <message>
|
ethkey sign <secret> <message>
|
||||||
ethkey verify <public> <signature> <message>
|
ethkey verify public <public> <signature> <message>
|
||||||
|
ethkey verify address <address> <signature> <message>
|
||||||
ethkey [-h | --help]
|
ethkey [-h | --help]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
@ -47,12 +48,15 @@ struct Args {
|
|||||||
cmd_brain: bool,
|
cmd_brain: bool,
|
||||||
cmd_sign: bool,
|
cmd_sign: bool,
|
||||||
cmd_verify: bool,
|
cmd_verify: bool,
|
||||||
|
cmd_public: bool,
|
||||||
|
cmd_address: bool,
|
||||||
arg_prefix: String,
|
arg_prefix: String,
|
||||||
arg_iterations: String,
|
arg_iterations: String,
|
||||||
arg_seed: String,
|
arg_seed: String,
|
||||||
arg_secret: String,
|
arg_secret: String,
|
||||||
arg_message: String,
|
arg_message: String,
|
||||||
arg_public: String,
|
arg_public: String,
|
||||||
|
arg_address: String,
|
||||||
arg_signature: String,
|
arg_signature: String,
|
||||||
flag_secret: bool,
|
flag_secret: bool,
|
||||||
flag_public: bool,
|
flag_public: bool,
|
||||||
@ -164,10 +168,17 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
|
|||||||
let signature = try!(sign(&secret, &message));
|
let signature = try!(sign(&secret, &message));
|
||||||
Ok(format!("{}", signature))
|
Ok(format!("{}", signature))
|
||||||
} else if args.cmd_verify {
|
} else if args.cmd_verify {
|
||||||
let public = try!(Public::from_str(&args.arg_public));
|
|
||||||
let signature = try!(Signature::from_str(&args.arg_signature));
|
let signature = try!(Signature::from_str(&args.arg_signature));
|
||||||
let message = try!(Message::from_str(&args.arg_message));
|
let message = try!(Message::from_str(&args.arg_message));
|
||||||
let ok = try!(verify(&public, &signature, &message));
|
let ok = if args.cmd_public {
|
||||||
|
let public = try!(Public::from_str(&args.arg_public));
|
||||||
|
try!(verify_public(&public, &signature, &message))
|
||||||
|
} else if args.cmd_address {
|
||||||
|
let address = try!(Address::from_str(&args.arg_address));
|
||||||
|
try!(verify_address(&address, &signature, &message))
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
Ok(format!("{}", ok))
|
Ok(format!("{}", ok))
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
@ -251,8 +262,19 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_valid() {
|
fn verify_valid_public() {
|
||||||
let command = vec!["ethkey", "verify", "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987"]
|
let command = vec!["ethkey", "verify", "public", "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987"]
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
|
let expected = "true".to_owned();
|
||||||
|
assert_eq!(execute(command).unwrap(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn verify_valid_address() {
|
||||||
|
let command = vec!["ethkey", "verify", "address", "26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987"]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
@ -263,7 +285,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_invalid() {
|
fn verify_invalid() {
|
||||||
let command = vec!["ethkey", "verify", "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec986"]
|
let command = vec!["ethkey", "verify", "public", "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec986"]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
@ -4,6 +4,13 @@ use rustc_serialize::hex::ToHex;
|
|||||||
use keccak::Keccak256;
|
use keccak::Keccak256;
|
||||||
use super::{Secret, Public, Address, SECP256K1, Error};
|
use super::{Secret, Public, Address, SECP256K1, Error};
|
||||||
|
|
||||||
|
pub fn public_to_address(public: &Public) -> Address {
|
||||||
|
let hash = public.keccak256();
|
||||||
|
let mut result = Address::default();
|
||||||
|
result.copy_from_slice(&hash[12..]);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
/// secp256k1 key pair
|
/// secp256k1 key pair
|
||||||
pub struct KeyPair {
|
pub struct KeyPair {
|
||||||
secret: Secret,
|
secret: Secret,
|
||||||
@ -60,10 +67,7 @@ impl KeyPair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn address(&self) -> Address {
|
pub fn address(&self) -> Address {
|
||||||
let hash = self.public.keccak256();
|
public_to_address(&self.public)
|
||||||
let mut result = Address::default();
|
|
||||||
result.copy_from_slice(&hash[12..]);
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ pub trait Generator {
|
|||||||
|
|
||||||
pub use self::brain::Brain;
|
pub use self::brain::Brain;
|
||||||
pub use self::error::Error;
|
pub use self::error::Error;
|
||||||
pub use self::keypair::KeyPair;
|
pub use self::keypair::{KeyPair, public_to_address};
|
||||||
pub use self::primitive::{Secret, Public, Address, Message};
|
pub use self::primitive::{Secret, Public, Address, Message};
|
||||||
pub use self::prefix::Prefix;
|
pub use self::prefix::Prefix;
|
||||||
pub use self::random::Random;
|
pub use self::random::Random;
|
||||||
pub use self::signature::{sign, verify, Signature};
|
pub use self::signature::{sign, verify_public, verify_address, recover, Signature};
|
||||||
|
@ -4,7 +4,7 @@ use std::str::FromStr;
|
|||||||
use secp256k1::{Message as SecpMessage, RecoverableSignature, RecoveryId, Error as SecpError};
|
use secp256k1::{Message as SecpMessage, RecoverableSignature, RecoveryId, Error as SecpError};
|
||||||
use secp256k1::key::{SecretKey, PublicKey};
|
use secp256k1::key::{SecretKey, PublicKey};
|
||||||
use rustc_serialize::hex::{ToHex, FromHex};
|
use rustc_serialize::hex::{ToHex, FromHex};
|
||||||
use {Secret, Public, SECP256K1, Error, Message};
|
use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Eq)]
|
#[derive(Eq)]
|
||||||
@ -113,7 +113,7 @@ pub fn sign(secret: &Secret, message: &Message) -> Result<Signature, Error> {
|
|||||||
Ok(Signature(data_arr))
|
Ok(Signature(data_arr))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify(public: &Public, signature: &Signature, message: &Message) -> Result<bool, Error> {
|
pub fn verify_public(public: &Public, signature: &Signature, message: &Message) -> Result<bool, Error> {
|
||||||
let context = &SECP256K1;
|
let context = &SECP256K1;
|
||||||
let rsig = try!(RecoverableSignature::from_compact(context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32))));
|
let rsig = try!(RecoverableSignature::from_compact(context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32))));
|
||||||
let sig = rsig.to_standard(context);
|
let sig = rsig.to_standard(context);
|
||||||
@ -132,11 +132,28 @@ pub fn verify(public: &Public, signature: &Signature, message: &Message) -> Resu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn verify_address(address: &Address, signature: &Signature, message: &Message) -> Result<bool, Error> {
|
||||||
|
let public = try!(recover(signature, message));
|
||||||
|
let recovered_address = public_to_address(&public);
|
||||||
|
Ok(address == &recovered_address)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recover(signature: &Signature, message: &Message) -> Result<Public, Error> {
|
||||||
|
let context = &SECP256K1;
|
||||||
|
let rsig = try!(RecoverableSignature::from_compact(context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32))));
|
||||||
|
let pubkey = try!(context.recover(&try!(SecpMessage::from_slice(&message[..])), &rsig));
|
||||||
|
let serialized = pubkey.serialize_vec(context, false);
|
||||||
|
|
||||||
|
let mut public = Public::default();
|
||||||
|
public.copy_from_slice(&serialized[1..65]);
|
||||||
|
Ok(public)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use {Generator, Random, Message};
|
use {Generator, Random, Message};
|
||||||
use super::{sign, verify, Signature};
|
use super::{sign, verify_public, verify_address, recover, Signature};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn signature_to_and_from_str() {
|
fn signature_to_and_from_str() {
|
||||||
@ -149,10 +166,26 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sign_and_verify() {
|
fn sign_and_recover_public() {
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let message = Message::default();
|
let message = Message::default();
|
||||||
let signature = sign(keypair.secret(), &message).unwrap();
|
let signature = sign(keypair.secret(), &message).unwrap();
|
||||||
assert!(verify(keypair.public(), &signature, &message).unwrap());
|
assert_eq!(keypair.public(), &recover(&signature, &message).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sign_and_verify_public() {
|
||||||
|
let keypair = Random.generate().unwrap();
|
||||||
|
let message = Message::default();
|
||||||
|
let signature = sign(keypair.secret(), &message).unwrap();
|
||||||
|
assert!(verify_public(keypair.public(), &signature, &message).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sign_and_verify_address() {
|
||||||
|
let keypair = Random.generate().unwrap();
|
||||||
|
let message = Message::default();
|
||||||
|
let signature = sign(keypair.secret(), &message).unwrap();
|
||||||
|
assert!(verify_address(&keypair.address(), &signature, &message).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ impl SafeAccount {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ethkey::{Generator, Random, verify, Message};
|
use ethkey::{Generator, Random, verify_public, Message};
|
||||||
use super::{Crypto, SafeAccount};
|
use super::{Crypto, SafeAccount};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -174,13 +174,13 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sign_and_verify() {
|
fn sign_and_verify_public() {
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
let password = "hello world";
|
let password = "hello world";
|
||||||
let message = Message::default();
|
let message = Message::default();
|
||||||
let account = SafeAccount::create(&keypair, [0u8; 16], password, 10240);
|
let account = SafeAccount::create(&keypair, [0u8; 16], password, 10240);
|
||||||
let signature = account.sign(password, &message).unwrap();
|
let signature = account.sign(password, &message).unwrap();
|
||||||
assert!(verify(keypair.public(), &signature, &message).unwrap());
|
assert!(verify_public(keypair.public(), &signature, &message).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! ethkey reexport to make documentation look pretty.
|
//! ethkey reexport to make documentation look pretty.
|
||||||
pub use _ethkey::{Address, Message, Signature, Public, Secret, Generator, sign, verify, Error, KeyPair, Random, Prefix};
|
pub use _ethkey::*;
|
||||||
use json;
|
use json;
|
||||||
|
|
||||||
impl Into<json::H160> for Address {
|
impl Into<json::H160> for Address {
|
||||||
|
Loading…
Reference in New Issue
Block a user