From 67a8e705a7858f7d26434d6ac471a7c88105e193 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 15 Jan 2019 17:14:58 +0100 Subject: [PATCH] Cache the secp256k1 object in secio (#856) * Cache the secp256k1 object in secio * Fix feature flag disabled --- protocols/secio/Cargo.toml | 4 ++-- protocols/secio/src/handshake.rs | 8 ++++---- protocols/secio/src/lib.rs | 10 ++++++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/protocols/secio/Cargo.toml b/protocols/secio/Cargo.toml index 33b3f527..6ef8b0f8 100644 --- a/protocols/secio/Cargo.toml +++ b/protocols/secio/Cargo.toml @@ -22,7 +22,7 @@ aes-ctr = "0.1.0" aesni = { version = "0.4.1", features = ["nocheck"], optional = true } twofish = "0.1.0" ctr = "0.1" -lazy_static = { version = "1.2.0", optional = true } +lazy_static = "1.2.0" rw-stream-sink = { version = "0.1.0", path = "../../misc/rw-stream-sink" } tokio-io = "0.1.0" sha2 = "0.7.1" @@ -39,7 +39,7 @@ stdweb = { version = "0.4", default-features = false } [features] default = ["rsa", "secp256k1"] rsa = ["ring/rsa_signing"] -aes-all = ["aesni", "lazy_static"] +aes-all = ["aesni"] [dev-dependencies] criterion = "0.2" diff --git a/protocols/secio/src/handshake.rs b/protocols/secio/src/handshake.rs index 2411781e..46ad1e2c 100644 --- a/protocols/secio/src/handshake.rs +++ b/protocols/secio/src/handshake.rs @@ -49,6 +49,8 @@ use tokio_io::{AsyncRead, AsyncWrite}; #[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))] use untrusted::Input as UntrustedInput; use crate::{KeyAgreement, SecioConfig, SecioKeyPairInner}; +#[cfg(feature = "secp256k1")] +use crate::SECP256K1; // This struct contains the whole context of a handshake, and is filled progressively // throughout the various parts of the handshake. @@ -398,8 +400,7 @@ where let data_to_sign = Sha256::digest(&data_to_sign); let message = secp256k1::Message::from_slice(data_to_sign.as_ref()) .expect("digest output length doesn't match secp256k1 input length"); - let secp256k1 = secp256k1::Secp256k1::signing_only(); - secp256k1 + SECP256K1 .sign(&message, private) .serialize_der() }, @@ -491,11 +492,10 @@ where let data_to_verify = Sha256::digest(&data_to_verify); let message = secp256k1::Message::from_slice(data_to_verify.as_ref()) .expect("digest output length doesn't match secp256k1 input length"); - let secp256k1 = secp256k1::Secp256k1::verification_only(); let signature = secp256k1::Signature::from_der(remote_exch.get_signature()); let remote_public_key = secp256k1::key::PublicKey::from_slice(remote_public_key); if let (Ok(signature), Ok(remote_public_key)) = (signature, remote_public_key) { - match secp256k1.verify(&message, &signature, &remote_public_key) { + match SECP256K1.verify(&message, &signature, &remote_public_key) { Ok(()) => (), Err(_) => { debug!("failed to verify the remote's signature"); diff --git a/protocols/secio/src/lib.rs b/protocols/secio/src/lib.rs index 8b2f5c8d..21ec9bc2 100644 --- a/protocols/secio/src/lib.rs +++ b/protocols/secio/src/lib.rs @@ -90,6 +90,7 @@ use bytes::BytesMut; use ed25519_dalek::Keypair as Ed25519KeyPair; use futures::stream::MapErr as StreamMapErr; use futures::{Future, Poll, Sink, StartSend, Stream}; +use lazy_static::lazy_static; use libp2p_core::{PeerId, PublicKey, upgrade::{UpgradeInfo, InboundUpgrade, OutboundUpgrade}}; use log::debug; #[cfg(all(feature = "rsa", not(any(target_os = "emscripten", target_os = "unknown"))))] @@ -115,6 +116,12 @@ pub use crate::algo_support::Digest; pub use crate::exchange::KeyAgreement; pub use crate::stream_cipher::Cipher; +// Cached `Secp256k1` context, to avoid recreating it every time. +#[cfg(feature = "secp256k1")] +lazy_static! { + static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); +} + /// Implementation of the `ConnectionUpgrade` trait of `libp2p_core`. Automatically applies /// secio on any connection. #[derive(Clone)] @@ -288,8 +295,7 @@ impl SecioKeyPair { } #[cfg(feature = "secp256k1")] SecioKeyPairInner::Secp256k1 { ref private } => { - let secp = secp256k1::Secp256k1::signing_only(); - let pubkey = secp256k1::key::PublicKey::from_secret_key(&secp, private); + let pubkey = secp256k1::key::PublicKey::from_secret_key(&SECP256K1, private); PublicKey::Secp256k1(pubkey.serialize().to_vec()) } }