Skip to content

Commit a1ea971

Browse files
author
Antoine Riard
committed
Implement KeysInterface for KeysManager util
1 parent 62b5118 commit a1ea971

File tree

1 file changed

+99
-2
lines changed

1 file changed

+99
-2
lines changed

src/ln/keysinterface.rs

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@
77
//!
88
99
use bitcoin::blockdata::transaction::OutPoint;
10-
use bitcoin::blockdata::script::Script;
10+
use bitcoin::blockdata::script::{Script, Builder};
11+
use bitcoin::blockdata::opcodes;
12+
use bitcoin::network::constants::Network;
13+
use bitcoin::util::bip32::{ExtendedPrivKey, ExtendedPubKey, ChildNumber};
1114

12-
use secp256k1::key::SecretKey;
15+
use secp256k1::key::{SecretKey, PublicKey};
16+
use secp256k1::Secp256k1;
17+
use secp256k1;
1318

1419
use ln::channel::ChannelKeys;
1520
use util::events;
21+
use util::logger::Logger;
22+
23+
use std::sync::Arc;
1624

1725
/// A trait to describe a wallet which sould receive data to be able to spend onchain outputs
1826
/// fron a lightning channel
@@ -87,3 +95,92 @@ pub trait KeysInterface: Send + Sync {
8795
/// For Channel N, keys correspond to ChannelKeys::new_from_seed(/3/N')
8896
fn get_channel_keys(&mut self) -> Option<ChannelKeys>;
8997
}
98+
99+
/// Utility for storing/deriving lightning keys materials
100+
pub struct KeysManager {
101+
network: Network,
102+
secp_ctx: Secp256k1<secp256k1::All>,
103+
master_key: Option<SecretKey>,
104+
node_secret: Option<SecretKey>,
105+
destination_script: Option<Script>,
106+
shutdown_pubkey: Option<PublicKey>,
107+
channel_master_seed: Option<ExtendedPrivKey>,
108+
current_channel_index: u32,
109+
110+
logger: Arc<Logger>,
111+
}
112+
113+
impl KeysManager {
114+
/// Constructs and empty KeysManager
115+
pub fn new(network: Network, logger: Arc<Logger>) -> KeysManager {
116+
KeysManager {
117+
network,
118+
secp_ctx: Secp256k1::new(),
119+
master_key: None,
120+
node_secret: None,
121+
destination_script: None,
122+
shutdown_pubkey: None,
123+
channel_master_seed: None,
124+
current_channel_index: 0,
125+
126+
logger,
127+
}
128+
}
129+
}
130+
131+
impl KeysInterface for KeysManager {
132+
fn provide_master_seed(&mut self, seed: &[u8; 32]) {
133+
self.master_key = match ExtendedPrivKey::new_master(&self.secp_ctx, self.network.clone(), seed) {
134+
Ok(master_key) => {
135+
self.node_secret = match master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(0)) {
136+
Ok(node_secret) => Some(node_secret.secret_key),
137+
Err(_) => None,
138+
};
139+
self.destination_script = match master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(1)) {
140+
Ok(destination_key) => Some(Builder::new().push_slice(&ExtendedPubKey::from_private(&self.secp_ctx, &destination_key).public_key.serialize()[..])
141+
.push_opcode(opcodes::All::OP_CHECKSIG)
142+
.into_script()),
143+
Err(_) => None,
144+
};
145+
self.shutdown_pubkey = match master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(2)) {
146+
Ok(shutdown_key) => Some(ExtendedPubKey::from_private(&self.secp_ctx, &shutdown_key).public_key),
147+
Err(_) => None,
148+
};
149+
self.channel_master_seed = match master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(3)) {
150+
Ok(channel_master_key) => Some(channel_master_key),
151+
Err(_) => None,
152+
};
153+
Some(master_key.secret_key)
154+
},
155+
Err(_) => None,
156+
};
157+
}
158+
159+
fn get_node_secret(&self) -> Option<SecretKey> {
160+
self.node_secret.clone()
161+
}
162+
163+
fn get_destination_script(&self) -> Option<Script> {
164+
self.destination_script.clone()
165+
}
166+
167+
fn get_shutdown_pubkey(&self) -> Option<PublicKey> {
168+
self.shutdown_pubkey.clone()
169+
}
170+
171+
fn get_channel_keys(&mut self) -> Option<ChannelKeys> {
172+
if let &Some(channel_master_key) = &self.channel_master_seed {
173+
if let Ok(channel_key) = channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::Hardened { index: self.current_channel_index }) {
174+
let channel_pubkey = ExtendedPubKey::from_private(&self.secp_ctx, &channel_key);
175+
let mut seed = [0; 32];
176+
for (arr, slice) in seed.iter_mut().zip((&channel_pubkey.public_key.serialize()[0..32]).iter()) {
177+
*arr = *slice;
178+
}
179+
if let Ok(channel_keys) = ChannelKeys::new_from_seed(&seed) {
180+
return Some(channel_keys);
181+
}
182+
}
183+
}
184+
None
185+
}
186+
}

0 commit comments

Comments
 (0)