Merge pull request #4 from str4d/json-output
Implement Zcash test vector output format
This commit is contained in:
commit
0e854b1ddd
|
@ -1,9 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
from binascii import hexlify
|
||||
from pyblake2 import blake2s
|
||||
|
||||
from sapling_jubjub import Point, JUBJUB_COFACTOR
|
||||
from sapling_utils import chunk
|
||||
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
|
||||
|
@ -51,44 +50,26 @@ VALUE_COMMITMENT_RANDOMNESS_BASE = find_group_hash(b'Zcash_cv', b'r')
|
|||
|
||||
|
||||
def main():
|
||||
print('''
|
||||
struct SaplingGenerators {
|
||||
skb: [u8; 32],
|
||||
pkb: [u8; 32],
|
||||
npb: [u8; 32],
|
||||
wprb: [u8; 32],
|
||||
vcvb: [u8; 32],
|
||||
vcrb: [u8; 32],
|
||||
};
|
||||
|
||||
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/sapling_generators.py
|
||||
let sapling_generators = SaplingGenerators {
|
||||
skb: [
|
||||
%s
|
||||
],
|
||||
pkb: [
|
||||
%s
|
||||
],
|
||||
npb: [
|
||||
%s
|
||||
],
|
||||
wprb: [
|
||||
%s
|
||||
],
|
||||
vcvb: [
|
||||
%s
|
||||
],
|
||||
vcrb: [
|
||||
%s
|
||||
],
|
||||
};''' % (
|
||||
chunk(hexlify(bytes(SPENDING_KEY_BASE))),
|
||||
chunk(hexlify(bytes(PROVING_KEY_BASE))),
|
||||
chunk(hexlify(bytes(NOTE_POSITION_BASE))),
|
||||
chunk(hexlify(bytes(WINDOWED_PEDERSEN_RANDOMNESS_BASE))),
|
||||
chunk(hexlify(bytes(VALUE_COMMITMENT_VALUE_BASE))),
|
||||
chunk(hexlify(bytes(VALUE_COMMITMENT_RANDOMNESS_BASE))),
|
||||
))
|
||||
render_tv(
|
||||
render_args(),
|
||||
'sapling_generators',
|
||||
(
|
||||
('skb', '[u8; 32]'),
|
||||
('pkb', '[u8; 32]'),
|
||||
('npb', '[u8; 32]'),
|
||||
('wprb', '[u8; 32]'),
|
||||
('vcvb', '[u8; 32]'),
|
||||
('vcrb', '[u8; 32]'),
|
||||
),
|
||||
{
|
||||
'skb': bytes(SPENDING_KEY_BASE),
|
||||
'pkb': bytes(PROVING_KEY_BASE),
|
||||
'npb': bytes(NOTE_POSITION_BASE),
|
||||
'wprb': bytes(WINDOWED_PEDERSEN_RANDOMNESS_BASE),
|
||||
'vcvb': bytes(VALUE_COMMITMENT_VALUE_BASE),
|
||||
'vcrb': bytes(VALUE_COMMITMENT_RANDOMNESS_BASE),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
from binascii import hexlify
|
||||
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 sapling_utils import chunk, leos2bsp, leos2ip
|
||||
from sapling_utils import leos2bsp, leos2ip
|
||||
from tv_output import render_args, render_tv
|
||||
|
||||
#
|
||||
# Utilities
|
||||
|
@ -91,26 +91,9 @@ class SpendingKey(object):
|
|||
|
||||
|
||||
def main():
|
||||
print('''
|
||||
struct TestVector {
|
||||
sk: [u8; 32],
|
||||
ask: [u8; 32],
|
||||
nsk: [u8; 32],
|
||||
ovk: [u8; 32],
|
||||
ak: [u8; 32],
|
||||
nk: [u8; 32],
|
||||
ivk: [u8; 32],
|
||||
default_d: [u8; 11],
|
||||
default_pk_d: [u8; 32],
|
||||
note_v: u64,
|
||||
note_r: [u8; 32],
|
||||
note_cm: [u8; 32],
|
||||
note_pos: u64,
|
||||
note_nf: [u8; 32],
|
||||
};
|
||||
args = render_args()
|
||||
|
||||
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/sapling_key_components.py
|
||||
let test_vectors = vec![''')
|
||||
test_vectors = []
|
||||
for i in range(0, 10):
|
||||
sk = SpendingKey(bytes([i] * 32))
|
||||
note_v = (2548793025584392057432895043257984320*i) % 2**64
|
||||
|
@ -122,62 +105,44 @@ def main():
|
|||
note_v)
|
||||
note_pos = (980705743285409327583205473820957432*i) % 2**MERKLE_DEPTH
|
||||
note_nf = note_nullifier(sk.nk(), note_cm, Fr(note_pos))
|
||||
print(''' TestVector {
|
||||
sk: [
|
||||
%s
|
||||
],
|
||||
ask: [
|
||||
%s
|
||||
],
|
||||
nsk: [
|
||||
%s
|
||||
],
|
||||
ovk: [
|
||||
%s
|
||||
],
|
||||
ak: [
|
||||
%s
|
||||
],
|
||||
nk: [
|
||||
%s
|
||||
],
|
||||
ivk: [
|
||||
%s
|
||||
],
|
||||
default_d: [
|
||||
%s
|
||||
],
|
||||
default_pk_d: [
|
||||
%s
|
||||
],
|
||||
note_v: %s,
|
||||
note_r: [
|
||||
%s
|
||||
],
|
||||
note_cm: [
|
||||
%s
|
||||
],
|
||||
note_pos: %s,
|
||||
note_nf: [
|
||||
%s
|
||||
],
|
||||
},''' % (
|
||||
chunk(hexlify(sk.data)),
|
||||
chunk(hexlify(bytes(sk.ask()))),
|
||||
chunk(hexlify(bytes(sk.nsk()))),
|
||||
chunk(hexlify(sk.ovk())),
|
||||
chunk(hexlify(bytes(sk.ak()))),
|
||||
chunk(hexlify(bytes(sk.nk()))),
|
||||
chunk(hexlify(bytes(sk.ivk()))),
|
||||
chunk(hexlify(sk.default_d())),
|
||||
chunk(hexlify(bytes(sk.default_pkd()))),
|
||||
note_v,
|
||||
chunk(hexlify(bytes(note_r))),
|
||||
chunk(hexlify(bytes(note_cm.u))),
|
||||
note_pos,
|
||||
chunk(hexlify(note_nf)),
|
||||
))
|
||||
print(' ];')
|
||||
test_vectors.append({
|
||||
'sk': sk.data,
|
||||
'ask': bytes(sk.ask()),
|
||||
'nsk': bytes(sk.nsk()),
|
||||
'ovk': sk.ovk(),
|
||||
'ak': bytes(sk.ak()),
|
||||
'nk': bytes(sk.nk()),
|
||||
'ivk': bytes(sk.ivk()),
|
||||
'default_d': sk.default_d(),
|
||||
'default_pk_d': bytes(sk.default_pkd()),
|
||||
'note_v': note_v,
|
||||
'note_r': bytes(note_r),
|
||||
'note_cm': bytes(note_cm.u),
|
||||
'note_pos': note_pos,
|
||||
'note_nf': note_nf,
|
||||
})
|
||||
|
||||
render_tv(
|
||||
args,
|
||||
'sapling_key_components',
|
||||
(
|
||||
('sk', '[u8; 32]'),
|
||||
('ask', '[u8; 32]'),
|
||||
('nsk', '[u8; 32]'),
|
||||
('ovk', '[u8; 32]'),
|
||||
('ak', '[u8; 32]'),
|
||||
('nk', '[u8; 32]'),
|
||||
('ivk', '[u8; 32]'),
|
||||
('default_d', '[u8; 11]'),
|
||||
('default_pk_d', '[u8; 32]'),
|
||||
('note_v', 'u64'),
|
||||
('note_r', '[u8; 32]'),
|
||||
('note_cm', '[u8; 32]'),
|
||||
('note_pos', 'u64'),
|
||||
('note_nf', '[u8; 32]'),
|
||||
),
|
||||
test_vectors,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
from binascii import hexlify
|
||||
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 sapling_utils import cldiv, chunk, leos2ip
|
||||
from sapling_utils import cldiv, leos2ip
|
||||
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):
|
||||
|
@ -74,20 +76,7 @@ def main():
|
|||
return bytes(ret)
|
||||
rj = RedJubjub(SPENDING_KEY_BASE, randbytes)
|
||||
|
||||
print('''
|
||||
struct TestVector {
|
||||
sk: [u8; 32],
|
||||
vk: [u8; 32],
|
||||
alpha: [u8; 32],
|
||||
rsk: [u8; 32],
|
||||
rvk: [u8; 32],
|
||||
m: [u8; 32],
|
||||
sig: [u8; 64],
|
||||
rsig: [u8; 64],
|
||||
};
|
||||
|
||||
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/sapling_signatures.py
|
||||
let test_vectors = vec![''')
|
||||
test_vectors = []
|
||||
for i in range(0, 10):
|
||||
sk = rj.gen_private()
|
||||
vk = rj.derive_public(sk)
|
||||
|
@ -103,42 +92,32 @@ def main():
|
|||
assert not rj.verify(vk, M, rsig)
|
||||
assert not rj.verify(rvk, M, sig)
|
||||
|
||||
print(''' TestVector {
|
||||
sk: [
|
||||
%s
|
||||
],
|
||||
vk: [
|
||||
%s
|
||||
],
|
||||
alpha: [
|
||||
%s
|
||||
],
|
||||
rsk: [
|
||||
%s
|
||||
],
|
||||
rvk: [
|
||||
%s
|
||||
],
|
||||
m: [
|
||||
%s
|
||||
],
|
||||
sig: [
|
||||
%s
|
||||
],
|
||||
rsig: [
|
||||
%s
|
||||
],
|
||||
},''' % (
|
||||
chunk(hexlify(bytes(sk))),
|
||||
chunk(hexlify(bytes(vk))),
|
||||
chunk(hexlify(bytes(alpha))),
|
||||
chunk(hexlify(bytes(rsk))),
|
||||
chunk(hexlify(bytes(rvk))),
|
||||
chunk(hexlify(M)),
|
||||
chunk(hexlify(sig)),
|
||||
chunk(hexlify(rsig)),
|
||||
))
|
||||
print(' ];')
|
||||
test_vectors.append({
|
||||
'sk': bytes(sk),
|
||||
'vk': bytes(vk),
|
||||
'alpha': bytes(alpha),
|
||||
'rsk': bytes(rsk),
|
||||
'rvk': bytes(rvk),
|
||||
'm': M,
|
||||
'sig': sig,
|
||||
'rsig': rsig,
|
||||
})
|
||||
|
||||
render_tv(
|
||||
args,
|
||||
'sapling_signatures',
|
||||
(
|
||||
('sk', '[u8; 32]'),
|
||||
('vk', '[u8; 32]'),
|
||||
('alpha', '[u8; 32]'),
|
||||
('rsk', '[u8; 32]'),
|
||||
('rvk', '[u8; 32]'),
|
||||
('m', '[u8; 32]'),
|
||||
('sig', '[u8; 64]'),
|
||||
('rsig', '[u8; 64]'),
|
||||
),
|
||||
test_vectors,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
def cldiv(n, divisor):
|
||||
return (n + (divisor - 1)) // divisor
|
||||
|
||||
def chunk(h):
|
||||
h = str(h, 'utf-8')
|
||||
return '0x' + ', 0x'.join([h[i:i+2] for i in range(0, len(h), 2)])
|
||||
|
||||
def i2lebsp(l, x):
|
||||
return [int(c) for c in format(x, '0%sb' % l)[::-1]]
|
||||
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
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)
|
||||
# If bitcoin_flavoured == True, 32-byte values are reversed
|
||||
#
|
||||
|
||||
def tv_value_json(value, bitcoin_flavoured):
|
||||
if type(value) == bytes:
|
||||
if bitcoin_flavoured and len(value) == 32:
|
||||
value = value[::-1]
|
||||
value = hexlify(value).decode()
|
||||
return value
|
||||
|
||||
def tv_json(filename, parts, vectors, bitcoin_flavoured):
|
||||
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]], bitcoin_flavoured) for p in parts]) for v in vectors
|
||||
]))
|
||||
print(']')
|
||||
|
||||
|
||||
#
|
||||
# Rust
|
||||
#
|
||||
|
||||
def tv_bytes_rust(name, value, pad):
|
||||
print('''%s%s: [
|
||||
%s%s
|
||||
%s],''' % (
|
||||
pad,
|
||||
name,
|
||||
pad,
|
||||
chunk(hexlify(value)),
|
||||
pad,
|
||||
))
|
||||
|
||||
def tv_int_rust(name, value, pad):
|
||||
print('%s%s: %d,' % (pad, name, value))
|
||||
|
||||
def tv_part_rust(name, value, indent=3):
|
||||
pad = ' ' * indent
|
||||
if type(value) == bytes:
|
||||
tv_bytes_rust(name, value, pad)
|
||||
elif type(value) == int:
|
||||
tv_int_rust(name, value, pad)
|
||||
else:
|
||||
raise ValueError('Invalid type(%s): %s' % (name, type(value)))
|
||||
|
||||
def tv_rust(filename, parts, vectors):
|
||||
print(' struct TestVector {')
|
||||
[print(' %s: %s,' % p) for p in parts]
|
||||
print(''' };
|
||||
|
||||
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/%s.py''' % (
|
||||
filename,
|
||||
))
|
||||
if type(vectors) == type({}):
|
||||
print(' let test_vector = TestVector {')
|
||||
[tv_part_rust(p[0], vectors[p[0]]) for p in parts]
|
||||
print(' };')
|
||||
elif type(vectors) == type([]):
|
||||
print(' let test_vectors = vec![')
|
||||
for vector in vectors:
|
||||
print(' TestVector {')
|
||||
[tv_part_rust(p[0], vector[p[0]], 4) for p in parts]
|
||||
print(' },')
|
||||
print(' ];')
|
||||
else:
|
||||
raise ValueError('Invalid type(vectors)')
|
||||
|
||||
|
||||
#
|
||||
# Rendering functions
|
||||
#
|
||||
|
||||
def render_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-t', '--target', choices=['zcash', '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 == 'zcash':
|
||||
tv_json(filename, parts, vectors, True)
|
Loading…
Reference in New Issue