Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions src/blind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,17 +916,30 @@ impl TxIn {
}
}

/// Data structure for Unifying inputs and pseudo-inputs.
/// Inputs or pseudo-inputs.
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum TxInType {
pub enum CtLocationType {
/// Regular input
Input(usize),
/// Issuance Pseudo-input
Issuance(usize),
/// Re-issuance pseudo-input
ReIssuance(usize),
Input,

/// Issuance pseudo-input
Issuance,

/// Reissuance pseudo-input
Reissuance,
}

/// Data structure for Unifying inputs and pseudo-inputs.
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct CtLocation {
/// Input index
pub input_index: usize,

/// Input or pseudo-input type
pub ty: CtLocationType,
}


impl Transaction {
/// Verify that the transaction has correctly calculated blinding
/// factors and they CT verification equation holds.
Expand Down Expand Up @@ -1078,7 +1091,7 @@ impl Transaction {
secp: &Secp256k1<C>,
spent_utxo_secrets: &[TxOutSecrets],
blind_issuances: bool,
) -> Result<BTreeMap<TxInType, (AssetBlindingFactor, ValueBlindingFactor, SecretKey)>, BlindError>
) -> Result<BTreeMap<CtLocation, (AssetBlindingFactor, ValueBlindingFactor, SecretKey)>, BlindError>
where
R: RngCore + CryptoRng,
C: Signing,
Expand All @@ -1090,13 +1103,13 @@ impl Transaction {
let (iss_vbf, iss_sk, tkn_vbf, tkn_sk) = txin.blind_issuances(secp, rng)?;
if txin.asset_issuance.amount.is_confidential() {
blinds.insert(
TxInType::Issuance(i),
CtLocation{ input_index: i, ty: CtLocationType::Issuance },
(AssetBlindingFactor::zero(), iss_vbf, iss_sk),
);
}
if txin.asset_issuance.inflation_keys.is_confidential() {
blinds.insert(
TxInType::ReIssuance(i),
CtLocation{ input_index: i, ty: CtLocationType::Reissuance },
(AssetBlindingFactor::zero(), tkn_vbf, tkn_sk),
);
}
Expand Down Expand Up @@ -1144,7 +1157,8 @@ impl Transaction {
spent_utxo_secrets,
)?;

blinds.insert(TxInType::Input(i), (abf, vbf, ephemeral_sk));
let location = CtLocation { input_index: i, ty: CtLocationType::Input};
blinds.insert(location, (abf, vbf, ephemeral_sk));
out_secrets.push(TxOutSecrets::new(
out.asset.explicit().unwrap(),
abf,
Expand Down Expand Up @@ -1184,7 +1198,8 @@ impl Transaction {
&out_secrets,
)?;

blinds.insert(TxInType::Input(last_index), (abf, vbf, ephemeral_sk));
let location = CtLocation{ input_index: last_index, ty: CtLocationType::Input };
blinds.insert(location, (abf, vbf, ephemeral_sk));
self.output[last_index] = conf_out;
Ok(blinds)
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub use bitcoin::hashes;
pub use crate::address::{Address, AddressError, AddressParams};
pub use crate::blind::{
BlindAssetProofs, BlindError, BlindValueProofs, ConfidentialTxOutError, RangeProofMessage,
SurjectionInput, TxOutError, TxOutSecrets, UnblindError, VerificationError,
SurjectionInput, TxOutError, TxOutSecrets, UnblindError, VerificationError, CtLocation, CtLocationType,
};
pub use crate::block::ExtData as BlockExtData;
pub use crate::block::{Block, BlockHeader};
Expand Down
27 changes: 17 additions & 10 deletions src/pset/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
//! Extension for PSET is based on PSET defined in BIP370.
//! <https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki>

use std::collections::HashMap;
use std::collections::{BTreeMap, HashMap};
use std::{cmp, io};

mod error;
Expand All @@ -46,7 +46,10 @@ use crate::{
confidential::{AssetBlindingFactor, ValueBlindingFactor},
TxOutSecrets,
};
use crate::{OutPoint, LockTime, Sequence, SurjectionInput, Transaction, TxIn, TxInWitness, TxOut, TxOutWitness, Txid};
use crate::{
LockTime, OutPoint, Sequence, SurjectionInput, Transaction, TxIn,
TxInWitness, TxOut, TxOutWitness, Txid, CtLocation, CtLocationType,
};
use secp256k1_zkp::rand::{CryptoRng, RngCore};
use secp256k1_zkp::{self, RangeProof, SecretKey, SurjectionProof};

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

let mut ret = BTreeMap::new(); // return all the random values used
if outs_to_blind.is_empty() {
// Return empty values if no outputs are marked for blinding
return Ok(Vec::new());
return Ok(ret);
}
// Blind each output as non-last and save the secrets
let surject_inputs = self.surjection_inputs(inp_txout_sec)?;
let mut out_secrets = vec![];
let mut ret = vec![]; // return all the random values used
for i in outs_to_blind {
let txout = self.outputs[i].to_txout();
let (txout, abf, vbf, _) = txout
let (txout, abf, vbf, ephemeral_sk) = txout
.to_non_last_confidential(
rng,
secp,
Expand Down Expand Up @@ -538,7 +541,8 @@ impl PartiallySignedTransaction {
));
}
// return blinding factors used
ret.push((abf, vbf));
let location = CtLocation{ input_index: i, ty: CtLocationType::Input};
ret.insert(location, (abf, vbf, ephemeral_sk));
}

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

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

// mutate the pset
{
Expand Down Expand Up @@ -690,7 +697,7 @@ impl PartiallySignedTransaction {

self.global.scalars.clear();
}
Ok(())
Ok(ret)
}
}

Expand Down