Skip to content

Commit 34de734

Browse files
committed
Ensure derive_channel_keys doesn't panic if per-run seed is high
b04d1b8 changed the way we calculate the `channel_keys_id` to include the 128-bit `user_channel_id` as well, shifting the counter up four bytes and the `starting_time_nanos` field up into the second four bytes. In `derive_channel_keys` we hash the full `channel_keys_id` with an HD-derived key from our master seed. Previously, that key was derived with an index of the per-restart counter, re-calculated by pulling the second four bytes out of the `user_channel_id`. Because the `channel_keys_id` fields were shifted up four bytes, that is now a reference to the `starting_time_nanos` value. This should be fine, the derivation doesn't really add any value here, its all being hashed anyway, except that derivation IDs must be below 2^31. This implies that we panic if the user passes a `starting_time_nanos` which has the high bit set. For those using the nanosecond part of the current time this isn't an issue - the value cannot exceed 1_000_000, which does not have the high bit set, however, some users may use some other per-run seed. Thus, here we simply drop the high bit from the seed, ensuring we don't panic. Note that this is backwards compatible as it only changes the key derivation in cases where we previously panicked. Ideally we'd drop the derivation entirely, but that would break backwards compatibility of key derivation.
1 parent f6a9382 commit 34de734

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

lightning/src/chain/keysinterface.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,9 @@ impl KeysManager {
10511051
// We only seriously intend to rely on the channel_master_key for true secure
10521052
// entropy, everything else just ensures uniqueness. We rely on the unique_start (ie
10531053
// starting_time provided in the constructor) to be unique.
1054-
let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(chan_id as u32).expect("key space exhausted")).expect("Your RNG is busted");
1054+
let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx,
1055+
ChildNumber::from_hardened_idx((chan_id as u32) % (1 << 31)).expect("key space exhausted")
1056+
).expect("Your RNG is busted");
10551057
unique_start.input(&child_privkey.private_key[..]);
10561058

10571059
let seed = Sha256::from_engine(unique_start).into_inner();

0 commit comments

Comments
 (0)