diff --git a/sapling_generators.py b/sapling_generators.py index 3007c6d..dd416bc 100644 --- a/sapling_generators.py +++ b/sapling_generators.py @@ -2,7 +2,7 @@ from pyblake2 import blake2s from sapling_jubjub import Point, JUBJUB_COFACTOR -from tv_output import tv_rust +from tv_output import render_args, render_tv # First 64 bytes of the BLAKE2s input during group hash. # This is chosen to be some random string that we couldn't have @@ -50,7 +50,8 @@ VALUE_COMMITMENT_RANDOMNESS_BASE = find_group_hash(b'Zcash_cv', b'r') def main(): - tv_rust( + render_tv( + render_args(), 'sapling_generators', ( ('skb', '[u8; 32]'), diff --git a/sapling_key_components.py b/sapling_key_components.py index 40ada1f..3264029 100644 --- a/sapling_key_components.py +++ b/sapling_key_components.py @@ -6,7 +6,7 @@ from sapling_jubjub import Fr from sapling_merkle_tree import MERKLE_DEPTH from sapling_notes import note_commit, note_nullifier from sapling_utils import leos2bsp, leos2ip -from tv_output import tv_rust +from tv_output import render_args, render_tv # # Utilities @@ -91,6 +91,8 @@ class SpendingKey(object): def main(): + args = render_args() + test_vectors = [] for i in range(0, 10): sk = SpendingKey(bytes([i] * 32)) @@ -120,7 +122,8 @@ def main(): 'note_nf': note_nf, }) - tv_rust( + render_tv( + args, 'sapling_key_components', ( ('sk', '[u8; 32]'), diff --git a/sapling_signatures.py b/sapling_signatures.py index 3088417..ead3bfd 100644 --- a/sapling_signatures.py +++ b/sapling_signatures.py @@ -6,7 +6,7 @@ from sapling_generators import SPENDING_KEY_BASE from sapling_jubjub import Fr, Point, r_j from sapling_key_components import to_scalar from sapling_utils import cldiv, leos2ip -from tv_output import tv_rust +from tv_output import render_args, render_tv def H(x): @@ -65,6 +65,8 @@ class RedJubjub(object): def main(): + args = render_args() + from random import Random rng = Random(0xabad533d) def randbytes(l): @@ -101,7 +103,8 @@ def main(): 'rsig': rsig, }) - tv_rust( + render_tv( + args, 'sapling_signatures', ( ('sk', '[u8; 32]'), diff --git a/tv_output.py b/tv_output.py index 53c09b7..791934a 100644 --- a/tv_output.py +++ b/tv_output.py @@ -1,10 +1,42 @@ +import argparse from binascii import hexlify +import json def chunk(h): h = str(h, 'utf-8') return '0x' + ', 0x'.join([h[i:i+2] for i in range(0, len(h), 2)]) + +# +# JSON (with string comments) +# + +def tv_value_json(value): + if type(value) == bytes: + value = hexlify(value).decode() + return value + +def tv_json(filename, parts, vectors): + if type(vectors) == type({}): + vectors = [vectors] + + print('''[ + ["From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/%s.py"], + ["%s"],''' % ( + filename, + ', '.join([p[0] for p in parts]) + )) + print(' ' + ',\n '.join([ + json.dumps([tv_value_json(v[p[0]]) for p in parts]) for v in vectors + ])) + print(']') + + +# +# Rust +# + def tv_bytes_rust(name, value, pad): print('''%s%s: [ %s%s @@ -49,3 +81,19 @@ def tv_rust(filename, parts, vectors): print(' ];') else: raise ValueError('Invalid type(vectors)') + + +# +# Rendering functions +# + +def render_args(): + parser = argparse.ArgumentParser() + parser.add_argument('-t', '--target', choices=['json', 'rust'], default='rust') + return parser.parse_args() + +def render_tv(args, filename, parts, vectors): + if args.target == 'rust': + tv_rust(filename, parts, vectors) + elif args.target == 'json': + tv_json(filename, parts, vectors)