output: TxOut,
/// The channel keys state used to proceed to derivation of signing key. Must
/// be pass to KeysInterface::derive_channel_keys.
- key_derivation_params: (u64, u64),
+ channel_keys_id: [u8; 32],
/// The revocation_pubkey used to derive witnessScript
revocation_pubkey: PublicKey
},
output: TxOut,
/// The channel keys state used to proceed to derivation of signing key. Must
/// be pass to KeysInterface::derive_channel_keys.
- key_derivation_params: (u64, u64),
+ channel_keys_id: [u8; 32],
}
}
outpoint.write(writer)?;
output.write(writer)?;
},
- &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref key_derivation_params, ref revocation_pubkey } => {
+ &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref per_commitment_point, ref to_self_delay, ref output, ref channel_keys_id, ref revocation_pubkey } => {
1u8.write(writer)?;
outpoint.write(writer)?;
per_commitment_point.write(writer)?;
to_self_delay.write(writer)?;
output.write(writer)?;
- key_derivation_params.0.write(writer)?;
- key_derivation_params.1.write(writer)?;
+ channel_keys_id.write(writer)?;
revocation_pubkey.write(writer)?;
},
- &SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref key_derivation_params } => {
+ &SpendableOutputDescriptor::StaticOutputCounterpartyPayment { ref outpoint, ref output, ref channel_keys_id } => {
2u8.write(writer)?;
outpoint.write(writer)?;
output.write(writer)?;
- key_derivation_params.0.write(writer)?;
- key_derivation_params.1.write(writer)?;
+ channel_keys_id.write(writer)?;
},
}
Ok(())
per_commitment_point: Readable::read(reader)?,
to_self_delay: Readable::read(reader)?,
output: Readable::read(reader)?,
- key_derivation_params: (Readable::read(reader)?, Readable::read(reader)?),
+ channel_keys_id: Readable::read(reader)?,
revocation_pubkey: Readable::read(reader)?,
}),
2u8 => Ok(SpendableOutputDescriptor::StaticOutputCounterpartyPayment {
outpoint: Readable::read(reader)?,
output: Readable::read(reader)?,
- key_derivation_params: (Readable::read(reader)?, Readable::read(reader)?),
+ channel_keys_id: Readable::read(reader)?,
}),
_ => Err(DecodeError::InvalidValue),
}
fn release_commitment_secret(&self, idx: u64) -> [u8; 32];
/// Gets the holder's channel public keys and basepoints
fn pubkeys(&self) -> &ChannelPublicKeys;
- /// Gets arbitrary identifiers describing the set of keys which are provided back to you in
- /// some SpendableOutputDescriptor types. These should be sufficient to identify this
+ /// Gets an arbitrary identifier describing the set of keys which are provided back to you in
+ /// some SpendableOutputDescriptor types. This should be sufficient to identify this
/// ChannelKeys object uniquely and lookup or re-derive its keys.
- fn key_derivation_params(&self) -> (u64, u64);
+ fn channel_keys_id(&self) -> [u8; 32];
/// Create a signature for a counterparty's commitment transaction and associated HTLC transactions.
///
/// The total value of this channel
channel_value_satoshis: u64,
/// Key derivation parameters
- key_derivation_params: (u64, u64),
+ channel_keys_id: [u8; 32],
}
impl InMemoryChannelKeys {
htlc_base_key: SecretKey,
commitment_seed: [u8; 32],
channel_value_satoshis: u64,
- key_derivation_params: (u64, u64)) -> InMemoryChannelKeys {
+ channel_keys_id: [u8; 32]) -> InMemoryChannelKeys {
let holder_channel_pubkeys =
InMemoryChannelKeys::make_holder_keys(secp_ctx, &funding_key, &revocation_base_key,
&payment_key, &delayed_payment_base_key,
channel_value_satoshis,
holder_channel_pubkeys,
channel_parameters: None,
- key_derivation_params,
+ channel_keys_id,
}
}
}
fn pubkeys(&self) -> &ChannelPublicKeys { &self.holder_channel_pubkeys }
- fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }
+ fn channel_keys_id(&self) -> [u8; 32] { self.channel_keys_id }
fn sign_counterparty_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, commitment_tx: &CommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
let trusted_tx = commitment_tx.trust();
self.commitment_seed.write(writer)?;
self.channel_parameters.write(writer)?;
self.channel_value_satoshis.write(writer)?;
- self.key_derivation_params.0.write(writer)?;
- self.key_derivation_params.1.write(writer)?;
+ self.channel_keys_id.write(writer)?;
Ok(())
}
InMemoryChannelKeys::make_holder_keys(&secp_ctx, &funding_key, &revocation_base_key,
&payment_key, &delayed_payment_base_key,
&htlc_base_key);
- let params_1 = Readable::read(reader)?;
- let params_2 = Readable::read(reader)?;
+ let keys_id = Readable::read(reader)?;
Ok(InMemoryChannelKeys {
funding_key,
channel_value_satoshis,
holder_channel_pubkeys,
channel_parameters: counterparty_channel_data,
- key_derivation_params: (params_1, params_2),
+ channel_keys_id: keys_id,
})
}
}
/// Derive an old set of ChannelKeys for per-channel secrets based on a key derivation
/// parameters.
/// Key derivation parameters are accessible through a per-channel secrets
- /// ChannelKeys::key_derivation_params and is provided inside DynamicOuputP2WSH in case of
+ /// ChannelKeys::channel_keys_id and is provided inside DynamicOuputP2WSH in case of
/// onchain output detection for which a corresponding delayed_payment_key must be derived.
- pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params_1: u64, params_2: u64) -> InMemoryChannelKeys {
- let chan_id = ((params_1 & 0xFFFF_FFFF_0000_0000) >> 32) as u32;
+ pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params: &[u8; 32]) -> InMemoryChannelKeys {
+ let chan_id = byte_utils::slice_to_be64(¶ms[0..8]);
+ assert!(chan_id <= std::u32::MAX as u64); // Otherwise the params field wasn't created by us
let mut unique_start = Sha256::engine();
- unique_start.input(&byte_utils::be64_to_array(params_2));
- unique_start.input(&byte_utils::be32_to_array(params_1 as u32));
+ unique_start.input(params);
unique_start.input(&self.seed);
// We only seriously intend to rely on the channel_master_key for true secure
// entropy, everything else just ensures uniqueness. We rely on the unique_start (ie
// starting_time provided in the constructor) to be unique.
- let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(chan_id).expect("key space exhausted")).expect("Your RNG is busted");
+ 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");
unique_start.input(&child_privkey.private_key.key[..]);
let seed = Sha256::from_engine(unique_start).into_inner();
htlc_base_key,
commitment_seed,
channel_value_satoshis,
- (params_1, params_2),
+ params.clone()
)
}
}
fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner {
let child_ix = self.channel_child_index.fetch_add(1, Ordering::AcqRel);
- let ix_and_nanos: u64 = (child_ix as u64) << 32 | (self.starting_time_nanos as u64);
- self.derive_channel_keys(channel_value_satoshis, ix_and_nanos, self.starting_time_secs)
+ assert!(child_ix <= std::u32::MAX as usize);
+ let mut id = [0; 32];
+ id[0..8].copy_from_slice(&byte_utils::be64_to_array(child_ix as u64));
+ id[8..16].copy_from_slice(&byte_utils::be64_to_array(self.starting_time_nanos as u64));
+ id[16..24].copy_from_slice(&byte_utils::be64_to_array(self.starting_time_secs));
+ self.derive_channel_keys(channel_value_satoshis, &id)
}
fn get_secure_random_bytes(&self) -> [u8; 32] {