Skip to content

Commit ae43d37

Browse files
committed
RUSTSEC-2021-0076 bump libsecp256k1
libsecp256k1 allows overflowing signatures https://rustsec.org/advisories/RUSTSEC-2021-0076 Changes were made to conform to libsecp256k1 version differences. Closes paritytech#9356
1 parent 993907f commit ae43d37

File tree

3 files changed

+97
-38
lines changed

3 files changed

+97
-38
lines changed

Cargo.lock

+64-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

primitives/core/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backen
4949
sha2 = { version = "0.9.2", default-features = false, optional = true }
5050
hex = { version = "0.4", default-features = false, optional = true }
5151
twox-hash = { version = "1.5.0", default-features = false, optional = true }
52-
libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"], optional = true }
52+
libsecp256k1 = { version = "0.6", default-features = false, features = ["hmac", "static-context"], optional = true }
5353
merlin = { version = "2.0", default-features = false, optional = true }
5454

5555
sp-runtime-interface = { version = "4.0.0-dev", default-features = false, path = "../runtime-interface" }

primitives/core/src/ecdsa.rs

+32-32
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
4040
use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId};
4141
use sp_runtime_interface::pass_by::PassByInner;
4242
#[cfg(feature = "full_crypto")]
43-
use secp256k1::{PublicKey, SecretKey};
43+
use libsecp256k1::{PublicKey, SecretKey};
4444

