From 1e8dd6321f390c440755f29197b487d8b64c152b Mon Sep 17 00:00:00 2001 From: arkpar Date: Sun, 17 Jan 2016 14:09:42 +0100 Subject: [PATCH] Global secp256k1 context --- util/src/crypto.rs | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/util/src/crypto.rs b/util/src/crypto.rs index 35bb3b7eb..7e1c5fce1 100644 --- a/util/src/crypto.rs +++ b/util/src/crypto.rs @@ -8,6 +8,10 @@ pub type Secret = H256; pub type Public = H512; pub type Signature = H520; +lazy_static! { + static ref SECP256K1: Secp256k1 = Secp256k1::new(); +} + impl Signature { /// Create a new signature from the R, S and V componenets. pub fn from_rsv(r: &H256, s: &H256, v: u8) -> Signature { @@ -82,10 +86,10 @@ pub struct KeyPair { impl KeyPair { /// Create a pair from secret key pub fn from_secret(secret: Secret) -> Result { - let context = Secp256k1::new(); - let s: key::SecretKey = try!(key::SecretKey::from_slice(&context, &secret)); - let pub_key = try!(key::PublicKey::from_secret_key(&context, &s)); - let serialized = pub_key.serialize_vec(&context, false); + let context = &SECP256K1; + let s: key::SecretKey = try!(key::SecretKey::from_slice(context, &secret)); + let pub_key = try!(key::PublicKey::from_secret_key(context, &s)); + let serialized = pub_key.serialize_vec(context, false); let p: Public = Public::from_slice(&serialized[1..65]); Ok(KeyPair { secret: secret, @@ -94,10 +98,10 @@ impl KeyPair { } /// Create a new random key pair pub fn create() -> Result { - let context = Secp256k1::new(); + let context = &SECP256K1; let mut rng = try!(OsRng::new()); let (sec, publ) = try!(context.generate_keypair(&mut rng)); - let serialized = publ.serialize_vec(&context, false); + let serialized = publ.serialize_vec(context, false); let p: Public = Public::from_slice(&serialized[1..65]); let s: Secret = unsafe { ::std::mem::transmute(sec) }; Ok(KeyPair { @@ -128,10 +132,10 @@ pub mod ec { /// Recovers Public key from signed message hash. pub fn recover(signature: &Signature, message: &H256) -> Result { use secp256k1::*; - let context = Secp256k1::new(); - let rsig = try!(RecoverableSignature::from_compact(&context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32)))); + let context = &crypto::SECP256K1; + let rsig = try!(RecoverableSignature::from_compact(context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32)))); let publ = try!(context.recover(&try!(Message::from_slice(&message)), &rsig)); - let serialized = publ.serialize_vec(&context, false); + let serialized = publ.serialize_vec(context, false); let p: Public = Public::from_slice(&serialized[1..65]); //TODO: check if it's the zero key and fail if so. Ok(p) @@ -140,10 +144,10 @@ pub mod ec { pub fn sign(secret: &Secret, message: &H256) -> Result { // TODO: allow creation of only low-s signatures. use secp256k1::*; - let context = Secp256k1::new(); + let context = &crypto::SECP256K1; let sec: &key::SecretKey = unsafe { ::std::mem::transmute(secret) }; let s = try!(context.sign_recoverable(&try!(Message::from_slice(&message)), sec)); - let (rec_id, data) = s.serialize_compact(&context); + let (rec_id, data) = s.serialize_compact(context); let mut signature: crypto::Signature = unsafe { ::std::mem::uninitialized() }; signature.clone_from_slice(&data); signature[64] = rec_id.to_i32() as u8; @@ -152,15 +156,15 @@ pub mod ec { /// Verify signature. pub fn verify(public: &Public, signature: &Signature, message: &H256) -> Result { use secp256k1::*; - let context = Secp256k1::new(); - 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 context = &crypto::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); let mut pdata: [u8; 65] = [4u8; 65]; let ptr = pdata[1..].as_mut_ptr(); let src = public.as_ptr(); unsafe { ::std::ptr::copy_nonoverlapping(src, ptr, 64) }; - let publ = try!(key::PublicKey::from_slice(&context, &pdata)); + let publ = try!(key::PublicKey::from_slice(context, &pdata)); match context.verify(&try!(Message::from_slice(&message)), &sig, &publ) { Ok(_) => Ok(true), Err(Error::IncorrectSignature) => Ok(false), @@ -190,17 +194,18 @@ pub mod ec { pub mod ecdh { use crypto::*; + use crypto::{self}; pub fn agree(secret: &Secret, public: &Public, ) -> Result { use secp256k1::*; - let context = Secp256k1::new(); + let context = &crypto::SECP256K1; let mut pdata: [u8; 65] = [4u8; 65]; let ptr = pdata[1..].as_mut_ptr(); let src = public.as_ptr(); unsafe { ::std::ptr::copy_nonoverlapping(src, ptr, 64) }; - let publ = try!(key::PublicKey::from_slice(&context, &pdata)); + let publ = try!(key::PublicKey::from_slice(context, &pdata)); let sec: &key::SecretKey = unsafe { ::std::mem::transmute(secret) }; - let shared = ecdh::SharedSecret::new_raw(&context, &publ, &sec); + let shared = ecdh::SharedSecret::new_raw(context, &publ, &sec); let s: Secret = unsafe { ::std::mem::transmute(shared) }; Ok(s) }