Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions test-vectors/json/orchard_zsa_asset_base.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions test-vectors/json/orchard_zsa_digests.json

Large diffs are not rendered by default.

40 changes: 20 additions & 20 deletions test-vectors/rust/orchard_zsa_asset_base.rs

Large diffs are not rendered by default.

110 changes: 55 additions & 55 deletions test-vectors/rust/orchard_zsa_digests.rs

Large diffs are not rendered by default.

40 changes: 20 additions & 20 deletions test-vectors/zcash/orchard_zsa_asset_base.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions test-vectors/zcash/orchard_zsa_digests.json

Large diffs are not rendered by default.

13 changes: 3 additions & 10 deletions zcash_test_vectors/orchard_zsa/asset_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,9 @@ def native_asset():
return group_hash(b"z.cash:Orchard-cv", b"v")


def asset_desc_digest(asset_desc):
h = blake2b(digest_size=32, person=b"ZSA-AssetDescCRH")
h.update(asset_desc)
return h.digest()


def encode_asset_id(key, asset_desc_hash):
def encode_asset_id(key, description):
version_byte = b"\x00"
return version_byte + key + asset_desc_hash
return version_byte + key + description


def asset_digest(encoded_asset_id):
Expand Down Expand Up @@ -89,8 +83,7 @@ def randbytes(l):

key_bytes = bytes(isk.ik)
description_bytes = get_random_unicode_bytes(512, rand)
asset_desc_hash = asset_desc_digest(description_bytes)
asset_base = zsa_value_base(asset_digest(encode_asset_id(key_bytes, asset_desc_hash)))
asset_base = zsa_value_base(asset_digest(encode_asset_id(key_bytes, description_bytes)))

