Cache the secp256k1 object in secio (#856)

* Cache the secp256k1 object in secio

* Fix feature flag disabled
This commit is contained in:
Pierre Krieger
2019-01-15 17:14:58 +01:00
committed by GitHub
parent 69abfbb18e
commit 67a8e705a7
3 changed files with 14 additions and 8 deletions

View File

@ -22,7 +22,7 @@ aes-ctr = "0.1.0"
aesni = { version = "0.4.1", features = ["nocheck"], optional = true } aesni = { version = "0.4.1", features = ["nocheck"], optional = true }
twofish = "0.1.0" twofish = "0.1.0"
ctr = "0.1" 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" } rw-stream-sink = { version = "0.1.0", path = "../../misc/rw-stream-sink" }
tokio-io = "0.1.0" tokio-io = "0.1.0"
sha2 = "0.7.1" sha2 = "0.7.1"
@ -39,7 +39,7 @@ stdweb = { version = "0.4", default-features = false }
[features] [features]
default = ["rsa", "secp256k1"] default = ["rsa", "secp256k1"]
rsa = ["ring/rsa_signing"] rsa = ["ring/rsa_signing"]
aes-all = ["aesni", "lazy_static"] aes-all = ["aesni"]
[dev-dependencies] [dev-dependencies]
criterion = "0.2" criterion = "0.2"

View File

@ -49,6 +49,8 @@ use tokio_io::{AsyncRead, AsyncWrite};
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))] #[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
use untrusted::Input as UntrustedInput; use untrusted::Input as UntrustedInput;
use crate::{KeyAgreement, SecioConfig, SecioKeyPairInner}; use crate::{KeyAgreement, SecioConfig, SecioKeyPairInner};
#[cfg(feature = "secp256k1")]
use crate::SECP256K1;
// This struct contains the whole context of a handshake, and is filled progressively // This struct contains the whole context of a handshake, and is filled progressively
// throughout the various parts of the handshake. // throughout the various parts of the handshake.
@ -398,8 +400,7 @@ where
let data_to_sign = Sha256::digest(&data_to_sign); let data_to_sign = Sha256::digest(&data_to_sign);
let message = secp256k1::Message::from_slice(data_to_sign.as_ref()) let message = secp256k1::Message::from_slice(data_to_sign.as_ref())
.expect("digest output length doesn't match secp256k1 input length"); .expect("digest output length doesn't match secp256k1 input length");
let secp256k1 = secp256k1::Secp256k1::signing_only(); SECP256K1
secp256k1
.sign(&message, private) .sign(&message, private)
.serialize_der() .serialize_der()
}, },
@ -491,11 +492,10 @@ where
let data_to_verify = Sha256::digest(&data_to_verify); let data_to_verify = Sha256::digest(&data_to_verify);
let message = secp256k1::Message::from_slice(data_to_verify.as_ref()) let message = secp256k1::Message::from_slice(data_to_verify.as_ref())
.expect("digest output length doesn't match secp256k1 input length"); .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 signature = secp256k1::Signature::from_der(remote_exch.get_signature());
let remote_public_key = secp256k1::key::PublicKey::from_slice(remote_public_key); let remote_public_key = secp256k1::key::PublicKey::from_slice(remote_public_key);
if let (Ok(signature), Ok(remote_public_key)) = (signature, 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(()) => (), Ok(()) => (),
Err(_) => { Err(_) => {
debug!("failed to verify the remote's signature"); debug!("failed to verify the remote's signature");

View File

@ -90,6 +90,7 @@ use bytes::BytesMut;
use ed25519_dalek::Keypair as Ed25519KeyPair; use ed25519_dalek::Keypair as Ed25519KeyPair;
use futures::stream::MapErr as StreamMapErr; use futures::stream::MapErr as StreamMapErr;
use futures::{Future, Poll, Sink, StartSend, Stream}; use futures::{Future, Poll, Sink, StartSend, Stream};
use lazy_static::lazy_static;
use libp2p_core::{PeerId, PublicKey, upgrade::{UpgradeInfo, InboundUpgrade, OutboundUpgrade}}; use libp2p_core::{PeerId, PublicKey, upgrade::{UpgradeInfo, InboundUpgrade, OutboundUpgrade}};
use log::debug; use log::debug;
#[cfg(all(feature = "rsa", not(any(target_os = "emscripten", target_os = "unknown"))))] #[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::exchange::KeyAgreement;
pub use crate::stream_cipher::Cipher; 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::All> = secp256k1::Secp256k1::new();
}
/// Implementation of the `ConnectionUpgrade` trait of `libp2p_core`. Automatically applies /// Implementation of the `ConnectionUpgrade` trait of `libp2p_core`. Automatically applies
/// secio on any connection. /// secio on any connection.
#[derive(Clone)] #[derive(Clone)]
@ -288,8 +295,7 @@ impl SecioKeyPair {
} }
#[cfg(feature = "secp256k1")] #[cfg(feature = "secp256k1")]
SecioKeyPairInner::Secp256k1 { ref private } => { SecioKeyPairInner::Secp256k1 { ref private } => {
let secp = secp256k1::Secp256k1::signing_only(); let pubkey = secp256k1::key::PublicKey::from_secret_key(&SECP256K1, private);
let pubkey = secp256k1::key::PublicKey::from_secret_key(&secp, private);
PublicKey::Secp256k1(pubkey.serialize().to_vec()) PublicKey::Secp256k1(pubkey.serialize().to_vec())
} }
} }