Skip to content

Commit da94539

Browse files
committed
Implement KeysInterface for KeysManager util
1 parent e315d22 commit da94539

File tree

1 file changed

+85
-1
lines changed

1 file changed

+85
-1
lines changed

src/chain/keysinterface.rs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@
33
//! on-chain output which is theirs.
44
55
use bitcoin::blockdata::transaction::{OutPoint, TxOut};
6-
use bitcoin::blockdata::script::Script;
6+
use bitcoin::blockdata::script::{Script, Builder};
7+
use bitcoin::blockdata::opcodes;
8+
use bitcoin::network::constants::Network;
9+
use bitcoin::util::hash::Hash160;
10+
use bitcoin::util::bip32::{ExtendedPrivKey, ExtendedPubKey, ChildNumber};
711

812
use secp256k1::key::{SecretKey, PublicKey};
913
use secp256k1::Secp256k1;
14+
use secp256k1;
1015

1116
use crypto::hkdf::{hkdf_extract,hkdf_expand};
1217

1318
use util::sha2::Sha256;
19+
use util::logger::Logger;
20+
21+
use std::sync::Arc;
1422

1523
/// When on-chain outputs are created by rust-lightning an event is generated which informs the
1624
/// user thereof. This enum descibes the format of the output and provides the OutPoint.
@@ -115,3 +123,79 @@ impl ChannelKeys {
115123
}
116124
}
117125
}
126+
127+
/// Simple CKeysInterface implementor that takes a 32-byte seed for use as a BIP 32 extended key
128+
/// and derives keys from that.
129+
///
130+
/// Your node_id is seed/0'
131+
/// ChannelMonitor closes may use seed/1'
132+
/// Cooperative closes may use seed/2'
133+
pub struct KeysManager {
134+
secp_ctx: Secp256k1<secp256k1::All>,
135+
node_secret: SecretKey,
136+
destination_script: Script,
137+
shutdown_pubkey: PublicKey,
138+
channel_master_key: ExtendedPrivKey,
139+
140+
logger: Arc<Logger>,
141+
}
142+
143+
impl KeysManager {
144+
/// Constructs a KeysManager from a 32-byte seed. If the seed is in some way biased (eg your
145+
/// RNG is busted) this may panic.
146+
pub fn new(seed: &[u8; 32], network: Network, logger: Arc<Logger>) -> KeysManager {
147+
let secp_ctx = Secp256k1::new();
148+
match ExtendedPrivKey::new_master(&secp_ctx, network.clone(), seed) {
149+
Ok(master_key) => {
150+
let node_secret = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0)).expect("Your RNG is busted").secret_key;
151+
let destination_script = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(1)) {
152+
Ok(destination_key) => {
153+
let pubkey_hash160 = Hash160::from_data(&ExtendedPubKey::from_private(&secp_ctx, &destination_key).public_key.serialize()[..]);
154+
Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0)
155+
.push_slice(pubkey_hash160.as_bytes())
156+
.into_script()
157+
},
158+
Err(_) => panic!("Your RNG is busted"),
159+
};
160+
let shutdown_pubkey = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(2)) {
161+
Ok(shutdown_key) => ExtendedPubKey::from_private(&secp_ctx, &shutdown_key).public_key,
162+
Err(_) => panic!("Your RNG is busted"),
163+
};
164+
let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3)).expect("Your RNG is busted");
165+
KeysManager {
166+
secp_ctx,
167+
node_secret,
168+
destination_script,
169+
shutdown_pubkey,
170+
channel_master_key,
171+
172+
logger,
173+
}
174+
},
175+
Err(_) => panic!("Your rng is busted"),
176+
}
177+
}
178+
}
179+
180+
impl KeysInterface for KeysManager {
181+
fn get_node_secret(&self) -> SecretKey {
182+
self.node_secret.clone()
183+
}
184+
185+
fn get_destination_script(&self) -> Script {
186+
self.destination_script.clone()
187+
}
188+
189+
fn get_shutdown_pubkey(&self) -> PublicKey {
190+
self.shutdown_pubkey.clone()
191+
}
192+
193+
fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys {
194+
let channel_pubkey = ExtendedPubKey::from_private(&self.secp_ctx, &self. channel_master_key);
195+
let mut seed = [0; 32];
196+
for (arr, slice) in seed.iter_mut().zip((&channel_pubkey.public_key.serialize()[0..32]).iter()) {
197+
*arr = *slice;
198+
}
199+
ChannelKeys::new_from_seed(&seed)
200+
}
201+
}

0 commit comments

Comments
 (0)