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`.
This commit is contained in:
parent
69dd363272
commit
2093b309f4
19
README.md
19
README.md
|
@ -2,10 +2,21 @@
|
||||||
|
|
||||||
Code to generate test vectors for various parts of Zcash.
|
Code to generate test vectors for various parts of Zcash.
|
||||||
|
|
||||||
Requirements:
|
The generated test vectors are checked into the repository:
|
||||||
- `pyblake2`
|
- `test-vectors/json/`: JSON format.
|
||||||
- `chacha20poly1305` (for `sapling_note_encryption.py`).
|
- `test-vectors/rust/`: Rust format, suitable for copying into a Rust library or
|
||||||
- `numpy` (for `orchard_poseidon.py` and dependents).
|
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
|
## License
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
|
|
||||||
from tv_output import render_args, render_tv
|
from zcash_test_vectors.output import render_args, render_tv
|
||||||
from f4jumble import f4jumble, f4jumble_inv, MAX_l_M
|
from zcash_test_vectors.f4jumble import f4jumble, f4jumble_inv, MAX_l_M
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from orchard_merkle_tree import empty_roots
|
from zcash_test_vectors.orchard.merkle_tree import empty_roots
|
||||||
from orchard_pallas import Fp
|
from zcash_test_vectors.orchard.pallas import Fp
|
||||||
from tv_output import render_args, render_tv
|
from zcash_test_vectors.output import render_args, render_tv
|
||||||
from utils import i2lebsp
|
from zcash_test_vectors.utils import i2lebsp
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from orchard_group_hash import map_to_curve_simple_swu
|
from zcash_test_vectors.orchard.group_hash import map_to_curve_simple_swu
|
||||||
from orchard_iso_pallas import Point as IsoPoint
|
from zcash_test_vectors.orchard.iso_pallas import Point as IsoPoint
|
||||||
from orchard_pallas import Fp
|
from zcash_test_vectors.orchard.pallas import Fp
|
||||||
from utils import leos2ip
|
from zcash_test_vectors.utils import leos2ip
|
||||||
from tv_output import render_args, render_tv
|
from zcash_test_vectors.output import render_args, render_tv
|
||||||
from tv_rand import Rand
|
from zcash_test_vectors.rand import Rand
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from orchard_pallas import Fp
|
from zcash_test_vectors.orchard.pallas import Fp
|
||||||
from orchard_poseidon import perm
|
from zcash_test_vectors.orchard import poseidon
|
||||||
from utils import leos2ip
|
from zcash_test_vectors.utils import leos2ip
|
||||||
from tv_output import render_args, render_tv
|
from zcash_test_vectors.output import render_args, render_tv
|
||||||
from tv_rand import Rand
|
from zcash_test_vectors.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]
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
test_vectors = [[Fp.ZERO, Fp(1)]]
|
test_vectors = [[Fp.ZERO, Fp(1)]]
|
||||||
|
@ -43,7 +35,7 @@ def main():
|
||||||
),
|
),
|
||||||
[{
|
[{
|
||||||
'input': list(map(bytes, input)),
|
'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],
|
} for input in test_vectors],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -27,3 +27,26 @@ numpy = "1.21.0"
|
||||||
chacha20poly1305 = "0.0.3"
|
chacha20poly1305 = "0.0.3"
|
||||||
cryptography = "36.0.0"
|
cryptography = "36.0.0"
|
||||||
pyblake2 = "1.1.2"
|
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"
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
tv_scripts=(
|
tv_scripts=(
|
||||||
f4jumble_long
|
|
||||||
f4jumble
|
f4jumble
|
||||||
orchard_empty_roots
|
|
||||||
orchard_generators
|
orchard_generators
|
||||||
orchard_group_hash
|
orchard_group_hash
|
||||||
orchard_key_components
|
orchard_key_components
|
||||||
orchard_map_to_curve
|
|
||||||
orchard_merkle_tree
|
orchard_merkle_tree
|
||||||
orchard_note_encryption
|
orchard_note_encryption
|
||||||
orchard_poseidon_hash
|
|
||||||
orchard_poseidon
|
orchard_poseidon
|
||||||
orchard_sinsemilla
|
orchard_sinsemilla
|
||||||
sapling_generators
|
sapling_generators
|
||||||
|
@ -18,13 +14,25 @@ tv_scripts=(
|
||||||
sapling_note_encryption
|
sapling_note_encryption
|
||||||
sapling_signatures
|
sapling_signatures
|
||||||
sapling_zip32
|
sapling_zip32
|
||||||
unified_address
|
|
||||||
unified_full_viewing_keys
|
|
||||||
zip_0143
|
zip_0143
|
||||||
zip_0243
|
zip_0243
|
||||||
zip_0244)
|
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[@]}"
|
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
|
do
|
||||||
echo "# $generator"
|
echo "# $generator"
|
||||||
poetry run python ./$generator.py -t $1 >test-vectors/$1/$generator.$2
|
poetry run python ./$generator.py -t $1 >test-vectors/$1/$generator.$2
|
||||||
|
|
|
@ -5,16 +5,16 @@ import math
|
||||||
from random import Random
|
from random import Random
|
||||||
import struct
|
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 zcash_test_vectors.output import render_args, render_tv, Some
|
||||||
from tv_rand import Rand, randbytes
|
from zcash_test_vectors.rand import Rand, randbytes
|
||||||
from zc_utils import write_compact_size, parse_compact_size
|
from zcash_test_vectors.zc_utils import write_compact_size, parse_compact_size
|
||||||
from f4jumble import f4jumble, f4jumble_inv
|
from zcash_test_vectors.f4jumble import f4jumble, f4jumble_inv
|
||||||
import sapling_key_components
|
from zcash_test_vectors.sapling import key_components as sapling_key_components
|
||||||
import orchard_key_components
|
from zcash_test_vectors.orchard import key_components as orchard_key_components
|
||||||
from unified_encoding import encode_unified, decode_unified
|
from zcash_test_vectors.unified_encoding import encode_unified, decode_unified
|
||||||
from unified_encoding import P2PKH_ITEM, P2SH_ITEM, SAPLING_ITEM, ORCHARD_ITEM
|
from zcash_test_vectors.unified_encoding import P2PKH_ITEM, P2SH_ITEM, SAPLING_ITEM, ORCHARD_ITEM
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = render_args()
|
args = render_args()
|
||||||
|
|
|
@ -8,15 +8,14 @@ import struct
|
||||||
from cryptography.hazmat.primitives.asymmetric import ec
|
from cryptography.hazmat.primitives.asymmetric import ec
|
||||||
from cryptography.hazmat.primitives.serialization import PublicFormat, Encoding
|
from cryptography.hazmat.primitives.serialization import PublicFormat, Encoding
|
||||||
|
|
||||||
from tv_output import render_args, render_tv, Some
|
from zcash_test_vectors.output import render_args, render_tv, Some
|
||||||
from tv_rand import Rand, randbytes
|
from zcash_test_vectors.rand import Rand, randbytes
|
||||||
from zc_utils import write_compact_size, parse_compact_size
|
from zcash_test_vectors.zc_utils import write_compact_size, parse_compact_size
|
||||||
from f4jumble import f4jumble, f4jumble_inv
|
from zcash_test_vectors.f4jumble import f4jumble, f4jumble_inv
|
||||||
import orchard_key_components
|
from zcash_test_vectors.orchard import key_components as orchard_key_components
|
||||||
import sapling_key_components
|
from zcash_test_vectors.sapling import zip32 as sapling_zip32
|
||||||
import sapling_zip32
|
from zcash_test_vectors.unified_encoding import encode_unified, decode_unified
|
||||||
from unified_encoding import encode_unified, decode_unified
|
from zcash_test_vectors.unified_encoding import P2PKH_ITEM, P2SH_ITEM, SAPLING_ITEM, ORCHARD_ITEM
|
||||||
from unified_encoding import P2PKH_ITEM, P2SH_ITEM, SAPLING_ITEM, ORCHARD_ITEM
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = render_args()
|
args = render_args()
|
||||||
|
|
|
@ -6,9 +6,9 @@ import struct
|
||||||
|
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
|
|
||||||
from tv_output import render_args, render_tv
|
from .output import render_args, render_tv
|
||||||
from tv_rand import Rand
|
from .rand import Rand
|
||||||
from utils import i2leosp
|
from .utils import i2leosp
|
||||||
|
|
||||||
|
|
||||||
# Maximum output length of BLAKE2b
|
# Maximum output length of BLAKE2b
|
|
@ -7,7 +7,7 @@ from binascii import unhexlify, hexlify
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
from cryptography.hazmat.backends import default_backend
|
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
|
# Morris Dworkin
|
||||||
# NIST Special Publication 800-38G
|
# NIST Special Publication 800-38G
|
|
@ -1,10 +1,10 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from orchard_group_hash import group_hash
|
from .group_hash import group_hash
|
||||||
from orchard_pallas import Fp, Scalar
|
from .pallas import Fp, Scalar
|
||||||
from orchard_sinsemilla import sinsemilla_hash_to_point
|
from .sinsemilla import sinsemilla_hash_to_point
|
||||||
from utils import i2lebsp
|
from ..utils import i2lebsp
|
||||||
|
|
||||||
# Commitment schemes used in Orchard https://zips.z.cash/protocol/nu5.pdf#concretecommit
|
# 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
|
# Test consistency of ValueCommit^{Orchard} with precomputed generators
|
||||||
def test_value_commit():
|
def test_value_commit():
|
||||||
from random import Random
|
from random import Random
|
||||||
from tv_rand import Rand
|
from ..rand import Rand
|
||||||
from orchard_generators import VALUE_COMMITMENT_RANDOMNESS_BASE, VALUE_COMMITMENT_VALUE_BASE
|
from .generators import VALUE_COMMITMENT_RANDOMNESS_BASE, VALUE_COMMITMENT_VALUE_BASE
|
||||||
|
|
||||||
rng = Random(0xabad533d)
|
rng = Random(0xabad533d)
|
||||||
def randbytes(l):
|
def randbytes(l):
|
|
@ -3,9 +3,9 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from pyblake2 import blake2s
|
from pyblake2 import blake2s
|
||||||
|
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
from orchard_group_hash import group_hash
|
from .group_hash import group_hash
|
||||||
from orchard_sinsemilla import sinsemilla_hash_to_point
|
from .sinsemilla import sinsemilla_hash_to_point
|
||||||
|
|
||||||
# https://zips.z.cash/protocol/nu5.pdf#concretespendauthsig
|
# https://zips.z.cash/protocol/nu5.pdf#concretespendauthsig
|
||||||
SPENDING_KEY_BASE = group_hash(b'z.cash:Orchard', b'G')
|
SPENDING_KEY_BASE = group_hash(b'z.cash:Orchard', b'G')
|
|
@ -3,14 +3,14 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
import orchard_iso_pallas
|
from . import iso_pallas
|
||||||
|
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
from orchard_pallas import Fp, p, q, PALLAS_B, Point
|
from .pallas import Fp, p, q, PALLAS_B, Point
|
||||||
from orchard_iso_pallas import PALLAS_ISO_B, PALLAS_ISO_A
|
from .iso_pallas import PALLAS_ISO_B, PALLAS_ISO_A
|
||||||
from utils import i2beosp, cldiv, beos2ip, i2leosp, lebs2ip
|
from ..utils import i2beosp, cldiv, beos2ip, i2leosp, lebs2ip
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
from tv_rand import Rand
|
from ..rand import Rand
|
||||||
|
|
||||||
# https://stackoverflow.com/questions/2612720/how-to-do-bitwise-exclusive-or-of-two-strings-in-python
|
# https://stackoverflow.com/questions/2612720/how-to-do-bitwise-exclusive-or-of-two-strings-in-python
|
||||||
def sxor(s1,s2):
|
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)
|
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):
|
def group_hash(d, m):
|
||||||
dst = d + b"-" + b"pallas" + b"_XMD:BLAKE2b_SSWU_RO_"
|
dst = d + b"-" + b"pallas" + b"_XMD:BLAKE2b_SSWU_RO_"
|
|
@ -2,8 +2,8 @@
|
||||||
# -*- coding: utf8 -*-
|
# -*- coding: utf8 -*-
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
import orchard_pallas
|
from . import pallas
|
||||||
from orchard_pallas import Fp, p, q, Scalar
|
from .pallas import Fp, p, q, Scalar
|
||||||
|
|
||||||
#
|
#
|
||||||
# Point arithmetic
|
# Point arithmetic
|
||||||
|
@ -60,7 +60,7 @@ class Point(object):
|
||||||
]
|
]
|
||||||
|
|
||||||
if self == Point.identity():
|
if self == Point.identity():
|
||||||
return orchard_pallas.identity()
|
return pallas.identity()
|
||||||
else:
|
else:
|
||||||
numerator_a = c[1] * self.x * self.x * self.x + c[2] * self.x * self.x + c[3] * self.x + c[4]
|
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]
|
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
|
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]
|
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):
|
def __init__(self, x, y, is_identity=False):
|
||||||
self.x = x
|
self.x = x
|
|
@ -1,16 +1,16 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from ff1 import ff1_aes256_encrypt
|
from ..ff1 import ff1_aes256_encrypt
|
||||||
from sapling_key_components import prf_expand
|
from ..sapling.key_components import prf_expand
|
||||||
|
|
||||||
from orchard_generators import NULLIFIER_K_BASE, SPENDING_KEY_BASE, group_hash
|
from .generators import NULLIFIER_K_BASE, SPENDING_KEY_BASE, group_hash
|
||||||
from orchard_pallas import Fp, Scalar, Point
|
from .pallas import Fp, Scalar, Point
|
||||||
from orchard_poseidon_hash import poseidon_hash
|
from . import poseidon
|
||||||
from orchard_commitments import commit_ivk
|
from .commitments import commit_ivk
|
||||||
from utils import i2leosp, i2lebsp, lebs2osp
|
from ..utils import i2leosp, i2lebsp, lebs2osp
|
||||||
from orchard_utils import to_base, to_scalar
|
from .utils import to_base, to_scalar
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
|
|
||||||
#
|
#
|
||||||
# PRFs and hashes
|
# PRFs and hashes
|
||||||
|
@ -23,7 +23,7 @@ def diversify_hash(d):
|
||||||
return P
|
return P
|
||||||
|
|
||||||
def prf_nf_orchard(nk, rho):
|
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):
|
def derive_nullifier(nk, rho: Fp, psi: Fp, cm):
|
||||||
scalar = prf_nf_orchard(nk, rho) + psi # addition mod p
|
scalar = prf_nf_orchard(nk, rho) + psi # addition mod p
|
||||||
|
@ -77,9 +77,9 @@ class FullViewingKey(object):
|
||||||
def main():
|
def main():
|
||||||
args = render_args()
|
args = render_args()
|
||||||
|
|
||||||
from orchard_note import OrchardNote
|
from .note import OrchardNote
|
||||||
from random import Random
|
from random import Random
|
||||||
from tv_rand import Rand
|
from zcash_test_vectors.rand import Rand
|
||||||
|
|
||||||
rng = Random(0xabad533d)
|
rng = Random(0xabad533d)
|
||||||
def randbytes(l):
|
def randbytes(l):
|
|
@ -3,11 +3,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from binascii import unhexlify
|
from binascii import unhexlify
|
||||||
|
|
||||||
from orchard_pallas import Fp
|
from .pallas import Fp
|
||||||
from orchard_sinsemilla import sinsemilla_hash
|
from .sinsemilla import sinsemilla_hash
|
||||||
|
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
from utils import i2lebsp, leos2bsp
|
from ..utils import i2lebsp, leos2bsp
|
||||||
|
|
||||||
# https://zips.z.cash/protocol/nu5.pdf#constants
|
# https://zips.z.cash/protocol/nu5.pdf#constants
|
||||||
MERKLE_DEPTH = 32
|
MERKLE_DEPTH = 32
|
||||||
|
@ -45,7 +45,7 @@ def main():
|
||||||
args = render_args()
|
args = render_args()
|
||||||
|
|
||||||
from random import Random
|
from random import Random
|
||||||
from tv_rand import Rand
|
from ..rand import Rand
|
||||||
|
|
||||||
rng = Random(0xabad533d)
|
rng = Random(0xabad533d)
|
||||||
def randbytes(l):
|
def randbytes(l):
|
|
@ -1,11 +1,11 @@
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from orchard_commitments import note_commit
|
from .commitments import note_commit
|
||||||
from orchard_key_components import diversify_hash, prf_expand, derive_nullifier, FullViewingKey, SpendingKey
|
from .key_components import diversify_hash, prf_expand, derive_nullifier, FullViewingKey, SpendingKey
|
||||||
from orchard_pallas import Point, Scalar
|
from .pallas import Point, Scalar
|
||||||
from orchard_utils import to_base, to_scalar
|
from .utils import to_base, to_scalar
|
||||||
|
|
||||||
from utils import leos2bsp
|
from ..utils import leos2bsp
|
||||||
|
|
||||||
class OrchardNote(object):
|
class OrchardNote(object):
|
||||||
def __init__(self, d, pk_d, v, rho, rseed):
|
def __init__(self, d, pk_d, v, rho, rseed):
|
|
@ -6,17 +6,17 @@ import struct
|
||||||
from chacha20poly1305 import ChaCha20Poly1305
|
from chacha20poly1305 import ChaCha20Poly1305
|
||||||
import os
|
import os
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
from transaction import MAX_MONEY
|
from ..transaction import MAX_MONEY
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
from tv_rand import Rand
|
from ..rand import Rand
|
||||||
|
|
||||||
from orchard_generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE
|
from .generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE
|
||||||
from orchard_pallas import Point, Scalar
|
from .pallas import Point, Scalar
|
||||||
from orchard_commitments import rcv_trapdoor, value_commit
|
from .commitments import rcv_trapdoor, value_commit
|
||||||
from orchard_key_components import diversify_hash, prf_expand, FullViewingKey, SpendingKey
|
from .key_components import diversify_hash, prf_expand, FullViewingKey, SpendingKey
|
||||||
from orchard_note import OrchardNote, OrchardNotePlaintext
|
from .note import OrchardNote, OrchardNotePlaintext
|
||||||
from orchard_utils import to_scalar
|
from .utils import to_scalar
|
||||||
from utils import leos2bsp
|
from ..utils import leos2bsp
|
||||||
|
|
||||||
# https://zips.z.cash/protocol/nu5.pdf#concreteorchardkdf
|
# https://zips.z.cash/protocol/nu5.pdf#concreteorchardkdf
|
||||||
def kdf_orchard(shared_secret, ephemeral_key):
|
def kdf_orchard(shared_secret, ephemeral_key):
|
|
@ -2,8 +2,8 @@
|
||||||
# -*- coding: utf8 -*-
|
# -*- coding: utf8 -*-
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from sapling_jubjub import FieldElement
|
from ..sapling.jubjub import FieldElement
|
||||||
from utils import leos2ip
|
from ..utils import leos2ip
|
||||||
|
|
||||||
p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
|
p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
|
||||||
q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
|
q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
|
|
@ -1,12 +1,12 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
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
|
import numpy as np
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from utils import leos2ip
|
from ..utils import leos2ip
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
from tv_rand import Rand
|
from ..rand import Rand
|
||||||
|
|
||||||
# Number of full rounds
|
# Number of full rounds
|
||||||
R_F = 8
|
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():
|
def main():
|
||||||
|
|
||||||
# These are test vectors from https://github.com/daira/pasta-hadeshash/commit/f7ca15dcf8568f1a4b2c4b7188815e80e9ab8975.
|
# These are test vectors from https://github.com/daira/pasta-hadeshash/commit/f7ca15dcf8568f1a4b2c4b7188815e80e9ab8975.
|
|
@ -3,13 +3,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
import orchard_iso_pallas
|
from .pallas import Fp, Point
|
||||||
|
from ..utils import cldiv, lebs2ip, i2leosp
|
||||||
from orchard_pallas import Fp, Point
|
from .group_hash import group_hash
|
||||||
from utils import cldiv, lebs2ip, i2leosp
|
from ..output import render_args, render_tv
|
||||||
from orchard_group_hash import group_hash
|
from ..rand import Rand
|
||||||
from tv_output import render_args, render_tv
|
|
||||||
from tv_rand import Rand
|
|
||||||
|
|
||||||
SINSEMILLA_K = 10
|
SINSEMILLA_K = 10
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from orchard_pallas import Fp, Scalar
|
from .pallas import Fp, Scalar
|
||||||
from utils import leos2ip
|
from ..utils import leos2ip
|
||||||
|
|
||||||
#
|
#
|
||||||
# Utilities
|
# Utilities
|
|
@ -3,9 +3,9 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from pyblake2 import blake2s
|
from pyblake2 import blake2s
|
||||||
|
|
||||||
from sapling_jubjub import Point, JUBJUB_COFACTOR
|
from .jubjub import Point, JUBJUB_COFACTOR
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
from utils import i2leosp
|
from ..utils import i2leosp
|
||||||
|
|
||||||
# First 64 bytes of the BLAKE2s input during group hash.
|
# First 64 bytes of the BLAKE2s input during group hash.
|
||||||
# This is chosen to be some random string that we couldn't have
|
# This is chosen to be some random string that we couldn't have
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
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
|
q_j = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
||||||
r_j = 6554484396890773809930967563523245729705921265872317281365359162392183254199
|
r_j = 6554484396890773809930967563523245729705921265872317281365359162392183254199
|
|
@ -3,12 +3,12 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from pyblake2 import blake2b, blake2s
|
from pyblake2 import blake2b, blake2s
|
||||||
|
|
||||||
from sapling_generators import PROVING_KEY_BASE, SPENDING_KEY_BASE, group_hash
|
from .generators import PROVING_KEY_BASE, SPENDING_KEY_BASE, group_hash
|
||||||
from sapling_jubjub import Fr
|
from .jubjub import Fr
|
||||||
from sapling_merkle_tree import MERKLE_DEPTH
|
from .merkle_tree import MERKLE_DEPTH
|
||||||
from sapling_notes import note_commit, note_nullifier
|
from .notes import note_commit, note_nullifier
|
||||||
from utils import leos2bsp, leos2ip
|
from ..utils import leos2bsp, leos2ip
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
|
|
||||||
#
|
#
|
||||||
# Utilities
|
# Utilities
|
|
@ -3,8 +3,8 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from binascii import unhexlify
|
from binascii import unhexlify
|
||||||
|
|
||||||
from sapling_pedersen import pedersen_hash
|
from .pedersen import pedersen_hash
|
||||||
from utils import i2lebsp, leos2bsp
|
from ..utils import i2lebsp, leos2bsp
|
||||||
|
|
||||||
MERKLE_DEPTH = 32
|
MERKLE_DEPTH = 32
|
||||||
|
|
|
@ -6,12 +6,12 @@ import os
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from sapling_generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE
|
from .generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE
|
||||||
from sapling_jubjub import Fr, JUBJUB_COFACTOR
|
from .jubjub import Fr, JUBJUB_COFACTOR
|
||||||
from sapling_key_components import SpendingKey, diversify_hash
|
from .key_components import SpendingKey, diversify_hash
|
||||||
from sapling_notes import note_commit
|
from .notes import note_commit
|
||||||
from utils import leos2bsp, leos2ip
|
from ..utils import leos2bsp, leos2ip
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
|
|
||||||
|
|
||||||
def kdf_sapling(shared_secret, epk):
|
def kdf_sapling(shared_secret, epk):
|
|
@ -3,11 +3,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from pyblake2 import blake2s
|
from pyblake2 import blake2s
|
||||||
|
|
||||||
from sapling_pedersen import (
|
from .pedersen import (
|
||||||
mixing_pedersen_hash,
|
mixing_pedersen_hash,
|
||||||
windowed_pedersen_commitment,
|
windowed_pedersen_commitment,
|
||||||
)
|
)
|
||||||
from utils import i2lebsp
|
from ..utils import i2lebsp
|
||||||
|
|
||||||
def note_commit(rcm, g_d, pk_d, v):
|
def note_commit(rcm, g_d, pk_d, v):
|
||||||
return windowed_pedersen_commitment(rcm, [1] * 6 + i2lebsp(64, v) + g_d + pk_d)
|
return windowed_pedersen_commitment(rcm, [1] * 6 + i2lebsp(64, v) + g_d + pk_d)
|
|
@ -1,13 +1,13 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from sapling_generators import (
|
from .generators import (
|
||||||
find_group_hash,
|
find_group_hash,
|
||||||
NOTE_POSITION_BASE,
|
NOTE_POSITION_BASE,
|
||||||
WINDOWED_PEDERSEN_RANDOMNESS_BASE,
|
WINDOWED_PEDERSEN_RANDOMNESS_BASE,
|
||||||
)
|
)
|
||||||
from sapling_jubjub import Fr, Point
|
from .jubjub import Fr, Point
|
||||||
from utils import cldiv, i2leosp
|
from ..utils import cldiv, i2leosp
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
|
@ -4,11 +4,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
import os
|
import os
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
|
|
||||||
from sapling_generators import SPENDING_KEY_BASE
|
from .generators import SPENDING_KEY_BASE
|
||||||
from sapling_jubjub import Fr, Point, r_j
|
from .jubjub import Fr, Point, r_j
|
||||||
from sapling_key_components import to_scalar
|
from .key_components import to_scalar
|
||||||
from utils import cldiv, leos2ip
|
from ..utils import cldiv, leos2ip
|
||||||
from tv_output import render_args, render_tv
|
from ..output import render_args, render_tv
|
||||||
|
|
||||||
|
|
||||||
def H(x):
|
def H(x):
|
|
@ -3,11 +3,11 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
|
|
||||||
from sapling_key_components import to_scalar, prf_expand, diversify_hash, DerivedAkNk, DerivedIvk
|
from .key_components import to_scalar, prf_expand, diversify_hash, DerivedAkNk, DerivedIvk
|
||||||
from sapling_generators import SPENDING_KEY_BASE, PROVING_KEY_BASE
|
from .generators import SPENDING_KEY_BASE, PROVING_KEY_BASE
|
||||||
from utils import i2leosp, i2lebsp, lebs2osp
|
from ..utils import i2leosp, i2lebsp, lebs2osp
|
||||||
from ff1 import ff1_aes256_encrypt
|
from ..ff1 import ff1_aes256_encrypt
|
||||||
from tv_output import render_args, render_tv, option, Some
|
from ..output import render_args, render_tv, option, Some
|
||||||
|
|
||||||
|
|
||||||
def encode_xsk_parts(ask, nsk, ovk, dk):
|
def encode_xsk_parts(ask, nsk, ovk, dk):
|
|
@ -1,18 +1,18 @@
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from orchard_pallas import (
|
from .orchard.pallas import (
|
||||||
Fp as PallasBase,
|
Fp as PallasBase,
|
||||||
Scalar as PallasScalar,
|
Scalar as PallasScalar,
|
||||||
)
|
)
|
||||||
from orchard_sinsemilla import group_hash as pallas_group_hash
|
from .orchard.sinsemilla import group_hash as pallas_group_hash
|
||||||
from sapling_generators import find_group_hash, SPENDING_KEY_BASE
|
from .sapling.generators import find_group_hash, SPENDING_KEY_BASE
|
||||||
from sapling_jubjub import (
|
from .sapling.jubjub import (
|
||||||
Fq,
|
Fq,
|
||||||
Point,
|
Point,
|
||||||
Fr as JubjubScalar,
|
Fr as JubjubScalar,
|
||||||
)
|
)
|
||||||
from utils import leos2ip
|
from .utils import leos2ip
|
||||||
from zc_utils import write_compact_size
|
from .zc_utils import write_compact_size
|
||||||
|
|
||||||
MAX_MONEY = 21000000 * 100000000
|
MAX_MONEY = 21000000 * 100000000
|
||||||
TX_EXPIRY_HEIGHT_THRESHOLD = 500000000
|
TX_EXPIRY_HEIGHT_THRESHOLD = 500000000
|
|
@ -2,9 +2,9 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
|
|
||||||
from random import Random
|
from random import Random
|
||||||
|
|
||||||
from zc_utils import write_compact_size, parse_compact_size
|
from .zc_utils import write_compact_size, parse_compact_size
|
||||||
from bech32m import bech32_encode, bech32_decode, convertbits, Encoding
|
from .bech32m import bech32_encode, bech32_decode, convertbits, Encoding
|
||||||
from f4jumble import f4jumble, f4jumble_inv
|
from .f4jumble import f4jumble, f4jumble_inv
|
||||||
|
|
||||||
P2PKH_ITEM = 0x00
|
P2PKH_ITEM = 0x00
|
||||||
P2SH_ITEM = 0x01
|
P2SH_ITEM = 0x01
|
|
@ -4,14 +4,14 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from transaction import (
|
from .transaction import (
|
||||||
LegacyTransaction,
|
LegacyTransaction,
|
||||||
MAX_MONEY,
|
MAX_MONEY,
|
||||||
OVERWINTER_TX_VERSION,
|
OVERWINTER_TX_VERSION,
|
||||||
Script,
|
Script,
|
||||||
)
|
)
|
||||||
from tv_output import render_args, render_tv, Some
|
from .output import render_args, render_tv, Some
|
||||||
from tv_rand import Rand
|
from .rand import Rand
|
||||||
|
|
||||||
|
|
||||||
SIGHASH_ALL = 1
|
SIGHASH_ALL = 1
|
|
@ -4,16 +4,16 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from transaction import (
|
from .transaction import (
|
||||||
LegacyTransaction,
|
LegacyTransaction,
|
||||||
MAX_MONEY,
|
MAX_MONEY,
|
||||||
SAPLING_TX_VERSION,
|
SAPLING_TX_VERSION,
|
||||||
Script,
|
Script,
|
||||||
)
|
)
|
||||||
from tv_output import render_args, render_tv, Some
|
from .output import render_args, render_tv, Some
|
||||||
from tv_rand import Rand
|
from .rand import Rand
|
||||||
|
|
||||||
from zip_0143 import (
|
from .zip_0143 import (
|
||||||
getHashJoinSplits,
|
getHashJoinSplits,
|
||||||
getHashOutputs,
|
getHashOutputs,
|
||||||
getHashPrevouts,
|
getHashPrevouts,
|
|
@ -4,15 +4,15 @@ import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
||||||
from pyblake2 import blake2b
|
from pyblake2 import blake2b
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from transaction import (
|
from .transaction import (
|
||||||
MAX_MONEY,
|
MAX_MONEY,
|
||||||
NU5_TX_VERSION,
|
NU5_TX_VERSION,
|
||||||
Script,
|
Script,
|
||||||
TransactionV5,
|
TransactionV5,
|
||||||
)
|
)
|
||||||
from tv_output import render_args, render_tv, Some
|
from .output import render_args, render_tv, Some
|
||||||
from tv_rand import Rand
|
from .rand import Rand
|
||||||
from zip_0143 import (
|
from .zip_0143 import (
|
||||||
getHashOutputs,
|
getHashOutputs,
|
||||||
getHashPrevouts,
|
getHashPrevouts,
|
||||||
getHashSequence,
|
getHashSequence,
|
Loading…
Reference in New Issue