Skip to content

Commit 72ed91e

Browse files
committed
Merge #243: pset: blind: return ephemeral private key
cc12b8e blind: TxInType -> CtLocation (Leonardo Comandini) e4144e6 pset: blind: return map instead of vec (Leonardo Comandini) d66b028 blind: export TxInType (Leonardo Comandini) 7e33283 pset: blind_last: return blinders and ephemeral secret key (Leonardo Comandini) 7dc5a78 pset: blind_non_last: return ephemeral secret key (Leonardo Comandini) Pull request description: Right now we have: * `Transaction::blind` returns abf, vbf and ephemeral private key * `PartiallySignedTransaction::blind_non_last` returns abf and vbf * `PartiallySignedTransaction::blind_last` returns nothing This PR makes things more consistent and makes ephemeral keys more easily accessible. It's a breaking change, but it's just augmenting the data, so it should be easy to handle downstream. ACKs for top commit: apoelstra: ACK cc12b8e; successfully ran local tests Tree-SHA512: 74a85dc5a4e6389330aeab2603b5985830e18491fb1891d1adad213a6c564118c04910b79541e2f4e5e9aad0f2bb828b9ecf6077697089de0104d3a3894e1ea2
2 parents d0eac19 + cc12b8e commit 72ed91e

File tree

3 files changed

+45
-23
lines changed

3 files changed

+45
-23
lines changed

src/blind.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -916,17 +916,30 @@ impl TxIn {
916916
}
917917
}
918918

