mirror of
https://github.com/stakwork/sphinx-key.git
synced 2025-12-17 07:14:23 +01:00
auth utils, log setup
This commit is contained in:
@@ -8,6 +8,7 @@ edition = "2018"
|
|||||||
secp256k1 = { version = "0.22.0", default-features = false, features = ["std", "rand-std", "bitcoin_hashes"] }
|
secp256k1 = { version = "0.22.0", default-features = false, features = ["std", "rand-std", "bitcoin_hashes"] }
|
||||||
anyhow = {version = "1", features = ["backtrace"]}
|
anyhow = {version = "1", features = ["backtrace"]}
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
base64 = { version = "0.13.0" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "no-std", "secp-recovery", "secp-lowmemory" ]
|
default = [ "no-std", "secp-recovery", "secp-lowmemory" ]
|
||||||
|
|||||||
@@ -1,31 +1,102 @@
|
|||||||
|
use anyhow::anyhow;
|
||||||
|
use anyhow::Result;
|
||||||
|
use base64::{decode_config, encode_config, URL_SAFE};
|
||||||
use secp256k1::ecdsa::Signature;
|
use secp256k1::ecdsa::Signature;
|
||||||
use secp256k1::hashes::sha256d::Hash as Sha256dHash;
|
use secp256k1::hashes::sha256d::Hash as Sha256dHash;
|
||||||
use secp256k1::hashes::Hash;
|
use secp256k1::hashes::Hash;
|
||||||
use secp256k1::{Message, Secp256k1, SecretKey};
|
use secp256k1::{Message, PublicKey, Secp256k1, SecretKey};
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
pub struct Token(u64);
|
pub struct Token(u64);
|
||||||
|
|
||||||
|
fn now() -> u64 {
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
let start = SystemTime::now();
|
||||||
|
let since_the_epoch = start
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.expect("Time went backwards");
|
||||||
|
since_the_epoch.as_nanos() as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn u64_to_bytes(input: u64) -> [u8; 8] {
|
||||||
|
input.to_le_bytes()
|
||||||
|
}
|
||||||
|
pub fn bytes_to_u64(bytes: [u8; 8]) -> u64 {
|
||||||
|
u64::from_le_bytes(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn base64_encode(input: &Vec<u8>) -> String {
|
||||||
|
encode_config(input, URL_SAFE)
|
||||||
|
}
|
||||||
|
pub fn base64_decode(input: &str) -> Result<Vec<u8>> {
|
||||||
|
let r = decode_config(input, URL_SAFE)?;
|
||||||
|
Ok(r)
|
||||||
|
}
|
||||||
|
|
||||||
impl Token {
|
impl Token {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self(0)
|
Self(now())
|
||||||
|
}
|
||||||
|
pub fn from_bytes(bytes: [u8; 8]) -> Self {
|
||||||
|
Self(bytes_to_u64(bytes))
|
||||||
|
}
|
||||||
|
pub fn from_base64(s: &str) -> Result<Self> {
|
||||||
|
if s.len() < 8 {
|
||||||
|
return Err(anyhow!("too short slice".to_string()));
|
||||||
|
}
|
||||||
|
let bytes = base64_decode(s)?;
|
||||||
|
let ts: [u8; 8] = bytes[..8].try_into()?;
|
||||||
|
Ok(Self(bytes_to_u64(ts)))
|
||||||
|
}
|
||||||
|
pub fn expected_len(&self) -> usize {
|
||||||
|
73
|
||||||
|
}
|
||||||
|
pub fn sign(&self, secret_key: &SecretKey) -> Result<Vec<u8>> {
|
||||||
|
let mut ts = u64_to_bytes(self.0).to_vec();
|
||||||
|
let sig = self.sign_message(&ts, secret_key)?;
|
||||||
|
println!("tts {:?}", ts);
|
||||||
|
ts.extend(sig);
|
||||||
|
assert_eq!(ts.len(), self.expected_len());
|
||||||
|
Ok(ts)
|
||||||
|
}
|
||||||
|
pub fn verify(&self, sig: Vec<u8>, public_key: &PublicKey) -> Result<()> {
|
||||||
|
// remove ts
|
||||||
|
// let (msg, sig) = input.split_at(8);
|
||||||
|
let msg = u64_to_bytes(self.0);
|
||||||
|
self.verify_message(&msg.to_vec(), &sig.to_vec(), public_key)
|
||||||
}
|
}
|
||||||
/// Sign a Lightning message
|
/// Sign a Lightning message
|
||||||
pub fn sign_message(
|
pub fn sign_message(&self, message: &Vec<u8>, secret_key: &SecretKey) -> Result<Vec<u8>> {
|
||||||
&self,
|
let encmsg = self.lightning_hash(message)?;
|
||||||
message: &Vec<u8>,
|
|
||||||
secret_key: &SecretKey,
|
|
||||||
) -> anyhow::Result<Vec<u8>> {
|
|
||||||
let mut buffer = String::from("Lightning Signed Message:").into_bytes();
|
|
||||||
buffer.extend(message);
|
|
||||||
let secp_ctx = Secp256k1::signing_only();
|
let secp_ctx = Secp256k1::signing_only();
|
||||||
let hash = Sha256dHash::hash(&buffer);
|
|
||||||
let encmsg = secp256k1::Message::from_slice(&hash[..])?;
|
|
||||||
let sig = secp_ctx.sign_ecdsa_recoverable(&encmsg, &secret_key);
|
let sig = secp_ctx.sign_ecdsa_recoverable(&encmsg, &secret_key);
|
||||||
let (rid, sig) = sig.serialize_compact();
|
let (rid, sig) = sig.serialize_compact();
|
||||||
let mut res = sig.to_vec();
|
let mut res = sig.to_vec();
|
||||||
res.push(rid.to_i32() as u8);
|
res.push(rid.to_i32() as u8);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
/// Verify a Lightning message
|
||||||
|
pub fn verify_message(
|
||||||
|
&self,
|
||||||
|
message: &Vec<u8>,
|
||||||
|
sig: &Vec<u8>,
|
||||||
|
public_key: &PublicKey,
|
||||||
|
) -> Result<()> {
|
||||||
|
let secp_ctx = Secp256k1::verification_only();
|
||||||
|
let encmsg = self.lightning_hash(message)?;
|
||||||
|
// remove the rid
|
||||||
|
let s = Signature::from_compact(&sig[..64])?;
|
||||||
|
secp_ctx.verify_ecdsa(&encmsg, &s, public_key)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
/// hash lightning message
|
||||||
|
pub fn lightning_hash(&self, message: &Vec<u8>) -> Result<Message> {
|
||||||
|
let mut buffer = String::from("Lightning Signed Message:").into_bytes();
|
||||||
|
buffer.extend(message);
|
||||||
|
let hash = Sha256dHash::hash(&buffer);
|
||||||
|
let encmsg = secp256k1::Message::from_slice(&hash[..])?;
|
||||||
|
Ok(encmsg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sign<T: secp256k1::Signing>(
|
pub fn sign<T: secp256k1::Signing>(
|
||||||
@@ -61,4 +132,30 @@ mod tests {
|
|||||||
let sig = sign(&secp, vec![1, 2, 3], &sk);
|
let sig = sign(&secp, vec![1, 2, 3], &sk);
|
||||||
assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
|
assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_token() {
|
||||||
|
let sk = secret_key();
|
||||||
|
let t = Token::new();
|
||||||
|
let res = t.sign(&sk).expect("couldnt make token");
|
||||||
|
let secp = Secp256k1::new();
|
||||||
|
let public_key = PublicKey::from_secret_key(&secp, &sk);
|
||||||
|
let (_, sig) = res.split_at(8);
|
||||||
|
t.verify(sig.to_vec(), &public_key).expect("couldnt verify");
|
||||||
|
println!("token verified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_decode() {
|
||||||
|
let sk = secret_key();
|
||||||
|
let secp = Secp256k1::new();
|
||||||
|
let public_key = PublicKey::from_secret_key(&secp, &sk);
|
||||||
|
let s = "aHt45kxY9xZCMvT5du5mTw-jx3X2g0Eg7QhHTIi6rBRAFqY_syx1SzcSoriXyPIVCWdG6T0I8xKXSEnoeajFdwmtQbHqC_qfAQ==";
|
||||||
|
let v = base64_decode(s).expect("couldnt decode");
|
||||||
|
let (_, sig) = v.split_at(8);
|
||||||
|
let t = Token::from_base64(s).expect("couldnt parse base64");
|
||||||
|
t.verify(sig.to_vec(), &public_key)
|
||||||
|
.expect("failed to verify");
|
||||||
|
println!("decoded token verified!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use std::env;
|
|||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
use vls_proxy::client::UnixClient;
|
use vls_proxy::client::UnixClient;
|
||||||
use vls_proxy::connection::{open_parent_fd, UnixConnection};
|
use vls_proxy::connection::{open_parent_fd, UnixConnection};
|
||||||
|
use vls_proxy::util::setup_logging;
|
||||||
|
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
pub sequence: u16,
|
pub sequence: u16,
|
||||||
@@ -33,7 +34,7 @@ pub struct ChannelReply {
|
|||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let parent_fd = open_parent_fd();
|
let parent_fd = open_parent_fd();
|
||||||
|
|
||||||
util::setup_logging("hsmd ", "info");
|
setup_logging("hsmd ", "info");
|
||||||
let app = App::new("signer")
|
let app = App::new("signer")
|
||||||
.setting(AppSettings::NoAutoVersion)
|
.setting(AppSettings::NoAutoVersion)
|
||||||
.about("CLN:mqtt - connects to an embedded VLS over a MQTT connection")
|
.about("CLN:mqtt - connects to an embedded VLS over a MQTT connection")
|
||||||
|
|||||||
Reference in New Issue
Block a user