Apply suggestions from code review

Co-authored-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Kris Nuttycombe 2022-01-18 14:48:57 -07:00 committed by Kris Nuttycombe
parent 7b2f9e27ae
commit eaa3ec56d0
3 changed files with 27 additions and 33 deletions

View File

@ -928,7 +928,7 @@ impl Transaction {
#[derive(Clone)]
pub struct TransparentDigests<A> {
pub prevout_digest: A,
pub prevouts_digest: A,
pub sequence_digest: A,
pub outputs_digest: A,
}

View File

@ -38,6 +38,7 @@ fn hasher(personal: &[u8; 16]) -> State {
}
/// Implements [ZIP 244 section S.2](https://zips.z.cash/zip-0244#s-2-transparent-sig-digest)
/// but only when used to produce the hash for a signature over a transparent input.
fn transparent_sig_digest<A: TransparentAuthorizingContext>(
txid_digests: &TransparentDigests<Blake2bHash>,
bundle: &transparent::Bundle<A>,
@ -48,39 +49,33 @@ fn transparent_sig_digest<A: TransparentAuthorizingContext>(
let flag_single = hash_type & SIGHASH_MASK == SIGHASH_SINGLE;
let flag_none = hash_type & SIGHASH_MASK == SIGHASH_NONE;
let prevout_digest = if flag_anyonecanpay {
let prevouts_digest = if flag_anyonecanpay {
transparent_prevout_hash::<A>(&[])
} else {
txid_digests.prevout_digest
txid_digests.prevouts_digest
};
let amounts_digest = {
let mut h = hasher(ZCASH_TRANSPARENT_AMOUNTS_HASH_PERSONALIZATION);
Array::write(
&mut h,
if flag_anyonecanpay {
vec![]
} else {
bundle.authorization.input_amounts()
},
|w, amount| w.write_all(&amount.to_i64_le_bytes()),
)
.unwrap();
if !flag_anyonecanpay {
Array::write(&mut h, bundle.authorization.input_amounts(), |w, amount| {
w.write_all(&amount.to_i64_le_bytes())
})
.unwrap();
}
h.finalize()
};
let scripts_digest = {
let mut h = hasher(ZCASH_TRANSPARENT_SCRIPTS_HASH_PERSONALIZATION);
Array::write(
&mut h,
if flag_anyonecanpay {
vec![]
} else {
bundle.authorization.input_scriptpubkeys()
},
|w, script| script.write(w),
)
.unwrap();
if !flag_anyonecanpay {
Array::write(
&mut h,
bundle.authorization.input_scriptpubkeys(),
|w, script| script.write(w),
)
.unwrap();
}
h.finalize()
};
@ -106,11 +101,10 @@ fn transparent_sig_digest<A: TransparentAuthorizingContext>(
txid_digests.outputs_digest
};
// If we are serializing an input (i.e. this is not a JoinSplit signature hash):
// a. outpoint (32-byte hash + 4-byte little endian)
// b. scriptCode of the input (serialized as scripts inside CTxOuts)
// c. value of the output spent by this input (8-byte little endian)
// d. nSequence of the input (4-byte little endian)
//S.2g.i: prevout (field encoding)
//S.2g.ii: value (8-byte signed little-endian)
//S.2g.iii: scriptPubKey (field encoding)
//S.2g.iv: nSequence (4-byte unsigned little-endian)
let mut ch = hasher(ZCASH_TRANSPARENT_INPUT_HASH_PERSONALIZATION);
if let SignableInput::Transparent {
index,
@ -125,16 +119,16 @@ fn transparent_sig_digest<A: TransparentAuthorizingContext>(
script_pubkey.write(&mut ch).unwrap();
ch.write_u32::<LittleEndian>(txin.sequence).unwrap();
}
let per_input_digest = ch.finalize();
let txin_sig_digest = ch.finalize();
let mut h = hasher(ZCASH_TRANSPARENT_HASH_PERSONALIZATION);
h.write_all(&[hash_type]).unwrap();
h.write_all(prevout_digest.as_bytes()).unwrap();
h.write_all(prevouts_digest.as_bytes()).unwrap();
h.write_all(amounts_digest.as_bytes()).unwrap();
h.write_all(scripts_digest.as_bytes()).unwrap();
h.write_all(sequence_digest.as_bytes()).unwrap();
h.write_all(outputs_digest.as_bytes()).unwrap();
h.write_all(per_input_digest.as_bytes()).unwrap();
h.write_all(txin_sig_digest.as_bytes()).unwrap();
h.finalize()
}

View File

@ -200,7 +200,7 @@ fn transparent_digests<A: transparent::Authorization>(
bundle: &transparent::Bundle<A>,
) -> TransparentDigests<Blake2bHash> {
TransparentDigests {
prevout_digest: transparent_prevout_hash(&bundle.vin),
prevouts_digest: transparent_prevout_hash(&bundle.vin),
sequence_digest: transparent_sequence_hash(&bundle.vin),
outputs_digest: transparent_outputs_hash(&bundle.vout),
}
@ -243,7 +243,7 @@ pub(crate) fn hash_transparent_txid_data(
) -> Blake2bHash {
let mut h = hasher(ZCASH_TRANSPARENT_HASH_PERSONALIZATION);
if let Some(d) = t_digests {
h.write_all(d.prevout_digest.as_bytes()).unwrap();
h.write_all(d.prevouts_digest.as_bytes()).unwrap();
h.write_all(d.sequence_digest.as_bytes()).unwrap();
h.write_all(d.outputs_digest.as_bytes()).unwrap();
}