Browse Source

Verify signed CETs using bitcoinconsensus

bdk-0.11
Lucas Soriano del Pino 3 years ago
committed by Philipp Hoenisch
parent
commit
dbc16b1ae9
No known key found for this signature in database GPG Key ID: E5F8E74C672BC666
  1. 114
      cfd_protocol/src/lib.rs

114
cfd_protocol/src/lib.rs

@ -50,7 +50,7 @@ mod tests {
let taker_dlc_amount = Amount::ONE_BTC;
let oracle = Oracle::new(&mut rng);
let (_event, announcement) = announce(&mut rng);
let (event, announcement) = announce(&mut rng);
let (maker_sk, maker_pk) = make_keypair(&mut rng);
let (taker_sk, taker_pk) = make_keypair(&mut rng);
@ -144,8 +144,10 @@ mod tests {
})
.collect::<Vec<_>>();
cets.iter()
.try_for_each(|cet| {
let cets_with_maker_encsig = cets
.clone()
.into_iter()
.map(|cet| {
let encsig = maker_cet_encsigs
.iter()
.find_map(|(txid, encsig)| (txid == &cet.txid()).then(|| encsig))
@ -156,8 +158,11 @@ mod tests {
&maker_pk,
&oracle.public_key(),
&announcement.nonce_pk(),
)
)?;
Ok((cet, *encsig))
})
.collect::<Result<Vec<_>>>()
.expect("valid maker cet encsigs");
let taker_cet_encsigs = cets
@ -171,8 +176,9 @@ mod tests {
})
.collect::<Vec<_>>();
cets.iter()
.try_for_each(|cet| {
let cets_with_taker_encsig = cets
.iter()
.map(|cet| {
let encsig = taker_cet_encsigs
.iter()
.find_map(|(txid, encsig)| (txid == &cet.txid()).then(|| encsig))
@ -183,8 +189,11 @@ mod tests {
&taker_pk,
&oracle.public_key(),
&announcement.nonce_pk(),
)
)?;
Ok((cet, *encsig))
})
.collect::<Result<Vec<_>>>()
.expect("valid taker cet encsigs");
let mut signed_lock_tx = lock_tx.to_psbt();
@ -221,7 +230,58 @@ mod tests {
dlc_amount.as_sat(),
bitcoin::consensus::serialize(&signed_refund_tx).as_slice(),
)
.expect("valid signed refund transaction");
let attestations = [Message::Win, Message::Lose]
.iter()
.map(|msg| (*msg, oracle.attest(&event, *msg)))
.collect::<Vec<_>>();
// TODO: Rewrite this so that it doesn't rely on the order of
// the two zipped iterators
let cets_with_sigs: Vec<(
ContractExecutionTransaction,
EcdsaAdaptorSignature,
EcdsaAdaptorSignature,
)> = cets_with_maker_encsig
.into_iter()
.zip(cets_with_taker_encsig)
.map(|((cet, maker_encsig), (_, taker_encsig))| (cet, maker_encsig, taker_encsig))
.collect::<Vec<_>>();
let signed_cets = attestations
.iter()
.map(|(oracle_msg, oracle_sig)| {
let (cet, maker_encsig, taker_encsig) = cets_with_sigs
.iter()
.find(|(cet, _, _)| &cet.message == oracle_msg)
.expect("one cet per message");
let (_nonce_pk, signature_scalar) = schnorrsig_decompose(oracle_sig).unwrap();
let maker_sig = maker_encsig.decrypt(&signature_scalar)?;
let taker_sig = taker_encsig.decrypt(&signature_scalar)?;
cet.clone()
.add_signatures((maker_pk, maker_sig), (taker_pk, taker_sig))
})
.collect::<Result<Vec<_>>>()
.unwrap();
signed_cets
.iter()
.try_for_each(|cet| {
lock_tx
.descriptor()
.address(Network::Regtest)
.expect("can derive address from descriptor")
.script_pubkey()
.verify(
0,
dlc_amount.as_sat(),
bitcoin::consensus::serialize(&cet).as_slice(),
)
})
.expect("valid signed CETs");
}
const BIP340_MIDSTATE: [u8; 32] = [
@ -272,6 +332,7 @@ mod tests {
inner: Transaction,
message: Message,
sighash: SigHash,
lock_output_descriptor: Descriptor<PublicKey>,
}
impl ContractExecutionTransaction {
@ -306,6 +367,7 @@ mod tests {
inner: tx,
message: payout.message,
sighash,
lock_output_descriptor: lock_tx.descriptor(),
}
}
@ -354,6 +416,28 @@ mod tests {
// TODO: Do it properly
100
}
pub fn add_signatures(
self,
(maker_pk, maker_sig): (PublicKey, Signature),
(taker_pk, taker_sig): (PublicKey, Signature),
) -> Result<Transaction> {
let satisfier = {
let mut satisfier = HashMap::with_capacity(2);
// The order in which these are inserted doesn't matter
satisfier.insert(maker_pk, (maker_sig, SigHashType::All));
satisfier.insert(taker_pk, (taker_sig, SigHashType::All));
satisfier
};
let mut tx_refund = self.inner;
self.lock_output_descriptor
.satisfy(&mut tx_refund.input[0], satisfier)?;
Ok(tx_refund)
}
}
#[derive(Debug, Clone)]
@ -606,7 +690,7 @@ mod tests {
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
enum Message {
Win,
Lose,
@ -648,7 +732,7 @@ mod tests {
schnorrsig::PublicKey::from_keypair(SECP256K1, &self.key_pair)
}
fn attest(&self, event: Event, msg: Message) -> schnorrsig::Signature {
fn attest(&self, event: &Event, msg: Message) -> schnorrsig::Signature {
secp_utils::schnorr_sign_with_nonce(&msg.into(), &self.key_pair, &event.nonce)
}
}
@ -742,6 +826,18 @@ mod tests {
(sk, pk)
}
/// Decompose a BIP340 signature into R and s.
pub fn schnorrsig_decompose(
signature: &schnorrsig::Signature,
) -> Result<(schnorrsig::PublicKey, SecretKey)> {
let bytes = signature.as_ref();
let nonce_pk = schnorrsig::PublicKey::from_slice(&bytes[0..32])?;
let s = SecretKey::from_slice(&bytes[32..64])?;
Ok((nonce_pk, s))
}
mod secp_utils {
use super::*;

Loading…
Cancel
Save