919-
/// Data structure for Unifying inputs and pseudo-inputs.
919+
/// Inputs or pseudo-inputs.
920920
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
921-
pub enum TxInType {
921+
pub enum CtLocationType {
922922
/// Regular input
923-
Input(usize),
924-
/// Issuance Pseudo-input
925-
Issuance(usize),
926-
/// Re-issuance pseudo-input
927-
ReIssuance(usize),
923+
Input,
924+
925+
/// Issuance pseudo-input
926+
Issuance,
927+
928+
/// Reissuance pseudo-input
929+
Reissuance,
928930
}
929931

932+
/// Data structure for Unifying inputs and pseudo-inputs.
933+
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
934+
pub struct CtLocation {
935+
/// Input index
936+
pub input_index: usize,
937+
938+
/// Input or pseudo-input type
939+
pub ty: CtLocationType,
940+
}
941+
942+
930943
impl Transaction {
931944
/// Verify that the transaction has correctly calculated blinding
932945
/// factors and they CT verification equation holds.
@@ -1078,7 +1091,7 @@ impl Transaction {
10781091
secp: &Secp256k1<C>,
10791092
spent_utxo_secrets: &[TxOutSecrets],
10801093
blind_issuances: bool,
1081-
) -> Result<BTreeMap<TxInType, (AssetBlindingFactor, ValueBlindingFactor, SecretKey)>, BlindError>
1094+
) -> Result<BTreeMap<CtLocation, (AssetBlindingFactor, ValueBlindingFactor, SecretKey)>, BlindError>
10821095
where
10831096
R: RngCore + CryptoRng,
10841097
C: Signing,
@@ -1090,13 +1103,13 @@ impl Transaction {
10901103
let (iss_vbf, iss_sk, tkn_vbf, tkn_sk) = txin.blind_issuances(secp, rng)?;
10911104
if txin.asset_issuance.amount.is_confidential() {
10921105
blinds.insert(
1093-
TxInType::Issuance(i),
1106+
CtLocation{ input_index: i, ty: CtLocationType::Issuance },
10941107
(AssetBlindingFactor::zero(), iss_vbf, iss_sk),
10951108
);
10961109
}
10971110
if txin.asset_issuance.inflation_keys.is_confidential() {
10981111
blinds.insert(
1099-
TxInType::ReIssuance(i),
1112+
CtLocation{ input_index: i, ty: CtLocationType::Reissuance },
11001113
(AssetBlindingFactor::zero(), tkn_vbf, tkn_sk),
11011114
);
11021115
}
@@ -1144,7 +1157,8 @@ impl Transaction {
11441157
spent_utxo_secrets,
11451158
)?;
11461159

1147-
blinds.insert(TxInType::Input(i), (abf, vbf, ephemeral_sk));
1160+
let location = CtLocation { input_index: i, ty: CtLocationType::Input};
1161+
blinds.insert(location, (abf, vbf, ephemeral_sk));
11481162
out_secrets.push(TxOutSecrets::new(
11491163
out.asset.explicit().unwrap(),
11501164
abf,
@@ -1184,7 +1198,8 @@ impl Transaction {
11841198
&out_secrets,
11851199
)?;
11861200

1187-
blinds.insert(TxInType::Input(last_index), (abf, vbf, ephemeral_sk));
1201+
let location = CtLocation{ input_index: last_index, ty: CtLocationType::Input };
1202+
blinds.insert(location, (abf, vbf, ephemeral_sk));
11881203
self.output[last_index] = conf_out;
11891204
Ok(blinds)
11901205
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub use bitcoin::hashes;
7878
pub use crate::address::{Address, AddressError, AddressParams};
7979
pub use crate::blind::{
8080
BlindAssetProofs, BlindError, BlindValueProofs, ConfidentialTxOutError, RangeProofMessage,
81-
SurjectionInput, TxOutError, TxOutSecrets, UnblindError, VerificationError,
81+
SurjectionInput, TxOutError, TxOutSecrets, UnblindError, VerificationError, CtLocation, CtLocationType,
8282
};
8383
pub use crate::block::ExtData as BlockExtData;
8484
pub use crate::block::{Block, BlockHeader};

src/pset/mod.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
//! Extension for PSET is based on PSET defined in BIP370.
2121
//! <https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki>
2222
23-
use std::collections::HashMap;
23+
use std::collections::{BTreeMap, HashMap};
2424
use std::{cmp, io};
2525

2626
mod error;
@@ -46,7 +46,10 @@ use crate::{
4646
confidential::{AssetBlindingFactor, ValueBlindingFactor},
4747
TxOutSecrets,
4848
};
49-
use crate::{OutPoint, LockTime, Sequence, SurjectionInput, Transaction, TxIn, TxInWitness, TxOut, TxOutWitness, Txid};
49+
use crate::{
50+
LockTime, OutPoint, Sequence, SurjectionInput, Transaction, TxIn,
51+
TxInWitness, TxOut, TxOutWitness, Txid, CtLocation, CtLocationType,
52+
};
5053
use secp256k1_zkp::rand::{CryptoRng, RngCore};
5154
use secp256k1_zkp::{self, RangeProof, SecretKey, SurjectionProof};
5255

@@ -478,20 +481,20 @@ impl PartiallySignedTransaction {
478481
rng: &mut R,
479482
secp: &secp256k1_zkp::Secp256k1<C>,
480483
inp_txout_sec: &HashMap<usize, TxOutSecrets>,
481-
) -> Result<Vec<(AssetBlindingFactor, ValueBlindingFactor)>, PsetBlindError> {
484+
) -> Result<BTreeMap<CtLocation, (AssetBlindingFactor, ValueBlindingFactor, SecretKey)>, PsetBlindError> {
482485
let (inp_secrets, outs_to_blind) = self.blind_checks(inp_txout_sec)?;
483486

487+
let mut ret = BTreeMap::new(); // return all the random values used
484488
if outs_to_blind.is_empty() {
485489
// Return empty values if no outputs are marked for blinding
486-
return Ok(Vec::new());
490+
return Ok(ret);
487491
}
488492
// Blind each output as non-last and save the secrets
489493
let surject_inputs = self.surjection_inputs(inp_txout_sec)?;
490494
let mut out_secrets = vec![];
491-
let mut ret = vec![]; // return all the random values used
492495
for i in outs_to_blind {
493496
let txout = self.outputs[i].to_txout();
494-
let (txout, abf, vbf, _) = txout
497+
let (txout, abf, vbf, ephemeral_sk) = txout
495498
.to_non_last_confidential(
496499
rng,
497500
secp,
@@ -538,7 +541,8 @@ impl PartiallySignedTransaction {
538541
));
539542
}
540543
// return blinding factors used
541-
ret.push((abf, vbf));
544+
let location = CtLocation{ input_index: i, ty: CtLocationType::Input};
545+
ret.insert(location, (abf, vbf, ephemeral_sk));
542546
}
543547

544548
// safe to unwrap because we have checked that there is atleast one output to blind
@@ -579,9 +583,10 @@ impl PartiallySignedTransaction {
579583
rng: &mut R,
580584
secp: &secp256k1_zkp::Secp256k1<C>,
581585
inp_txout_sec: &HashMap<usize, TxOutSecrets>,
582-
) -> Result<(), PsetBlindError> {
586+
) -> Result<BTreeMap<CtLocation, (AssetBlindingFactor, ValueBlindingFactor, SecretKey)>, PsetBlindError> {
583587
let (mut inp_secrets, mut outs_to_blind) = self.blind_checks(inp_txout_sec)?;
584588

589+
let mut ret = BTreeMap::new();
585590
if outs_to_blind.is_empty() {
586591
// Atleast one output must be marked for blinding for pset blind_last
587592
return Err(PsetBlindError::AtleastOneOutputBlind);
@@ -594,7 +599,7 @@ impl PartiallySignedTransaction {
594599
let ind = self.outputs[last_out_index].blinder_index;
595600
self.outputs[last_out_index].blinder_index = None;
596601
// Blind normally without the last index
597-
self.blind_non_last(rng, secp, inp_txout_sec)?;
602+
ret = self.blind_non_last(rng, secp, inp_txout_sec)?;
598603
// Restore who blinded the last output
599604
self.outputs[last_out_index].blinder_index = ind;
600605
// inp_secrets contributed to self.global.scalars, unset it so we don't count them
@@ -657,6 +662,8 @@ impl PartiallySignedTransaction {
657662
);
658663
let (value_commitment, nonce, rangeproof) =
659664
blind_res.map_err(|e| PsetBlindError::ConfidentialTxOutError(last_out_index, e))?;
665+
let location = CtLocation{ input_index: last_out_index, ty: CtLocationType::Input};
666+
ret.insert(location, (out_abf, final_vbf, ephemeral_sk));
660667

661668
// mutate the pset
662669
{
@@ -690,7 +697,7 @@ impl PartiallySignedTransaction {
690697

691698
self.global.scalars.clear();
692699
}
693-
Ok(())
700+
Ok(ret)
694701
}
695702
}
696703

0 commit comments

Comments
 (0)