ethkey and ethstore use hash structures from bigint (#1851)

* Address renamed to H160 at bigint library level

* moved uint specific test from util to bigint library

* naming

* unifing hashes in progress

* unifing hashes

* cleanup redundant unwraps in tests

* fixed compiling
This commit is contained in:
Marek Kotewicz
2016-08-15 15:09:00 +02:00
committed by Gav Wood
parent e6d9fb2ad3
commit c39761c042
32 changed files with 245 additions and 396 deletions

View File

@@ -10,6 +10,7 @@ tiny-keccak = "1.0"
eth-secp256k1 = { git = "https://github.com/ethcore/rust-secp256k1" }
rustc-serialize = "0.3"
docopt = { version = "0.6", optional = true }
bigint = { path = "../util/bigint" }
[features]
default = []

View File

@@ -18,12 +18,11 @@ extern crate docopt;
extern crate rustc_serialize;
extern crate ethkey;
use std::str::FromStr;
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, Address, sign, verify_public, verify_address};
use ethkey::{KeyPair, Random, Brain, Prefix, Error as EthkeyError, Generator, sign, verify_public, verify_address};
pub const USAGE: &'static str = r#"
Ethereum keys generator.
@@ -148,9 +147,9 @@ fn main() {
fn display(keypair: KeyPair, mode: DisplayMode) -> String {
match mode {
DisplayMode::KeyPair => format!("{}", keypair),
DisplayMode::Secret => format!("{}", keypair.secret()),
DisplayMode::Public => format!("{}", keypair.public()),
DisplayMode::Address => format!("{}", keypair.address()),
DisplayMode::Secret => format!("{:?}", keypair.secret()),
DisplayMode::Public => format!("{:?}", keypair.public()),
DisplayMode::Address => format!("{:?}", keypair.address()),
}
}
@@ -161,7 +160,7 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
return if args.cmd_info {
let display_mode = DisplayMode::new(&args);
let secret = try!(Secret::from_str(&args.arg_secret));
let secret = try!(args.arg_secret.parse().map_err(|_| EthkeyError::InvalidSecret));
let keypair = try!(KeyPair::from_secret(secret));
Ok(display(keypair, display_mode))
} else if args.cmd_generate {
@@ -179,18 +178,18 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
};
Ok(display(try!(keypair), display_mode))
} else if args.cmd_sign {
let secret = try!(Secret::from_str(&args.arg_secret));
let message = try!(Message::from_str(&args.arg_message));
let secret = try!(args.arg_secret.parse().map_err(|_| EthkeyError::InvalidSecret));
let message = try!(args.arg_message.parse().map_err(|_| EthkeyError::InvalidMessage));
let signature = try!(sign(&secret, &message));
Ok(format!("{}", signature))
} else if args.cmd_verify {
let signature = try!(Signature::from_str(&args.arg_signature));
let message = try!(Message::from_str(&args.arg_message));
let signature = try!(args.arg_signature.parse().map_err(|_| EthkeyError::InvalidSignature));
let message = try!(args.arg_message.parse().map_err(|_| EthkeyError::InvalidMessage));
let ok = if args.cmd_public {
let public = try!(Public::from_str(&args.arg_public));
let public = try!(args.arg_public.parse().map_err(|_| EthkeyError::InvalidPublic));
try!(verify_public(&public, &signature, &message))
} else if args.cmd_address {
let address = try!(Address::from_str(&args.arg_address));
let address = try!(args.arg_address.parse().map_err(|_| EthkeyError::InvalidAddress));
try!(verify_address(&address, &signature, &message))
} else {
unreachable!();
@@ -212,7 +211,7 @@ mod tests {
.map(Into::into)
.collect::<Vec<String>>();
let expected =
let expected =
"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55
public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124
address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
@@ -226,7 +225,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
.map(Into::into)
.collect::<Vec<String>>();
let expected =
let expected =
"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55
public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124
address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
@@ -272,7 +271,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
.into_iter()
.map(Into::into)
.collect::<Vec<String>>();
let expected = "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200".to_owned();
assert_eq!(execute(command).unwrap(), expected);
}

View File

@@ -38,8 +38,8 @@ pub enum Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match *self {
Error::InvalidSecret => "Invalid secret key".into(),
Error::InvalidPublic => "Invalid public key".into(),
Error::InvalidSecret => "Invalid secret".into(),
Error::InvalidPublic => "Invalid public".into(),
Error::InvalidAddress => "Invalid address".into(),
Error::InvalidSignature => "Invalid EC signature".into(),
Error::InvalidMessage => "Invalid AES message".into(),

View File

@@ -20,13 +20,13 @@ extern crate lazy_static;
extern crate tiny_keccak;
extern crate secp256k1;
extern crate rustc_serialize;
extern crate bigint;
mod brain;
mod error;
mod keypair;
mod keccak;
mod prefix;
mod primitive;
mod random;
mod signature;
@@ -43,7 +43,13 @@ pub trait Generator {
pub use self::brain::Brain;
pub use self::error::Error;
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_public, verify_address, recover, Signature};
use bigint::hash::{H160, H256, H512};
pub type Address = H160;
pub type Secret = H256;
pub type Message = H256;
pub type Public = H512;

View File

@@ -14,125 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::ops::{Deref, DerefMut};
use std::{fmt, cmp, hash};
use std::str::FromStr;
use rustc_serialize::hex::{ToHex, FromHex};
use Error;
macro_rules! impl_primitive {
($name: ident, $size: expr, $err: expr) => {
#[repr(C)]
#[derive(Eq)]
pub struct $name([u8; $size]);
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.to_hex())
}
}
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.to_hex())
}
}
impl FromStr for $name {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.from_hex() {
Ok(ref hex) if hex.len() == $size => {
let mut res = $name::default();
res.copy_from_slice(hex);
Ok(res)
},
_ => Err($err)
}
}
}
impl PartialEq for $name {
fn eq(&self, other: &Self) -> bool {
let self_ref: &[u8] = &self.0;
let other_ref: &[u8] = &other.0;
self_ref == other_ref
}
}
impl PartialOrd for $name {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
let self_ref: &[u8] = &self.0;
let other_ref: &[u8] = &other.0;
self_ref.partial_cmp(other_ref)
}
}
impl Ord for $name {
fn cmp(&self, other: &Self) -> cmp::Ordering {
let self_ref: &[u8] = &self.0;
let other_ref: &[u8] = &other.0;
self_ref.cmp(other_ref)
}
}
impl Clone for $name {
fn clone(&self) -> Self {
let mut res = Self::default();
res.copy_from_slice(&self.0);
res
}
}
impl Default for $name {
fn default() -> Self {
$name([0u8; $size])
}
}
impl From<[u8; $size]> for $name {
fn from(s: [u8; $size]) -> Self {
$name(s)
}
}
impl Into<[u8; $size]> for $name {
fn into(self) -> [u8; $size] {
self.0
}
}
impl hash::Hash for $name {
fn hash<H>(&self, state: &mut H) where H: hash::Hasher {
let self_ref: &[u8] = &self.0;
self_ref.hash(state)
}
}
impl Deref for $name {
type Target = [u8; $size];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for $name {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
}
}
impl_primitive!(Address, 20, Error::InvalidAddress);
impl_primitive!(Secret, 32, Error::InvalidSecret);
impl_primitive!(Message, 32, Error::InvalidMessage);
impl_primitive!(Public, 64, Error::InvalidPublic);
#[cfg(test)]
mod tests {
}

View File

@@ -15,11 +15,13 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::ops::{Deref, DerefMut};
use std::cmp::PartialEq;
use std::{mem, fmt};
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 bigint::hash::H520;
use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address};
#[repr(C)]
@@ -45,7 +47,7 @@ impl Signature {
// manual implementation large arrays don't have trait impls by default.
// remove when integer generics exist
impl ::std::cmp::PartialEq for Signature {
impl PartialEq for Signature {
fn eq(&self, other: &Self) -> bool {
&self.0[..] == &other.0[..]
}
@@ -101,6 +103,18 @@ impl Into<[u8; 65]> for Signature {
}
}
impl From<Signature> for H520 {
fn from(s: Signature) -> Self {
H520::from(s.0)
}
}
impl From<H520> for Signature {
fn from(bytes: H520) -> Self {
Signature(bytes.into())
}
}
impl Deref for Signature {
type Target = [u8; 65];