1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
pub mod nonce;
pub mod token;
pub use secp256k1;
use anyhow::{anyhow, Result};
use secp256k1::ecdsa::{self, Signature};
use secp256k1::hashes::sha256::Hash as Sha256Hash;
use secp256k1::hashes::Hash;
use secp256k1::{Message, PublicKey, Secp256k1, SecretKey};
const MAGIC_NUMBER: i32 = 31;
pub fn sign_message(message: &[u8], secret_key: &SecretKey) -> Result<Vec<u8>> {
let encmsg = lightning_hash(message)?;
let secp_ctx = Secp256k1::signing_only();
let sig = secp_ctx.sign_ecdsa_recoverable(&encmsg, &secret_key);
let (rid, sig) = sig.serialize_compact();
let mut fin = vec![(rid.to_i32() + MAGIC_NUMBER) as u8];
fin.extend_from_slice(&sig[..]);
Ok(fin)
}
pub fn verify_message(message: &[u8], sig: &[u8; 65], public_key: &PublicKey) -> Result<()> {
let secp_ctx = Secp256k1::verification_only();
let encmsg = lightning_hash(message)?;
let s = Signature::from_compact(&sig[1..])?;
secp_ctx.verify_ecdsa(&encmsg, &s, public_key)?;
Ok(())
}
pub fn recover_pubkey(message: &[u8], sig: &[u8; 65]) -> Result<PublicKey> {
if sig.len() < 65 {
return Err(anyhow!("too short sig".to_string()));
}
let encmsg = lightning_hash(message)?;
let secp = Secp256k1::verification_only();
let id = ecdsa::RecoveryId::from_i32(sig[0] as i32 - MAGIC_NUMBER)?;
let s = ecdsa::RecoverableSignature::from_compact(&sig[1..], id)?;
Ok(secp.recover_ecdsa(&encmsg, &s)?)
}
pub fn lightning_hash(message: &[u8]) -> Result<Message> {
let mut buffer = String::from("Lightning Signed Message:").into_bytes();
buffer.extend(message);
let hash1 = Sha256Hash::hash(&buffer[..]);
let hash2 = Sha256Hash::hash(&hash1[..]);
let encmsg = secp256k1::Message::from_slice(&hash2[..])?;
Ok(encmsg)
}