4545
/// An identifier used to match public keys against ecdsa keys
4646
pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ecds");
@@ -103,7 +103,7 @@ impl Public {
103103
/// This will convert the full public key into the compressed format.
104104
#[cfg(feature = "std")]
105105
pub fn from_full(full: &[u8]) -> Result<Self, ()> {
106-
secp256k1::PublicKey::parse_slice(full, None)
106+
libsecp256k1::PublicKey::parse_slice(full, None)
107107
.map(|k| k.serialize_compressed())
108108
.map(Self)
109109
.map_err(|_| ())
@@ -348,29 +348,29 @@ impl Signature {
348348
/// Recover the public key from this signature and a message.
349349
#[cfg(feature = "full_crypto")]
350350
pub fn recover<M: AsRef<[u8]>>(&self, message: M) -> Option<Public> {
351-
let message = secp256k1::Message::parse(&blake2_256(message.as_ref()));
351+
let message = libsecp256k1::Message::parse(&blake2_256(message.as_ref()));
352352
let sig: (_, _) = self.try_into().ok()?;
353-
secp256k1::recover(&message, &sig.0, &sig.1)
353+
libsecp256k1::recover(&message, &sig.0, &sig.1)
354354
.ok()
355355
.map(|recovered| Public(recovered.serialize_compressed()))
356356
}
357357

358358
/// Recover the public key from this signature and a pre-hashed message.
359359
#[cfg(feature = "full_crypto")]
360360
pub fn recover_prehashed(&self, message: &[u8; 32]) -> Option<Public> {
361-
let message = secp256k1::Message::parse(message);
362-
361+
let message = libsecp256k1::Message::parse(message);
362+
363363
let sig: (_, _) = self.try_into().ok()?;
364364

365-
secp256k1::recover(&message, &sig.0, &sig.1)
365+
libsecp256k1::recover(&message, &sig.0, &sig.1)
366366
.ok()
367367
.map(|key| Public(key.serialize_compressed()))
368368
}
369369
}
370370

371371
#[cfg(feature = "full_crypto")]
372-
impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature {
373-
fn from(x: (secp256k1::Signature, secp256k1::RecoveryId)) -> Signature {
372+
impl From<(libsecp256k1::Signature, libsecp256k1::RecoveryId)> for Signature {
373+
fn from(x: (libsecp256k1::Signature, libsecp256k1::RecoveryId)) -> Signature {
374374
let mut r = Self::default();
375375
r.0[0..64].copy_from_slice(&x.0.serialize()[..]);
376376
r.0[64] = x.1.serialize();
@@ -379,12 +379,12 @@ impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature {
379379
}
380380

381381
#[cfg(feature = "full_crypto")]
382-
impl<'a> TryFrom<&'a Signature> for (secp256k1::Signature, secp256k1::RecoveryId) {
382+
impl<'a> TryFrom<&'a Signature> for (libsecp256k1::Signature, libsecp256k1::RecoveryId) {
383383
type Error = ();
384-
fn try_from(x: &'a Signature) -> Result<(secp256k1::Signature, secp256k1::RecoveryId), Self::Error> {
384+
fn try_from(x: &'a Signature) -> Result<(libsecp256k1::Signature, libsecp256k1::RecoveryId), Self::Error> {
385385
Ok((
386-
secp256k1::Signature::parse_slice(&x.0[0..64]).expect("hardcoded to 64 bytes; qed"),
387-
secp256k1::RecoveryId::parse(x.0[64]).map_err(|_| ())?,
386+
libsecp256k1::Signature::parse_standard_slice(&x.0[0..64]).expect("hardcoded to 64 bytes; qed"),
387+
libsecp256k1::RecoveryId::parse(x.0[64]).map_err(|_| ())?,
388388
))
389389
}
390390
}
@@ -490,15 +490,15 @@ impl TraitPair for Pair {
490490

491491
/// Sign a message.
492492
fn sign(&self, message: &[u8]) -> Signature {
493-
let message = secp256k1::Message::parse(&blake2_256(message));
494-
secp256k1::sign(&message, &self.secret).into()
493+
let message = libsecp256k1::Message::parse(&blake2_256(message));
494+
libsecp256k1::sign(&message, &self.secret).into()
495495
}
496496

497497
/// Verify a signature on a message. Returns true if the signature is good.
498498
fn verify<M: AsRef<[u8]>>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool {
499-
let message = secp256k1::Message::parse(&blake2_256(message.as_ref()));
499+
let message = libsecp256k1::Message::parse(&blake2_256(message.as_ref()));
500500
let sig: (_, _) = match sig.try_into() { Ok(x) => x, _ => return false };
501-
match secp256k1::recover(&message, &sig.0, &sig.1) {
501+
match libsecp256k1::recover(&message, &sig.0, &sig.1) {
502502
Ok(actual) => pubkey.0[..] == actual.serialize_compressed()[..],
503503
_ => false,
504504
}
@@ -509,11 +509,11 @@ impl TraitPair for Pair {
509509
/// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct
510510
/// size. Use it only if you're coming from byte buffers and need the speed.
511511
fn verify_weak<P: AsRef<[u8]>, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool {
512-
let message = secp256k1::Message::parse(&blake2_256(message.as_ref()));
512+
let message = libsecp256k1::Message::parse(&blake2_256(message.as_ref()));
513513
if sig.len() != 65 { return false }
514-
let ri = match secp256k1::RecoveryId::parse(sig[64]) { Ok(x) => x, _ => return false };
515-
let sig = match secp256k1::Signature::parse_slice(&sig[0..64]) { Ok(x) => x, _ => return false };
516-
match secp256k1::recover(&message, &sig, &ri) {
514+
let ri = match libsecp256k1::RecoveryId::parse(sig[64]) { Ok(x) => x, _ => return false };
515+
let sig = match libsecp256k1::Signature::parse_standard_slice(&sig[0..64]) { Ok(x) => x, _ => return false };
516+
match libsecp256k1::recover(&message, &sig, &ri) {
517517
Ok(actual) => pubkey.as_ref() == &actual.serialize()[1..],
518518
_ => false,
519519
}
@@ -546,25 +546,25 @@ impl Pair {
546546

547547
/// Sign a pre-hashed message
548548
pub fn sign_prehashed(&self, message: &[u8; 32]) -> Signature {
549-
let message = secp256k1::Message::parse(message);
550-
secp256k1::sign(&message, &self.secret).into()
549+
let message = libsecp256k1::Message::parse(message);
550+
libsecp256k1::sign(&message, &self.secret).into()
551551
}
552552

553553
/// Verify a signature on a pre-hashed message. Return `true` if the signature is valid
554554
/// and thus matches the given `public` key.
555555
pub fn verify_prehashed(sig: &Signature, message: &[u8; 32], public: &Public) -> bool {
556-
let message = secp256k1::Message::parse(message);
557-
556+
let message = libsecp256k1::Message::parse(message);
557+
558558
let sig: (_, _) = match sig.try_into() {
559559
Ok(x) => x,
560560
_ => return false,
561561
};
562-
563-
match secp256k1::recover(&message, &sig.0, &sig.1) {
562+
563+
match libsecp256k1::recover(&message, &sig.0, &sig.1) {
564564
Ok(actual) => public.0[..] == actual.serialize_compressed()[..],
565565
_ => false,
566566
}
567-
}
567+
}
568568
}
569569

570570
impl CryptoType for Public {
@@ -803,7 +803,7 @@ mod test {
803803
// `msg` shouldn't be mangled
804804
let msg = [0u8; 32];
805805
let sig1 = pair.sign_prehashed(&msg);
806-
let sig2: Signature = secp256k1::sign(&secp256k1::Message::parse(&msg), &pair.secret).into();
806+
let sig2: Signature = libsecp256k1::sign(&libsecp256k1::Message::parse(&msg), &pair.secret).into();
807807

808808
assert_eq!(sig1, sig2);
809809

@@ -815,15 +815,15 @@ mod test {
815815
// using pre-hashed `msg` works
816816
let msg = keccak_256(b"this should be hashed");
817817
let sig1 = pair.sign_prehashed(&msg);
818-
let sig2: Signature = secp256k1::sign(&secp256k1::Message::parse(&msg), &pair.secret).into();
818+
let sig2: Signature = libsecp256k1::sign(&libsecp256k1::Message::parse(&msg), &pair.secret).into();
819819

820-
assert_eq!(sig1, sig2);
820+
assert_eq!(sig1, sig2);
821821
}
822822

823823
#[test]
824824
fn verify_prehashed_works() {
825825
let (pair, _, _) = Pair::generate_with_phrase(Some("password"));
826-
826+
827827
// `msg` and `sig` match
828828
let msg = keccak_256(b"this should be hashed");
829829
let sig = pair.sign_prehashed(&msg);

0 commit comments

Comments
 (0)