Fix bugs in construction of Sapling txid hashes.

This commit is contained in:
Kris Nuttycombe 2021-06-04 11:05:56 -06:00
parent df0095ebba
commit 4623f98d9a
3 changed files with 21 additions and 13 deletions

View File

@ -640,7 +640,11 @@ impl Transaction {
let orchard_bundle = Self::read_v5_orchard(&mut reader)?;
#[cfg(feature = "zfuture")]
let tze_bundle = Self::read_tze(&mut reader)?;
let tze_bundle = if version.has_tze() {
Self::read_tze(&mut reader)?
} else {
None
};
let data = TransactionData {
version,

View File

@ -162,9 +162,9 @@ fn zip_0243() {
fn zip_0244() {
for tv in self::data::zip_0244::make_test_vectors() {
let tx = Transaction::read(&tv.tx[..], BranchId::Nu5).unwrap();
let txid_parts = tx.deref().digest(TxIdDigester);
assert_eq!(tx.txid.as_ref(), &tv.txid);
let txid_parts = tx.deref().digest(TxIdDigester);
match tv.transparent_input {
Some(n) => {
let script = Script(tv.script_code.unwrap());

View File

@ -157,8 +157,12 @@ pub(crate) fn hash_sapling_spends<A: sapling::Authorization>(
}
let mut h = hasher(ZCASH_SAPLING_SPENDS_HASH_PERSONALIZATION);
h.write_all(&ch.finalize().as_bytes()).unwrap();
h.write_all(&nh.finalize().as_bytes()).unwrap();
if !shielded_spends.is_empty() {
let compact_digest = ch.finalize();
h.write_all(&compact_digest.as_bytes()).unwrap();
let noncompact_digest = nh.finalize();
h.write_all(&noncompact_digest.as_bytes()).unwrap();
}
h.finalize()
}
@ -185,9 +189,11 @@ pub(crate) fn hash_sapling_outputs<A>(shielded_outputs: &[OutputDescription<A>])
}
let mut h = hasher(ZCASH_SAPLING_OUTPUTS_HASH_PERSONALIZATION);
h.write_all(&ch.finalize().as_bytes()).unwrap();
h.write_all(&mh.finalize().as_bytes()).unwrap();
h.write_all(&nh.finalize().as_bytes()).unwrap();
if !shielded_outputs.is_empty() {
h.write_all(&ch.finalize().as_bytes()).unwrap();
h.write_all(&mh.finalize().as_bytes()).unwrap();
h.write_all(&nh.finalize().as_bytes()).unwrap();
}
h.finalize()
}
@ -258,18 +264,16 @@ fn hash_sapling_txid_data<A: sapling::Authorization>(
) -> Blake2bHash {
let mut h = hasher(ZCASH_SAPLING_HASH_PERSONALIZATION);
if let Some(bundle) = sapling_bundle {
if !bundle.shielded_spends.is_empty() {
if !(bundle.shielded_spends.is_empty() && bundle.shielded_outputs.is_empty()) {
h.write_all(hash_sapling_spends(&bundle.shielded_spends).as_bytes())
.unwrap();
}
if !bundle.shielded_outputs.is_empty() {
h.write_all(hash_sapling_outputs(&bundle.shielded_outputs).as_bytes())
.unwrap();
}
h.write_all(&bundle.value_balance.to_i64_le_bytes())
.unwrap();
h.write_all(&bundle.value_balance.to_i64_le_bytes())
.unwrap();
}
}
h.finalize()
}