Skip to content

Commit 25958a2

Browse files
feat(identity): make secp256k1::SecretKey::sign infallible
Previously, this function would return an error in case the provided digest is not of 32 bytes long. As per our [spec](https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#secp256k1), we hash _all_ messages with SHA256 before signing, thus this error can never happen in practice. This brings us one step closer to an infallible `Keypair::sign` which is now only fallible due to RSA signing. If we manage to fix that as well, constructors like `noise::Config::new` will become infallible. Pull-Request: #3850.
1 parent 1bf6264 commit 25958a2

File tree

3 files changed

+20
-16
lines changed

3 files changed

+20
-16
lines changed

identity/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
- Make `Keypair` and `PublicKey` opaque.
99
See [PR 3866].
1010

11+
- Remove `identity::secp256k1::SecretKey::sign_hash` and make `identity::secp256k1::SecretKey::sign` infallible.
12+
See [PR 3850].
13+
14+
[PR 3850]: https://github.com/libp2p/rust-libp2p/pull/3850
1115
[PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715
1216
[PR 3863]: https://github.com/libp2p/rust-libp2p/pull/3863
1317
[PR 3866]: https://github.com/libp2p/rust-libp2p/pull/3866

identity/src/keypair.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ impl Keypair {
198198
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
199199
KeyPairInner::Rsa(ref pair) => pair.sign(msg),
200200
#[cfg(feature = "secp256k1")]
201-
KeyPairInner::Secp256k1(ref pair) => pair.secret().sign(msg),
201+
KeyPairInner::Secp256k1(ref pair) => Ok(pair.secret().sign(msg)),
202202
#[cfg(feature = "ecdsa")]
203203
KeyPairInner::Ecdsa(ref pair) => Ok(pair.secret().sign(msg)),
204204
}

identity/src/secp256k1.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
//! Secp256k1 keys.
2222
23-
use super::error::{DecodingError, SigningError};
23+
use super::error::DecodingError;
2424
use asn1_der::typed::{DerDecodable, Sequence};
2525
use core::cmp;
2626
use core::fmt;
@@ -142,25 +142,25 @@ impl SecretKey {
142142
/// ECDSA signature, as defined in [RFC3278].
143143
///
144144
/// [RFC3278]: https://tools.ietf.org/html/rfc3278#section-8.2
145-
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
146-
self.sign_hash(Sha256::digest(msg).as_ref())
147-
}
145+
pub fn sign(&self, msg: &[u8]) -> Vec<u8> {
146+
let generic_array = Sha256::digest(msg);
148147

149-
/// Returns the raw bytes of the secret key.
150-
pub fn to_bytes(&self) -> [u8; 32] {
151-
self.0.serialize()
152-
}
148+
// FIXME: Once `generic-array` hits 1.0, we should be able to just use `Into` here.
149+
let mut array = [0u8; 32];
150+
array.copy_from_slice(generic_array.as_slice());
151+
152+
let message = Message::parse(&array);
153153

154-
/// Sign a raw message of length 256 bits with this secret key, produces a DER-encoded
155-
/// ECDSA signature.
156-
pub fn sign_hash(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
157-
let m = Message::parse_slice(msg)
158-
.map_err(|_| SigningError::new("failed to parse secp256k1 digest"))?;
159-
Ok(libsecp256k1::sign(&m, &self.0)
154+
libsecp256k1::sign(&message, &self.0)
160155
.0
161156
.serialize_der()
162157
.as_ref()
163-
.into())
158+
.into()
159+
}
160+
161+
/// Returns the raw bytes of the secret key.
162+
pub fn to_bytes(&self) -> [u8; 32] {
163+
self.0.serialize()
164164
}
165165
}
166166

0 commit comments

Comments
 (0)