Skip to content

Commit

Permalink
Merge pull request #2438 from ralexstokes/add-aggregate-pks-fn
Browse files Browse the repository at this point in the history
Move BLS extensions to new file in Altair
  • Loading branch information
djrtwo authored Jun 7, 2021
2 parents 335d7ce + 6ecbc5e commit 30f2a07
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 18 deletions.
26 changes: 24 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ def floorlog2(x: int) -> uint64:
'''


OPTIMIZED_BLS_AGGREGATE_PUBKEYS = '''
def eth2_aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey:
return bls.AggregatePKs(pubkeys)
'''


class ProtocolDefinition(NamedTuple):
# just function definitions currently. May expand with configuration vars in future.
functions: Dict[str, str]
Expand Down Expand Up @@ -305,6 +311,11 @@ def invariant_checks(cls) -> str:
"""
raise NotImplementedError()

@classmethod
@abstractmethod
def implement_optimizations(cls, functions: Dict[str, str]) -> Dict[str, str]:
raise NotImplementedError()

@classmethod
@abstractmethod
def build_spec(cls, preset_name: str,
Expand Down Expand Up @@ -429,6 +440,10 @@ def hardcoded_custom_type_dep_constants(cls) -> Dict[str, str]:
def invariant_checks(cls) -> str:
return ''

@classmethod
def implement_optimizations(cls, functions: Dict[str, str]) -> Dict[str, str]:
return functions

@classmethod
def build_spec(cls, preset_name: str,
source_files: Sequence[Path], preset_files: Sequence[Path], config_file: Path) -> str:
Expand Down Expand Up @@ -482,6 +497,11 @@ def invariant_checks(cls) -> str:
TIMELY_HEAD_WEIGHT + TIMELY_SOURCE_WEIGHT + TIMELY_TARGET_WEIGHT + SYNC_REWARD_WEIGHT + PROPOSER_WEIGHT
) == WEIGHT_DENOMINATOR'''

@classmethod
def implement_optimizations(cls, functions: Dict[str, str]) -> Dict[str, str]:
if "eth2_aggregate_pubkeys" in functions:
functions["eth2_aggregate_pubkeys"] = OPTIMIZED_BLS_AGGREGATE_PUBKEYS.strip()
return super().implement_optimizations(functions)

#
# MergeSpecBuilder
Expand Down Expand Up @@ -588,7 +608,8 @@ def format_protocol(protocol_name: str, protocol_def: ProtocolDefinition) -> str
for k in list(spec_object.functions):
if "ceillog2" in k or "floorlog2" in k:
del spec_object.functions[k]
functions_spec = '\n\n\n'.join(spec_object.functions.values())
functions = builder.implement_optimizations(spec_object.functions)
functions_spec = '\n\n\n'.join(functions.values())

# Access global dict of config vars for runtime configurables
for name in spec_object.config_vars.keys():
Expand Down Expand Up @@ -831,7 +852,7 @@ def initialize_options(self):
self.out_dir = 'pyspec_output'
self.build_targets = """
minimal:presets/minimal:configs/minimal.yaml
mainnet:presets/mainnet:configs/mainnet.yaml
mainnet:presets/mainnet:configs/mainnet.yaml
"""