test_vectors.append({
'key': key_bytes,
Expand Down
10 changes: 5 additions & 5 deletions zcash_test_vectors/orchard_zsa/digests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ def orchard_zsa_digest(tx):

if len(tx.vActionGroupsOrchard) > 0:
digest.update(orchard_zsa_action_groups_digest(tx))
digest.update(orchard_zsa_burn_digest(tx))
digest.update(struct.pack('<Q', tx.valueBalanceOrchard))

return digest.digest()
Expand All @@ -31,6 +30,7 @@ def orchard_zsa_action_groups_digest(tx):
digest.update(struct.pack('<B', ag.flagsOrchard))
digest.update(bytes(ag.anchorOrchard))
digest.update(struct.pack('<I', ag.nAGExpiryHeight))
digest.update(orchard_zsa_burn_digest(ag))

return digest.digest()

Expand Down Expand Up @@ -87,11 +87,11 @@ def orchard_zsa_actions_noncompact_digest(ag):
return digest.digest()


def orchard_zsa_burn_digest(tx):
def orchard_zsa_burn_digest(ag):
digest = blake2b(digest_size=32, person=b'ZTxIdOrcBurnHash')

if len(tx.vAssetBurnOrchardZSA) > 0:
for desc in tx.vAssetBurnOrchardZSA:
if len(ag.vAssetBurnOrchardZSA) > 0:
for desc in ag.vAssetBurnOrchardZSA:
digest.update(bytes(desc.assetBase))
digest.update(struct.pack('<Q', desc.valueBurn))

Expand Down Expand Up @@ -120,7 +120,7 @@ def issue_actions_digest(tx):

for action in tx.vIssueActions:
digest.update(issue_notes_digest(action))
digest.update(action.asset_desc_hash)
digest.update(action.asset_desc)
digest.update(struct.pack('<B', action.flagsIssuance))

return digest.digest()
Expand Down
49 changes: 25 additions & 24 deletions zcash_test_vectors/transaction_v6.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .orchard.pallas import Point
from .orchard_zsa.key_components import IssuanceKeys
from .orchard_zsa.digests import NU7_VERSION_GROUP_ID, NU7_TX_VERSION_BYTES
from .orchard_zsa.asset_base import zsa_value_base, asset_digest, encode_asset_id, get_random_unicode_bytes, asset_desc_digest
from .orchard_zsa.asset_base import zsa_value_base, asset_digest, encode_asset_id, get_random_unicode_bytes
from .zc_utils import write_compact_size
from .transaction import (
NOTEENCRYPTION_AUTH_BYTES, ZC_SAPLING_ENCPLAINTEXT_SIZE,
Expand Down Expand Up @@ -40,17 +40,17 @@ def __bytes__(self):
class IssueActionDescription(object):
def __init__(self, rand, ik):
self.assetDescSize = rand.u32() % 512 + 1
self.asset_desc_hash = asset_desc_digest(get_random_unicode_bytes(self.assetDescSize, rand))
self.asset_desc = get_random_unicode_bytes(self.assetDescSize, rand)
self.vNotes = []
for _ in range(rand.u8() % 5):
self.vNotes.append(IssueNote(rand, ik, self.asset_desc_hash))
self.vNotes.append(IssueNote(rand, ik, self.asset_desc))
self.flagsIssuance = rand.u8() & 1 # Only one bit is reserved for the finalize flag currently

def __bytes__(self):
ret = b''

ret += write_compact_size(self.assetDescSize)
ret += bytes(self.asset_desc_hash)
ret += bytes(self.asset_desc)
ret += write_compact_size(len(self.vNotes))
if len(self.vNotes) > 0:
for note in self.vNotes:
Expand All @@ -61,11 +61,11 @@ def __bytes__(self):


class IssueNote(object):
def __init__(self, rand, ik, asset_desc_hash):
def __init__(self, rand, ik, asset_desc):
fvk_r = FullViewingKey.from_spending_key(SpendingKey(rand.b(32)))
self.recipient = fvk_r.default_d() + bytes(fvk_r.default_pkd())
self.value = rand.u64()
asset_digest_bytes = asset_digest(encode_asset_id(ik, asset_desc_hash))
asset_digest_bytes = asset_digest(encode_asset_id(ik, asset_desc))
self.assetBase = zsa_value_base(asset_digest_bytes)
self.rho = Point.rand(rand).extract()
self.rseed = rand.b(32)
Expand All @@ -82,7 +82,7 @@ def __bytes__(self):


class ActionGroupDescription(object):
def __init__(self, rand, anchor_orchard, proofs_orchard, is_coinbase):
def __init__(self, rand, anchor_orchard, proofs_orchard, is_coinbase, have_burn):
self.vActionsOrchard = []
# There must always be a non-zero number of Action Descriptions in an Action Group.
for _ in range(rand.u8() % 4 + 1):
Expand All @@ -98,21 +98,37 @@ def __init__(self, rand, anchor_orchard, proofs_orchard, is_coinbase):
self.proofsOrchard = proofs_orchard
self.nAGExpiryHeight = 0

# OrchardZSA Burn Fields
self.vAssetBurnOrchardZSA = []
if have_burn:
for _ in range(rand.u8() % 5):
self.vAssetBurnOrchardZSA.append(AssetBurnDescription(rand))


def __bytes__(self):
ret = b''
ret += write_compact_size(len(self.vActionsOrchard))
for desc in self.vActionsOrchard:
ret += bytes(desc) # Excludes spendAuthSig
ret += struct.pack('B', self.flagsOrchard)
ret += bytes(self.anchorOrchard)
ret += struct.pack('<I', self.nAGExpiryHeight)
ret += self.orchard_zsa_burn_field_bytes()
ret += write_compact_size(len(self.proofsOrchard))
ret += self.proofsOrchard
ret += struct.pack('<I', self.nAGExpiryHeight)
for desc in self.vActionsOrchard:
ret += bytes(desc.spendAuthSig)

return ret

def orchard_zsa_burn_field_bytes(self):
ret = b''
ret += write_compact_size(len(self.vAssetBurnOrchardZSA))
if len(self.vAssetBurnOrchardZSA) > 0:
for desc in self.vAssetBurnOrchardZSA:
ret += bytes(desc)
return ret


class TransactionV6(TransactionBase):
def __init__(self, rand, consensus_branch_id, have_orchard_zsa=True, have_burn=True, have_issuance=True):
Expand All @@ -131,13 +147,7 @@ def __init__(self, rand, consensus_branch_id, have_orchard_zsa=True, have_burn=T
self.vActionGroupsOrchard = []
if have_orchard_zsa:
# For NU7 we have a maximum of one Action Group.
self.vActionGroupsOrchard.append(ActionGroupDescription(rand, self.anchorOrchard, self.proofsOrchard, self.is_coinbase()))

# OrchardZSA Burn Fields
self.vAssetBurnOrchardZSA = []
if have_burn:
for _ in range(rand.u8() % 5):
self.vAssetBurnOrchardZSA.append(AssetBurnDescription(rand))
self.vActionGroupsOrchard.append(ActionGroupDescription(rand, self.anchorOrchard, self.proofsOrchard, self.is_coinbase(), have_burn))

# OrchardZSA Issuance Fields
self.vIssueActions = []
Expand All @@ -153,14 +163,6 @@ def __init__(self, rand, consensus_branch_id, have_orchard_zsa=True, have_burn=T
def version_bytes():
return NU7_TX_VERSION_BYTES

def orchard_zsa_burn_field_bytes(self):
ret = b''
ret += write_compact_size(len(self.vAssetBurnOrchardZSA))
if len(self.vAssetBurnOrchardZSA) > 0:
for desc in self.vAssetBurnOrchardZSA:
ret += bytes(desc)
return ret

def issuance_field_bytes(self):
ret = b''
ret += write_compact_size(len(self.vIssueActions))
Expand All @@ -183,7 +185,6 @@ def __bytes__(self):
for ag in self.vActionGroupsOrchard:
ret += bytes(ag)
ret += struct.pack('<Q', self.valueBalanceOrchard)
ret += self.orchard_zsa_burn_field_bytes()
ret += bytes(self.bindingSigOrchard)

# OrchardZSA Issuance Fields
Expand Down