Esempio n. 1
0
 def _hsig_input(self, index):
     '''
     inputs for the hsig hash
     '''
     hsig_input = z.ZcashByteData()
     hsig_input += self.tx_joinsplits[index].random_seed
     hsig_input += self.tx_joinsplits[index].nullifiers
     hsig_input += self.joinsplit_pubkey
     return hsig_input.to_bytes()
Esempio n. 2
0
    def _hash_prevouts(self, anyone_can_pay: bool) -> bytes:
        if anyone_can_pay:
            return b'\x00' * 32

        data = z.ZcashByteData()
        for tx_in in self.tx_ins:
            data += tx_in.outpoint
        return utils.blake2b(data=data.to_bytes(),
                             digest_size=32,
                             person=b'ZcashPrevoutHash')
Esempio n. 3
0
 def _sighash_final_hashing(self, copy_tx, sighash_type):
     '''
     SproutTx, int -> bytes
     Returns the hash that should be signed
     https://en.bitcoin.it/wiki/OP_CHECKSIG#Procedure_for_Hashtype_SIGHASH_ANYONECANPAY
     '''
     sighash = z.ZcashByteData()
     sighash += copy_tx.to_bytes()
     sighash += utils.i2le_padded(sighash_type, 4)
     return utils.hash256(sighash.to_bytes())
Esempio n. 4
0
    def _hash_sequence(self, sighash_type: int, anyone_can_pay: bool) -> bytes:
        if anyone_can_pay or sighash_type == shared.SIGHASH_SINGLE:
            return b'\x00' * 32

        data = z.ZcashByteData()
        for tx_in in self.tx_ins:
            data += tx_in.sequence

        return utils.blake2b(data=data.to_bytes(),
                             digest_size=32,
                             person=b'ZcashSequencHash')
Esempio n. 5
0
    def _hash_shielded_outputs(self) -> bytes:
        if len(self.tx_shielded_outputs) == 0:
            return b'\x00' * 32

        data = z.ZcashByteData()

        for so in self.tx_shielded_outputs:
            data += so

        return utils.blake2b(data=data.to_bytes(),
                             digest_size=32,
                             person=b'ZcashSOutputHash')
Esempio n. 6
0
    def _hash_shielded_spends(self) -> bytes:
        if len(self.tx_shielded_spends) == 0:
            return b'\x00' * 32

        data = z.ZcashByteData()

        for ss in self.tx_shielded_spends:
            data += ss[:320]  # Strip off spend_auth_sig

        return utils.blake2b(data=data.to_bytes(),
                             digest_size=32,
                             person=b'ZcashSSpendsHash')
Esempio n. 7
0
 def _primary_input(self, index):
     '''
     Primary input for the zkproof
     '''
     primary_input = z.ZcashByteData()
     primary_input += self.tx_joinsplits[index].anchor
     primary_input += self.tx_joinsplits[index].nullifiers
     primary_input += self.tx_joinsplits[index].commitments
     primary_input += self.tx_joinsplits[index].vpub_old
     primary_input += self.tx_joinsplits[index].vpub_new
     primary_input += self.hsigs[index]
     primary_input += self.tx_joinsplits[index].vmacs
     return primary_input.to_bytes()
Esempio n. 8
0
    def _hash_joinsplits(self) -> bytes:
        if len(self.tx_joinsplits) == 0:
            return b'\x00' * 32

        data = z.ZcashByteData()

        for joinsplit in self.tx_joinsplits:
            data += joinsplit

        data += cast(bytes, self.joinsplit_pubkey)

        return utils.blake2b(data=data.to_bytes(),
                             digest_size=32,
                             person=b'ZcashJSplitsHash')
Esempio n. 9
0
    def sighash(self,
                sighash_type: int,
                prevout_value: bytes,
                index: int = 0,
                joinsplit: bool = False,
                script_code: Optional[bytes] = None,
                anyone_can_pay: bool = False) -> bytes:
        '''
        ZIP243
        https://github.com/zcash/zips/blob/master/zip-0243.rst
        '''

        if joinsplit and anyone_can_pay:
            raise ValueError('ANYONECANPAY can\'t be used with joinsplits')

        data = z.ZcashByteData()

        data += self.header
        data += self.group_id

        data += self._hash_prevouts(anyone_can_pay)
        data += self._hash_sequence(sighash_type, anyone_can_pay)
        data += self._hash_outputs(sighash_type, index)
        data += self._hash_joinsplits()
        data += self._hash_shielded_spends()
        data += self._hash_shielded_outputs()

        data += self.lock_time
        data += self.expiry_height
        data += self.value_balance

        if anyone_can_pay:
            sighash_type = sighash_type | shared.SIGHASH_ANYONECANPAY
        data += utils.i2le_padded(sighash_type, 4)

        if not joinsplit:
            data += self.tx_ins[index].outpoint
            data += cast(bytes, script_code)
            data += prevout_value
            data += self.tx_ins[index].sequence

        return utils.blake2b(data=data.to_bytes(),
                             digest_size=32,
                             person=b'ZcashSigHash' +
                             bytes.fromhex('bb09b876'))  # Branch ID
Esempio n. 10
0
    def _hash_outputs(self, sighash_type: int, index: int) -> bytes:
        if sighash_type not in [shared.SIGHASH_ALL, shared.SIGHASH_SINGLE]:
            return b'\x00' * 32

        data = z.ZcashByteData()

        if sighash_type == shared.SIGHASH_ALL:
            for tx_out in self.tx_outs:
                data += tx_out

        if sighash_type == shared.SIGHASH_SINGLE:
            if index > len(self.tx_outs):
                raise NotImplementedError(
                    'I refuse to implement the SIGHASH_SINGLE bug.')
            data += self.tx_outs[index]

        return utils.blake2b(data=data.to_bytes(),
                             digest_size=32,
                             person=b'ZcashOutputsHash')
Esempio n. 11
0
    def sighash(self, sighash_type, index=0, joinsplit=False, script_code=None,
                anyone_can_pay=False, prevout_value=None):
        '''
        ZIP143
        https://github.com/zcash/zips/blob/master/zip-0143.rst
        '''

        if joinsplit and anyone_can_pay:
            raise ValueError('ANYONECANPAY can\'t be used with joinsplits')

        data = z.ZcashByteData()

        data += self.header
        data += self.group_id

        data += self._hash_prevouts(anyone_can_pay)
        data += self._hash_sequence(sighash_type, anyone_can_pay)
        data += self._hash_outputs(sighash_type, index)
        data += self._hash_joinsplits()

        data += self.lock_time
        data += self.expiry_height
        if anyone_can_pay:
            sighash_type = sighash_type | shared.SIGHASH_ANYONECANPAY
        data += utils.i2le_padded(sighash_type, 4)

        if not joinsplit:
            data += self.tx_ins[index].outpoint
            data += script_code
            data += prevout_value
            data += self.tx_ins[index].sequence

        return utils.blake2b(
            data=data.to_bytes(),
            digest_size=32,
            person=b'ZcashSigHash' + bytes.fromhex('191ba85b'))  # Branch ID