X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fmessage_signing.rs;h=8beff835a4bffe1f0b3d59e672380323b6164f98;hb=8a1c538f88ffc3f387ce3f54ded2d49ab9c9aa31;hp=c39da1d533e51b7fbc0f94f30b1947040139be54;hpb=df829a85263e0bc675ca696c0f6ff0a49d89e623;p=rust-lightning diff --git a/lightning/src/util/message_signing.rs b/lightning/src/util/message_signing.rs index c39da1d5..8beff835 100644 --- a/lightning/src/util/message_signing.rs +++ b/lightning/src/util/message_signing.rs @@ -12,13 +12,13 @@ //! Note this is not part of the specs, but follows lnd's signing and verifying protocol, which can is defined as follows: //! //! signature = zbase32(SigRec(sha256d(("Lightning Signed Message:" + msg))) -//! zbase32 from https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt +//! zbase32 from //! SigRec has first byte 31 + recovery id, followed by 64 byte sig. //! //! This implementation is compatible with both lnd's and c-lightning's //! -//! https://lightning.readthedocs.io/lightning-signmessage.7.html -//! https://api.lightning.community/#signmessage +//! +//! use prelude::*; use crate::util::zbase32; @@ -36,6 +36,11 @@ fn sigrec_encode(sig_rec: RecoverableSignature) -> Vec { } fn sigrec_decode(sig_rec: Vec) -> Result { + // Signature must be 64 + 1 bytes long (compact signature + recovery id) + if sig_rec.len() != 65 { + return Err(Error::InvalidSignature); + } + let rsig = &sig_rec[1..]; let rid = sig_rec[0] as i32 - 31; @@ -48,11 +53,11 @@ fn sigrec_decode(sig_rec: Vec) -> Result { /// Creates a digital signature of a message given a SecretKey, like the node's secret. /// A receiver knowing the PublicKey (e.g. the node's id) and the message can be sure that the signature was generated by the caller. /// Signatures are EC recoverable, meaning that given the message and the signature the PublicKey of the signer can be extracted. -pub fn sign(msg: &[u8], sk: SecretKey) -> Result { +pub fn sign(msg: &[u8], sk: &SecretKey) -> Result { let secp_ctx = Secp256k1::signing_only(); let msg_hash = sha256d::Hash::hash(&[LN_MESSAGE_PREFIX, msg].concat()); - let sig = secp_ctx.sign_recoverable(&Message::from_slice(&msg_hash)?, &sk); + let sig = secp_ctx.sign_recoverable(&Message::from_slice(&msg_hash)?, sk); Ok(zbase32::encode(&sigrec_encode(sig))) } @@ -74,9 +79,9 @@ pub fn recover_pk(msg: &[u8], sig: &str) -> Result { /// Verifies a message was signed by a PrivateKey that derives to a given PublicKey, given a message, a signature, /// and the PublicKey. -pub fn verify(msg: &[u8], sig: &str, pk: PublicKey) -> bool { +pub fn verify(msg: &[u8], sig: &str, pk: &PublicKey) -> bool { match recover_pk(msg, sig) { - Ok(x) => x == pk, + Ok(x) => x == *pk, Err(_) => false } } @@ -91,7 +96,7 @@ mod test { #[test] fn test_sign() { let message = "test message"; - let zbase32_sig = sign(message.as_bytes(), ONE_KEY); + let zbase32_sig = sign(message.as_bytes(), &ONE_KEY); assert_eq!(zbase32_sig.unwrap(), "d9tibmnic9t5y41hg7hkakdcra94akas9ku3rmmj4ag9mritc8ok4p5qzefs78c9pqfhpuftqqzhydbdwfg7u6w6wdxcqpqn4sj4e73e") } @@ -108,10 +113,10 @@ mod test { #[test] fn test_verify() { let message = "another message"; - let sig = sign(message.as_bytes(), ONE_KEY).unwrap(); + let sig = sign(message.as_bytes(), &ONE_KEY).unwrap(); let pk = PublicKey::from_secret_key(&Secp256k1::signing_only(), &ONE_KEY); - assert!(verify(message.as_bytes(), &sig, pk)) + assert!(verify(message.as_bytes(), &sig, &pk)) } #[test] @@ -135,7 +140,7 @@ mod test { ]; for c in &corpus { - assert!(verify(c[1].as_bytes(), c[2], PublicKey::from_str(c[3]).unwrap())) + assert!(verify(c[1].as_bytes(), c[2], &PublicKey::from_str(c[3]).unwrap())) } } }