Skip to content
Merged
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
206 changes: 113 additions & 93 deletions test-vectors/rust/orchard_note_encryption.rs

Large diffs are not rendered by default.

683 changes: 299 additions & 384 deletions test-vectors/rust/zip_0244.rs

Large diffs are not rendered by default.

13 changes: 6 additions & 7 deletions zcash_test_vectors/orchard/commitments.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
#!/usr/bin/env python3
import sys;

from zcash_test_vectors.orchard.asset_id import asset_id, native_asset
import sys

assert sys.version_info[0] >= 3, "Python 3 required."

from .group_hash import group_hash
from .pallas import Fp, Scalar, Point
from .sinsemilla import sinsemilla_hash_to_point
from ..utils import i2lebsp
from .asset_id import asset_id, native_asset
from ..utils import i2lebsp, leos2bsp

# Commitment schemes used in Orchard https://zips.z.cash/protocol/nu5.pdf#concretecommit

Expand Down Expand Up @@ -37,10 +36,10 @@ def sinsemilla_short_commit(r: Scalar, D, M):

# ZIP-226 (https://github.com/zcash/zips/pull/628)
def note_commit(rcm, g_d, pk_d, v, asset, rho, psi):
if asset:
return note_commit_zsa(rcm, g_d, pk_d, v, asset, rho, psi)
else:
if asset == leos2bsp(bytes(native_asset())):
return note_commit_orchard(rcm, g_d, pk_d, v, rho, psi)
else:
return note_commit_zsa(rcm, g_d, pk_d, v, asset, rho, psi)

# https://zips.z.cash/protocol/nu5.pdf#concreteorchardnotecommit
def note_commit_orchard(rcm, g_d, pk_d, v, rho, psi):
Expand Down
31 changes: 14 additions & 17 deletions zcash_test_vectors/orchard/note.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import struct

from .asset_id import native_asset
from .commitments import note_commit
from .key_components import diversify_hash, prf_expand, derive_nullifier, FullViewingKey, SpendingKey
from .pallas import Point, Scalar
from .utils import to_base, to_scalar

from ..utils import leos2bsp


class OrchardNote(object):
def __init__(self, d, pk_d, v, asset, rho, rseed):
assert isinstance(v, int)
Expand Down Expand Up @@ -40,23 +41,21 @@ def psi(self):

def note_commitment(self):
g_d = diversify_hash(self.d)
asset = self.asset and leos2bsp(self.asset)
return note_commit(self.rcm, leos2bsp(bytes(g_d)), leos2bsp(bytes(self.pk_d)), self.v, asset, self.rho, self.psi)
# asset = self.asset and leos2bsp(self.asset)
return note_commit(self.rcm, leos2bsp(bytes(g_d)), leos2bsp(bytes(self.pk_d)), self.v, leos2bsp(bytes(self.asset)), self.rho, self.psi)

def note_plaintext(self, memo):
return OrchardNotePlaintext(self.d, self.v, self.asset, self.rseed, memo)
return OrchardNotePlaintext(self.d, self.v, self.rseed, self.asset, memo)

# https://zips.z.cash/protocol/nu5.pdf#notept
class OrchardNotePlaintext(object):
def __init__(self, d, v, asset, rseed, memo):
def __init__(self, d, v, rseed, asset, memo):
self.leadbyte = bytes.fromhex('03' if asset else '02')
self.d = d
self.v = v
self.asset = asset
self.rseed = rseed
self.memo = memo
if asset:
assert(max(memo[512-32:]) == 0)

@staticmethod
def from_bytes(buf):
Expand All @@ -70,21 +69,21 @@ def from_bytes(buf):
@staticmethod
def _from_bytes_orchard(buf):
return OrchardNotePlaintext(
buf[1:12], # d
buf[1:12], # d
struct.unpack('<Q', buf[12:20])[0], # v
None, # asset
buf[20:52], # rseed
buf[52:564], # memo
buf[20:52], # rseed
None, # asset
buf[52:564], # memo
)

@staticmethod
def _from_bytes_zsa(buf):
return OrchardNotePlaintext(
buf[1:12], # d
struct.unpack('<Q', buf[12:20])[0], # v
buf[52:84], # asset
buf[20:52], # rseed
buf[84:564] + bytes(32), # memo
buf[52:84], # asset
buf[84:596] # memo
)

