port BLS tests to new suite format

This commit is contained in:
protolambda 2019-04-11 19:15:23 +10:00
parent d7b7640221
commit 9a0fd0afb9
No known key found for this signature in database
GPG Key ID: EC89FDBB2B4C7623
2 changed files with 131 additions and 81 deletions

View File

@ -2,16 +2,14 @@
BLS test vectors generator BLS test vectors generator
""" """
# Standard library
import sys
from typing import Tuple from typing import Tuple
# Third-party from eth_utils import (
import yaml to_tuple, int_to_big_endian
from py_ecc import bls )
from gen_base import gen_runner, gen_suite, gen_typing
# Ethereum from py_ecc import bls
from eth_utils import int_to_big_endian, big_endian_to_int
def int_to_hex(n: int) -> str: def int_to_hex(n: int) -> str:
@ -34,9 +32,9 @@ DOMAINS = [
] ]
MESSAGES = [ MESSAGES = [
b'\x00' * 32, bytes(b'\x00' * 32),
b'\x56' * 32, bytes(b'\x56' * 32),
b'\xab' * 32, bytes(b'\xab' * 32),
] ]
PRIVKEYS = [ PRIVKEYS = [
@ -80,82 +78,79 @@ def hash_message_compressed(msg: bytes, domain: int) -> Tuple[str, str]:
return [int_to_hex(z1), int_to_hex(z2)] return [int_to_hex(z1), int_to_hex(z2)]
if __name__ == '__main__':
# Order not preserved - https://github.com/yaml/pyyaml/issues/110 @to_tuple
metadata = { def case01_message_hash_G2_uncompressed():
'title': 'BLS signature and aggregation tests', for msg in MESSAGES:
'summary': 'Test vectors for BLS signature', for domain in DOMAINS:
'test_suite': 'bls', yield {
'fork': 'phase0-0.5.0', 'input': {
'message': '0x' + msg.hex(),
'domain': int_to_hex(domain)
},
'output': hash_message(msg, domain)
} }
case01_message_hash_G2_uncompressed = [] @to_tuple
def case02_message_hash_G2_compressed():
for msg in MESSAGES: for msg in MESSAGES:
for domain in DOMAINS: for domain in DOMAINS:
case01_message_hash_G2_uncompressed.append({ yield {
'input': {'message': '0x' + msg.hex(), 'domain': int_to_hex(domain)}, 'input': {
'output': hash_message(msg, domain) 'message': '0x' + msg.hex(),
}) 'domain': int_to_hex(domain)
},
case02_message_hash_G2_compressed = []
for msg in MESSAGES:
for domain in DOMAINS:
case02_message_hash_G2_compressed.append({
'input': {'message': '0x' + msg.hex(), 'domain': int_to_hex(domain)},
'output': hash_message_compressed(msg, domain) 'output': hash_message_compressed(msg, domain)
}) }
case03_private_to_public_key = [] @to_tuple
#  Used in later cases def case03_private_to_public_key():
pubkeys = [bls.privtopub(privkey) for privkey in PRIVKEYS] pubkeys = [bls.privtopub(privkey) for privkey in PRIVKEYS]
#  Used in public key aggregation
pubkeys_serial = ['0x' + pubkey.hex() for pubkey in pubkeys] pubkeys_serial = ['0x' + pubkey.hex() for pubkey in pubkeys]
case03_private_to_public_key = [ for privkey, pubkey_serial in zip(PRIVKEYS, pubkeys_serial):
{ yield {
'input': int_to_hex(privkey), 'input': int_to_hex(privkey),
'output': pubkey_serial, 'output': pubkey_serial,
} }
for privkey, pubkey_serial in zip(PRIVKEYS, pubkeys_serial)
]
case04_sign_messages = [] @to_tuple
sigs = [] # used in verify def case04_sign_messages():
for privkey in PRIVKEYS: for privkey in PRIVKEYS:
for message in MESSAGES: for message in MESSAGES:
for domain in DOMAINS: for domain in DOMAINS:
sig = bls.sign(message, privkey, domain) sig = bls.sign(message, privkey, domain)
case04_sign_messages.append({ yield {
'input': { 'input': {
'privkey': int_to_hex(privkey), 'privkey': int_to_hex(privkey),
'message': '0x' + message.hex(), 'message': '0x' + message.hex(),
'domain': int_to_hex(domain) 'domain': int_to_hex(domain)
}, },
'output': '0x' + sig.hex() 'output': '0x' + sig.hex()
}) }
sigs.append(sig)
# TODO: case05_verify_messages: Verify messages signed in case04 # TODO: case05_verify_messages: Verify messages signed in case04
# It takes too long, empty for now # It takes too long, empty for now
case06_aggregate_sigs = []
@to_tuple
def case06_aggregate_sigs():
for domain in DOMAINS: for domain in DOMAINS:
for message in MESSAGES: for message in MESSAGES:
sigs = [] sigs = [bls.sign(message, privkey, domain) for privkey in PRIVKEYS]
for privkey in PRIVKEYS: yield {
sig = bls.sign(message, privkey, domain)
sigs.append(sig)
case06_aggregate_sigs.append({
'input': ['0x' + sig.hex() for sig in sigs], 'input': ['0x' + sig.hex() for sig in sigs],
'output': '0x' + bls.aggregate_signatures(sigs).hex(), 'output': '0x' + bls.aggregate_signatures(sigs).hex(),
}) }
case07_aggregate_pubkeys = [ @to_tuple
{ def case07_aggregate_pubkeys():
pubkeys = [bls.privtopub(privkey) for privkey in PRIVKEYS]
pubkeys_serial = ['0x' + pubkey.hex() for pubkey in pubkeys]
yield {
'input': pubkeys_serial, 'input': pubkeys_serial,
'output': '0x' + bls.aggregate_pubkeys(pubkeys).hex(), 'output': '0x' + bls.aggregate_pubkeys(pubkeys).hex(),
} }
]
# TODO # TODO
# Aggregate verify # Aggregate verify
@ -163,26 +158,80 @@ if __name__ == '__main__':
# TODO # TODO
# Proof-of-possession # Proof-of-possession
with open(sys.argv[2] + "test_bls.yml", 'w') as outfile:
# Dump at top level
yaml.dump(metadata, outfile, default_flow_style=False)
# default_flow_style will unravel "ValidatorRecord" and "committee" line,
# exploding file size
yaml.dump(
{'case01_message_hash_G2_uncompressed': case01_message_hash_G2_uncompressed},
outfile,
)
yaml.dump(
{'case02_message_hash_G2_compressed': case02_message_hash_G2_compressed},
outfile,
)
yaml.dump(
{'case03_private_to_public_key': case03_private_to_public_key},
outfile,
)
yaml.dump({'case04_sign_messages': case04_sign_messages}, outfile)
# Too time consuming to generate def bls_msg_hash_uncompressed_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
# yaml.dump({'case05_verify_messages': case05_verify_messages}, outfile) return ("g2_uncompressed", "msg_hash", gen_suite.render_suite(
yaml.dump({'case06_aggregate_sigs': case06_aggregate_sigs}, outfile) title="BLS G2 Uncompressed msg hash",
yaml.dump({'case07_aggregate_pubkeys': case07_aggregate_pubkeys}, outfile) summary="BLS G2 Uncompressed msg hash",
forks_timeline="mainnet",
forks=["phase0"],
config="mainnet",
handler="msg_hash",
test_cases=case01_message_hash_G2_uncompressed()))
def bls_msg_hash_compressed_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
return ("g2_compressed", "msg_hash", gen_suite.render_suite(
title="BLS G2 Compressed msg hash",
summary="BLS G2 Compressed msg hash",
forks_timeline="mainnet",
forks=["phase0"],
config="mainnet",
handler="msg_hash",
test_cases=case02_message_hash_G2_compressed()))
def bls_priv_to_pub_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
return ("priv_to_pub", "priv_to_pub", gen_suite.render_suite(
title="BLS private key to pubkey",
summary="BLS Convert private key to public key",
forks_timeline="mainnet",
forks=["phase0"],
config="mainnet",
handler="priv_to_pub",
test_cases=case03_private_to_public_key()))
def bls_sign_msg_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
return ("sign_msg", "sign_msg", gen_suite.render_suite(
title="BLS sign msg",
summary="BLS Sign a message",
forks_timeline="mainnet",
forks=["phase0"],
config="mainnet",
handler="sign_msg",
test_cases=case04_sign_messages()))
def bls_aggregate_sigs_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
return ("aggregate_sigs", "aggregate_sigs", gen_suite.render_suite(
title="BLS aggregate sigs",
summary="BLS Aggregate signatures",
forks_timeline="mainnet",
forks=["phase0"],
config="mainnet",
handler="aggregate_sigs",
test_cases=case06_aggregate_sigs()))
def bls_aggregate_pubkeys_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
return ("aggregate_pubkeys", "aggregate_pubkeys", gen_suite.render_suite(
title="BLS aggregate pubkeys",
summary="BLS Aggregate public keys",
forks_timeline="mainnet",
forks=["phase0"],
config="mainnet",
handler="aggregate_pubkeys",
test_cases=case07_aggregate_pubkeys()))
if __name__ == "__main__":
gen_runner.run_generator("shuffling", [
bls_msg_hash_compressed_suite,
bls_msg_hash_uncompressed_suite,
bls_priv_to_pub_suite,
bls_sign_msg_suite,
bls_aggregate_sigs_suite,
bls_aggregate_pubkeys_suite
])

View File

@ -1,2 +1,3 @@
py-ecc==1.6.0 py-ecc==1.6.0
PyYAML==4.2b1 eth-utils==1.4.1
../../test_libs/gen_helpers