Skip to content

Latest commit

 

History

History
207 lines (156 loc) · 8.85 KB

cip-0020.md

File metadata and controls

207 lines (156 loc) · 8.85 KB
cip title author discussions-to status type category created license
20
Generic hash function support via extensible precompile
James Prestwich <[email protected]>
Superseded
Standards
Ring 0
2020-10-25
Apache 2.0

Important

This feature has been removed in CIP-63.

Terminology

The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119.

Simple Summary

This CIP specifies an extensible precompile that provides access to multiple hash functions to the EVM. It also specifies a process for including new hash functions in the precompile.

Abstract

As a descendant of the EVM, Celo supports only a handful of common hash functions. This restricts the design-space of Celo protocols, and prevents certain protocols from being evaluated by the EVM. We propose a single precompile that provides access to common cryptographic hashes, and can be easily extended with minimal impact on chain security and performance.

We also propose a reduced subset of the CIP process that applies specifically to hash function enrollment. This CIP20 process is intended to reduce the burden of review on CIP editors and Celo Blockchain developers, as well as speed inclusion of useful functionality for dapp developers.

Motivation

  • Provide support for common cryptographic hash functions
  • Expand options for on-chain verification of protocols not specifically designed for EVM compatibility - e.g. Verification of off-chain signatures using Blake2Xs, including Celo's own epoch commitments within a smart contract. - e.g. Verification of remote Proof of Work from a wide variety of chains
  • Provide a clear route for acceptance and adoption of additional hash functions

Specification

As of FORK_BLOCK_NUMBER we introduce a new precompiled contract at address 0xE2 that provides access to a set of pre-determined hash functions. The input to this pre-compile consists of a one-byte selector, a function-specific parameter block, and the preimage. The output of this pre-compile is dependent on the selector, and may be fixed- or variable-length. If the selector is unknown (not on the current compatibility list), or the function-specific, the precompile MUST return an error.

Proposing an extension

To be eligible for inclusion, a proposed hash function meet the following criteria:

  1. There MUST be a standardized specification for the function.
  2. There MUST be an existing high-quality implementation in Go.
    1. The proposer SHOULD provide an implementation of the precompile extension.
    2. The proposer SHOULD also provide test vectors, and fuzzing setups for this implementation.
    3. The proposer SHOULD provide benchmarks according to the standardized CIP20 benchmarking process below.
  3. The function MUST be pure.
    1. This is intended to disqualify ethash and other stateful functions.
  4. The function MUST NOT be memory intensive
    1. This is intended to disqualify "memory-hard" hash functions and other potential DoS vectors
    2. E.g. scrypt, argon
  5. The function SHOULD NOT be a combination of other hash functions
    1. Prefer adding each component separately, and building the composition as a Solidity function.
    2. This is intended to disqualify common PoW-specific combinations.
    3. E.g. sha256d, X11,

Once these criteria are met the function must be proposed via a pull request. The pull request SHOULD include a link to an existing implementation and concrete use case for the new hash function. The pull request MUST be named according to the following template: [CIP-0020 Extension] DigestFunctionName.

The pull request MUST update this CIP with the following information:

  1. A new row in the table below
    1. The status MUST be set to Proposed.
    2. The selector MUST be marked TODO. Selectors will be assigned by the CIP editors, not the proposer.
  2. If any function-specific parameters are required:
    1. A link to full documentation in a new file in the CIP-0020/ folder.
  3. If the ouput is not a fixed-length digest:
    1. A link to full documentation in a new file in the CIP-0020/ folder.

The pull request MUST NOT:

  1. Modify any existing table row or text outside of the table.
  2. Conflict with the selector or name of any existing function.
  3. Modify any other files in this repository.

Review of new hash functions

New hash functions will be reviewed by participants of the Celo ACD calls. Review will be scheduled via the ACD call process. Submitters are responsible for requesting that their submission be included in the agenda.

Reviewers MAY ask the proposer for additional justification or to clarify decisions made with respect to the input and output formats. Rough consensus of ACD call participants is required, but Reviewers SHOULD accept any proposal that meets all criteria and contains a well-tested implementation.

Supported Digest Functions

Function Name Extended Docs Input Format Output Format Link to specification Status
0x00 SHA3-256 n/a preimage only 32 bytes link Proposed
0x01 SHA3-512 n/a preimage only 64 bytes link Proposed
0x02 Keccak-512 n/a preimage only 64 bytes link Proposed
0x03 SHA2-512 n/a preimage only 64 bytes link
0x10 Blake2s CIP-0020/blake2s.md configuration, key, and preimage Variable link Proposed

Gas Costs

Calling the precompile with an undefined selector or otherwise invalid input will cost INVALID_CIP20_INPUT_GAS (initially set to 200) gas and cause an error.

New hash functions MUST include a gas cost function and MUST include benchmarks that justify that function. This function SHOULD account for setup costs and per-block processing of input. To conform to existing hash function precompile and opcode behavior, we recommend they be priced as a base gas cost for the invocation plus an amount of gas per EVM word processed.

The initial SHA-3 variants (SHA3-256, SHA3-512, and Keccak-512) will be priced identically to the existing Keccak-256 at 30 + (6 * words).

The initial SHA-2 variant (SHA2-512) will be priced identically to the existing SHA2-256 precompile. It will cost 60 + (12 * words).

Please refer to the blake2s document for details of the blake2s gas pricing function.

EVM_WORD_SIZE: int = 32

def price_word_metered_hash(
	base: int,
	per_word: int,
	input: bytes
) -> int:
    length_ceiling = len(input) + EVM_WORD_SIZE - 1
    words = length_ceiling // EVM_WORD_SIZE
    return base + words * per_word

def price_sha3_variant(input: bytes) -> int:
    return price_word_metered_hash(30, 6, input)

def price_sha2_512(input: bytes) -> int:
    return price_word_metered_hash(60, 12, input)

Rationale

I considered adding one precompile per hash function, with each function having its own CIP. This would use a potentially large, fragmented, portion of the precompile address space. Subjecting a new hash function to the full CIP review process seems unnecessary, as the use cases are clear and the risk is low.

CIP-20 Benchmarking Process

## TODO ##

Test Cases

  • To follow.

Implementation

Security Considerations

  • This is a permanent departure from compatibility with the Ethereum EVM, and its functionality ought to be wrapped in a Celo-specific contract to prevent accidental use in an Ethereum-targeted contract.

  • Given that this is a pure function exposed at the contract layer, it is unlikely to have a significant risk on the consensus or governance processes.

  • Each hash function will need to be priced separately. The pricing function for this precompile will grow in complexity over time.

  • If more than 200 hash functions are merged, the selector space will become crowded and we will need to plan to add a second selector byte.

License

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