def finalize_options(self):
Expand All @@ -853,6 +874,7 @@ def finalize_options(self):
specs/phase0/validator.md
specs/phase0/weak-subjectivity.md
specs/altair/beacon-chain.md
specs/altair/bls.md
specs/altair/fork.md
specs/altair/validator.md
specs/altair/p2p-interface.md
Expand Down
22 changes: 6 additions & 16 deletions specs/altair/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
- [`SyncAggregate`](#syncaggregate)
- [`SyncCommittee`](#synccommittee)
- [Helper functions](#helper-functions)
- [`Predicates`](#predicates)
- [`eth2_fast_aggregate_verify`](#eth2_fast_aggregate_verify)
- [Crypto](#crypto)
- [Misc](#misc-1)
- [`add_flag`](#add_flag)
- [`has_flag`](#has_flag)
Expand Down Expand Up @@ -107,7 +106,6 @@ Altair is the first beacon chain hard fork. Its main features are:

| Name | Value |
| - | - |
| `G2_POINT_AT_INFINITY` | `BLSSignature(b'\xc0' + b'\x00' * 95)` |
| `PARTICIPATION_FLAG_WEIGHTS` | `[TIMELY_SOURCE_WEIGHT, TIMELY_TARGET_WEIGHT, TIMELY_HEAD_WEIGHT]` |

## Preset
Expand Down Expand Up @@ -220,19 +218,11 @@ class SyncCommittee(Container):

## Helper functions

### `Predicates`
### Crypto

#### `eth2_fast_aggregate_verify`

```python
def eth2_fast_aggregate_verify(pubkeys: Sequence[BLSPubkey], message: Bytes32, signature: BLSSignature) -> bool:
"""
Wrapper to ``bls.FastAggregateVerify`` accepting the ``G2_POINT_AT_INFINITY`` signature when ``pubkeys`` is empty.
"""
if len(pubkeys) == 0 and signature == G2_POINT_AT_INFINITY:
return True
return bls.FastAggregateVerify(pubkeys, message, signature)
```
Refer to the definitions in the [phase 0 document regarding BLS signatures](../phase0/beacon-chain.md#bls-signatures)
and the extensions defined in the [Altair BLS document](./bls.md). This specification assumes knowledge of
the functionality described in those documents.

### Misc

Expand Down Expand Up @@ -297,7 +287,7 @@ def get_next_sync_committee(state: BeaconState) -> SyncCommittee:
"""
indices = get_next_sync_committee_indices(state)
pubkeys = [state.validators[index].pubkey for index in indices]
aggregate_pubkey = bls.AggregatePKs(pubkeys)
aggregate_pubkey = eth2_aggregate_pubkeys(pubkeys)
return SyncCommittee(pubkeys=pubkeys, aggregate_pubkey=aggregate_pubkey)
```

Expand Down
65 changes: 65 additions & 0 deletions specs/altair/bls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Ethereum 2.0 Altair BLS extensions

## Table of contents

<!-- TOC -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Introduction](#introduction)
- [Constants](#constants)
- [Extensions](#extensions)
- [`eth2_aggregate_pubkeys`](#eth2_aggregate_pubkeys)
- [`eth2_fast_aggregate_verify`](#eth2_fast_aggregate_verify)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->

## Introduction

A number of extensions are defined to handle BLS signatures in the Altair upgrade.

Knowledge of the [phase 0 specification](../phase0/beacon-chain.md) is assumed, including type definitions.

## Constants

| Name | Value |
| - | - |
| `G2_POINT_AT_INFINITY` | `BLSSignature(b'\xc0' + b'\x00' * 95)` |

## Extensions

### `eth2_aggregate_pubkeys`

An additional function `AggregatePKs` is defined to extend the
[IETF BLS signature draft standard v4](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04)
spec referenced in the phase 0 document.

```python
def eth2_aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey:
"""
Return the aggregate public key for the public keys in ``pubkeys``.
NOTE: the ``+`` operation should be interpreted as elliptic curve point addition, which takes as input
elliptic curve points that must be decoded from the input ``BLSPubkey``s.
This implementation is for demonstrative purposes only and ignores encoding/decoding concerns.
Refer to the BLS signature draft standard for more information.
"""
assert len(pubkeys) > 0
result = copy(pubkeys[0])
for pubkey in pubkeys[1:]:
result += pubkey
return result
```

### `eth2_fast_aggregate_verify`

```python
def eth2_fast_aggregate_verify(pubkeys: Sequence[BLSPubkey], message: Bytes32, signature: BLSSignature) -> bool:
"""
Wrapper to ``bls.FastAggregateVerify`` accepting the ``G2_POINT_AT_INFINITY`` signature when ``pubkeys`` is empty.
"""
if len(pubkeys) == 0 and signature == G2_POINT_AT_INFINITY:
return True
return bls.FastAggregateVerify(pubkeys, message, signature)
```

0 comments on commit 30f2a07

Please sign in to comment.