Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP 665 updates #983

Merged
merged 9 commits into from
Apr 20, 2018
68 changes: 57 additions & 11 deletions EIPS/eip-665.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,49 @@ The addition of a native compiled function, in a precompiled contract, to the EV

## Motivation

One motivation for Ed25519 signature verification in smart contracts is to associate existing off-chain systems, records or accounts that use Ed25519 with blockchain transactions.
Ed25519 and Ed448 (that is, EdDSA using Curve25519 or Curve448) are IETF recommendations ([RFC7748](https://tools.ietf.org/html/rfc7748)) with some attractive properties:

* Ed25519 is intended to operate at around the 128-bit security level and Ed448 at around the 224-bit security level
* EdDSA uses small public keys (32 or 57 octets) and signatures (64 or 114 octets) for Ed25519 and Ed448, respectively
* Ed25519/Ed448 are designed so that fast, constant-time (timing attack resistant) and generally side-channel resistant implementations are easier to produce

Despite being around only for some years, post-Snowden, these curves [have gained wide use](https://ianix.com/pub/ed25519-deployment.html) quickly in various protocols and systems:

* TLS / ECDH(E) (session keys)
* TLS / x.509 (client and server certificates)
* DNSSEC (zone signing)
* OpenSSH (user keys)
* GNUPG/OpenPGP (user keys)
* OpenBSD Signify (software signing)

One motivation for Ed25519 signature verification in smart contracts is to **associate** existing off-chain systems, records or accounts that use Ed25519 (like above) with blockchain addresses or **delegate** by allowing to sign data with Ed25519 (only), and then submit this Ed25519-signed data anonymously (via any Eth sender address) to the blockchain, having the contract check the Ed25519 signature of the transaction.

Another motivation is the processing of external, Ed25519 proof-of-stake based blockchains within Ethereum smart contracts.

When a transactions contains data that comes with an Ed25519 signature, that proves that the sender of the Ethereum transaction was also in control of the private key (and the data), and this allows the contract to establish an association between the blockchain and the external system or account, and the external system establish the reverse relation.

For example, a contract might check a Ed25519 signed piece of data submitted to the Ethereum transaction like the current block number. That proves to the contract, that the sender is in possession of both the Ethereum private key and the Ed25518 private key, and hence the contract will accept an association between both. This again can be the root anchor for various powerful applications, as now a potentially crypto holding key owner has proven to be in control of some external off-chain system or account, like e.g. a DNS server, a DNS domain, a cluster node and so on.
For example, a contract might check a Ed25519 signed piece of data submitted to the Ethereum transaction like the current block number. That proves to the contract, that the sender is in possession of both the Ethereum private key and the Ed25519 private key, and hence the contract will accept an association between both. This again can be the root anchor for various powerful applications, as now a potentially crypto holding key owner has proven to be in control of some external off-chain system or account, like e.g. a DNS server, a DNS domain, a cluster node and so on.

## Specification

If `block.number >= CONSTANTINOPLE_FORK_BLKNUM`, add a precompiled contract for Ed25519 signature verification (`ED25519VFY`).

The proposal adds a new precompiled function `ED25519VFY` with the following input and output.

`ED25519VFY` takes as input 128 bytes:
`ED25519VFY` takes as **input 128 octets**:

1. **message**: The 32-byte message that was signed
2. **public key**: The 32-byte Ed25519 public key of the signer
3. **signature**: The 64-byte Ed25519 signature
1. **message**: the 32-octet message that was signed
2. **public key**: the 32-octet Ed25519 public key of the signer
3. **signature**: the 64-octet Ed25519 signature

`ED25519VFY` returns as output 1 byte:
`ED25519VFY` returns as **output 4 octets**:

1. **result**: `0x00` if signature is valid, else invalid signature
* `0x00000000` if signature is valid
* any non-zero value indicates a signature verification failure

### Address

The address of `ED25519VFY` is **`0x8`.**
The address of `ED25519VFY` is **`0x9`.**

### Gas costs

Expand All @@ -72,19 +88,49 @@ More test vectors can be found in the regression tests of NaCl (see references).

## Implementation

NaCl is a high-quality implementation of Ed25519, available from the same team that created the algorithms and cryptography behind Ed25519.
### libsodium

libsodium is a mature, high-quality C implementation of Ed25519, with bindings for many languages.

Further, libsodium is (to my knowledge, and as of today 2018/04) the only Ed25519 implementation that has gone through a [Security Assessment](https://www.privateinternetaccess.com/blog/2017/08/libsodium-v1-0-12-and-v1-0-13-security-assessment/).

To minimize consensus failure risks, the proposal recommends to use libsodium for adding the precompile in all Ethereum client implementations.

> Note: as an alternative to libsodium, I looked into HACL, an implementation of Ed25519 in F* (a ML dialect) that can be transpiled to C, and that was formally verified for functional correctness and memory safety of the resulting C code. However, this is new and compared to libsodium which is a "know thing" seems risky nevertheless.

### libsodium bindings

Here is an overview of the language bindings to libsodium for four Ethereum clients this proposal recommends:

Client | Language | libsodium binding
---+---+---
Geth | Go | use cgo with C [libsodium](https://github.com/jedisct1/libsodium)
Parity | Rust | [sodiumoxide](https://github.com/dnaq/sodiumoxide)
PyEthereum | Python | [PyNaCl](https://github.com/pyca/pynacl)
cpp-ethereum | C++ | [libsodium](https://github.com/jedisct1/libsodium)

### PRs

Implementations of this proposal are here:

The library should allow implementations of the proposed `ed25519verify` function with few lines of code in the hosting Ethereum implementation.
1. [go-ethereum PR #16453](https://github.com/ethereum/go-ethereum/pull/16453)
2. [pyethereum PR #862](https://github.com/ethereum/pyethereum/pull/862)
3. [parity PR #8330](https://github.com/paritytech/parity/pull/8330)
4. [cpp-ethereum PR #4945](https://github.com/ethereum/cpp-ethereum/pull/4945)

## References

* RFC7748 - Elliptic Curves for Security https://tools.ietf.org/html/rfc7748
* Definition of Ed25519: https://ed25519.cr.yp.to/ed25519-20110926.pdf
* Ed25519 - high-speed high-security signatures: https://ed25519.cr.yp.to/
* NaCl - Networking and Cryptography library: https://nacl.cr.yp.to/sign.html
* NaCl Crypto Libraries (which contains Ed25519): https://ianix.com/pub/ed25519-deployment.html
* Test vectors for Ed25519: https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-6
* NaCl regression tests: https://ed25519.cr.yp.to/python/sign.py and https://ed25519.cr.yp.to/python/sign.input
* On the recoverability of public keys from signature+message (alone): https://crypto.stackexchange.com/questions/9936/what-signature-schemes-allow-recovering-the-public-key-from-a-signature
* Bernstein, D., "Curve25519: new Diffie-Hellman speed records", DOI 10.1007/11745853_14, February 2006, http://cr.yp.to/ecdh.html
* Hamburg, M., "Ed448-Goldilocks, a new elliptic curve", June 2015, http://eprint.iacr.org/2015/625>
* RFC8080: Edwards-Curve Digital Security Algorithm (EdDSA) for DNSSEC (https://tools.ietf.org/html/rfc8080)

## Copyright

Expand Down