Skip to content

Commit

Permalink
WIP: stateless keys
Browse files Browse the repository at this point in the history
  • Loading branch information
benthecarman committed Dec 8, 2023
1 parent 102b372 commit f146635
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 21 deletions.
19 changes: 17 additions & 2 deletions dlc-manager/src/channel_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ macro_rules! get_signed_channel_state {
}
}};
}
use crate::utils::SerialIds;
pub(crate) use get_signed_channel_state;

/// Creates an [`OfferedChannel`] and an associated [`OfferedContract`] using
Expand All @@ -74,6 +75,7 @@ pub fn offer_channel<C: Signing, W: Deref, B: Deref, T: Deref>(
cet_nsequence: u32,
refund_delay: u32,
wallet: &W,
seed: [u8; 32],
blockchain: &B,
time: &T,
) -> Result<(OfferedChannel, OfferedContract), Error>
Expand All @@ -82,8 +84,13 @@ where
B::Target: Blockchain,
T::Target: Time,
{
let (offer_params, _, funding_inputs_info) = crate::utils::get_party_params(
let temp_id = get_new_temporary_id();
let serial_ids = SerialIds::generate();
let funding_privkey = crate::utils::compute_secret_key(seed, temp_id, serial_ids);
let (offer_params, funding_inputs_info) = crate::utils::get_party_params(
secp,
funding_privkey,
serial_ids,
contract.offer_collateral,
contract.fee_rate,
wallet,
Expand All @@ -92,6 +99,7 @@ where
let party_points = crate::utils::get_party_base_points(secp, wallet)?;

let offered_contract = OfferedContract::new(
temp_id,
contract,
oracle_announcements.to_vec(),
&offer_params,
Expand Down Expand Up @@ -136,6 +144,7 @@ pub fn accept_channel_offer<W: Deref, B: Deref>(
offered_channel: &OfferedChannel,
offered_contract: &OfferedContract,
wallet: &W,
seed: [u8; 32],
blockchain: &B,
) -> Result<(AcceptedChannel, AcceptedContract, AcceptChannel), Error>
where
Expand All @@ -146,8 +155,12 @@ where

let total_collateral = offered_contract.total_collateral;

let (accept_params, _, funding_inputs) = crate::utils::get_party_params(
let serial_ids = SerialIds::generate();
let fund_secret_key = crate::utils::compute_secret_key(seed, offered_contract.id, serial_ids);
let (accept_params, funding_inputs) = crate::utils::get_party_params(
secp,
fund_secret_key,
serial_ids,
total_collateral - offered_contract.offer_params.collateral,
offered_contract.fee_rate_per_vb,
wallet,
Expand Down Expand Up @@ -967,7 +980,9 @@ where
S::Target: Signer,
T::Target: Time,
{
let temp_id = get_new_temporary_id();
let mut offered_contract = OfferedContract::new(
temp_id,
contract_input,
oracle_announcements,
&signed_channel.own_params,
Expand Down
3 changes: 2 additions & 1 deletion dlc-manager/src/contract/offered_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl OfferedContract {

/// Creates a new [`OfferedContract`] from the given parameters.
pub fn new(
temp_id: [u8; 32],
contract: &ContractInput,
oracle_announcements: Vec<Vec<OracleAnnouncement>>,
offer_params: &PartyParams,
Expand Down Expand Up @@ -102,7 +103,7 @@ impl OfferedContract {
})
.collect::<Vec<ContractInfo>>();
OfferedContract {
id: crate::utils::get_new_temporary_id(),
id: temp_id,
is_offer_party: true,
contract_info,
offer_params: offer_params.clone(),
Expand Down
18 changes: 16 additions & 2 deletions dlc-manager/src/contract_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use secp256k1_zkp::{
ecdsa::Signature, All, EcdsaAdaptorSignature, PublicKey, Secp256k1, SecretKey, Signing,
};

use crate::utils::{get_new_temporary_id, SerialIds};
use crate::{
contract::{
accepted_contract::AcceptedContract, contract_info::ContractInfo,
Expand All @@ -32,6 +33,7 @@ pub fn offer_contract<C: Signing, W: Deref, B: Deref, T: Deref>(
refund_delay: u32,
counter_party: &PublicKey,
wallet: &W,
seed: [u8; 32],
blockchain: &B,
time: &T,
) -> Result<(OfferedContract, OfferDlc), Error>
Expand All @@ -42,15 +44,21 @@ where
{
contract_input.validate()?;

let (party_params, _, funding_inputs_info) = crate::utils::get_party_params(
let temp_id = get_new_temporary_id();
let serial_ids = SerialIds::generate();
let funding_privkey = crate::utils::compute_secret_key(seed, temp_id, serial_ids);
let (party_params, funding_inputs_info) = crate::utils::get_party_params(
secp,
funding_privkey,
serial_ids,
contract_input.offer_collateral,
contract_input.fee_rate,
wallet,
blockchain,
)?;

let offered_contract = OfferedContract::new(
temp_id,
contract_input,
oracle_announcements,
&party_params,
Expand All @@ -71,6 +79,7 @@ pub fn accept_contract<W: Deref, B: Deref>(
secp: &Secp256k1<All>,
offered_contract: &OfferedContract,
wallet: &W,
seed: [u8; 32],
blockchain: &B,
) -> Result<(AcceptedContract, AcceptDlc), crate::Error>
where
Expand All @@ -79,8 +88,12 @@ where
{
let total_collateral = offered_contract.total_collateral;

let (accept_params, fund_secret_key, funding_inputs) = crate::utils::get_party_params(
let serial_ids = SerialIds::generate();
let fund_secret_key = crate::utils::compute_secret_key(seed, offered_contract.id, serial_ids);
let (accept_params, funding_inputs) = crate::utils::get_party_params(
secp,
fund_secret_key,
serial_ids,
total_collateral - offered_contract.offer_params.collateral,
offered_contract.fee_rate_per_vb,
wallet,
Expand Down Expand Up @@ -766,6 +779,7 @@ mod tests {
secp256k1_zkp::SECP256K1,
&offered_contract,
&wallet,
[0; 32],
&blockchain,
)
.expect("Not to fail");
Expand Down
20 changes: 19 additions & 1 deletion dlc-manager/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ where
store: S,
secp: Secp256k1<All>,
chain_monitor: ChainMonitor,
seed: [u8; 32],
time: T,
fee_estimator: F,
}
Expand Down Expand Up @@ -174,6 +175,7 @@ where
blockchain: B,
store: S,
oracles: HashMap<XOnlyPublicKey, O>,
seed: [u8; 32],
time: T,
fee_estimator: F,
) -> Result<Self, Error> {
Expand All @@ -191,6 +193,7 @@ where
time,
fee_estimator,
chain_monitor,
seed,
})
}

Expand Down Expand Up @@ -306,6 +309,7 @@ where
REFUND_DELAY,
&counter_party,
&self.wallet,
self.seed,
&self.blockchain,
&self.time,
)?;
Expand All @@ -331,6 +335,7 @@ where
&self.secp,
&offered_contract,
&self.wallet,
self.seed,
&self.blockchain,
)?;

Expand Down Expand Up @@ -877,6 +882,7 @@ where
CET_NSEQUENCE,
REFUND_DELAY,
&self.wallet,
self.seed,
&self.blockchain,
&self.time,
)?;
Expand Down Expand Up @@ -920,6 +926,7 @@ where
&offered_channel,
&offered_contract,
&self.wallet,
self.seed,
&self.blockchain,
)?;

Expand Down Expand Up @@ -2366,7 +2373,18 @@ mod test {

mocks::mock_time::set_time(0);

Manager::new(wallet, blockchain.clone(), store, oracles, time, blockchain).unwrap()
let seed = [0; 32];

Manager::new(
wallet,
blockchain.clone(),
store,
oracles,
seed,
time,
blockchain,
)
.unwrap()
}

fn pubkey() -> PublicKey {
Expand Down
44 changes: 37 additions & 7 deletions dlc-manager/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! #Utils
use std::ops::Deref;

use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine, Hmac, HmacEngine};
use bitcoin::{consensus::Encodable, Txid};
use dlc::{PartyParams, TxInputInfo};
use dlc_messages::{
Expand Down Expand Up @@ -59,26 +61,54 @@ pub(crate) fn compute_id(
res
}

/// Computes the secret key from the temporary id and the seed.
pub(crate) fn compute_secret_key(
seed: [u8; 32],
temporary_id: [u8; 32],
serial_ids: SerialIds,
) -> SecretKey {
let mut hmac = HmacEngine::<Sha256>::new(&seed);
hmac.input(&temporary_id);
hmac.input(&serial_ids.payout_serial_id.to_be_bytes());
hmac.input(&serial_ids.change_serial_id.to_be_bytes());
let secret_bytes = Hmac::from_engine(hmac).into_inner();
SecretKey::from_slice(&secret_bytes).expect("Secret key is valid")
}

#[derive(Debug, Clone, Copy)]
pub(crate) struct SerialIds {
pub payout_serial_id: u64,
pub change_serial_id: u64,
}

impl SerialIds {
pub(crate) fn generate() -> Self {
SerialIds {
payout_serial_id: get_new_serial_id(),
change_serial_id: get_new_serial_id(),
}
}
}

pub(crate) fn get_party_params<C: Signing, W: Deref, B: Deref>(
secp: &Secp256k1<C>,
funding_privkey: SecretKey,
serial_ids: SerialIds,
own_collateral: u64,
fee_rate: u64,
wallet: &W,
blockchain: &B,
) -> Result<(PartyParams, SecretKey, Vec<FundingInputInfo>), Error>
) -> Result<(PartyParams, Vec<FundingInputInfo>), Error>
where
W::Target: Wallet,
B::Target: Blockchain,
{
let funding_privkey = wallet.get_new_secret_key()?;
let funding_pubkey = PublicKey::from_secret_key(secp, &funding_privkey);

let payout_addr = wallet.get_new_address()?;
let payout_spk = payout_addr.script_pubkey();
let payout_serial_id = get_new_serial_id();
let change_addr = wallet.get_new_change_address()?;
let change_spk = change_addr.script_pubkey();
let change_serial_id = get_new_serial_id();

// Add base cost of fund tx + CET / 2 and a CET output to the collateral.
let appr_required_amount =
Expand Down Expand Up @@ -116,15 +146,15 @@ where
let party_params = PartyParams {
fund_pubkey: funding_pubkey,
change_script_pubkey: change_spk,
change_serial_id,
change_serial_id: serial_ids.payout_serial_id,
payout_script_pubkey: payout_spk,
payout_serial_id,
payout_serial_id: serial_ids.payout_serial_id,
inputs: funding_tx_info,
collateral: own_collateral,
input_amount: total_input,
};

Ok((party_params, funding_privkey, funding_inputs_info))
Ok((party_params, funding_inputs_info))
}

pub(crate) fn get_party_base_points<C: Signing, W: Deref>(
Expand Down
7 changes: 6 additions & 1 deletion dlc-manager/tests/channel_execution_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use test_utils::{get_enum_test_params, TestParams};
use std::sync::mpsc::{Receiver, Sender};
use std::thread;

use bitcoin::secp256k1::rand::random;
use std::{
collections::HashMap,
sync::{
Expand Down Expand Up @@ -250,7 +251,7 @@ fn channel_renew_race_test() {
}

fn channel_execution_test(test_params: TestParams, path: TestPath) {
env_logger::init();
env_logger::try_init().ok();
let (alice_send, bob_receive) = channel::<Option<Message>>();
let (bob_send, alice_receive) = channel::<Option<Message>>();
let (sync_send, sync_receive) = channel::<()>();
Expand Down Expand Up @@ -339,12 +340,14 @@ fn channel_execution_test(test_params: TestParams, path: TestPath) {
refresh_wallet(&alice_wallet, 200000000);
refresh_wallet(&bob_wallet, 200000000);

let alice_seed = random::<[u8; 32]>();
let alice_manager = Arc::new(Mutex::new(
Manager::new(
Arc::clone(&alice_wallet),
Arc::clone(&electrs),
alice_store,
alice_oracles,
alice_seed,
Arc::clone(&mock_time),
Arc::clone(&electrs),
)
Expand All @@ -354,12 +357,14 @@ fn channel_execution_test(test_params: TestParams, path: TestPath) {
let alice_manager_loop = Arc::clone(&alice_manager);
let alice_manager_send = Arc::clone(&alice_manager);

let bob_seed = random::<[u8; 32]>();
let bob_manager = Arc::new(Mutex::new(
Manager::new(
Arc::clone(&bob_wallet),
Arc::clone(&electrs),
Arc::clone(&bob_store),
bob_oracles,
bob_seed,
Arc::clone(&mock_time),
Arc::clone(&electrs),
)
Expand Down
Loading

0 comments on commit f146635

Please sign in to comment.