Merge pull request #316 from nuttycom/sighash_components
Make the functions which produce the components of the sighash reusable.
This commit is contained in:
commit
97ef1592bb
|
@ -19,7 +19,8 @@ jobs:
|
|||
|
||||
- name: Fetch path to Zcash parameters
|
||||
working-directory: ./zcash_proofs
|
||||
run: echo "::set-env name=ZCASH_PARAMS::$(cargo run --release --example get-params-path --features directories)"
|
||||
shell: bash
|
||||
run: echo "ZCASH_PARAMS=$(cargo run --release --example get-params-path --features directories)" >> $GITHUB_ENV
|
||||
- name: Cache Zcash parameters
|
||||
id: cache-params
|
||||
uses: actions/cache@v2
|
||||
|
@ -144,7 +145,8 @@ jobs:
|
|||
|
||||
- name: Fetch path to Zcash parameters
|
||||
working-directory: ./zcash_proofs
|
||||
run: echo "::set-env name=ZCASH_PARAMS::$(cargo run --release --example get-params-path --features directories)"
|
||||
shell: bash
|
||||
run: echo "ZCASH_PARAMS=$(cargo run --release --example get-params-path --features directories)" >> $GITHUB_ENV
|
||||
- name: Cache Zcash parameters
|
||||
id: cache-params
|
||||
uses: actions/cache@v2
|
||||
|
|
|
@ -13,7 +13,9 @@ use crate::{
|
|||
};
|
||||
|
||||
use super::{
|
||||
components::{Amount, TxOut},
|
||||
components::{
|
||||
Amount, JSDescription, OutputDescription, SpendDescription, TxIn, TxOut, TzeIn, TzeOut,
|
||||
},
|
||||
Transaction, TransactionData, OVERWINTER_VERSION_GROUP_ID, SAPLING_TX_VERSION,
|
||||
SAPLING_VERSION_GROUP_ID, ZFUTURE_VERSION_GROUP_ID,
|
||||
};
|
||||
|
@ -77,9 +79,9 @@ impl SigHashVersion {
|
|||
}
|
||||
}
|
||||
|
||||
fn prevout_hash(tx: &TransactionData) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(tx.vin.len() * 36);
|
||||
for t_in in &tx.vin {
|
||||
fn prevout_hash(vin: &[TxIn]) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(vin.len() * 36);
|
||||
for t_in in vin {
|
||||
t_in.prevout.write(&mut data).unwrap();
|
||||
}
|
||||
Blake2bParams::new()
|
||||
|
@ -88,9 +90,9 @@ fn prevout_hash(tx: &TransactionData) -> Blake2bHash {
|
|||
.hash(&data)
|
||||
}
|
||||
|
||||
fn sequence_hash(tx: &TransactionData) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(tx.vin.len() * 4);
|
||||
for t_in in &tx.vin {
|
||||
fn sequence_hash(vin: &[TxIn]) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(vin.len() * 4);
|
||||
for t_in in vin {
|
||||
(&mut data)
|
||||
.write_u32::<LittleEndian>(t_in.sequence)
|
||||
.unwrap();
|
||||
|
@ -101,9 +103,9 @@ fn sequence_hash(tx: &TransactionData) -> Blake2bHash {
|
|||
.hash(&data)
|
||||
}
|
||||
|
||||
fn outputs_hash(tx: &TransactionData) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(tx.vout.len() * (4 + 1));
|
||||
for t_out in &tx.vout {
|
||||
fn outputs_hash(vout: &[TxOut]) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(vout.len() * (4 + 1));
|
||||
for t_out in vout {
|
||||
t_out.write(&mut data).unwrap();
|
||||
}
|
||||
Blake2bParams::new()
|
||||
|
@ -121,28 +123,32 @@ fn single_output_hash(tx_out: &TxOut) -> Blake2bHash {
|
|||
.hash(&data)
|
||||
}
|
||||
|
||||
fn joinsplits_hash(tx: &TransactionData) -> Blake2bHash {
|
||||
fn joinsplits_hash(
|
||||
txversion: u32,
|
||||
joinsplits: &[JSDescription],
|
||||
joinsplit_pubkey: &[u8; 32],
|
||||
) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(
|
||||
tx.joinsplits.len()
|
||||
* if tx.version < SAPLING_TX_VERSION {
|
||||
joinsplits.len()
|
||||
* if txversion < SAPLING_TX_VERSION {
|
||||
1802 // JSDescription with PHGR13 proof
|
||||
} else {
|
||||
1698 // JSDescription with Groth16 proof
|
||||
},
|
||||
);
|
||||
for js in &tx.joinsplits {
|
||||
for js in joinsplits {
|
||||
js.write(&mut data).unwrap();
|
||||
}
|
||||
data.extend_from_slice(&tx.joinsplit_pubkey.unwrap());
|
||||
data.extend_from_slice(joinsplit_pubkey);
|
||||
Blake2bParams::new()
|
||||
.hash_length(32)
|
||||
.personal(ZCASH_JOINSPLITS_HASH_PERSONALIZATION)
|
||||
.hash(&data)
|
||||
}
|
||||
|
||||
fn shielded_spends_hash(tx: &TransactionData) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(tx.shielded_spends.len() * 384);
|
||||
for s_spend in &tx.shielded_spends {
|
||||
fn shielded_spends_hash(shielded_spends: &[SpendDescription]) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(shielded_spends.len() * 384);
|
||||
for s_spend in shielded_spends {
|
||||
data.extend_from_slice(&s_spend.cv.to_bytes());
|
||||
data.extend_from_slice(s_spend.anchor.to_repr().as_ref());
|
||||
data.extend_from_slice(&s_spend.nullifier);
|
||||
|
@ -155,9 +161,9 @@ fn shielded_spends_hash(tx: &TransactionData) -> Blake2bHash {
|
|||
.hash(&data)
|
||||
}
|
||||
|
||||
fn shielded_outputs_hash(tx: &TransactionData) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(tx.shielded_outputs.len() * 948);
|
||||
for s_out in &tx.shielded_outputs {
|
||||
fn shielded_outputs_hash(shielded_outputs: &[OutputDescription]) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(shielded_outputs.len() * 948);
|
||||
for s_out in shielded_outputs {
|
||||
s_out.write(&mut data).unwrap();
|
||||
}
|
||||
Blake2bParams::new()
|
||||
|
@ -166,9 +172,9 @@ fn shielded_outputs_hash(tx: &TransactionData) -> Blake2bHash {
|
|||
.hash(&data)
|
||||
}
|
||||
|
||||
fn tze_inputs_hash(tx: &TransactionData) -> Blake2bHash {
|
||||
fn tze_inputs_hash(tze_inputs: &[TzeIn]) -> Blake2bHash {
|
||||
let mut data = vec![];
|
||||
for tzein in &tx.tze_inputs {
|
||||
for tzein in tze_inputs {
|
||||
tzein.write_without_witness(&mut data).unwrap();
|
||||
}
|
||||
Blake2bParams::new()
|
||||
|
@ -177,9 +183,9 @@ fn tze_inputs_hash(tx: &TransactionData) -> Blake2bHash {
|
|||
.hash(&data)
|
||||
}
|
||||
|
||||
fn tze_outputs_hash(tx: &TransactionData) -> Blake2bHash {
|
||||
fn tze_outputs_hash(tze_outputs: &[TzeOut]) -> Blake2bHash {
|
||||
let mut data = vec![];
|
||||
for tzeout in &tx.tze_outputs {
|
||||
for tzeout in tze_outputs {
|
||||
tzeout.write(&mut data).unwrap();
|
||||
}
|
||||
Blake2bParams::new()
|
||||
|
@ -243,19 +249,23 @@ pub fn signature_hash_data<'a>(
|
|||
|
||||
update_u32!(h, tx.header(), tmp);
|
||||
update_u32!(h, tx.version_group_id, tmp);
|
||||
update_hash!(h, hash_type & SIGHASH_ANYONECANPAY == 0, prevout_hash(tx));
|
||||
update_hash!(
|
||||
h,
|
||||
hash_type & SIGHASH_ANYONECANPAY == 0,
|
||||
prevout_hash(&tx.vin)
|
||||
);
|
||||
update_hash!(
|
||||
h,
|
||||
hash_type & SIGHASH_ANYONECANPAY == 0
|
||||
&& (hash_type & SIGHASH_MASK) != SIGHASH_SINGLE
|
||||
&& (hash_type & SIGHASH_MASK) != SIGHASH_NONE,
|
||||
sequence_hash(tx)
|
||||
sequence_hash(&tx.vin)
|
||||
);
|
||||
|
||||
if (hash_type & SIGHASH_MASK) != SIGHASH_SINGLE
|
||||
&& (hash_type & SIGHASH_MASK) != SIGHASH_NONE
|
||||
{
|
||||
h.update(outputs_hash(tx).as_ref());
|
||||
h.update(outputs_hash(&tx.vout).as_ref());
|
||||
} else if (hash_type & SIGHASH_MASK) == SIGHASH_SINGLE {
|
||||
match signable_input {
|
||||
SignableInput::Transparent { index, .. } if index < tx.vout.len() => {
|
||||
|
@ -267,16 +277,32 @@ pub fn signature_hash_data<'a>(
|
|||
h.update(&[0; 32]);
|
||||
};
|
||||
if sigversion == SigHashVersion::ZFuture {
|
||||
update_hash!(h, !tx.tze_inputs.is_empty(), tze_inputs_hash(tx));
|
||||
update_hash!(h, !tx.tze_outputs.is_empty(), tze_outputs_hash(tx));
|
||||
update_hash!(
|
||||
h,
|
||||
!tx.tze_inputs.is_empty(),
|
||||
tze_inputs_hash(&tx.tze_inputs)
|
||||
);
|
||||
update_hash!(
|
||||
h,
|
||||
!tx.tze_outputs.is_empty(),
|
||||
tze_outputs_hash(&tx.tze_outputs)
|
||||
);
|
||||
}
|
||||
update_hash!(h, !tx.joinsplits.is_empty(), joinsplits_hash(tx));
|
||||
update_hash!(
|
||||
h,
|
||||
!tx.joinsplits.is_empty(),
|
||||
joinsplits_hash(tx.version, &tx.joinsplits, &tx.joinsplit_pubkey.unwrap())
|
||||
);
|
||||
if sigversion == SigHashVersion::Sapling || sigversion == SigHashVersion::ZFuture {
|
||||
update_hash!(h, !tx.shielded_spends.is_empty(), shielded_spends_hash(tx));
|
||||
update_hash!(
|
||||
h,
|
||||
!tx.shielded_spends.is_empty(),
|
||||
shielded_spends_hash(&tx.shielded_spends)
|
||||
);
|
||||
update_hash!(
|
||||
h,
|
||||
!tx.shielded_outputs.is_empty(),
|
||||
shielded_outputs_hash(tx)
|
||||
shielded_outputs_hash(&tx.shielded_outputs)
|
||||
);
|
||||
}
|
||||
update_u32!(h, tx.lock_time, tmp);
|
||||
|
|
Loading…
Reference in New Issue