Make hash_type a property of the SignableInput::Transparent

This commit is contained in:
Kris Nuttycombe 2022-01-06 12:56:12 -07:00
parent 145d1a57f7
commit 37fdf88462
6 changed files with 43 additions and 39 deletions

View File

@ -27,7 +27,7 @@ use crate::{
},
transparent::{self, builder::TransparentBuilder},
},
sighash::{signature_hash, SignableInput, SIGHASH_ALL},
sighash::{signature_hash, SignableInput},
txid::TxIdDigester,
Transaction, TransactionData, TxVersion, Unauthorized,
},
@ -372,12 +372,8 @@ impl<'a, P: consensus::Parameters, R: RngCore> Builder<'a, P, R> {
// the commitment being signed is shared across all Sapling inputs; once
// V4 transactions are deprecated this should just be the txid, but
// for now we need to continue to compute it here.
let shielded_sig_commitment = signature_hash(
&unauthed_tx,
SIGHASH_ALL,
&SignableInput::Shielded,
&txid_parts,
);
let shielded_sig_commitment =
signature_hash(&unauthed_tx, &SignableInput::Shielded, &txid_parts);
let (sapling_bundle, tx_metadata) = match unauthed_tx
.sapling_bundle

View File

@ -202,11 +202,7 @@ impl TransparentAuthorizingContext for Unauthorized {
#[cfg(feature = "transparent-inputs")]
impl TransparentAuthorizingContext for Unauthorized {
fn input_amounts(&self) -> Vec<Amount> {
return self
.inputs
.iter()
.map(|txin| txin.coin.value.clone())
.collect();
return self.inputs.iter().map(|txin| txin.coin.value).collect();
}
fn input_scripts(&self) -> Vec<Script> {
@ -230,12 +226,12 @@ impl Bundle<Unauthorized> {
.inputs
.iter()
.enumerate()
.map(|(i, info)| {
.map(|(index, info)| {
let sighash = signature_hash(
mtx,
SIGHASH_ALL,
&SignableInput::Transparent {
index: i,
hash_type: SIGHASH_ALL,
index,
script_code: &info.coin.script_pubkey,
value: info.coin.value,
},

View File

@ -24,6 +24,7 @@ pub const SIGHASH_ANYONECANPAY: u8 = 0x80;
pub enum SignableInput<'a> {
Shielded,
Transparent {
hash_type: u8,
index: usize,
script_code: &'a Script,
value: Amount,
@ -36,6 +37,17 @@ pub enum SignableInput<'a> {
},
}
impl<'a> SignableInput<'a> {
pub fn hash_type(&self) -> u8 {
match self {
SignableInput::Shielded => SIGHASH_ALL,
SignableInput::Transparent { hash_type, .. } => *hash_type,
#[cfg(feature = "zfuture")]
SignableInput::Tze { .. } => SIGHASH_ALL,
}
}
}
pub struct SignatureHash(Blake2bHash);
impl AsRef<[u8; 32]> for SignatureHash {
@ -70,18 +82,17 @@ pub fn signature_hash<
A: Authorization<SaplingAuth = SA, TransparentAuth = TA>,
>(
tx: &TransactionData<A>,
hash_type: u8,
signable_input: &SignableInput<'a>,
txid_parts: &TxDigests<Blake2bHash>,
) -> SignatureHash {
SignatureHash(match tx.version {
TxVersion::Sprout(_) | TxVersion::Overwinter | TxVersion::Sapling => {
v4_signature_hash(tx, hash_type, signable_input)
v4_signature_hash(tx, signable_input)
}
TxVersion::Zip225 => v5_signature_hash(tx, hash_type, signable_input, txid_parts),
TxVersion::Zip225 => v5_signature_hash(tx, signable_input, txid_parts),
#[cfg(feature = "zfuture")]
TxVersion::ZFuture => v5_signature_hash(tx, hash_type, signable_input, txid_parts),
TxVersion::ZFuture => v5_signature_hash(tx, signable_input, txid_parts),
})
}

View File

@ -140,9 +140,9 @@ pub fn v4_signature_hash<
A: Authorization<SaplingAuth = SA>,
>(
tx: &TransactionData<A>,
hash_type: u8,
signable_input: &SignableInput<'_>,
) -> Blake2bHash {
let hash_type = signable_input.hash_type();
if tx.version.has_overwinter() {
let mut personal = [0; 16];
(&mut personal[..12]).copy_from_slice(ZCASH_SIGHASH_PERSONALIZATION_PREFIX);
@ -245,6 +245,7 @@ pub fn v4_signature_hash<
index,
script_code,
value,
..
} => {
if let Some(bundle) = tx.transparent_bundle.as_ref() {
let mut data = vec![];

View File

@ -42,8 +42,8 @@ fn transparent_sig_digest<A: TransparentAuthorizingContext>(
txid_digests: &TransparentDigests<Blake2bHash>,
bundle: &transparent::Bundle<A>,
input: &SignableInput<'_>,
hash_type: u8,
) -> Blake2bHash {
let hash_type = input.hash_type();
let flag_anyonecanpay = hash_type & SIGHASH_ANYONECANPAY != 0;
let flag_single = hash_type & SIGHASH_MASK == SIGHASH_SINGLE;
let flag_none = hash_type & SIGHASH_MASK == SIGHASH_NONE;
@ -116,6 +116,7 @@ fn transparent_sig_digest<A: TransparentAuthorizingContext>(
index,
script_code,
value,
..
} = input
{
let txin = &bundle.vin[*index];
@ -172,7 +173,6 @@ pub fn v5_signature_hash<
A: Authorization<TransparentAuth = TA>,
>(
tx: &TransactionData<A>,
hash_type: u8,
signable_input: &SignableInput<'_>,
txid_parts: &TxDigests<Blake2bHash>,
) -> Blake2bHash {
@ -188,7 +188,6 @@ pub fn v5_signature_hash<
.expect("Transparent txid digests are missing."),
&bundle,
signable_input,
hash_type,
)
} else {
hash_transparent_txid_data(txid_parts.transparent_digests.as_ref())

View File

@ -127,6 +127,7 @@ fn zip_0143() {
let tx = Transaction::read(&tv.tx[..], tv.consensus_branch_id).unwrap();
let signable_input = match tv.transparent_input {
Some(n) => SignableInput::Transparent {
hash_type: tv.hash_type as u8,
index: n as usize,
script_code: &tv.script_code,
value: Amount::from_nonnegative_i64(tv.amount).unwrap(),
@ -135,7 +136,7 @@ fn zip_0143() {
};
assert_eq!(
v4_signature_hash(tx.deref(), tv.hash_type as u8, &signable_input).as_ref(),
v4_signature_hash(tx.deref(), &signable_input).as_ref(),
tv.sighash
);
}
@ -147,6 +148,7 @@ fn zip_0243() {
let tx = Transaction::read(&tv.tx[..], tv.consensus_branch_id).unwrap();
let signable_input = match tv.transparent_input {
Some(n) => SignableInput::Transparent {
hash_type: tv.hash_type as u8,
index: n as usize,
script_code: &tv.script_code,
value: Amount::from_nonnegative_i64(tv.amount).unwrap(),
@ -155,7 +157,7 @@ fn zip_0243() {
};
assert_eq!(
v4_signature_hash(tx.deref(), tv.hash_type as u8, &signable_input).as_ref(),
v4_signature_hash(tx.deref(), &signable_input).as_ref(),
tv.sighash
);
}
@ -259,25 +261,27 @@ fn zip_0244() {
match tv.transparent_input {
Some(n) => {
let script = Script(tv.script_code.unwrap());
let signable_input = SignableInput::Transparent {
let value = Amount::from_nonnegative_i64(tv.amount.unwrap()).unwrap();
let script_code = &Script(tv.script_code.unwrap());
let signable_input = |hash_type| SignableInput::Transparent {
hash_type,
index: n as usize,
script_code: &script,
value: Amount::from_nonnegative_i64(tv.amount.unwrap()).unwrap(),
script_code,
value,
};
assert_eq!(
v5_signature_hash(&txdata, SIGHASH_ALL, &signable_input, &txid_parts).as_ref(),
v5_signature_hash(&txdata, &signable_input(SIGHASH_ALL), &txid_parts).as_ref(),
&tv.sighash_all
);
assert_eq!(
v5_signature_hash(&txdata, SIGHASH_NONE, &signable_input, &txid_parts).as_ref(),
v5_signature_hash(&txdata, &signable_input(SIGHASH_NONE), &txid_parts).as_ref(),
&tv.sighash_none.unwrap()
);
assert_eq!(
v5_signature_hash(&txdata, SIGHASH_SINGLE, &signable_input, &txid_parts)
v5_signature_hash(&txdata, &signable_input(SIGHASH_SINGLE), &txid_parts)
.as_ref(),
&tv.sighash_single.unwrap()
);
@ -285,8 +289,7 @@ fn zip_0244() {
assert_eq!(
v5_signature_hash(
&txdata,
SIGHASH_ALL | SIGHASH_ANYONECANPAY,
&signable_input,
&signable_input(SIGHASH_ALL | SIGHASH_ANYONECANPAY),
&txid_parts,
)
.as_ref(),
@ -296,8 +299,7 @@ fn zip_0244() {
assert_eq!(
v5_signature_hash(
&txdata,
SIGHASH_NONE | SIGHASH_ANYONECANPAY,
&signable_input,
&signable_input(SIGHASH_NONE | SIGHASH_ANYONECANPAY),
&txid_parts,
)
.as_ref(),
@ -307,8 +309,7 @@ fn zip_0244() {
assert_eq!(
v5_signature_hash(
&txdata,
SIGHASH_SINGLE | SIGHASH_ANYONECANPAY,
&signable_input,
&signable_input(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY),
&txid_parts,
)
.as_ref(),
@ -319,7 +320,7 @@ fn zip_0244() {
let signable_input = SignableInput::Shielded;
assert_eq!(
v5_signature_hash(&txdata, SIGHASH_ALL, &signable_input, &txid_parts).as_ref(),
v5_signature_hash(&txdata, &signable_input, &txid_parts).as_ref(),
tv.sighash_all
);
}