def __bytes__(self):
Expand All @@ -109,7 +108,7 @@ def _to_bytes_zsa(self):
struct.pack('<Q', self.v) +
self.rseed +
self.asset +
self.memo[:512-32]
self.memo
)

def dummy_nullifier(self, rand):
Expand All @@ -119,11 +118,9 @@ def dummy_nullifier(self, rand):
d = fvk.default_d()

v = 0
asset = None

rseed = rand.b(32)
rho = Point.rand(rand).extract()

note = OrchardNote(d, pk_d, v, asset, rho, rseed)
note = OrchardNote(d, pk_d, v, native_asset(), rho, rseed)
cm = note.note_commitment()
return derive_nullifier(fvk.nk, rho, note.psi, cm)
34 changes: 10 additions & 24 deletions zcash_test_vectors/orchard/note_encryption.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
#!/usr/bin/env python3
import sys;

from zcash_test_vectors.orchard.asset_id import native_asset
from .asset_id import native_asset

assert sys.version_info[0] >= 3, "Python 3 required."

from chacha20poly1305 import ChaCha20Poly1305
from hashlib import blake2b
import os
import struct

from ..transaction import MAX_MONEY
from ..output import render_args, render_tv, option, Some
from ..output import render_args, render_tv
from ..rand import Rand

from .generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE
from .pallas import Point, Scalar
from .commitments import rcv_trapdoor, value_commit
from .key_components import diversify_hash, prf_expand, FullViewingKey, SpendingKey
from .note import OrchardNote, OrchardNotePlaintext
from .utils import to_scalar
from ..utils import leos2bsp

# https://zips.z.cash/protocol/nu5.pdf#concreteorchardkdf
def kdf_orchard(shared_secret, ephemeral_key):
Expand Down Expand Up @@ -213,27 +209,17 @@ def randbytes(l):

is_native = i < 10
asset_point = native_asset() if is_native else Point.rand(rand)
asset_bytes_opt = None if is_native else bytes(asset_point)
asset_bytes = bytes(asset_point)
rseed = rand.b(32)

memo = b'\xff' + rand.b(511)
if not is_native:
# Set the end of the memo to zeros
memo = memo[:512-32] + bytes(32)

np = OrchardNotePlaintext(
d,
rand.u64(),
asset_bytes_opt,
rseed,
memo
)

np = OrchardNotePlaintext(d, rand.u64(), rseed, asset_bytes, memo)

rcv = rcv_trapdoor(rand)
cv = value_commit(rcv, Scalar(np.v), asset_point)

rho = np.dummy_nullifier(rand)
note = OrchardNote(d, pk_d, np.v, asset_bytes_opt, rho, rseed)
note = OrchardNote(d, pk_d, np.v, asset_bytes, rho, rseed)
cm = note.note_commitment()

ne = OrchardNoteEncryption(rand)
Expand All @@ -259,6 +245,7 @@ def randbytes(l):
'default_pk_d': bytes(pk_d),
'v': np.v,
'rseed': note.rseed,
'asset': asset_bytes,
'memo': np.memo,
'cv_net': bytes(cv),
'rho': bytes(rho),
Expand All @@ -272,7 +259,6 @@ def randbytes(l):
'ock': ne.ock,
'op': ne.op,
'c_out': transmitted_note_ciphertext.c_out,
'asset': asset_bytes_opt,
})

