port BLS tests to new suite format
This commit is contained in:
parent
d7b7640221
commit
9a0fd0afb9
|
@ -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,109 +78,160 @@ 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',
|
|
||||||
'summary': 'Test vectors for BLS signature',
|
|
||||||
'test_suite': 'bls',
|
|
||||||
'fork': 'phase0-0.5.0',
|
|
||||||
}
|
|
||||||
|
|
||||||
case01_message_hash_G2_uncompressed = []
|
|
||||||
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': {
|
||||||
|
'message': '0x' + msg.hex(),
|
||||||
|
'domain': int_to_hex(domain)
|
||||||
|
},
|
||||||
'output': hash_message(msg, domain)
|
'output': hash_message(msg, domain)
|
||||||
})
|
}
|
||||||
|
|
||||||
case02_message_hash_G2_compressed = []
|
@to_tuple
|
||||||
|
def case02_message_hash_G2_compressed():
|
||||||
for msg in MESSAGES:
|
for msg in MESSAGES:
|
||||||
for domain in DOMAINS:
|
for domain in DOMAINS:
|
||||||
case02_message_hash_G2_compressed.append({
|
yield {
|
||||||
'input': {'message': '0x' + msg.hex(), 'domain': int_to_hex(domain)},
|
'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():
|
||||||
'input': pubkeys_serial,
|
pubkeys = [bls.privtopub(privkey) for privkey in PRIVKEYS]
|
||||||
'output': '0x' + bls.aggregate_pubkeys(pubkeys).hex(),
|
pubkeys_serial = ['0x' + pubkey.hex() for pubkey in pubkeys]
|
||||||
}
|
yield {
|
||||||
]
|
'input': pubkeys_serial,
|
||||||
|
'output': '0x' + bls.aggregate_pubkeys(pubkeys).hex(),
|
||||||
|
}
|
||||||
|
|
||||||
# TODO
|
|
||||||
# Aggregate verify
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
# Proof-of-possession
|
# Aggregate verify
|
||||||
|
|
||||||
with open(sys.argv[2] + "test_bls.yml", 'w') as outfile:
|
# TODO
|
||||||
# Dump at top level
|
# Proof-of-possession
|
||||||
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
|
|
||||||
# yaml.dump({'case05_verify_messages': case05_verify_messages}, outfile)
|
def bls_msg_hash_uncompressed_suite(configs_path: str) -> gen_typing.TestSuiteOutput:
|
||||||
yaml.dump({'case06_aggregate_sigs': case06_aggregate_sigs}, outfile)
|
return ("g2_uncompressed", "msg_hash", gen_suite.render_suite(
|
||||||
yaml.dump({'case07_aggregate_pubkeys': case07_aggregate_pubkeys}, outfile)
|
title="BLS G2 Uncompressed msg hash",
|
||||||
|
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
|
||||||
|
])
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue