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 brain <seed> [options]
|
||||
ethkey sign <secret> <message>
|
||||
ethkey verify <public> <signature> <message>
|
||||
ethkey verify public <public> <signature> <message>
|
||||
ethkey verify address <address> <signature> <message>
|
||||
ethkey [-h | --help]
|
||||
|
||||
Options:
|
||||
@ -126,15 +127,32 @@ c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8
|
||||
|
||||
--
|
||||
|
||||
#### `verify <public> <signature> <message>`
|
||||
#### `verify public <public> <signature> <message>`
|
||||
*Verify the signature.*
|
||||
|
||||
- `<secret>` - ethereum public, 64 bytes long
|
||||
- `<public>` - ethereum public, 64 bytes long
|
||||
- `<signature>` - message signature, 65 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 docopt::Docopt;
|
||||
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#"
|
||||
Ethereum keys generator.
|
||||
@ -19,7 +19,8 @@ Usage:
|
||||
ethkey generate prefix <prefix> <iterations> [options]
|
||||
ethkey generate brain <seed> [options]
|
||||
ethkey sign <secret> <message>
|
||||
ethkey verify <public> <signature> <message>
|
||||
ethkey verify public <public> <signature> <message>
|
||||
ethkey verify address <address> <signature> <message>
|
||||
ethkey [-h | --help]
|
||||
|
||||
Options:
|
||||
@ -47,12 +48,15 @@ struct Args {
|
||||
cmd_brain: bool,
|
||||
cmd_sign: bool,
|
||||
cmd_verify: bool,
|
||||
cmd_public: bool,
|
||||
cmd_address: bool,
|
||||
arg_prefix: String,
|
||||
arg_iterations: String,
|
||||
arg_seed: String,
|
||||
arg_secret: String,
|
||||
arg_message: String,
|
||||
arg_public: String,
|
||||
arg_address: String,
|
||||
arg_signature: String,
|
||||
flag_secret: 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));
|
||||
Ok(format!("{}", signature))
|
||||
} else if args.cmd_verify {
|
||||
let public = try!(Public::from_str(&args.arg_public));
|
||||
let signature = try!(Signature::from_str(&args.arg_signature));
|
||||
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))
|
||||
} else {
|
||||
unreachable!();
|
||||
@ -251,8 +262,19 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_valid() {
|
||||
let command = vec!["ethkey", "verify", "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987"]
|
||||
fn verify_valid_public() {
|
||||
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()
|
||||
.map(Into::into)
|
||||
.collect::<Vec<String>>();
|
||||
@ -263,7 +285,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
||||
|
||||
#[test]
|
||||
fn verify_invalid() {
|
||||
let command = vec!["ethkey", "verify", "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec986"]
|
||||
let command = vec!["ethkey", "verify", "public", "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec986"]
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect::<Vec<String>>();
|
||||
|
@ -4,6 +4,13 @@ use rustc_serialize::hex::ToHex;
|
||||
use keccak::Keccak256;
|
||||
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
|
||||
pub struct KeyPair {
|
||||
secret: Secret,
|
||||
@ -60,10 +67,7 @@ impl KeyPair {
|
||||
}
|
||||
|
||||
pub fn address(&self) -> Address {
|
||||
let hash = self.public.keccak256();
|
||||
let mut result = Address::default();
|
||||
result.copy_from_slice(&hash[12..]);
|
||||
result
|
||||
public_to_address(&self.public)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ pub trait Generator {
|
||||
|
||||
pub use self::brain::Brain;
|
||||
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::prefix::Prefix;
|
||||
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::key::{SecretKey, PublicKey};
|
||||
use rustc_serialize::hex::{ToHex, FromHex};
|
||||
use {Secret, Public, SECP256K1, Error, Message};
|
||||
use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Eq)]
|
||||
@ -113,7 +113,7 @@ pub fn sign(secret: &Secret, message: &Message) -> Result<Signature, Error> {
|
||||
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 rsig = try!(RecoverableSignature::from_compact(context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32))));
|
||||
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)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
use {Generator, Random, Message};
|
||||
use super::{sign, verify, Signature};
|
||||
use super::{sign, verify_public, verify_address, recover, Signature};
|
||||
|
||||
#[test]
|
||||
fn signature_to_and_from_str() {
|
||||
@ -149,10 +166,26 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_and_verify() {
|
||||
fn sign_and_recover_public() {
|
||||
let keypair = Random.generate().unwrap();
|
||||
let message = Message::default();
|
||||
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)]
|
||||
mod tests {
|
||||
use ethkey::{Generator, Random, verify, Message};
|
||||
use ethkey::{Generator, Random, verify_public, Message};
|
||||
use super::{Crypto, SafeAccount};
|
||||
|
||||
#[test]
|
||||
@ -174,13 +174,13 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_and_verify() {
|
||||
fn sign_and_verify_public() {
|
||||
let keypair = Random.generate().unwrap();
|
||||
let password = "hello world";
|
||||
let message = Message::default();
|
||||
let account = SafeAccount::create(&keypair, [0u8; 16], password, 10240);
|
||||
let signature = account.sign(password, &message).unwrap();
|
||||
assert!(verify(keypair.public(), &signature, &message).unwrap());
|
||||
assert!(verify_public(keypair.public(), &signature, &message).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! 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;
|
||||
|
||||
impl Into<json::H160> for Address {
|
||||
|
Loading…
Reference in New Issue
Block a user