render_tv(
Expand All @@ -285,6 +271,7 @@ def randbytes(l):
('default_pk_d', '[u8; 32]'),
('v', 'u64'),
('rseed', '[u8; 32]'),
('asset', '[u8; 32]'),
('memo', '[u8; 512]'),
('cv_net', '[u8; 32]'),
('rho', '[u8; 32]'),
Expand All @@ -293,12 +280,11 @@ def randbytes(l):
('ephemeral_key', '[u8; 32]'),
('shared_secret', '[u8; 32]'),
('k_enc', '[u8; 32]'),
('p_enc', '[u8; 564]'),
('c_enc', '[u8; 580]'),
('p_enc', '[u8; 596]'),
('c_enc', '[u8; 612]'),
('ock', '[u8; 32]'),
('op', '[u8; 64]'),
('c_out', '[u8; 80]'),
('asset', 'Option<[u8; 32]>'),
),
test_vectors,
)
Expand Down
5 changes: 4 additions & 1 deletion zcash_test_vectors/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@
ZC_R_SIZE = 32
ZC_MEMO_SIZE = 512
ZC_DIVERSIFIER_SIZE = 11
ZC_ORCHARD_ZSA_ASSET_SIZE = 32
ZC_JUBJUB_POINT_SIZE = 32
ZC_JUBJUB_SCALAR_SIZE = 32
ZC_NOTEPLAINTEXT_SIZE = ZC_NOTEPLAINTEXT_LEADING + ZC_V_SIZE + ZC_RHO_SIZE + ZC_R_SIZE + ZC_MEMO_SIZE
ZC_SAPLING_ENCPLAINTEXT_SIZE = ZC_NOTEPLAINTEXT_LEADING + ZC_DIVERSIFIER_SIZE + ZC_V_SIZE + ZC_R_SIZE + ZC_MEMO_SIZE
ZC_SAPLING_OUTPLAINTEXT_SIZE = ZC_JUBJUB_POINT_SIZE + ZC_JUBJUB_SCALAR_SIZE
ZC_SAPLING_ENCCIPHERTEXT_SIZE = ZC_SAPLING_ENCPLAINTEXT_SIZE + NOTEENCRYPTION_AUTH_BYTES
ZC_SAPLING_OUTCIPHERTEXT_SIZE = ZC_SAPLING_OUTPLAINTEXT_SIZE + NOTEENCRYPTION_AUTH_BYTES
ZC_ORCHARD_ZSA_ENCPLAINTEXT_SIZE = ZC_SAPLING_ENCPLAINTEXT_SIZE + ZC_ORCHARD_ZSA_ASSET_SIZE
ZC_ORCHARD_ZSA_ENCCIPHERTEXT_SIZE = ZC_ORCHARD_ZSA_ENCPLAINTEXT_SIZE + NOTEENCRYPTION_AUTH_BYTES

# BN254 encoding of G1 elements. p[1] is big-endian.
def pack_g1(p):
Expand Down Expand Up @@ -167,7 +170,7 @@ def __init__(self, rand):
self.rk = pallas_group_hash(b'TVRandPt', rand.b(32))
self.cmx = PallasBase(leos2ip(rand.b(32)))
self.ephemeralKey = pallas_group_hash(b'TVRandPt', rand.b(32))
self.encCiphertext = rand.b(ZC_SAPLING_ENCCIPHERTEXT_SIZE)
self.encCiphertext = rand.b(ZC_ORCHARD_ZSA_ENCCIPHERTEXT_SIZE)
self.outCiphertext = rand.b(ZC_SAPLING_OUTCIPHERTEXT_SIZE)
self.spendAuthSig = RedPallasSignature(rand)

Expand Down
6 changes: 3 additions & 3 deletions zcash_test_vectors/zip_0244.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,21 +160,21 @@ def orchard_actions_compact_digest(tx):
digest.update(bytes(desc.nullifier))
digest.update(bytes(desc.cmx))
digest.update(bytes(desc.ephemeralKey))
digest.update(desc.encCiphertext[:52])
digest.update(desc.encCiphertext[:84])
return digest.digest()

def orchard_actions_memos_digest(tx):
digest = blake2b(digest_size=32, person=b'ZTxIdOrcActMHash')
for desc in tx.vActionsOrchard:
digest.update(desc.encCiphertext[52:564])
digest.update(desc.encCiphertext[84:596])
return digest.digest()

def orchard_actions_noncompact_digest(tx):
digest = blake2b(digest_size=32, person=b'ZTxIdOrcActNHash')
for desc in tx.vActionsOrchard:
digest.update(bytes(desc.cv))
digest.update(bytes(desc.rk))
digest.update(desc.encCiphertext[564:])
digest.update(desc.encCiphertext[596:])
digest.update(desc.outCiphertext)
return digest.digest()

Expand Down