From 2093b309f4299f00bfca9845bbd8be02295cd9c9 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 7 Jan 2022 14:52:55 +0000 Subject: [PATCH] Refactor test vectors into package Scripts that were previously run via: poetry run python ./SCRIPT_NAME.py and have been moved, can now be run as: poetry run SCRIPT_NAME Some top-level scripts remain, where they only generate test vectors and do not contain any Zcash logic. These now use the `zcash_test_vectors` package, and can't be run directly unless this package is made available in `PYTHONPATH`. --- README.md | 19 +++++++++++---- f4jumble_long.py | 4 ++-- orchard_empty_roots.py | 8 +++---- orchard_map_to_curve.py | 12 +++++----- orchard_poseidon_hash.py | 20 +++++----------- pyproject.toml | 23 ++++++++++++++++++ regenerate.sh | 20 +++++++++++----- unified_address.py | 18 +++++++------- unified_full_viewing_keys.py | 17 +++++++------ zcash_test_vectors/__init__.py | 0 bech32m.py => zcash_test_vectors/bech32m.py | 0 f4jumble.py => zcash_test_vectors/f4jumble.py | 6 ++--- ff1.py => zcash_test_vectors/ff1.py | 2 +- zcash_test_vectors/orchard/__init__.py | 0 .../orchard/commitments.py | 12 +++++----- .../orchard/generators.py | 6 ++--- .../orchard/group_hash.py | 14 +++++------ .../orchard/iso_pallas.py | 8 +++---- .../orchard/key_components.py | 24 +++++++++---------- .../orchard/merkle_tree.py | 10 ++++---- .../orchard/note.py | 10 ++++---- .../orchard/note_encryption.py | 20 ++++++++-------- .../orchard/pallas.py | 4 ++-- .../orchard/poseidon.py | 16 +++++++++---- .../orchard/sinsemilla.py | 12 ++++------ .../orchard/utils.py | 4 ++-- tv_output.py => zcash_test_vectors/output.py | 0 tv_rand.py => zcash_test_vectors/rand.py | 0 zcash_test_vectors/sapling/__init__.py | 0 .../sapling/generators.py | 6 ++--- .../sapling/jubjub.py | 2 +- .../sapling/key_components.py | 12 +++++----- .../sapling/merkle_tree.py | 4 ++-- .../sapling/note_encryption.py | 12 +++++----- .../sapling/notes.py | 4 ++-- .../sapling/pedersen.py | 6 ++--- .../sapling/redjubjub.py | 10 ++++---- .../sapling/zip32.py | 10 ++++---- .../transaction.py | 12 +++++----- .../unified_encoding.py | 6 ++--- utils.py => zcash_test_vectors/utils.py | 0 zc_utils.py => zcash_test_vectors/zc_utils.py | 0 zip_0143.py => zcash_test_vectors/zip_0143.py | 6 ++--- zip_0243.py => zcash_test_vectors/zip_0243.py | 8 +++---- zip_0244.py => zcash_test_vectors/zip_0244.py | 8 +++---- 45 files changed, 217 insertions(+), 178 deletions(-) create mode 100644 zcash_test_vectors/__init__.py rename bech32m.py => zcash_test_vectors/bech32m.py (100%) rename f4jumble.py => zcash_test_vectors/f4jumble.py (96%) rename ff1.py => zcash_test_vectors/ff1.py (98%) create mode 100644 zcash_test_vectors/orchard/__init__.py rename orchard_commitments.py => zcash_test_vectors/orchard/commitments.py (88%) rename orchard_generators.py => zcash_test_vectors/orchard/generators.py (93%) rename orchard_group_hash.py => zcash_test_vectors/orchard/group_hash.py (94%) rename orchard_iso_pallas.py => zcash_test_vectors/orchard/iso_pallas.py (96%) rename orchard_key_components.py => zcash_test_vectors/orchard/key_components.py (87%) rename orchard_merkle_tree.py => zcash_test_vectors/orchard/merkle_tree.py (95%) rename orchard_note.py => zcash_test_vectors/orchard/note.py (88%) rename orchard_note_encryption.py => zcash_test_vectors/orchard/note_encryption.py (94%) rename orchard_pallas.py => zcash_test_vectors/orchard/pallas.py (99%) rename orchard_poseidon.py => zcash_test_vectors/orchard/poseidon.py (98%) rename orchard_sinsemilla.py => zcash_test_vectors/orchard/sinsemilla.py (92%) rename orchard_utils.py => zcash_test_vectors/orchard/utils.py (76%) rename tv_output.py => zcash_test_vectors/output.py (100%) rename tv_rand.py => zcash_test_vectors/rand.py (100%) create mode 100644 zcash_test_vectors/sapling/__init__.py rename sapling_generators.py => zcash_test_vectors/sapling/generators.py (95%) rename sapling_jubjub.py => zcash_test_vectors/sapling/jubjub.py (99%) rename sapling_key_components.py => zcash_test_vectors/sapling/key_components.py (92%) rename sapling_merkle_tree.py => zcash_test_vectors/sapling/merkle_tree.py (91%) rename sapling_note_encryption.py => zcash_test_vectors/sapling/note_encryption.py (93%) rename sapling_notes.py => zcash_test_vectors/sapling/notes.py (91%) rename sapling_pedersen.py => zcash_test_vectors/sapling/pedersen.py (93%) rename sapling_signatures.py => zcash_test_vectors/sapling/redjubjub.py (93%) rename sapling_zip32.py => zcash_test_vectors/sapling/zip32.py (95%) rename transaction.py => zcash_test_vectors/transaction.py (98%) rename unified_encoding.py => zcash_test_vectors/unified_encoding.py (93%) rename utils.py => zcash_test_vectors/utils.py (100%) rename zc_utils.py => zcash_test_vectors/zc_utils.py (100%) rename zip_0143.py => zcash_test_vectors/zip_0143.py (97%) rename zip_0243.py => zcash_test_vectors/zip_0243.py (97%) rename zip_0244.py => zcash_test_vectors/zip_0244.py (99%) diff --git a/README.md b/README.md index b8a2ea6..ef283c4 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,21 @@ Code to generate test vectors for various parts of Zcash. -Requirements: -- `pyblake2` -- `chacha20poly1305` (for `sapling_note_encryption.py`). -- `numpy` (for `orchard_poseidon.py` and dependents). +The generated test vectors are checked into the repository: +- `test-vectors/json/`: JSON format. +- `test-vectors/rust/`: Rust format, suitable for copying into a Rust library or + application to use from `#[cfg(test)]` code. +- `test-vectors/zcash/`: Bitcoin-flavoured JSON format (where 256-bit values are + encoded as byte-reversed hex strings), for use in `zcashd` unit tests. + +To generate the test vectors yourself (for example, to generate a larger set +after adjusting: + +- Install [`poetry`](https://python-poetry.org/). +- `poetry install` +- `poetry run SCRIPT_NAME [-t json|rust|zcash]` + - `SCRIPT_NAME` is either one of the scripts listed in `pyproject.toml`, or + one of the Python files in the root directory. ## License diff --git a/f4jumble_long.py b/f4jumble_long.py index f8af499..d1cc0ca 100755 --- a/f4jumble_long.py +++ b/f4jumble_long.py @@ -3,8 +3,8 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from pyblake2 import blake2b -from tv_output import render_args, render_tv -from f4jumble import f4jumble, f4jumble_inv, MAX_l_M +from zcash_test_vectors.output import render_args, render_tv +from zcash_test_vectors.f4jumble import f4jumble, f4jumble_inv, MAX_l_M def main(): diff --git a/orchard_empty_roots.py b/orchard_empty_roots.py index fb52896..e09e68c 100755 --- a/orchard_empty_roots.py +++ b/orchard_empty_roots.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from orchard_merkle_tree import empty_roots -from orchard_pallas import Fp -from tv_output import render_args, render_tv -from utils import i2lebsp +from zcash_test_vectors.orchard.merkle_tree import empty_roots +from zcash_test_vectors.orchard.pallas import Fp +from zcash_test_vectors.output import render_args, render_tv +from zcash_test_vectors.utils import i2lebsp def main(): diff --git a/orchard_map_to_curve.py b/orchard_map_to_curve.py index d38140d..c08640a 100755 --- a/orchard_map_to_curve.py +++ b/orchard_map_to_curve.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from orchard_group_hash import map_to_curve_simple_swu -from orchard_iso_pallas import Point as IsoPoint -from orchard_pallas import Fp -from utils import leos2ip -from tv_output import render_args, render_tv -from tv_rand import Rand +from zcash_test_vectors.orchard.group_hash import map_to_curve_simple_swu +from zcash_test_vectors.orchard.iso_pallas import Point as IsoPoint +from zcash_test_vectors.orchard.pallas import Fp +from zcash_test_vectors.utils import leos2ip +from zcash_test_vectors.output import render_args, render_tv +from zcash_test_vectors.rand import Rand def main(): diff --git a/orchard_poseidon_hash.py b/orchard_poseidon_hash.py index 9d6dc68..048ea07 100755 --- a/orchard_poseidon_hash.py +++ b/orchard_poseidon_hash.py @@ -1,19 +1,11 @@ #!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from orchard_pallas import Fp -from orchard_poseidon import perm -from utils import leos2ip -from tv_output import render_args, render_tv -from tv_rand import Rand - -# Initial capacity element -CAPACITY_ELEMENT = Fp(1 << 65) - -def poseidon_hash(x, y): - assert isinstance(x, Fp) - assert isinstance(y, Fp) - return perm([x, y, CAPACITY_ELEMENT])[0] +from zcash_test_vectors.orchard.pallas import Fp +from zcash_test_vectors.orchard import poseidon +from zcash_test_vectors.utils import leos2ip +from zcash_test_vectors.output import render_args, render_tv +from zcash_test_vectors.rand import Rand def main(): test_vectors = [[Fp.ZERO, Fp(1)]] @@ -43,7 +35,7 @@ def main(): ), [{ 'input': list(map(bytes, input)), - 'output': bytes(poseidon_hash(input[0], input[1])), + 'output': bytes(poseidon.hash(input[0], input[1])), } for input in test_vectors], ) diff --git a/pyproject.toml b/pyproject.toml index 7701516..32f7942 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,3 +27,26 @@ numpy = "1.21.0" chacha20poly1305 = "0.0.3" cryptography = "36.0.0" pyblake2 = "1.1.2" + +[tool.poetry.scripts] +# General test vectors +f4jumble = "zcash_test_vectors.f4jumble:main" +zip_0143 = "zcash_test_vectors.zip_0143:main" +zip_0243 = "zcash_test_vectors.zip_0243:main" +zip_0244 = "zcash_test_vectors.zip_0244:main" + +# Sapling test vectors +sapling_generators = "zcash_test_vectors.sapling.generators:main" +sapling_key_components = "zcash_test_vectors.sapling.key_components:main" +sapling_note_encryption = "zcash_test_vectors.sapling.note_encryption:main" +sapling_signatures = "zcash_test_vectors.sapling.redjubjub:main" +sapling_zip32 = "zcash_test_vectors.sapling.zip32:main" + +# Orchard test vectors +orchard_generators = "zcash_test_vectors.orchard.generators:main" +orchard_group_hash = "zcash_test_vectors.orchard.group_hash:main" +orchard_key_components = "zcash_test_vectors.orchard.key_components:main" +orchard_merkle_tree = "zcash_test_vectors.orchard.merkle_tree:main" +orchard_note_encryption = "zcash_test_vectors.orchard.note_encryption:main" +orchard_poseidon = "zcash_test_vectors.orchard.poseidon:main" +orchard_sinsemilla = "zcash_test_vectors.orchard.sinsemilla:main" diff --git a/regenerate.sh b/regenerate.sh index 4f39c7d..5ebfbef 100755 --- a/regenerate.sh +++ b/regenerate.sh @@ -1,16 +1,12 @@ #!/usr/bin/env bash tv_scripts=( - f4jumble_long f4jumble - orchard_empty_roots orchard_generators orchard_group_hash orchard_key_components - orchard_map_to_curve orchard_merkle_tree orchard_note_encryption - orchard_poseidon_hash orchard_poseidon orchard_sinsemilla sapling_generators @@ -18,13 +14,25 @@ tv_scripts=( sapling_note_encryption sapling_signatures sapling_zip32 - unified_address - unified_full_viewing_keys zip_0143 zip_0243 zip_0244) +tv_external_scripts=( + f4jumble_long + orchard_empty_roots + orchard_map_to_curve + orchard_poseidon_hash + unified_address + unified_full_viewing_keys) + for generator in "${tv_scripts[@]}" +do + echo "# $generator" + poetry run $generator -t $1 >test-vectors/$1/$generator.$2 +done + +for generator in "${tv_external_scripts[@]}" do echo "# $generator" poetry run python ./$generator.py -t $1 >test-vectors/$1/$generator.$2 diff --git a/unified_address.py b/unified_address.py index 80514aa..059983f 100755 --- a/unified_address.py +++ b/unified_address.py @@ -5,16 +5,16 @@ import math from random import Random import struct -from bech32m import bech32_encode, bech32_decode, convertbits, Encoding +from zcash_test_vectors.bech32m import bech32_encode, bech32_decode, convertbits, Encoding -from tv_output import render_args, render_tv, Some -from tv_rand import Rand, randbytes -from zc_utils import write_compact_size, parse_compact_size -from f4jumble import f4jumble, f4jumble_inv -import sapling_key_components -import orchard_key_components -from unified_encoding import encode_unified, decode_unified -from unified_encoding import P2PKH_ITEM, P2SH_ITEM, SAPLING_ITEM, ORCHARD_ITEM +from zcash_test_vectors.output import render_args, render_tv, Some +from zcash_test_vectors.rand import Rand, randbytes +from zcash_test_vectors.zc_utils import write_compact_size, parse_compact_size +from zcash_test_vectors.f4jumble import f4jumble, f4jumble_inv +from zcash_test_vectors.sapling import key_components as sapling_key_components +from zcash_test_vectors.orchard import key_components as orchard_key_components +from zcash_test_vectors.unified_encoding import encode_unified, decode_unified +from zcash_test_vectors.unified_encoding import P2PKH_ITEM, P2SH_ITEM, SAPLING_ITEM, ORCHARD_ITEM def main(): args = render_args() diff --git a/unified_full_viewing_keys.py b/unified_full_viewing_keys.py index 962a524..0c29384 100755 --- a/unified_full_viewing_keys.py +++ b/unified_full_viewing_keys.py @@ -8,15 +8,14 @@ import struct from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.serialization import PublicFormat, Encoding -from tv_output import render_args, render_tv, Some -from tv_rand import Rand, randbytes -from zc_utils import write_compact_size, parse_compact_size -from f4jumble import f4jumble, f4jumble_inv -import orchard_key_components -import sapling_key_components -import sapling_zip32 -from unified_encoding import encode_unified, decode_unified -from unified_encoding import P2PKH_ITEM, P2SH_ITEM, SAPLING_ITEM, ORCHARD_ITEM +from zcash_test_vectors.output import render_args, render_tv, Some +from zcash_test_vectors.rand import Rand, randbytes +from zcash_test_vectors.zc_utils import write_compact_size, parse_compact_size +from zcash_test_vectors.f4jumble import f4jumble, f4jumble_inv +from zcash_test_vectors.orchard import key_components as orchard_key_components +from zcash_test_vectors.sapling import zip32 as sapling_zip32 +from zcash_test_vectors.unified_encoding import encode_unified, decode_unified +from zcash_test_vectors.unified_encoding import P2PKH_ITEM, P2SH_ITEM, SAPLING_ITEM, ORCHARD_ITEM def main(): args = render_args() diff --git a/zcash_test_vectors/__init__.py b/zcash_test_vectors/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bech32m.py b/zcash_test_vectors/bech32m.py similarity index 100% rename from bech32m.py rename to zcash_test_vectors/bech32m.py diff --git a/f4jumble.py b/zcash_test_vectors/f4jumble.py similarity index 96% rename from f4jumble.py rename to zcash_test_vectors/f4jumble.py index f6f0e44..2a634e0 100755 --- a/f4jumble.py +++ b/zcash_test_vectors/f4jumble.py @@ -6,9 +6,9 @@ import struct from pyblake2 import blake2b -from tv_output import render_args, render_tv -from tv_rand import Rand -from utils import i2leosp +from .output import render_args, render_tv +from .rand import Rand +from .utils import i2leosp # Maximum output length of BLAKE2b diff --git a/ff1.py b/zcash_test_vectors/ff1.py similarity index 98% rename from ff1.py rename to zcash_test_vectors/ff1.py index cf99992..84fd8ba 100755 --- a/ff1.py +++ b/zcash_test_vectors/ff1.py @@ -7,7 +7,7 @@ from binascii import unhexlify, hexlify from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend -from utils import bebs2ip, i2bebsp, beos2ip, bebs2osp, cldiv +from .utils import bebs2ip, i2bebsp, beos2ip, bebs2osp, cldiv # Morris Dworkin # NIST Special Publication 800-38G diff --git a/zcash_test_vectors/orchard/__init__.py b/zcash_test_vectors/orchard/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/orchard_commitments.py b/zcash_test_vectors/orchard/commitments.py similarity index 88% rename from orchard_commitments.py rename to zcash_test_vectors/orchard/commitments.py index c512a0d..c476081 100755 --- a/orchard_commitments.py +++ b/zcash_test_vectors/orchard/commitments.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from orchard_group_hash import group_hash -from orchard_pallas import Fp, Scalar -from orchard_sinsemilla import sinsemilla_hash_to_point -from utils import i2lebsp +from .group_hash import group_hash +from .pallas import Fp, Scalar +from .sinsemilla import sinsemilla_hash_to_point +from ..utils import i2lebsp # Commitment schemes used in Orchard https://zips.z.cash/protocol/nu5.pdf#concretecommit @@ -56,8 +56,8 @@ def rivk_trapdoor(rand): # Test consistency of ValueCommit^{Orchard} with precomputed generators def test_value_commit(): from random import Random - from tv_rand import Rand - from orchard_generators import VALUE_COMMITMENT_RANDOMNESS_BASE, VALUE_COMMITMENT_VALUE_BASE + from ..rand import Rand + from .generators import VALUE_COMMITMENT_RANDOMNESS_BASE, VALUE_COMMITMENT_VALUE_BASE rng = Random(0xabad533d) def randbytes(l): diff --git a/orchard_generators.py b/zcash_test_vectors/orchard/generators.py similarity index 93% rename from orchard_generators.py rename to zcash_test_vectors/orchard/generators.py index dff66e7..fdbf55e 100755 --- a/orchard_generators.py +++ b/zcash_test_vectors/orchard/generators.py @@ -3,9 +3,9 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from pyblake2 import blake2s -from tv_output import render_args, render_tv -from orchard_group_hash import group_hash -from orchard_sinsemilla import sinsemilla_hash_to_point +from ..output import render_args, render_tv +from .group_hash import group_hash +from .sinsemilla import sinsemilla_hash_to_point # https://zips.z.cash/protocol/nu5.pdf#concretespendauthsig SPENDING_KEY_BASE = group_hash(b'z.cash:Orchard', b'G') diff --git a/orchard_group_hash.py b/zcash_test_vectors/orchard/group_hash.py similarity index 94% rename from orchard_group_hash.py rename to zcash_test_vectors/orchard/group_hash.py index 6202f27..b153c80 100755 --- a/orchard_group_hash.py +++ b/zcash_test_vectors/orchard/group_hash.py @@ -3,14 +3,14 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." import math -import orchard_iso_pallas +from . import iso_pallas from pyblake2 import blake2b -from orchard_pallas import Fp, p, q, PALLAS_B, Point -from orchard_iso_pallas import PALLAS_ISO_B, PALLAS_ISO_A -from utils import i2beosp, cldiv, beos2ip, i2leosp, lebs2ip -from tv_output import render_args, render_tv -from tv_rand import Rand +from .pallas import Fp, p, q, PALLAS_B, Point +from .iso_pallas import PALLAS_ISO_B, PALLAS_ISO_A +from ..utils import i2beosp, cldiv, beos2ip, i2leosp, lebs2ip +from ..output import render_args, render_tv +from ..rand import Rand # https://stackoverflow.com/questions/2612720/how-to-do-bitwise-exclusive-or-of-two-strings-in-python def sxor(s1,s2): @@ -122,7 +122,7 @@ def map_to_curve_simple_swu(u): y = y if e3 else -y #y = CMOV(-y, y, e3) - return orchard_iso_pallas.Point(x, y) + return iso_pallas.Point(x, y) def group_hash(d, m): dst = d + b"-" + b"pallas" + b"_XMD:BLAKE2b_SSWU_RO_" diff --git a/orchard_iso_pallas.py b/zcash_test_vectors/orchard/iso_pallas.py similarity index 96% rename from orchard_iso_pallas.py rename to zcash_test_vectors/orchard/iso_pallas.py index fbdfe93..71a6412 100755 --- a/orchard_iso_pallas.py +++ b/zcash_test_vectors/orchard/iso_pallas.py @@ -2,8 +2,8 @@ # -*- coding: utf8 -*- import sys; assert sys.version_info[0] >= 3, "Python 3 required." -import orchard_pallas -from orchard_pallas import Fp, p, q, Scalar +from . import pallas +from .pallas import Fp, p, q, Scalar # # Point arithmetic @@ -60,7 +60,7 @@ class Point(object): ] if self == Point.identity(): - return orchard_pallas.identity() + return pallas.identity() else: numerator_a = c[1] * self.x * self.x * self.x + c[2] * self.x * self.x + c[3] * self.x + c[4] denominator_a = self.x * self.x + c[5] * self.x + c[6] @@ -68,7 +68,7 @@ class Point(object): numerator_b = (c[7] * self.x * self.x * self.x + c[8] * self.x * self.x + c[9] * self.x + c[10]) * self.y denominator_b = self.x * self.x * self.x + c[11] * self.x * self.x + c[12] * self.x + c[13] - return orchard_pallas.Point(numerator_a / denominator_a, numerator_b / denominator_b) + return pallas.Point(numerator_a / denominator_a, numerator_b / denominator_b) def __init__(self, x, y, is_identity=False): self.x = x diff --git a/orchard_key_components.py b/zcash_test_vectors/orchard/key_components.py similarity index 87% rename from orchard_key_components.py rename to zcash_test_vectors/orchard/key_components.py index 1ede873..b630928 100755 --- a/orchard_key_components.py +++ b/zcash_test_vectors/orchard/key_components.py @@ -1,16 +1,16 @@ #!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from ff1 import ff1_aes256_encrypt -from sapling_key_components import prf_expand +from ..ff1 import ff1_aes256_encrypt +from ..sapling.key_components import prf_expand -from orchard_generators import NULLIFIER_K_BASE, SPENDING_KEY_BASE, group_hash -from orchard_pallas import Fp, Scalar, Point -from orchard_poseidon_hash import poseidon_hash -from orchard_commitments import commit_ivk -from utils import i2leosp, i2lebsp, lebs2osp -from orchard_utils import to_base, to_scalar -from tv_output import render_args, render_tv +from .generators import NULLIFIER_K_BASE, SPENDING_KEY_BASE, group_hash +from .pallas import Fp, Scalar, Point +from . import poseidon +from .commitments import commit_ivk +from ..utils import i2leosp, i2lebsp, lebs2osp +from .utils import to_base, to_scalar +from ..output import render_args, render_tv # # PRFs and hashes @@ -23,7 +23,7 @@ def diversify_hash(d): return P def prf_nf_orchard(nk, rho): - return poseidon_hash(nk, rho) + return poseidon.hash(nk, rho) def derive_nullifier(nk, rho: Fp, psi: Fp, cm): scalar = prf_nf_orchard(nk, rho) + psi # addition mod p @@ -77,9 +77,9 @@ class FullViewingKey(object): def main(): args = render_args() - from orchard_note import OrchardNote + from .note import OrchardNote from random import Random - from tv_rand import Rand + from zcash_test_vectors.rand import Rand rng = Random(0xabad533d) def randbytes(l): diff --git a/orchard_merkle_tree.py b/zcash_test_vectors/orchard/merkle_tree.py similarity index 95% rename from orchard_merkle_tree.py rename to zcash_test_vectors/orchard/merkle_tree.py index 2cc30b7..d6508ae 100755 --- a/orchard_merkle_tree.py +++ b/zcash_test_vectors/orchard/merkle_tree.py @@ -3,11 +3,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from binascii import unhexlify -from orchard_pallas import Fp -from orchard_sinsemilla import sinsemilla_hash +from .pallas import Fp +from .sinsemilla import sinsemilla_hash -from tv_output import render_args, render_tv -from utils import i2lebsp, leos2bsp +from ..output import render_args, render_tv +from ..utils import i2lebsp, leos2bsp # https://zips.z.cash/protocol/nu5.pdf#constants MERKLE_DEPTH = 32 @@ -45,7 +45,7 @@ def main(): args = render_args() from random import Random - from tv_rand import Rand + from ..rand import Rand rng = Random(0xabad533d) def randbytes(l): diff --git a/orchard_note.py b/zcash_test_vectors/orchard/note.py similarity index 88% rename from orchard_note.py rename to zcash_test_vectors/orchard/note.py index e11a311..2a9cebc 100644 --- a/orchard_note.py +++ b/zcash_test_vectors/orchard/note.py @@ -1,11 +1,11 @@ import struct -from orchard_commitments import note_commit -from orchard_key_components import diversify_hash, prf_expand, derive_nullifier, FullViewingKey, SpendingKey -from orchard_pallas import Point, Scalar -from orchard_utils import to_base, to_scalar +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 +from ..utils import leos2bsp class OrchardNote(object): def __init__(self, d, pk_d, v, rho, rseed): diff --git a/orchard_note_encryption.py b/zcash_test_vectors/orchard/note_encryption.py similarity index 94% rename from orchard_note_encryption.py rename to zcash_test_vectors/orchard/note_encryption.py index ce09c95..701b469 100755 --- a/orchard_note_encryption.py +++ b/zcash_test_vectors/orchard/note_encryption.py @@ -6,17 +6,17 @@ import struct from chacha20poly1305 import ChaCha20Poly1305 import os from pyblake2 import blake2b -from transaction import MAX_MONEY -from tv_output import render_args, render_tv -from tv_rand import Rand +from ..transaction import MAX_MONEY +from ..output import render_args, render_tv +from ..rand import Rand -from orchard_generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE -from orchard_pallas import Point, Scalar -from orchard_commitments import rcv_trapdoor, value_commit -from orchard_key_components import diversify_hash, prf_expand, FullViewingKey, SpendingKey -from orchard_note import OrchardNote, OrchardNotePlaintext -from orchard_utils import to_scalar -from utils import leos2bsp +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): diff --git a/orchard_pallas.py b/zcash_test_vectors/orchard/pallas.py similarity index 99% rename from orchard_pallas.py rename to zcash_test_vectors/orchard/pallas.py index 0ed16e2..6f69bca 100644 --- a/orchard_pallas.py +++ b/zcash_test_vectors/orchard/pallas.py @@ -2,8 +2,8 @@ # -*- coding: utf8 -*- import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from sapling_jubjub import FieldElement -from utils import leos2ip +from ..sapling.jubjub import FieldElement +from ..utils import leos2ip p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 diff --git a/orchard_poseidon.py b/zcash_test_vectors/orchard/poseidon.py similarity index 98% rename from orchard_poseidon.py rename to zcash_test_vectors/orchard/poseidon.py index 4b1e591..403508a 100755 --- a/orchard_poseidon.py +++ b/zcash_test_vectors/orchard/poseidon.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from orchard_pallas import Fp +from ..orchard.pallas import Fp import numpy as np from itertools import chain -from utils import leos2ip -from tv_output import render_args, render_tv -from tv_rand import Rand +from ..utils import leos2ip +from ..output import render_args, render_tv +from ..rand import Rand # Number of full rounds R_F = 8 @@ -148,6 +148,14 @@ MDS_MATRIX = [ ] ] +# Initial capacity element +CAPACITY_ELEMENT = Fp(1 << 65) + +def hash(x, y): + assert isinstance(x, Fp) + assert isinstance(y, Fp) + return perm([x, y, CAPACITY_ELEMENT])[0] + def main(): # These are test vectors from https://github.com/daira/pasta-hadeshash/commit/f7ca15dcf8568f1a4b2c4b7188815e80e9ab8975. diff --git a/orchard_sinsemilla.py b/zcash_test_vectors/orchard/sinsemilla.py similarity index 92% rename from orchard_sinsemilla.py rename to zcash_test_vectors/orchard/sinsemilla.py index 920be76..de7ca0b 100755 --- a/orchard_sinsemilla.py +++ b/zcash_test_vectors/orchard/sinsemilla.py @@ -3,13 +3,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." import math -import orchard_iso_pallas - -from orchard_pallas import Fp, Point -from utils import cldiv, lebs2ip, i2leosp -from orchard_group_hash import group_hash -from tv_output import render_args, render_tv -from tv_rand import Rand +from .pallas import Fp, Point +from ..utils import cldiv, lebs2ip, i2leosp +from .group_hash import group_hash +from ..output import render_args, render_tv +from ..rand import Rand SINSEMILLA_K = 10 diff --git a/orchard_utils.py b/zcash_test_vectors/orchard/utils.py similarity index 76% rename from orchard_utils.py rename to zcash_test_vectors/orchard/utils.py index af8be00..6de3139 100644 --- a/orchard_utils.py +++ b/zcash_test_vectors/orchard/utils.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from orchard_pallas import Fp, Scalar -from utils import leos2ip +from .pallas import Fp, Scalar +from ..utils import leos2ip # # Utilities diff --git a/tv_output.py b/zcash_test_vectors/output.py similarity index 100% rename from tv_output.py rename to zcash_test_vectors/output.py diff --git a/tv_rand.py b/zcash_test_vectors/rand.py similarity index 100% rename from tv_rand.py rename to zcash_test_vectors/rand.py diff --git a/zcash_test_vectors/sapling/__init__.py b/zcash_test_vectors/sapling/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sapling_generators.py b/zcash_test_vectors/sapling/generators.py similarity index 95% rename from sapling_generators.py rename to zcash_test_vectors/sapling/generators.py index e4af823..caed3b4 100755 --- a/sapling_generators.py +++ b/zcash_test_vectors/sapling/generators.py @@ -3,9 +3,9 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from pyblake2 import blake2s -from sapling_jubjub import Point, JUBJUB_COFACTOR -from tv_output import render_args, render_tv -from utils import i2leosp +from .jubjub import Point, JUBJUB_COFACTOR +from ..output import render_args, render_tv +from ..utils import i2leosp # First 64 bytes of the BLAKE2s input during group hash. # This is chosen to be some random string that we couldn't have diff --git a/sapling_jubjub.py b/zcash_test_vectors/sapling/jubjub.py similarity index 99% rename from sapling_jubjub.py rename to zcash_test_vectors/sapling/jubjub.py index 7a0a40f..a575d8e 100644 --- a/sapling_jubjub.py +++ b/zcash_test_vectors/sapling/jubjub.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from utils import i2lebsp, leos2ip, i2leosp +from ..utils import i2lebsp, leos2ip, i2leosp q_j = 52435875175126190479447740508185965837690552500527637822603658699938581184513 r_j = 6554484396890773809930967563523245729705921265872317281365359162392183254199 diff --git a/sapling_key_components.py b/zcash_test_vectors/sapling/key_components.py similarity index 92% rename from sapling_key_components.py rename to zcash_test_vectors/sapling/key_components.py index e23eef4..94ae667 100755 --- a/sapling_key_components.py +++ b/zcash_test_vectors/sapling/key_components.py @@ -3,12 +3,12 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from pyblake2 import blake2b, blake2s -from sapling_generators import PROVING_KEY_BASE, SPENDING_KEY_BASE, group_hash -from sapling_jubjub import Fr -from sapling_merkle_tree import MERKLE_DEPTH -from sapling_notes import note_commit, note_nullifier -from utils import leos2bsp, leos2ip -from tv_output import render_args, render_tv +from .generators import PROVING_KEY_BASE, SPENDING_KEY_BASE, group_hash +from .jubjub import Fr +from .merkle_tree import MERKLE_DEPTH +from .notes import note_commit, note_nullifier +from ..utils import leos2bsp, leos2ip +from ..output import render_args, render_tv # # Utilities diff --git a/sapling_merkle_tree.py b/zcash_test_vectors/sapling/merkle_tree.py similarity index 91% rename from sapling_merkle_tree.py rename to zcash_test_vectors/sapling/merkle_tree.py index 7cd047b..29ac6c5 100755 --- a/sapling_merkle_tree.py +++ b/zcash_test_vectors/sapling/merkle_tree.py @@ -3,8 +3,8 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from binascii import unhexlify -from sapling_pedersen import pedersen_hash -from utils import i2lebsp, leos2bsp +from .pedersen import pedersen_hash +from ..utils import i2lebsp, leos2bsp MERKLE_DEPTH = 32 diff --git a/sapling_note_encryption.py b/zcash_test_vectors/sapling/note_encryption.py similarity index 93% rename from sapling_note_encryption.py rename to zcash_test_vectors/sapling/note_encryption.py index d6a522d..891aa4b 100755 --- a/sapling_note_encryption.py +++ b/zcash_test_vectors/sapling/note_encryption.py @@ -6,12 +6,12 @@ import os from pyblake2 import blake2b import struct -from sapling_generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE -from sapling_jubjub import Fr, JUBJUB_COFACTOR -from sapling_key_components import SpendingKey, diversify_hash -from sapling_notes import note_commit -from utils import leos2bsp, leos2ip -from tv_output import render_args, render_tv +from .generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE +from .jubjub import Fr, JUBJUB_COFACTOR +from .key_components import SpendingKey, diversify_hash +from .notes import note_commit +from ..utils import leos2bsp, leos2ip +from ..output import render_args, render_tv def kdf_sapling(shared_secret, epk): diff --git a/sapling_notes.py b/zcash_test_vectors/sapling/notes.py similarity index 91% rename from sapling_notes.py rename to zcash_test_vectors/sapling/notes.py index c4e0dc2..9f6516f 100644 --- a/sapling_notes.py +++ b/zcash_test_vectors/sapling/notes.py @@ -3,11 +3,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from pyblake2 import blake2s -from sapling_pedersen import ( +from .pedersen import ( mixing_pedersen_hash, windowed_pedersen_commitment, ) -from utils import i2lebsp +from ..utils import i2lebsp def note_commit(rcm, g_d, pk_d, v): return windowed_pedersen_commitment(rcm, [1] * 6 + i2lebsp(64, v) + g_d + pk_d) diff --git a/sapling_pedersen.py b/zcash_test_vectors/sapling/pedersen.py similarity index 93% rename from sapling_pedersen.py rename to zcash_test_vectors/sapling/pedersen.py index 649ed46..9edd8a9 100644 --- a/sapling_pedersen.py +++ b/zcash_test_vectors/sapling/pedersen.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." -from sapling_generators import ( +from .generators import ( find_group_hash, NOTE_POSITION_BASE, WINDOWED_PEDERSEN_RANDOMNESS_BASE, ) -from sapling_jubjub import Fr, Point -from utils import cldiv, i2leosp +from .jubjub import Fr, Point +from ..utils import cldiv, i2leosp # diff --git a/sapling_signatures.py b/zcash_test_vectors/sapling/redjubjub.py similarity index 93% rename from sapling_signatures.py rename to zcash_test_vectors/sapling/redjubjub.py index f2bc335..b3b140c 100755 --- a/sapling_signatures.py +++ b/zcash_test_vectors/sapling/redjubjub.py @@ -4,11 +4,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." import os from pyblake2 import blake2b -from sapling_generators import SPENDING_KEY_BASE -from sapling_jubjub import Fr, Point, r_j -from sapling_key_components import to_scalar -from utils import cldiv, leos2ip -from tv_output import render_args, render_tv +from .generators import SPENDING_KEY_BASE +from .jubjub import Fr, Point, r_j +from .key_components import to_scalar +from ..utils import cldiv, leos2ip +from ..output import render_args, render_tv def H(x): diff --git a/sapling_zip32.py b/zcash_test_vectors/sapling/zip32.py similarity index 95% rename from sapling_zip32.py rename to zcash_test_vectors/sapling/zip32.py index 6ffc9f9..d4a14e0 100755 --- a/sapling_zip32.py +++ b/zcash_test_vectors/sapling/zip32.py @@ -3,11 +3,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from pyblake2 import blake2b -from sapling_key_components import to_scalar, prf_expand, diversify_hash, DerivedAkNk, DerivedIvk -from sapling_generators import SPENDING_KEY_BASE, PROVING_KEY_BASE -from utils import i2leosp, i2lebsp, lebs2osp -from ff1 import ff1_aes256_encrypt -from tv_output import render_args, render_tv, option, Some +from .key_components import to_scalar, prf_expand, diversify_hash, DerivedAkNk, DerivedIvk +from .generators import SPENDING_KEY_BASE, PROVING_KEY_BASE +from ..utils import i2leosp, i2lebsp, lebs2osp +from ..ff1 import ff1_aes256_encrypt +from ..output import render_args, render_tv, option, Some def encode_xsk_parts(ask, nsk, ovk, dk): diff --git a/transaction.py b/zcash_test_vectors/transaction.py similarity index 98% rename from transaction.py rename to zcash_test_vectors/transaction.py index 0ca65d1..2d88d0c 100644 --- a/transaction.py +++ b/zcash_test_vectors/transaction.py @@ -1,18 +1,18 @@ import struct -from orchard_pallas import ( +from .orchard.pallas import ( Fp as PallasBase, Scalar as PallasScalar, ) -from orchard_sinsemilla import group_hash as pallas_group_hash -from sapling_generators import find_group_hash, SPENDING_KEY_BASE -from sapling_jubjub import ( +from .orchard.sinsemilla import group_hash as pallas_group_hash +from .sapling.generators import find_group_hash, SPENDING_KEY_BASE +from .sapling.jubjub import ( Fq, Point, Fr as JubjubScalar, ) -from utils import leos2ip -from zc_utils import write_compact_size +from .utils import leos2ip +from .zc_utils import write_compact_size MAX_MONEY = 21000000 * 100000000 TX_EXPIRY_HEIGHT_THRESHOLD = 500000000 diff --git a/unified_encoding.py b/zcash_test_vectors/unified_encoding.py similarity index 93% rename from unified_encoding.py rename to zcash_test_vectors/unified_encoding.py index e2cd24b..49a3ad0 100644 --- a/unified_encoding.py +++ b/zcash_test_vectors/unified_encoding.py @@ -2,9 +2,9 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from random import Random -from zc_utils import write_compact_size, parse_compact_size -from bech32m import bech32_encode, bech32_decode, convertbits, Encoding -from f4jumble import f4jumble, f4jumble_inv +from .zc_utils import write_compact_size, parse_compact_size +from .bech32m import bech32_encode, bech32_decode, convertbits, Encoding +from .f4jumble import f4jumble, f4jumble_inv P2PKH_ITEM = 0x00 P2SH_ITEM = 0x01 diff --git a/utils.py b/zcash_test_vectors/utils.py similarity index 100% rename from utils.py rename to zcash_test_vectors/utils.py diff --git a/zc_utils.py b/zcash_test_vectors/zc_utils.py similarity index 100% rename from zc_utils.py rename to zcash_test_vectors/zc_utils.py diff --git a/zip_0143.py b/zcash_test_vectors/zip_0143.py similarity index 97% rename from zip_0143.py rename to zcash_test_vectors/zip_0143.py index 5b3cd09..77e6399 100755 --- a/zip_0143.py +++ b/zcash_test_vectors/zip_0143.py @@ -4,14 +4,14 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from pyblake2 import blake2b import struct -from transaction import ( +from .transaction import ( LegacyTransaction, MAX_MONEY, OVERWINTER_TX_VERSION, Script, ) -from tv_output import render_args, render_tv, Some -from tv_rand import Rand +from .output import render_args, render_tv, Some +from .rand import Rand SIGHASH_ALL = 1 diff --git a/zip_0243.py b/zcash_test_vectors/zip_0243.py similarity index 97% rename from zip_0243.py rename to zcash_test_vectors/zip_0243.py index 7118c94..b860db8 100755 --- a/zip_0243.py +++ b/zcash_test_vectors/zip_0243.py @@ -4,16 +4,16 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from pyblake2 import blake2b import struct -from transaction import ( +from .transaction import ( LegacyTransaction, MAX_MONEY, SAPLING_TX_VERSION, Script, ) -from tv_output import render_args, render_tv, Some -from tv_rand import Rand +from .output import render_args, render_tv, Some +from .rand import Rand -from zip_0143 import ( +from .zip_0143 import ( getHashJoinSplits, getHashOutputs, getHashPrevouts, diff --git a/zip_0244.py b/zcash_test_vectors/zip_0244.py similarity index 99% rename from zip_0244.py rename to zcash_test_vectors/zip_0244.py index 70a9662..7d53e4f 100755 --- a/zip_0244.py +++ b/zcash_test_vectors/zip_0244.py @@ -4,15 +4,15 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required." from pyblake2 import blake2b import struct -from transaction import ( +from .transaction import ( MAX_MONEY, NU5_TX_VERSION, Script, TransactionV5, ) -from tv_output import render_args, render_tv, Some -from tv_rand import Rand -from zip_0143 import ( +from .output import render_args, render_tv, Some +from .rand import Rand +from .zip_0143 import ( getHashOutputs, getHashPrevouts, getHashSequence,