From d8d068640011541ef99fe29cc6438c1c986168ac Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 4 Aug 2021 01:55:18 +0800 Subject: [PATCH 1/6] Add tests for the Altair BLS helpers --- tests/formats/bls/README.md | 2 + tests/formats/bls/eth2_aggregate_pubkeys.md | 19 +++ .../formats/bls/eth2_fast_aggregate_verify.md | 17 +++ tests/formats/bls/fast_aggregate_verify.md | 2 +- tests/generators/bls/main.py | 144 +++++++++++++++++- 5 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 tests/formats/bls/eth2_aggregate_pubkeys.md create mode 100644 tests/formats/bls/eth2_fast_aggregate_verify.md diff --git a/tests/formats/bls/README.md b/tests/formats/bls/README.md index 65154ba1c..65018631a 100644 --- a/tests/formats/bls/README.md +++ b/tests/formats/bls/README.md @@ -7,6 +7,8 @@ The BLS test suite runner has the following handlers: - [`aggregate_verify`](./aggregate_verify.md) - [`aggregate`](./aggregate.md) +- [`eth2_aggregate_pubkeys`](./eth2_aggregate_pubkeys.md) +- [`eth2_fast_aggregate_verify`](./eth2_fast_aggregate_verify.md) - [`fast_aggregate_verify`](./fast_aggregate_verify.md) - [`sign`](./sign.md) - [`verify`](./verify.md) diff --git a/tests/formats/bls/eth2_aggregate_pubkeys.md b/tests/formats/bls/eth2_aggregate_pubkeys.md new file mode 100644 index 000000000..dd35b3166 --- /dev/null +++ b/tests/formats/bls/eth2_aggregate_pubkeys.md @@ -0,0 +1,19 @@ +# Test format: Ethereum-customized BLS pubkeys aggregation + +A BLS pubkeys aggregation combines a series of pubkeys into a single pubkey. + +## Test case format + +The test data is declared in a `data.yaml` file: + +```yaml +input: List[BLS Pubkey] -- list of input BLS pubkeys +output: BLS Pubkey -- expected output, single BLS pubkeys or empty. +``` + +- `BLS Pubkey` here is encoded as a string: hexadecimal encoding of 48 bytes (96 nibbles), prefixed with `0x`. +- No output value if the input is invalid. + +## Condition + +The `eth2_aggregate_pubkeys` handler should aggregate the signatures in the `input`, and the result should match the expected `output`. diff --git a/tests/formats/bls/eth2_fast_aggregate_verify.md b/tests/formats/bls/eth2_fast_aggregate_verify.md new file mode 100644 index 000000000..ddc1b5208 --- /dev/null +++ b/tests/formats/bls/eth2_fast_aggregate_verify.md @@ -0,0 +1,17 @@ +# Test format: Ethereum-customized BLS fast aggregate verify + +Verify the signature against the given pubkeys and one message. + +## Test case format + +The test data is declared in a `data.yaml` file: + +```yaml +input: + pubkeys: List[bytes48] -- the pubkey + message: bytes32 -- the message + signature: bytes96 -- the signature to verify against pubkeys and message +output: bool -- VALID or INVALID +``` + +All byte(s) fields are encoded as strings, hexadecimal encoding, prefixed with `0x`. diff --git a/tests/formats/bls/fast_aggregate_verify.md b/tests/formats/bls/fast_aggregate_verify.md index 7e3899a15..3366cbb79 100644 --- a/tests/formats/bls/fast_aggregate_verify.md +++ b/tests/formats/bls/fast_aggregate_verify.md @@ -1,4 +1,4 @@ -# Test format: BLS sign message +# Test format: BLS fast aggregate verify Verify the signature against the given pubkeys and one message. diff --git a/tests/generators/bls/main.py b/tests/generators/bls/main.py index 3ebaa1354..877324a2e 100644 --- a/tests/generators/bls/main.py +++ b/tests/generators/bls/main.py @@ -12,8 +12,10 @@ from eth_utils import ( import milagro_bls_binding as milagro_bls from eth2spec.utils import bls -from eth2spec.test.helpers.constants import PHASE0 +from eth2spec.test.helpers.constants import PHASE0, ALTAIR +from eth2spec.test.helpers.typing import SpecForkName from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing +from eth2spec.altair import spec def to_bytes(i): @@ -51,6 +53,7 @@ PRIVKEYS = [ ] PUBKEYS = [bls.SkToPk(privkey) for privkey in PRIVKEYS] +ZERO_PUBKEY = b'\x00' * 48 Z1_PUBKEY = b'\xc0' + b'\x00' * 47 NO_SIGNATURE = b'\x00' * 96 Z2_SIGNATURE = b'\xc0' + b'\x00' * 95 @@ -355,7 +358,130 @@ def case05_aggregate_verify(): } +def case06_eth2_aggregate_pubkeys(): + aggregate_pubkey = spec.eth2_aggregate_pubkeys(PUBKEYS) + assert aggregate_pubkey == milagro_bls._AggregatePKs(PUBKEYS) + yield f'eth2_aggregate_pubkeys_some_pubkeys', { + 'input': [encode_hex(pubkey) for pubkey in PUBKEYS], + 'output': encode_hex(aggregate_pubkey), + } + + # Invalid pubkeys -- len(pubkeys) == 0 + expect_exception(spec.eth2_aggregate_pubkeys, []) + expect_exception(milagro_bls._AggregatePKs, []) + yield f'eth2_aggregate_pubkeys_', { + 'input': [], + 'output': None, + } + + # Invalid pubkeys -- [ZERO_PUBKEY] + expect_exception(spec.eth2_aggregate_pubkeys, [ZERO_PUBKEY]) + expect_exception(milagro_bls._AggregatePKs, [ZERO_PUBKEY]) + yield f'eth2_aggregate_pubkeys_all_zero_pubkey', { + 'input': [encode_hex(ZERO_PUBKEY)], + 'output': None, + } + + # TODO: TBD + # Valid to aggregate G1 point at infinity + # aggregate_pubkey = spec.eth2_aggregate_pubkeys([Z1_PUBKEY]) + # assert aggregate_pubkey == milagro_bls._AggregatePKs([Z1_PUBKEY]) == Z1_PUBKEY + # yield f'eth2_aggregate_pubkeys_infinity_pubkey', { + # 'input': [encode_hex(Z1_PUBKEY)], + # 'output': encode_hex(aggregate_pubkey), + # } + + +def case07_eth2_fast_aggregate_verify(): + """ + Similar to `case04_fast_aggregate_verify` except for the empty case + """ + for i, message in enumerate(MESSAGES): + privkeys = PRIVKEYS[:i + 1] + sigs = [bls.Sign(privkey, message) for privkey in privkeys] + aggregate_signature = bls.Aggregate(sigs) + pubkeys = [bls.SkToPk(privkey) for privkey in privkeys] + pubkeys_serial = [encode_hex(pubkey) for pubkey in pubkeys] + + # Valid signature + identifier = f'{pubkeys_serial}_{encode_hex(message)}' + assert spec.eth2_fast_aggregate_verify(pubkeys, message, aggregate_signature) + yield f'eth2_fast_aggregate_verify_valid_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { + 'input': { + 'pubkeys': pubkeys_serial, + 'message': encode_hex(message), + 'signature': encode_hex(aggregate_signature), + }, + 'output': True, + } + + # Invalid signature -- extra pubkey + pubkeys_extra = pubkeys + [bls.SkToPk(PRIVKEYS[-1])] + pubkeys_extra_serial = [encode_hex(pubkey) for pubkey in pubkeys_extra] + identifier = f'{pubkeys_extra_serial}_{encode_hex(message)}' + assert not spec.eth2_fast_aggregate_verify(pubkeys_extra, message, aggregate_signature) + yield f'eth_fast_aggregate_verify_extra_pubkey_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { + 'input': { + 'pubkeys': pubkeys_extra_serial, + 'message': encode_hex(message), + 'signature': encode_hex(aggregate_signature), + }, + 'output': False, + } + + # Invalid signature -- tampered with signature + tampered_signature = aggregate_signature[:-4] + b'\xff\xff\xff\xff' + identifier = f'{pubkeys_serial}_{encode_hex(message)}' + assert not spec.eth2_fast_aggregate_verify(pubkeys, message, tampered_signature) + yield f'eth2_fast_aggregate_verify_tampered_signature_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { + 'input': { + 'pubkeys': pubkeys_serial, + 'message': encode_hex(message), + 'signature': encode_hex(tampered_signature), + }, + 'output': False, + } + + # NOTE: Unlike `FastAggregateVerify`, len(pubkeys) == 0 and signature == Z1_SIGNATURE is VALID + assert spec.eth2_fast_aggregate_verify([], message, Z2_SIGNATURE) + yield f'eth2_fast_aggregate_verify_na_pubkeys_and_infinity_signature', { + 'input': { + 'pubkeys': [], + 'message': encode_hex(message), + 'signature': encode_hex(Z2_SIGNATURE), + }, + 'output': True, + } + + # Invalid pubkeys and signature -- len(pubkeys) == 0 and signature == 0x00... + assert not spec.eth2_fast_aggregate_verify([], message, NO_SIGNATURE) + yield f'eth2_fast_aggregate_verify_na_pubkeys_and_na_signature', { + 'input': { + 'pubkeys': [], + 'message': encode_hex(message), + 'signature': encode_hex(NO_SIGNATURE), + }, + 'output': False, + } + + # Invalid pubkeys and signature -- pubkeys contains point at infinity + pubkeys = PUBKEYS.copy() + pubkeys_with_infinity = pubkeys + [Z1_PUBKEY] + signatures = [bls.Sign(privkey, SAMPLE_MESSAGE) for privkey in PRIVKEYS] + aggregate_signature = bls.Aggregate(signatures) + assert not spec.eth2_fast_aggregate_verify(pubkeys_with_infinity, SAMPLE_MESSAGE, aggregate_signature) + yield f'eth2_fast_aggregate_verify_infinity_pubkey', { + 'input': { + 'pubkeys': [encode_hex(pubkey) for pubkey in pubkeys_with_infinity], + 'message': encode_hex(SAMPLE_MESSAGE), + 'signature': encode_hex(aggregate_signature), + }, + 'output': False, + } + + def create_provider(handler_name: str, + fork_name: SpecForkName, test_case_fn: Callable[[], Iterable[Tuple[str, Dict[str, Any]]]]) -> gen_typing.TestProvider: def prepare_fn() -> None: @@ -368,7 +494,7 @@ def create_provider(handler_name: str, print(data) (case_name, case_content) = data yield gen_typing.TestCase( - fork_name=PHASE0, + fork_name=fork_name, preset_name='general', runner_name='bls', handler_name=handler_name, @@ -383,9 +509,13 @@ def create_provider(handler_name: str, if __name__ == "__main__": bls.use_py_ecc() # Py-ecc is chosen instead of Milagro, since the code is better understood to be correct. gen_runner.run_generator("bls", [ - create_provider('sign', case01_sign), - create_provider('verify', case02_verify), - create_provider('aggregate', case03_aggregate), - create_provider('fast_aggregate_verify', case04_fast_aggregate_verify), - create_provider('aggregate_verify', case05_aggregate_verify), + # PHASE0 + create_provider('sign', PHASE0, case01_sign), + create_provider('verify', PHASE0, case02_verify), + create_provider('aggregate', PHASE0, case03_aggregate), + create_provider('fast_aggregate_verify', PHASE0, case04_fast_aggregate_verify), + create_provider('aggregate_verify', PHASE0, case05_aggregate_verify), + # ALTAIR + create_provider('eth2_aggregate_pubkeys', ALTAIR, case06_eth2_aggregate_pubkeys), + create_provider('eth2_fast_aggregate_verify', ALTAIR, case07_eth2_fast_aggregate_verify), ]) From 43a1617ffa94a8483f9cda7abec12dce88a2bef3 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 4 Aug 2021 21:12:19 +0800 Subject: [PATCH 2/6] Ensure that the given PKs are valid PKs + fix typos --- specs/altair/bls.md | 4 +++ specs/phase0/beacon-chain.md | 1 + tests/core/pyspec/eth2spec/utils/bls.py | 7 ++++ tests/generators/bls/main.py | 48 ++++++++++++++----------- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/specs/altair/bls.md b/specs/altair/bls.md index 529236056..e31da02ff 100644 --- a/specs/altair/bls.md +++ b/specs/altair/bls.md @@ -46,6 +46,10 @@ def eth2_aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey: Refer to the BLS signature draft standard for more information. """ assert len(pubkeys) > 0 + for pubkey in pubkeys: + # Ensure that the given inputs are valid pubkeys + assert bls.KeyValidate(pubkey) + result = copy(pubkeys[0]) for pubkey in pubkeys[1:]: result += pubkey diff --git a/specs/phase0/beacon-chain.md b/specs/phase0/beacon-chain.md index 0169e2725..5ab9b75fd 100644 --- a/specs/phase0/beacon-chain.md +++ b/specs/phase0/beacon-chain.md @@ -647,6 +647,7 @@ The [IETF BLS signature draft standard v4](https://tools.ietf.org/html/draft-irt - `def Aggregate(signatures: Sequence[BLSSignature]) -> BLSSignature` - `def FastAggregateVerify(pubkeys: Sequence[BLSPubkey], message: Bytes, signature: BLSSignature) -> bool` - `def AggregateVerify(pubkeys: Sequence[BLSPubkey], messages: Sequence[Bytes], signature: BLSSignature) -> bool` +- `def KeyValidate(pubkey: BLSPubkey) -> bool` The above functions are accessed through the `bls` module, e.g. `bls.Verify`. diff --git a/tests/core/pyspec/eth2spec/utils/bls.py b/tests/core/pyspec/eth2spec/utils/bls.py index dc4daca49..5bda0232f 100644 --- a/tests/core/pyspec/eth2spec/utils/bls.py +++ b/tests/core/pyspec/eth2spec/utils/bls.py @@ -95,6 +95,13 @@ def signature_to_G2(signature): @only_with_bls(alt_return=STUB_PUBKEY) def AggregatePKs(pubkeys): + if bls == py_ecc_bls: + for pubkey in pubkeys: + assert bls.KeyValidate(pubkey) + elif bls == milagro_bls: + # milagro_bls._AggregatePKs checks KeyValidate internally + pass + return bls._AggregatePKs(list(pubkeys)) diff --git a/tests/generators/bls/main.py b/tests/generators/bls/main.py index 877324a2e..467560e70 100644 --- a/tests/generators/bls/main.py +++ b/tests/generators/bls/main.py @@ -369,7 +369,7 @@ def case06_eth2_aggregate_pubkeys(): # Invalid pubkeys -- len(pubkeys) == 0 expect_exception(spec.eth2_aggregate_pubkeys, []) expect_exception(milagro_bls._AggregatePKs, []) - yield f'eth2_aggregate_pubkeys_', { + yield f'eth2_aggregate_pubkeys_empty_list', { 'input': [], 'output': None, } @@ -377,19 +377,27 @@ def case06_eth2_aggregate_pubkeys(): # Invalid pubkeys -- [ZERO_PUBKEY] expect_exception(spec.eth2_aggregate_pubkeys, [ZERO_PUBKEY]) expect_exception(milagro_bls._AggregatePKs, [ZERO_PUBKEY]) - yield f'eth2_aggregate_pubkeys_all_zero_pubkey', { + yield f'eth2_aggregate_pubkeys_na_pubkey', { 'input': [encode_hex(ZERO_PUBKEY)], 'output': None, } - # TODO: TBD - # Valid to aggregate G1 point at infinity - # aggregate_pubkey = spec.eth2_aggregate_pubkeys([Z1_PUBKEY]) - # assert aggregate_pubkey == milagro_bls._AggregatePKs([Z1_PUBKEY]) == Z1_PUBKEY - # yield f'eth2_aggregate_pubkeys_infinity_pubkey', { - # 'input': [encode_hex(Z1_PUBKEY)], - # 'output': encode_hex(aggregate_pubkey), - # } + # Invalid pubkeys -- G1 point at infinity + expect_exception(spec.eth2_aggregate_pubkeys, [Z1_PUBKEY]) + expect_exception(milagro_bls._AggregatePKs, [Z1_PUBKEY]) + yield f'eth2_aggregate_pubkeys_infinity_pubkey', { + 'input': [encode_hex(Z1_PUBKEY)], + 'output': None, + } + + # Invalid pubkeys -- b'\x40\x00\x00\x00....\x00' pubkey + x40_pubkey = b'\x40' + b'\00' * 47 + expect_exception(spec.eth2_aggregate_pubkeys, [x40_pubkey]) + expect_exception(milagro_bls._AggregatePKs, [x40_pubkey]) + yield f'eth2_aggregate_pubkeys_x40_pubkey', { + 'input': [encode_hex(x40_pubkey)], + 'output': None, + } def case07_eth2_fast_aggregate_verify(): @@ -420,7 +428,7 @@ def case07_eth2_fast_aggregate_verify(): pubkeys_extra_serial = [encode_hex(pubkey) for pubkey in pubkeys_extra] identifier = f'{pubkeys_extra_serial}_{encode_hex(message)}' assert not spec.eth2_fast_aggregate_verify(pubkeys_extra, message, aggregate_signature) - yield f'eth_fast_aggregate_verify_extra_pubkey_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { + yield f'eth2_fast_aggregate_verify_extra_pubkey_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { 'input': { 'pubkeys': pubkeys_extra_serial, 'message': encode_hex(message), @@ -480,8 +488,8 @@ def case07_eth2_fast_aggregate_verify(): } -def create_provider(handler_name: str, - fork_name: SpecForkName, +def create_provider(fork_name: SpecForkName, + handler_name: str, test_case_fn: Callable[[], Iterable[Tuple[str, Dict[str, Any]]]]) -> gen_typing.TestProvider: def prepare_fn() -> None: @@ -510,12 +518,12 @@ if __name__ == "__main__": bls.use_py_ecc() # Py-ecc is chosen instead of Milagro, since the code is better understood to be correct. gen_runner.run_generator("bls", [ # PHASE0 - create_provider('sign', PHASE0, case01_sign), - create_provider('verify', PHASE0, case02_verify), - create_provider('aggregate', PHASE0, case03_aggregate), - create_provider('fast_aggregate_verify', PHASE0, case04_fast_aggregate_verify), - create_provider('aggregate_verify', PHASE0, case05_aggregate_verify), + create_provider(PHASE0, 'sign', case01_sign), + create_provider(PHASE0, 'verify', case02_verify), + create_provider(PHASE0, 'aggregate', case03_aggregate), + create_provider(PHASE0, 'fast_aggregate_verify', case04_fast_aggregate_verify), + create_provider(PHASE0, 'aggregate_verify', case05_aggregate_verify), # ALTAIR - create_provider('eth2_aggregate_pubkeys', ALTAIR, case06_eth2_aggregate_pubkeys), - create_provider('eth2_fast_aggregate_verify', ALTAIR, case07_eth2_fast_aggregate_verify), + create_provider(ALTAIR, 'eth2_aggregate_pubkeys', case06_eth2_aggregate_pubkeys), + create_provider(ALTAIR, 'eth2_fast_aggregate_verify', case07_eth2_fast_aggregate_verify), ]) From a8383be878dc69540903b5a9eee8a555b79880e9 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 5 Aug 2021 11:12:36 +0800 Subject: [PATCH 3/6] Apply suggestions from code review Co-authored-by: Alex Stokes --- tests/formats/bls/eth2_aggregate_pubkeys.md | 4 ++-- tests/generators/bls/main.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/formats/bls/eth2_aggregate_pubkeys.md b/tests/formats/bls/eth2_aggregate_pubkeys.md index dd35b3166..b07d9bd06 100644 --- a/tests/formats/bls/eth2_aggregate_pubkeys.md +++ b/tests/formats/bls/eth2_aggregate_pubkeys.md @@ -1,6 +1,6 @@ -# Test format: Ethereum-customized BLS pubkeys aggregation +# Test format: Ethereum-customized BLS pubkey aggregation -A BLS pubkeys aggregation combines a series of pubkeys into a single pubkey. +A BLS pubkey aggregation combines a series of pubkeys into a single pubkey. ## Test case format diff --git a/tests/generators/bls/main.py b/tests/generators/bls/main.py index 467560e70..42754a581 100644 --- a/tests/generators/bls/main.py +++ b/tests/generators/bls/main.py @@ -450,7 +450,7 @@ def case07_eth2_fast_aggregate_verify(): 'output': False, } - # NOTE: Unlike `FastAggregateVerify`, len(pubkeys) == 0 and signature == Z1_SIGNATURE is VALID + # NOTE: Unlike `FastAggregateVerify`, len(pubkeys) == 0 and signature == Z2_SIGNATURE is VALID assert spec.eth2_fast_aggregate_verify([], message, Z2_SIGNATURE) yield f'eth2_fast_aggregate_verify_na_pubkeys_and_infinity_signature', { 'input': { From 3b86bd340f493dcfdbc8d3b9c9d93f630e4736ac Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 5 Aug 2021 11:20:49 +0800 Subject: [PATCH 4/6] Rename eth2_* to eth_* --- tests/formats/bls/README.md | 4 +- ...te_pubkeys.md => eth_aggregate_pubkeys.md} | 2 +- ...verify.md => eth_fast_aggregate_verify.md} | 0 tests/generators/bls/main.py | 52 +++++++++---------- 4 files changed, 29 insertions(+), 29 deletions(-) rename tests/formats/bls/{eth2_aggregate_pubkeys.md => eth_aggregate_pubkeys.md} (78%) rename tests/formats/bls/{eth2_fast_aggregate_verify.md => eth_fast_aggregate_verify.md} (100%) diff --git a/tests/formats/bls/README.md b/tests/formats/bls/README.md index 65018631a..77a9654a8 100644 --- a/tests/formats/bls/README.md +++ b/tests/formats/bls/README.md @@ -7,8 +7,8 @@ The BLS test suite runner has the following handlers: - [`aggregate_verify`](./aggregate_verify.md) - [`aggregate`](./aggregate.md) -- [`eth2_aggregate_pubkeys`](./eth2_aggregate_pubkeys.md) -- [`eth2_fast_aggregate_verify`](./eth2_fast_aggregate_verify.md) +- [`eth_aggregate_pubkeys`](./eth_aggregate_pubkeys.md) +- [`eth_fast_aggregate_verify`](./eth_fast_aggregate_verify.md) - [`fast_aggregate_verify`](./fast_aggregate_verify.md) - [`sign`](./sign.md) - [`verify`](./verify.md) diff --git a/tests/formats/bls/eth2_aggregate_pubkeys.md b/tests/formats/bls/eth_aggregate_pubkeys.md similarity index 78% rename from tests/formats/bls/eth2_aggregate_pubkeys.md rename to tests/formats/bls/eth_aggregate_pubkeys.md index b07d9bd06..86d0e3cd0 100644 --- a/tests/formats/bls/eth2_aggregate_pubkeys.md +++ b/tests/formats/bls/eth_aggregate_pubkeys.md @@ -16,4 +16,4 @@ output: BLS Pubkey -- expected output, single BLS pubkeys or empty. ## Condition -The `eth2_aggregate_pubkeys` handler should aggregate the signatures in the `input`, and the result should match the expected `output`. +The `eth_aggregate_pubkeys` handler should aggregate the signatures in the `input`, and the result should match the expected `output`. diff --git a/tests/formats/bls/eth2_fast_aggregate_verify.md b/tests/formats/bls/eth_fast_aggregate_verify.md similarity index 100% rename from tests/formats/bls/eth2_fast_aggregate_verify.md rename to tests/formats/bls/eth_fast_aggregate_verify.md diff --git a/tests/generators/bls/main.py b/tests/generators/bls/main.py index 42754a581..0d6f4942e 100644 --- a/tests/generators/bls/main.py +++ b/tests/generators/bls/main.py @@ -358,49 +358,49 @@ def case05_aggregate_verify(): } -def case06_eth2_aggregate_pubkeys(): - aggregate_pubkey = spec.eth2_aggregate_pubkeys(PUBKEYS) +def case06_eth_aggregate_pubkeys(): + aggregate_pubkey = spec.eth_aggregate_pubkeys(PUBKEYS) assert aggregate_pubkey == milagro_bls._AggregatePKs(PUBKEYS) - yield f'eth2_aggregate_pubkeys_some_pubkeys', { + yield f'eth_aggregate_pubkeys_some_pubkeys', { 'input': [encode_hex(pubkey) for pubkey in PUBKEYS], 'output': encode_hex(aggregate_pubkey), } # Invalid pubkeys -- len(pubkeys) == 0 - expect_exception(spec.eth2_aggregate_pubkeys, []) + expect_exception(spec.eth_aggregate_pubkeys, []) expect_exception(milagro_bls._AggregatePKs, []) - yield f'eth2_aggregate_pubkeys_empty_list', { + yield f'eth_aggregate_pubkeys_empty_list', { 'input': [], 'output': None, } # Invalid pubkeys -- [ZERO_PUBKEY] - expect_exception(spec.eth2_aggregate_pubkeys, [ZERO_PUBKEY]) + expect_exception(spec.eth_aggregate_pubkeys, [ZERO_PUBKEY]) expect_exception(milagro_bls._AggregatePKs, [ZERO_PUBKEY]) - yield f'eth2_aggregate_pubkeys_na_pubkey', { + yield f'eth_aggregate_pubkeys_na_pubkey', { 'input': [encode_hex(ZERO_PUBKEY)], 'output': None, } # Invalid pubkeys -- G1 point at infinity - expect_exception(spec.eth2_aggregate_pubkeys, [Z1_PUBKEY]) + expect_exception(spec.eth_aggregate_pubkeys, [Z1_PUBKEY]) expect_exception(milagro_bls._AggregatePKs, [Z1_PUBKEY]) - yield f'eth2_aggregate_pubkeys_infinity_pubkey', { + yield f'eth_aggregate_pubkeys_infinity_pubkey', { 'input': [encode_hex(Z1_PUBKEY)], 'output': None, } # Invalid pubkeys -- b'\x40\x00\x00\x00....\x00' pubkey x40_pubkey = b'\x40' + b'\00' * 47 - expect_exception(spec.eth2_aggregate_pubkeys, [x40_pubkey]) + expect_exception(spec.eth_aggregate_pubkeys, [x40_pubkey]) expect_exception(milagro_bls._AggregatePKs, [x40_pubkey]) - yield f'eth2_aggregate_pubkeys_x40_pubkey', { + yield f'eth_aggregate_pubkeys_x40_pubkey', { 'input': [encode_hex(x40_pubkey)], 'output': None, } -def case07_eth2_fast_aggregate_verify(): +def case07_eth_fast_aggregate_verify(): """ Similar to `case04_fast_aggregate_verify` except for the empty case """ @@ -413,8 +413,8 @@ def case07_eth2_fast_aggregate_verify(): # Valid signature identifier = f'{pubkeys_serial}_{encode_hex(message)}' - assert spec.eth2_fast_aggregate_verify(pubkeys, message, aggregate_signature) - yield f'eth2_fast_aggregate_verify_valid_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { + assert spec.eth_fast_aggregate_verify(pubkeys, message, aggregate_signature) + yield f'eth_fast_aggregate_verify_valid_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { 'input': { 'pubkeys': pubkeys_serial, 'message': encode_hex(message), @@ -427,8 +427,8 @@ def case07_eth2_fast_aggregate_verify(): pubkeys_extra = pubkeys + [bls.SkToPk(PRIVKEYS[-1])] pubkeys_extra_serial = [encode_hex(pubkey) for pubkey in pubkeys_extra] identifier = f'{pubkeys_extra_serial}_{encode_hex(message)}' - assert not spec.eth2_fast_aggregate_verify(pubkeys_extra, message, aggregate_signature) - yield f'eth2_fast_aggregate_verify_extra_pubkey_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { + assert not spec.eth_fast_aggregate_verify(pubkeys_extra, message, aggregate_signature) + yield f'eth_fast_aggregate_verify_extra_pubkey_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { 'input': { 'pubkeys': pubkeys_extra_serial, 'message': encode_hex(message), @@ -440,8 +440,8 @@ def case07_eth2_fast_aggregate_verify(): # Invalid signature -- tampered with signature tampered_signature = aggregate_signature[:-4] + b'\xff\xff\xff\xff' identifier = f'{pubkeys_serial}_{encode_hex(message)}' - assert not spec.eth2_fast_aggregate_verify(pubkeys, message, tampered_signature) - yield f'eth2_fast_aggregate_verify_tampered_signature_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { + assert not spec.eth_fast_aggregate_verify(pubkeys, message, tampered_signature) + yield f'eth_fast_aggregate_verify_tampered_signature_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', { 'input': { 'pubkeys': pubkeys_serial, 'message': encode_hex(message), @@ -451,8 +451,8 @@ def case07_eth2_fast_aggregate_verify(): } # NOTE: Unlike `FastAggregateVerify`, len(pubkeys) == 0 and signature == Z2_SIGNATURE is VALID - assert spec.eth2_fast_aggregate_verify([], message, Z2_SIGNATURE) - yield f'eth2_fast_aggregate_verify_na_pubkeys_and_infinity_signature', { + assert spec.eth_fast_aggregate_verify([], message, Z2_SIGNATURE) + yield f'eth_fast_aggregate_verify_na_pubkeys_and_infinity_signature', { 'input': { 'pubkeys': [], 'message': encode_hex(message), @@ -462,8 +462,8 @@ def case07_eth2_fast_aggregate_verify(): } # Invalid pubkeys and signature -- len(pubkeys) == 0 and signature == 0x00... - assert not spec.eth2_fast_aggregate_verify([], message, NO_SIGNATURE) - yield f'eth2_fast_aggregate_verify_na_pubkeys_and_na_signature', { + assert not spec.eth_fast_aggregate_verify([], message, NO_SIGNATURE) + yield f'eth_fast_aggregate_verify_na_pubkeys_and_na_signature', { 'input': { 'pubkeys': [], 'message': encode_hex(message), @@ -477,8 +477,8 @@ def case07_eth2_fast_aggregate_verify(): pubkeys_with_infinity = pubkeys + [Z1_PUBKEY] signatures = [bls.Sign(privkey, SAMPLE_MESSAGE) for privkey in PRIVKEYS] aggregate_signature = bls.Aggregate(signatures) - assert not spec.eth2_fast_aggregate_verify(pubkeys_with_infinity, SAMPLE_MESSAGE, aggregate_signature) - yield f'eth2_fast_aggregate_verify_infinity_pubkey', { + assert not spec.eth_fast_aggregate_verify(pubkeys_with_infinity, SAMPLE_MESSAGE, aggregate_signature) + yield f'eth_fast_aggregate_verify_infinity_pubkey', { 'input': { 'pubkeys': [encode_hex(pubkey) for pubkey in pubkeys_with_infinity], 'message': encode_hex(SAMPLE_MESSAGE), @@ -524,6 +524,6 @@ if __name__ == "__main__": create_provider(PHASE0, 'fast_aggregate_verify', case04_fast_aggregate_verify), create_provider(PHASE0, 'aggregate_verify', case05_aggregate_verify), # ALTAIR - create_provider(ALTAIR, 'eth2_aggregate_pubkeys', case06_eth2_aggregate_pubkeys), - create_provider(ALTAIR, 'eth2_fast_aggregate_verify', case07_eth2_fast_aggregate_verify), + create_provider(ALTAIR, 'eth_aggregate_pubkeys', case06_eth_aggregate_pubkeys), + create_provider(ALTAIR, 'eth_fast_aggregate_verify', case07_eth_fast_aggregate_verify), ]) From 93af122b2db71b9d33f6e5fc963273a6adb8c211 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 5 Aug 2021 12:09:30 +0800 Subject: [PATCH 5/6] PR feedback from @ralexstokes and add single pubkey aggregate tests --- specs/altair/bls.md | 5 +- .../test_process_attester_slashing.py | 8 +- tests/core/pyspec/eth2spec/utils/bls.py | 8 +- tests/generators/bls/main.py | 90 +++++++++++-------- 4 files changed, 61 insertions(+), 50 deletions(-) diff --git a/specs/altair/bls.md b/specs/altair/bls.md index a09c6b3e3..06b0313a9 100644 --- a/specs/altair/bls.md +++ b/specs/altair/bls.md @@ -46,9 +46,8 @@ def eth_aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey: Refer to the BLS signature draft standard for more information. """ assert len(pubkeys) > 0 - for pubkey in pubkeys: - # Ensure that the given inputs are valid pubkeys - assert bls.KeyValidate(pubkey) + # Ensure that the given inputs are valid pubkeys + assert all(bls.KeyValidate(pubkey) for pubkey in pubkeys) result = copy(pubkeys[0]) for pubkey in pubkeys[1:]: diff --git a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_attester_slashing.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_attester_slashing.py index b620a7342..13d64e03b 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_attester_slashing.py +++ b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_attester_slashing.py @@ -306,7 +306,7 @@ def test_att1_empty_indices(spec, state): attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=True) attester_slashing.attestation_1.attesting_indices = [] - attester_slashing.attestation_1.signature = spec.bls.Z2_SIGNATURE + attester_slashing.attestation_1.signature = spec.bls.G2_POINT_AT_INFINITY yield from run_attester_slashing_processing(spec, state, attester_slashing, False) @@ -318,7 +318,7 @@ def test_att2_empty_indices(spec, state): attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=False) attester_slashing.attestation_2.attesting_indices = [] - attester_slashing.attestation_2.signature = spec.bls.Z2_SIGNATURE + attester_slashing.attestation_2.signature = spec.bls.G2_POINT_AT_INFINITY yield from run_attester_slashing_processing(spec, state, attester_slashing, False) @@ -330,10 +330,10 @@ def test_all_empty_indices(spec, state): attester_slashing = get_valid_attester_slashing(spec, state, signed_1=False, signed_2=False) attester_slashing.attestation_1.attesting_indices = [] - attester_slashing.attestation_1.signature = spec.bls.Z2_SIGNATURE + attester_slashing.attestation_1.signature = spec.bls.G2_POINT_AT_INFINITY attester_slashing.attestation_2.attesting_indices = [] - attester_slashing.attestation_2.signature = spec.bls.Z2_SIGNATURE + attester_slashing.attestation_2.signature = spec.bls.G2_POINT_AT_INFINITY yield from run_attester_slashing_processing(spec, state, attester_slashing, False) diff --git a/tests/core/pyspec/eth2spec/utils/bls.py b/tests/core/pyspec/eth2spec/utils/bls.py index 5bda0232f..9211e0ff0 100644 --- a/tests/core/pyspec/eth2spec/utils/bls.py +++ b/tests/core/pyspec/eth2spec/utils/bls.py @@ -10,9 +10,8 @@ bls = py_ecc_bls STUB_SIGNATURE = b'\x11' * 96 STUB_PUBKEY = b'\x22' * 48 -Z1_PUBKEY = b'\xc0' + b'\x00' * 47 -Z2_SIGNATURE = b'\xc0' + b'\x00' * 95 -STUB_COORDINATES = _signature_to_G2(Z2_SIGNATURE) +G2_POINT_AT_INFINITY = b'\xc0' + b'\x00' * 95 +STUB_COORDINATES = _signature_to_G2(G2_POINT_AT_INFINITY) def use_milagro(): @@ -96,8 +95,7 @@ def signature_to_G2(signature): @only_with_bls(alt_return=STUB_PUBKEY) def AggregatePKs(pubkeys): if bls == py_ecc_bls: - for pubkey in pubkeys: - assert bls.KeyValidate(pubkey) + assert all(bls.KeyValidate(pubkey) for pubkey in pubkeys) elif bls == milagro_bls: # milagro_bls._AggregatePKs checks KeyValidate internally pass diff --git a/tests/generators/bls/main.py b/tests/generators/bls/main.py index 0d6f4942e..75468b162 100644 --- a/tests/generators/bls/main.py +++ b/tests/generators/bls/main.py @@ -54,9 +54,11 @@ PRIVKEYS = [ PUBKEYS = [bls.SkToPk(privkey) for privkey in PRIVKEYS] ZERO_PUBKEY = b'\x00' * 48 -Z1_PUBKEY = b'\xc0' + b'\x00' * 47 -NO_SIGNATURE = b'\x00' * 96 -Z2_SIGNATURE = b'\xc0' + b'\x00' * 95 +G1_POINT_AT_INFINITY = b'\xc0' + b'\x00' * 47 + +ZERO_SIGNATURE = b'\x00' * 96 +G2_POINT_AT_INFINITY = b'\xc0' + b'\x00' * 95 + ZERO_PRIVKEY = 0 ZERO_PRIVKEY_BYTES = b'\x00' * 32 @@ -149,13 +151,13 @@ def case02_verify(): } # Invalid pubkey and signature with the point at infinity - assert not bls.Verify(Z1_PUBKEY, SAMPLE_MESSAGE, Z2_SIGNATURE) - assert not milagro_bls.Verify(Z1_PUBKEY, SAMPLE_MESSAGE, Z2_SIGNATURE) + assert not bls.Verify(G1_POINT_AT_INFINITY, SAMPLE_MESSAGE, G2_POINT_AT_INFINITY) + assert not milagro_bls.Verify(G1_POINT_AT_INFINITY, SAMPLE_MESSAGE, G2_POINT_AT_INFINITY) yield f'verify_infinity_pubkey_and_infinity_signature', { 'input': { - 'pubkey': encode_hex(Z1_PUBKEY), + 'pubkey': encode_hex(G1_POINT_AT_INFINITY), 'message': encode_hex(SAMPLE_MESSAGE), - 'signature': encode_hex(Z2_SIGNATURE), + 'signature': encode_hex(G2_POINT_AT_INFINITY), }, 'output': False, } @@ -181,10 +183,10 @@ def case03_aggregate(): } # Valid to aggregate G2 point at infinity - aggregate_sig = bls.Aggregate([Z2_SIGNATURE]) - assert aggregate_sig == milagro_bls.Aggregate([Z2_SIGNATURE]) == Z2_SIGNATURE + aggregate_sig = bls.Aggregate([G2_POINT_AT_INFINITY]) + assert aggregate_sig == milagro_bls.Aggregate([G2_POINT_AT_INFINITY]) == G2_POINT_AT_INFINITY yield f'aggregate_infinity_signature', { - 'input': [encode_hex(Z2_SIGNATURE)], + 'input': [encode_hex(G2_POINT_AT_INFINITY)], 'output': encode_hex(aggregate_sig), } @@ -240,32 +242,32 @@ def case04_fast_aggregate_verify(): } # Invalid pubkeys and signature -- len(pubkeys) == 0 and signature == Z1_SIGNATURE - assert not bls.FastAggregateVerify([], message, Z2_SIGNATURE) - assert not milagro_bls.FastAggregateVerify([], message, Z2_SIGNATURE) + assert not bls.FastAggregateVerify([], message, G2_POINT_AT_INFINITY) + assert not milagro_bls.FastAggregateVerify([], message, G2_POINT_AT_INFINITY) yield f'fast_aggregate_verify_na_pubkeys_and_infinity_signature', { 'input': { 'pubkeys': [], 'message': encode_hex(message), - 'signature': encode_hex(Z2_SIGNATURE), + 'signature': encode_hex(G2_POINT_AT_INFINITY), }, 'output': False, } # Invalid pubkeys and signature -- len(pubkeys) == 0 and signature == 0x00... - assert not bls.FastAggregateVerify([], message, NO_SIGNATURE) - assert not milagro_bls.FastAggregateVerify([], message, NO_SIGNATURE) - yield f'fast_aggregate_verify_na_pubkeys_and_na_signature', { + assert not bls.FastAggregateVerify([], message, ZERO_SIGNATURE) + assert not milagro_bls.FastAggregateVerify([], message, ZERO_SIGNATURE) + yield f'fast_aggregate_verify_na_pubkeys_and_zero_signature', { 'input': { 'pubkeys': [], 'message': encode_hex(message), - 'signature': encode_hex(NO_SIGNATURE), + 'signature': encode_hex(ZERO_SIGNATURE), }, 'output': False, } # Invalid pubkeys and signature -- pubkeys contains point at infinity pubkeys = PUBKEYS.copy() - pubkeys_with_infinity = pubkeys + [Z1_PUBKEY] + pubkeys_with_infinity = pubkeys + [G1_POINT_AT_INFINITY] signatures = [bls.Sign(privkey, SAMPLE_MESSAGE) for privkey in PRIVKEYS] aggregate_signature = bls.Aggregate(signatures) assert not bls.FastAggregateVerify(pubkeys_with_infinity, SAMPLE_MESSAGE, aggregate_signature) @@ -320,31 +322,31 @@ def case05_aggregate_verify(): } # Invalid pubkeys and signature -- len(pubkeys) == 0 and signature == Z1_SIGNATURE - assert not bls.AggregateVerify([], [], Z2_SIGNATURE) - assert not milagro_bls.AggregateVerify([], [], Z2_SIGNATURE) + assert not bls.AggregateVerify([], [], G2_POINT_AT_INFINITY) + assert not milagro_bls.AggregateVerify([], [], G2_POINT_AT_INFINITY) yield f'aggregate_verify_na_pubkeys_and_infinity_signature', { 'input': { 'pubkeys': [], 'messages': [], - 'signature': encode_hex(Z2_SIGNATURE), + 'signature': encode_hex(G2_POINT_AT_INFINITY), }, 'output': False, } # Invalid pubkeys and signature -- len(pubkeys) == 0 and signature == 0x00... - assert not bls.AggregateVerify([], [], NO_SIGNATURE) - assert not milagro_bls.AggregateVerify([], [], NO_SIGNATURE) - yield f'aggregate_verify_na_pubkeys_and_na_signature', { + assert not bls.AggregateVerify([], [], ZERO_SIGNATURE) + assert not milagro_bls.AggregateVerify([], [], ZERO_SIGNATURE) + yield f'aggregate_verify_na_pubkeys_and_zero_signature', { 'input': { 'pubkeys': [], 'messages': [], - 'signature': encode_hex(NO_SIGNATURE), + 'signature': encode_hex(ZERO_SIGNATURE), }, 'output': False, } # Invalid pubkeys and signature -- pubkeys contains point at infinity - pubkeys_with_infinity = pubkeys + [Z1_PUBKEY] + pubkeys_with_infinity = pubkeys + [G1_POINT_AT_INFINITY] messages_with_sample = messages + [SAMPLE_MESSAGE] assert not bls.AggregateVerify(pubkeys_with_infinity, messages_with_sample, aggregate_signature) assert not milagro_bls.AggregateVerify(pubkeys_with_infinity, messages_with_sample, aggregate_signature) @@ -359,9 +361,21 @@ def case05_aggregate_verify(): def case06_eth_aggregate_pubkeys(): + for pubkey in PUBKEYS: + encoded_pubkey = encode_hex(pubkey) + aggregate_pubkey = spec.eth_aggregate_pubkeys([pubkey]) + # Should be unchanged + assert aggregate_pubkey == milagro_bls._AggregatePKs([pubkey]) == pubkey + # Valid pubkey + yield f'eth_aggregate_pubkeys_valid_{(hash(bytes(encoded_pubkey, "utf-8"))[:8]).hex()}', { + 'input': [encode_hex(pubkey)], + 'output': encode_hex(aggregate_pubkey), + } + + # Valid pubkeys aggregate_pubkey = spec.eth_aggregate_pubkeys(PUBKEYS) assert aggregate_pubkey == milagro_bls._AggregatePKs(PUBKEYS) - yield f'eth_aggregate_pubkeys_some_pubkeys', { + yield f'eth_aggregate_pubkeys_valid_pubkeys', { 'input': [encode_hex(pubkey) for pubkey in PUBKEYS], 'output': encode_hex(aggregate_pubkey), } @@ -377,16 +391,16 @@ def case06_eth_aggregate_pubkeys(): # Invalid pubkeys -- [ZERO_PUBKEY] expect_exception(spec.eth_aggregate_pubkeys, [ZERO_PUBKEY]) expect_exception(milagro_bls._AggregatePKs, [ZERO_PUBKEY]) - yield f'eth_aggregate_pubkeys_na_pubkey', { + yield f'eth_aggregate_pubkeys_zero_pubkey', { 'input': [encode_hex(ZERO_PUBKEY)], 'output': None, } # Invalid pubkeys -- G1 point at infinity - expect_exception(spec.eth_aggregate_pubkeys, [Z1_PUBKEY]) - expect_exception(milagro_bls._AggregatePKs, [Z1_PUBKEY]) + expect_exception(spec.eth_aggregate_pubkeys, [G1_POINT_AT_INFINITY]) + expect_exception(milagro_bls._AggregatePKs, [G1_POINT_AT_INFINITY]) yield f'eth_aggregate_pubkeys_infinity_pubkey', { - 'input': [encode_hex(Z1_PUBKEY)], + 'input': [encode_hex(G1_POINT_AT_INFINITY)], 'output': None, } @@ -450,31 +464,31 @@ def case07_eth_fast_aggregate_verify(): 'output': False, } - # NOTE: Unlike `FastAggregateVerify`, len(pubkeys) == 0 and signature == Z2_SIGNATURE is VALID - assert spec.eth_fast_aggregate_verify([], message, Z2_SIGNATURE) + # NOTE: Unlike `FastAggregateVerify`, len(pubkeys) == 0 and signature == G2_POINT_AT_INFINITY is VALID + assert spec.eth_fast_aggregate_verify([], message, G2_POINT_AT_INFINITY) yield f'eth_fast_aggregate_verify_na_pubkeys_and_infinity_signature', { 'input': { 'pubkeys': [], 'message': encode_hex(message), - 'signature': encode_hex(Z2_SIGNATURE), + 'signature': encode_hex(G2_POINT_AT_INFINITY), }, 'output': True, } # Invalid pubkeys and signature -- len(pubkeys) == 0 and signature == 0x00... - assert not spec.eth_fast_aggregate_verify([], message, NO_SIGNATURE) - yield f'eth_fast_aggregate_verify_na_pubkeys_and_na_signature', { + assert not spec.eth_fast_aggregate_verify([], message, ZERO_SIGNATURE) + yield f'eth_fast_aggregate_verify_na_pubkeys_and_zero_signature', { 'input': { 'pubkeys': [], 'message': encode_hex(message), - 'signature': encode_hex(NO_SIGNATURE), + 'signature': encode_hex(ZERO_SIGNATURE), }, 'output': False, } # Invalid pubkeys and signature -- pubkeys contains point at infinity pubkeys = PUBKEYS.copy() - pubkeys_with_infinity = pubkeys + [Z1_PUBKEY] + pubkeys_with_infinity = pubkeys + [G1_POINT_AT_INFINITY] signatures = [bls.Sign(privkey, SAMPLE_MESSAGE) for privkey in PRIVKEYS] aggregate_signature = bls.Aggregate(signatures) assert not spec.eth_fast_aggregate_verify(pubkeys_with_infinity, SAMPLE_MESSAGE, aggregate_signature) From ad4445fa9e0609c8d449c7a880e44179a1421a8e Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 6 Aug 2021 16:39:35 +0800 Subject: [PATCH 6/6] Apply PR feedback from Danny and clean up the BLS test format docs --- tests/formats/bls/aggregate.md | 2 ++ tests/formats/bls/aggregate_verify.md | 13 ++++++++++--- tests/formats/bls/eth_aggregate_pubkeys.md | 2 +- tests/formats/bls/eth_fast_aggregate_verify.md | 13 ++++++++++--- tests/formats/bls/fast_aggregate_verify.md | 13 ++++++++++--- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/tests/formats/bls/aggregate.md b/tests/formats/bls/aggregate.md index af8444540..81ce85fe6 100644 --- a/tests/formats/bls/aggregate.md +++ b/tests/formats/bls/aggregate.md @@ -14,6 +14,8 @@ output: BLS Signature -- expected output, single BLS signature or empty. - `BLS Signature` here is encoded as a string: hexadecimal encoding of 96 bytes (192 nibbles), prefixed with `0x`. - No output value if the input is invalid. +All byte(s) fields are encoded as strings, hexadecimal encoding, prefixed with `0x`. + ## Condition The `aggregate` handler should aggregate the signatures in the `input`, and the result should match the expected `output`. diff --git a/tests/formats/bls/aggregate_verify.md b/tests/formats/bls/aggregate_verify.md index 3985de9f4..9b251af46 100644 --- a/tests/formats/bls/aggregate_verify.md +++ b/tests/formats/bls/aggregate_verify.md @@ -8,10 +8,17 @@ The test data is declared in a `data.yaml` file: ```yaml input: - pubkeys: List[bytes48] -- the pubkeys + pubkeys: List[BLS Pubkey] -- the pubkeys messages: List[bytes32] -- the messages - signature: bytes96 -- the signature to verify against pubkeys and messages -output: bool -- VALID or INVALID + signature: BLS Signature -- the signature to verify against pubkeys and messages +output: bool -- true (VALID) or false (INVALID) ``` +- `BLS Pubkey` here is encoded as a string: hexadecimal encoding of 48 bytes (96 nibbles), prefixed with `0x`. +- `BLS Signature` here is encoded as a string: hexadecimal encoding of 96 bytes (192 nibbles), prefixed with `0x`. + All byte(s) fields are encoded as strings, hexadecimal encoding, prefixed with `0x`. + +## Condition + +The `aggregate_verify` handler should verify the signature with pubkeys and messages in the `input`, and the result should match the expected `output`. diff --git a/tests/formats/bls/eth_aggregate_pubkeys.md b/tests/formats/bls/eth_aggregate_pubkeys.md index 86d0e3cd0..4f66adec2 100644 --- a/tests/formats/bls/eth_aggregate_pubkeys.md +++ b/tests/formats/bls/eth_aggregate_pubkeys.md @@ -8,7 +8,7 @@ The test data is declared in a `data.yaml` file: ```yaml input: List[BLS Pubkey] -- list of input BLS pubkeys -output: BLS Pubkey -- expected output, single BLS pubkeys or empty. +output: BLSPubkey -- expected output, single BLS pubkeys or empty. ``` - `BLS Pubkey` here is encoded as a string: hexadecimal encoding of 48 bytes (96 nibbles), prefixed with `0x`. diff --git a/tests/formats/bls/eth_fast_aggregate_verify.md b/tests/formats/bls/eth_fast_aggregate_verify.md index ddc1b5208..83b5484e0 100644 --- a/tests/formats/bls/eth_fast_aggregate_verify.md +++ b/tests/formats/bls/eth_fast_aggregate_verify.md @@ -8,10 +8,17 @@ The test data is declared in a `data.yaml` file: ```yaml input: - pubkeys: List[bytes48] -- the pubkey + pubkeys: List[BLS Pubkey] -- list of input BLS pubkeys message: bytes32 -- the message - signature: bytes96 -- the signature to verify against pubkeys and message -output: bool -- VALID or INVALID + signature: BLS Signature -- the signature to verify against pubkeys and message +output: bool -- true (VALID) or false (INVALID) ``` +- `BLS Pubkey` here is encoded as a string: hexadecimal encoding of 48 bytes (96 nibbles), prefixed with `0x`. +- `BLS Signature` here is encoded as a string: hexadecimal encoding of 96 bytes (192 nibbles), prefixed with `0x`. + All byte(s) fields are encoded as strings, hexadecimal encoding, prefixed with `0x`. + +## Condition + +The `eth_fast_aggregate_verify` handler should verify the signature with pubkeys and message in the `input`, and the result should match the expected `output`. diff --git a/tests/formats/bls/fast_aggregate_verify.md b/tests/formats/bls/fast_aggregate_verify.md index 3366cbb79..38ea29bb5 100644 --- a/tests/formats/bls/fast_aggregate_verify.md +++ b/tests/formats/bls/fast_aggregate_verify.md @@ -8,10 +8,17 @@ The test data is declared in a `data.yaml` file: ```yaml input: - pubkeys: List[bytes48] -- the pubkey + pubkeys: List[BLS Pubkey] -- list of input BLS pubkeys message: bytes32 -- the message - signature: bytes96 -- the signature to verify against pubkeys and message -output: bool -- VALID or INVALID + signature: BLS Signature -- the signature to verify against pubkeys and message +output: bool -- true (VALID) or false (INVALID) ``` +- `BLS Pubkey` here is encoded as a string: hexadecimal encoding of 48 bytes (96 nibbles), prefixed with `0x`. +- `BLS Signature` here is encoded as a string: hexadecimal encoding of 96 bytes (192 nibbles), prefixed with `0x`. + All byte(s) fields are encoded as strings, hexadecimal encoding, prefixed with `0x`. + +## Condition + +The `fast_aggregate_verify` handler should verify the signature with pubkeys and message in the `input`, and the result should match the expected `output`.