Skip to content
This repository has been archived by the owner on Nov 3, 2022. It is now read-only.

Commit

Permalink
Merge pull request #6 from golemfactory/gu-keystore
Browse files Browse the repository at this point in the history
keystore initial revision
  • Loading branch information
prekucki authored Aug 27, 2018
2 parents e601e61 + 22c557f commit d4b2476
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 11 deletions.
50 changes: 46 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
members= [
'gu-provider',
'gu-hub',
'gu-keystore',
'gu-ethkeys',
'gu-p2p',
'gu-persist',
]
Expand Down
14 changes: 14 additions & 0 deletions gu-ethkeys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "gu-ethkeys"
version = "0.1.0"
authors = ["Golem Unlimited Team, Piotr Chromiec <[email protected]>"]

[dependencies]
log = "0.4"
env_logger = "0.5"
lazy_static = "1.0"
rand = "0.4"
eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" }
tiny-keccak = "1.4"
rustc-hex = "1.0"
lazycell = "1.0"
32 changes: 32 additions & 0 deletions gu-ethkeys/examples/simple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate gu_ethkeys;
extern crate secp256k1;

use std::env;
use gu_ethkeys::{KeyPair, EthKey};
use secp256k1::Message;

fn main() {
if env::var("RUST_LOG").is_err() {
env::set_var("RUST_LOG", "info")
}
env_logger::init();

info!("Starting app {:?}", env::args());

let keys : KeyPair = KeyPair::generate();
info!("Generated keys: {}", keys);
info!("Generated private key: {:?}", keys.private());
info!("Generated public key: {:?}", keys.public());
info!("Generated address: {:?}", keys.address());

let mut v = [0u8; 32];
v[0]=39u8;
v[1]=50u8;
let msg : Message = Message::from(v);
let sig = keys.sign(msg).unwrap();
info!("signature {:?} for {:?}", sig, msg);
assert!(keys.verify(msg, sig).is_ok());
}
124 changes: 124 additions & 0 deletions gu-ethkeys/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
extern crate rand;
extern crate secp256k1;
#[macro_use]
extern crate lazy_static;
extern crate tiny_keccak;
extern crate rustc_hex;
extern crate lazycell;

use std::fmt;
use std::path::Path;
use rand::os::OsRng;
use secp256k1::Secp256k1;
use secp256k1::key::{SecretKey, PublicKey};
pub use secp256k1::{Message, Signature, Error};
use tiny_keccak::Keccak;
use rustc_hex::ToHex;
use lazycell::LazyCell;

const KEY_FILE_NAME: &str = "keystore.json";
const ADDRESS_LENGTH: usize = 20;

pub type Address = [u8; ADDRESS_LENGTH];

lazy_static! {
static ref SECP256K1: Secp256k1 = Secp256k1::new();
}

pub trait EthKey {
/// generates random keys: secret + public
fn generate() -> Self;

/// get private key
fn private(&self) -> &SecretKey;

/// get public key
fn public(&self) -> &PublicKey;

/// get ethereum address
fn address(&self) -> &Address;

/// signs message with sef key
fn sign(&self, msg: Message) -> Result<Signature, Error>;

/// verifies signature for message and self key
fn verify(&self, msg: Message, sig: Signature) -> Result<(), Error>;

/// ciphers given plain data
fn encrypt(&self, plain: &[u8]) -> Result<Vec<u8>, Error>;

/// deciphers given encrypted data
fn decrypt(&self, encrypted: &[u8]) -> Result<Vec<u8>, Error>;

/// stores keys on disk with pass
fn serialize(&self, file_path: &Path, passwd: &str);

/// reads keys from disk; pass needed
fn deserialize(&self, file_path: &Path, passwd: &str);
}

#[derive(Debug)]
pub struct KeyPair {
private: SecretKey,
public: PublicKey,
address: LazyCell<Address>,
}

impl EthKey for KeyPair {
fn generate() -> Self {
let mut rng = OsRng::new().unwrap();
let (private, public) = SECP256K1.generate_keypair(&mut rng)
.expect("should generate key pair");

KeyPair { private, public, address: LazyCell::new() }
}

fn private(&self) -> &SecretKey {
&self.private
}

fn public(&self) -> &PublicKey {
&self.public
}

fn address(&self) -> &Address {
self.address.borrow_with(|| {
let mut hash = [0u8; 32];
Keccak::keccak256(&self.public.serialize_vec(&SECP256K1, false), &mut hash);
let mut result = [0u8; ADDRESS_LENGTH];
result.copy_from_slice(&hash[12..]);
result
})
}

fn sign(&self, msg: Message) -> Result<Signature, Error> {
SECP256K1.sign(&msg, &self.private)
}

fn verify(&self, msg: Message, sig: Signature) -> Result<(), Error> {
SECP256K1.verify(&msg, &sig, &self.public)
}

fn encrypt(&self, plain: &[u8]) -> Result<Vec<u8>, Error> {
unimplemented!("{:?}", plain)
}

fn decrypt(&self, encrypted: &[u8]) -> Result<Vec<u8>, Error> {
unimplemented!("{:?}", encrypted)
}

fn serialize(&self, file_path: &Path, passwd: &str) {
unimplemented!("{:?}, {:?}", file_path, passwd)
}

fn deserialize(&self, file_path: &Path, passwd: &str) {
unimplemented!("{:?}, {:?}", file_path, passwd)
}
}

impl fmt::Display for KeyPair {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "\n\t{:?}\n\t{:?}\n\tAddress({})",
self.private, self.public, self.address().to_hex())
}
}
5 changes: 0 additions & 5 deletions gu-keystore/Cargo.toml

This file was deleted.

1 change: 0 additions & 1 deletion gu-keystore/src/lib.rs

This file was deleted.

0 comments on commit d4b2476

Please sign in to comment.