Skip to content

Latest commit

 

History

History
74 lines (44 loc) · 3.72 KB

cip-0026.md

File metadata and controls

74 lines (44 loc) · 3.72 KB
cip title author discussions-to status type category (*only required for Standards Track) created license
26
Precompile for getting BLS public key for a given validator in a historical block
Sami Mäkelä (@mrsmkl)
Final
Standards Track
Ring 0
2020-11-17
Apache 2.0

Simple Summary

Adding a precompile that returns the BLS public key of a given validator in a given block.

Abstract

Returns the BLS public key of a validator in the same way as the existing precompile for getting the validator address.

Motivation

Currently it's not possible to get the validator BLS public key used for consensus from the chain. It's only possible to get the current BLS key that would be active in the next epoch. However the keys are needed to implement slashing in the case of bad epoch snark data (see CIP-20).

Specification

The address of the precompile is 0xE1 The input is interpreted in the same way as precompile for getting the validator address: it is 64 bytes, first 32 bytes are an integer representing the index of validator to get, and the second 32 bytes are an integer representing the block to access. These input values have the same conditions as the precompile for getting validator address: index must be smaller than the number of validator for the given block, and block number must be smaller than current block number.

Returns the BLS public key in uncompressed format as 192 byte string. In the case of Celo, the BLS public key is a point in the BLS12-377 elliptic curve defined over Fp2 (G2). A value of Fp2 is represented as two numbers smaller than the base field modulus. These numbers are encoded as 64 byte little endian strings (function LE). So if we have a point (a+bi,c+di), it is serialized as LE(a) || LE(b) || LE(c) || LE(d).

Gas usage

The precompile will use 1000 gas, same as the current precompile to get the validator address.

Rationale

(From discord #plumo channel)

The problem we've stumbled upon is that the BLS key might change during an epoch and so we can't get the BLS key that is expected to be used in consensus and should be used for slashing detection.

We've discussed a few possible solutions:

  1. modifying the validators contract to include that information
  2. using the proofs of possession that validators submit when updating BLS keys
  3. introducing a new precompile that gets the consensus-activated BLS keys of the validator set at a block

A brief pros/cons for the approaches:

  1. pros: easy-ish to implement and very natural. cons: might be hard to deploy, as the validators contract is already pushing the boundaries of the gas limit + we need to upgrade the contract, which introduces risks. We additionally need the ability to decompress points.
  2. pros: no changes needed to any smart contract. cons: complex to implement + decompression of points is needed.
  3. pros: easy to implement and we can hide the complexity of point decompression inside the precompile. It's a generic precompile that can be used elsewhere. cons: a new precompile.

@asaj and @kobigurk felt that the best option is 3 and @asaj on to get a sense of acceptance in the All Core Devs calls today, and there was no objection.

Backwards Compatibility

Adds new precompile, so a hard fork is needed.

Test Cases

Unit tests in branch mrsmkl/precompile-bls-key

Implementation

Branch celo-org/celo-blockchain#1250

Security Considerations

The precompile is very similar to an existing one, so there shouldn't be too many security implications. Mostly have to be sure that all the edge cases are handled properly and to make sure there's no non-deterministic behavior.

License

This work is licensed under the Apache License, Version 2.0.