From 89a87948bf18bd456092665cb79eb7ffaf80dac0 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Sun, 16 Jun 2019 00:11:40 -0400 Subject: [PATCH 01/39] Brought issue #152 into the repo as a draft EIP. Thanks @tjade273! --- EIPS/eip-draft-blake2b-f-precompile.md | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 EIPS/eip-draft-blake2b-f-precompile.md diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-draft-blake2b-f-precompile.md new file mode 100644 index 00000000000000..87eea5344e46e4 --- /dev/null +++ b/EIPS/eip-draft-blake2b-f-precompile.md @@ -0,0 +1,49 @@ +# Title + +Title: Add RFC 7693 compression function `F` contract +Author: Tjaden Hess +Status: Draft +Type: Standard Track +Layer: Consensus (hard-fork) +Created 2016-10-04 + +### Abstract + +This EIP introduces a new precompiled contract which implements the compression function F used in the BLAKE2b cryptographic hashing algorithm, for the purpose of allowing interoperability between the Zcash blockchain and the EVM, and introducing more flexible cryptographic hash primitives to the EVM. + +## Parameters + +* `METROPOLIS_FORK_BLKNUM`: TBD +* `GFROUND`: TBD + +## Specification + +Adds a precompile at address `0x0000....0d` which accepts [ABI encoded](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) arguments corresponding to the function signature + +``` +F(bytes32[2] h, bytes32[4] m, uint t , bool f, uint rounds) returns (bytes32[2] h_new); +``` + +where `h`, `m`, `t` and `f` are the current state, the new message, the byte counter and a finalization flag, as defined in [RFC 7693](https://tools.ietf.org/html/rfc7693), and `rounds` is the number of rounds of mixing to perform (BLAKE2b uses 12, BLAKE2s uses 10). `h_new` is the updated state of the hash. + +Each operation will cost `GFROUND * rounds`. + +## Motivation + +Besides being a useful cryptographic hash function and SHA3 finalist, BLAKE2b allows for efficient verification of the Equihash PoW used in Zcash, making a BTC Relay - style SPV client possible on Ethereum. A single verification of an Equihash PoW verification requires 512 iterations of the hash function, making verification of Zcash block headers prohibitively expensive if a Solidity implementation of BLAKE2b is used. + +The BLAKE2b algorithm is highly optimized for 64-bit CPUs, and is faster than MD5 on modern processors. + +Interoperability with Zcash could enable contracts like trustless atomic swaps between the chains, which could provide a much needed aspect of privacy to the very public Ethereum blockchain. + +## Rationale + +The most frequent concern with EIPs of this type is that the addition of specific functions at the protocol level is an infringement on Ethereum's "featureless" design. It is true that a more elegant solution to the issue is to simply improve the scalability characteristics of the network so as to make calculating functions requiring millions of gas practical for everyday use. In the meantime, however, I believe that certain operations are worth subsidising via precompiled contracts and there is significant precedent for this, most notably the inclusion of the SHA256 prcompiled contract, which is included largely to allow inter-operation with the Bitcoin blockchain. + +Additionally, BLAKE2b is an excellent candidate for precompilation because of the extremely asymetric efficiency which it exhibits. BLAKE2b is heavily optimized for modern 64-bit CPUs, specifically utilizing 24 and 63-bit rotations to allow parallelism through SIMD instructions and little-endian arithmetic. These characteristics provide exceptional speed on native CPUs: 3.08 cycles per byte, or 1 gibibyte per second on an Intel i5. + +In contrast, the big-endian 32 byte semantics of the EVM are not conducive to efficient implementation of BLAKE2, and thus the gas cost associated with computing the hash on the EVM is disproportionate to the true cost of computing the function natively. + +Implementation of only the core F compression function allows substantial flexibility and extensibility while keeping changes at the protocol level to a minimum. This will allow functions like tree hashing, incremental hashing, and keyed, salted, and personalized hashing as well as variable length digests, none of which are currently available on the EVM. + +There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x000....0000d` being empty. Te likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value, with negligible risk of collision. From 843d377daa125ed702fefbd54259d2a0655b33b6 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Sun, 16 Jun 2019 00:27:17 -0400 Subject: [PATCH 02/39] Make the draft EIP consistent with the template Also added myself as an author --- EIPS/eip-draft-blake2b-f-precompile.md | 59 ++++++++++++++++++-------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-draft-blake2b-f-precompile.md index 87eea5344e46e4..45608eed5b6ecb 100644 --- a/EIPS/eip-draft-blake2b-f-precompile.md +++ b/EIPS/eip-draft-blake2b-f-precompile.md @@ -1,22 +1,37 @@ -# Title - -Title: Add RFC 7693 compression function `F` contract -Author: Tjaden Hess +--- +eip: +Title: Add Blake2 compression function `F` precompile +Author: Tjaden Hess , Matt Luongo (@mhluongo) +discussions-to: https://ethereum-magicians.org/t/blake2b-f-precompile/3157 Status: Draft -Type: Standard Track -Layer: Consensus (hard-fork) +type: Standards Track +category Core Created 2016-10-04 +--- + + + +## Simple Summary + -### Abstract +This EIP will enable the Blake2b hash function to run cheaply on the EVM, allowing easier interoperability between Ethereum and Zcash as well as other Equihash-based PoW coins. + +## Abstract + This EIP introduces a new precompiled contract which implements the compression function F used in the BLAKE2b cryptographic hashing algorithm, for the purpose of allowing interoperability between the Zcash blockchain and the EVM, and introducing more flexible cryptographic hash primitives to the EVM. -## Parameters +## Motivation + -* `METROPOLIS_FORK_BLKNUM`: TBD -* `GFROUND`: TBD +Besides being a useful cryptographic hash function and SHA3 finalist, BLAKE2b allows for efficient verification of the Equihash PoW used in Zcash, making a BTC Relay - style SPV client possible on Ethereum. A single verification of an Equihash PoW verification requires 512 iterations of the hash function, making verification of Zcash block headers prohibitively expensive if a Solidity implementation of BLAKE2b is used. + +The BLAKE2b algorithm is highly optimized for 64-bit CPUs, and is faster than MD5 on modern processors. + +Interoperability with Zcash could enable contracts like trustless atomic swaps between the chains, which could provide a much needed aspect of privacy to the very public Ethereum blockchain. ## Specification + Adds a precompile at address `0x0000....0d` which accepts [ABI encoded](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) arguments corresponding to the function signature @@ -28,15 +43,8 @@ where `h`, `m`, `t` and `f` are the current state, the new message, the byte cou Each operation will cost `GFROUND * rounds`. -## Motivation - -Besides being a useful cryptographic hash function and SHA3 finalist, BLAKE2b allows for efficient verification of the Equihash PoW used in Zcash, making a BTC Relay - style SPV client possible on Ethereum. A single verification of an Equihash PoW verification requires 512 iterations of the hash function, making verification of Zcash block headers prohibitively expensive if a Solidity implementation of BLAKE2b is used. - -The BLAKE2b algorithm is highly optimized for 64-bit CPUs, and is faster than MD5 on modern processors. - -Interoperability with Zcash could enable contracts like trustless atomic swaps between the chains, which could provide a much needed aspect of privacy to the very public Ethereum blockchain. - ## Rationale + The most frequent concern with EIPs of this type is that the addition of specific functions at the protocol level is an infringement on Ethereum's "featureless" design. It is true that a more elegant solution to the issue is to simply improve the scalability characteristics of the network so as to make calculating functions requiring millions of gas practical for everyday use. In the meantime, however, I believe that certain operations are worth subsidising via precompiled contracts and there is significant precedent for this, most notably the inclusion of the SHA256 prcompiled contract, which is included largely to allow inter-operation with the Bitcoin blockchain. @@ -47,3 +55,18 @@ In contrast, the big-endian 32 byte semantics of the EVM are not conducive to ef Implementation of only the core F compression function allows substantial flexibility and extensibility while keeping changes at the protocol level to a minimum. This will allow functions like tree hashing, incremental hashing, and keyed, salted, and personalized hashing as well as variable length digests, none of which are currently available on the EVM. There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x000....0000d` being empty. Te likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value, with negligible risk of collision. + +## Backwards Compatibility + +All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. + +## Test Cases + +Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. + +## Implementation + +The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 3bcce1dffc36f239d67740f3ac46e11dc25ecd17 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Sun, 16 Jun 2019 00:52:55 -0400 Subject: [PATCH 03/39] Break backwards compatibility into its own section --- EIPS/eip-draft-blake2b-f-precompile.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-draft-blake2b-f-precompile.md index 45608eed5b6ecb..6a943865bd32dd 100644 --- a/EIPS/eip-draft-blake2b-f-precompile.md +++ b/EIPS/eip-draft-blake2b-f-precompile.md @@ -19,7 +19,7 @@ This EIP will enable the Blake2b hash function to run cheaply on the EVM, allowi ## Abstract -This EIP introduces a new precompiled contract which implements the compression function F used in the BLAKE2b cryptographic hashing algorithm, for the purpose of allowing interoperability between the Zcash blockchain and the EVM, and introducing more flexible cryptographic hash primitives to the EVM. +This EIP introduces a new precompiled contract which implements the compression function `F` used in the BLAKE2b cryptographic hashing algorithm, for the purpose of allowing interoperability between the EVM and Zcash, as well as introducing more flexible cryptographic hash primitives to the EVM. ## Motivation @@ -33,7 +33,7 @@ Interoperability with Zcash could enable contracts like trustless atomic swaps b ## Specification -Adds a precompile at address `0x0000....0d` which accepts [ABI encoded](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) arguments corresponding to the function signature +Adds a precompile at address `0x0d` which accepts [ABI encoded](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) arguments corresponding to the function signature ``` F(bytes32[2] h, bytes32[4] m, uint t , bool f, uint rounds) returns (bytes32[2] h_new); @@ -54,11 +54,10 @@ In contrast, the big-endian 32 byte semantics of the EVM are not conducive to ef Implementation of only the core F compression function allows substantial flexibility and extensibility while keeping changes at the protocol level to a minimum. This will allow functions like tree hashing, incremental hashing, and keyed, salted, and personalized hashing as well as variable length digests, none of which are currently available on the EVM. -There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x000....0000d` being empty. Te likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value, with negligible risk of collision. - ## Backwards Compatibility -All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. + +There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x0d` being empty. The likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value with negligible risk of collision. ## Test Cases From c3f4c685428ac1d8bd0169657a82ac067a7f8839 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Sun, 16 Jun 2019 01:11:11 -0400 Subject: [PATCH 04/39] Added notes about the in-progress implementation Should have a working geth precompile and initial benchmarks shortly --- EIPS/eip-draft-blake2b-f-precompile.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-draft-blake2b-f-precompile.md index 6a943865bd32dd..7ae7ec7ae0a50e 100644 --- a/EIPS/eip-draft-blake2b-f-precompile.md +++ b/EIPS/eip-draft-blake2b-f-precompile.md @@ -60,12 +60,16 @@ Implementation of only the core F compression function allows substantial flexib There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x0d` being empty. The likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value with negligible risk of collision. ## Test Cases + -Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. + +Test cases are in progress, and can be followed along in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f) as well as our fork of [go-ethereum](https://github.com/keep-network/go-ethereum). ## Implementation -The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. + +Implementations are in progress, and can be followed along in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f) as well as our fork of [go-ethereum](https://github.com/keep-network/go-ethereum). ## Copyright + Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 92916e129b0f701c7814face19cf9d6608f008d0 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Sun, 16 Jun 2019 17:45:57 -0400 Subject: [PATCH 05/39] Specify EIP-2046 as a requirement While 2046's cheaper precompile contract calls aren't a requirement for this EIP's implementation, shipping this precompile without EIP-2046 would make the F function expensive for some of the motivating usecases. --- EIPS/eip-draft-blake2b-f-precompile.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-draft-blake2b-f-precompile.md index 7ae7ec7ae0a50e..506b317120cb0a 100644 --- a/EIPS/eip-draft-blake2b-f-precompile.md +++ b/EIPS/eip-draft-blake2b-f-precompile.md @@ -1,12 +1,13 @@ --- eip: -Title: Add Blake2 compression function `F` precompile -Author: Tjaden Hess , Matt Luongo (@mhluongo) +title: Add Blake2 compression function `F` precompile +author: Tjaden Hess , Matt Luongo (@mhluongo) discussions-to: https://ethereum-magicians.org/t/blake2b-f-precompile/3157 -Status: Draft +status: Draft type: Standards Track -category Core -Created 2016-10-04 +category: Core +created 2016-10-04 +requires: 2046 --- From 764ff73bca1702c6bbb582f52d77282ffd977d5e Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Thu, 20 Jun 2019 15:31:40 -0400 Subject: [PATCH 06/39] Don't use ABI encoding for precompile Replace the existing ABI encoding interface to the BLAKE2b `F` precompile with a loosely pack struct that's `staticcall`-friendly. H/t to @pdyraga for putting together the interface! --- EIPS/eip-draft-blake2b-f-precompile.md | 72 ++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-draft-blake2b-f-precompile.md index 506b317120cb0a..f23a16bbf788cf 100644 --- a/EIPS/eip-draft-blake2b-f-precompile.md +++ b/EIPS/eip-draft-blake2b-f-precompile.md @@ -34,13 +34,79 @@ Interoperability with Zcash could enable contracts like trustless atomic swaps b ## Specification -Adds a precompile at address `0x0d` which accepts [ABI encoded](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) arguments corresponding to the function signature +We propose adding a precompiled contract at address `0x09` wrapping the [BLAkE2b `F` compression function](https://tools.ietf.org/html/rfc7693#section-3.2). Rather than the ABI-encoded call structure proposed in [#152](https://github.com/ethereum/EIPs/issues/152), this design better matches other precompiles and works well with a standard `staticcall`. +The precompile requires 6 inputs, corresponding to the inputs specified in the [BLAKE2b RFC](https://tools.ietf.org/html/rfc7693#section-3.2) + +- `h` - the state vector +- `m` - the message block vector +- `t_0, t_1` - offset counters +- `f` - the final block indicator flag +- `rounds` - the number of rounds + +Loosely packing the data in equal 32-byte slots means an easier job for app developers, and also appears to be compatible with how other precompiles accept input data. + +``` +[ bytes32[0] | bytes32[1] ][ bytes32[2] | bytes32[3] | bytes32[4] | bytes32[5] ] +[ 64 bytes for h ][ 128 bytes for m ] + +[ bytes32[6] ][ bytes32[7] ] +[ 24 bytes padding | 8 bytes for t_0 ][ 24 bytes padding | 8 bytes for t_1 ] + +[ bytes32[8] ][ bytes32[9] ] +[ 31 bytes padding | 1 byte for f ][ 28 bytes padding | 4 bytes for rounds] ``` -F(bytes32[2] h, bytes32[4] m, uint t , bool f, uint rounds) returns (bytes32[2] h_new); + +The precompile can be wrapped easily in Solidity to provide a more development-friendly interface to `F`. + +```solidity + function F(bytes32[2] memory h, bytes32[4] memory m, uint64[2] memory t, bool f, uint32 rounds) public view returns (bytes32[2] memory) { + bytes32[2] memory output; + + bytes32 _t0 = bytes32(uint256(t[0])); + bytes32 _t1 = bytes32(uint256(t[1])); + + bytes32 _f; + if (f) { + _f = hex"0000000000000000000000000000000000000000000000000000000000000001"; + } + + bytes32 _rounds = bytes32(uint256(rounds)); + + bytes32[10] memory args = [ h[0], h[1], m[0], m[1], m[2], m[3], _t0, _t1, _f, _rounds ]; + + assembly { + if iszero(staticcall(not(0), 0x09, args, 0x140, output, 0x40)) { + revert(0, 0) + } + } + return output; + } + + function callF() public view returns (bytes32[2] memory) { + bytes32[2] memory h; + h[0] = hex"6a09e627f3bcc909bb67ae8484caa73b3c6ef372fe94b82ba54ff53a5f1d36f1"; + h[1] = hex"510e527fade682d19b05688c2b3e6c1f1f83d9abfb41bd6b5be0cd19137e2179"; + + bytes32[4] memory m; + m[0] = hex"278400340e6b05c5752592c52c4f121292eafc51cc01a997b4aed13409298fad"; + m[1] = hex"0d99ccc8f76453d9b3661e5c4d325d7751147db17489046d1682d50eefa4a1da"; + m[2] = hex"0000000000000000000000000000000000000000000000000000000000000000"; + m[3] = hex"0000000000000000000000000000000000000000000000000000000000000000"; + + uint64[2] memory t; + t[0] = 18446744073709551552; + t[1] = 18446744073709551615; + + bool f = true; + + uint32 rounds = 12; + + return F(h, m, t, f, rounds); + } ``` -where `h`, `m`, `t` and `f` are the current state, the new message, the byte counter and a finalization flag, as defined in [RFC 7693](https://tools.ietf.org/html/rfc7693), and `rounds` is the number of rounds of mixing to perform (BLAKE2b uses 12, BLAKE2s uses 10). `h_new` is the updated state of the hash. +### Gas costs and benchmarks Each operation will cost `GFROUND * rounds`. From 15c33529d06ca3f6a6e7eecf2984073d4e1f2176 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Thu, 20 Jun 2019 15:37:53 -0400 Subject: [PATCH 07/39] Add @pdyraga to the EIP authors. --- EIPS/eip-draft-blake2b-f-precompile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-draft-blake2b-f-precompile.md index f23a16bbf788cf..08f559da80fb14 100644 --- a/EIPS/eip-draft-blake2b-f-precompile.md +++ b/EIPS/eip-draft-blake2b-f-precompile.md @@ -1,7 +1,7 @@ --- eip: title: Add Blake2 compression function `F` precompile -author: Tjaden Hess , Matt Luongo (@mhluongo) +author: Tjaden Hess , Matt Luongo (@mhluongo), Piotr Dyraga (@pdyraga) discussions-to: https://ethereum-magicians.org/t/blake2b-f-precompile/3157 status: Draft type: Standards Track From 552e602db6c8c5c98457d0d4594226bdc6a68256 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Thu, 20 Jun 2019 15:42:46 -0400 Subject: [PATCH 08/39] Remove less relevant EIP rationale Let's not relitigate precompiles, WASM, etc in thie EIP :) --- EIPS/eip-draft-blake2b-f-precompile.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-draft-blake2b-f-precompile.md index 08f559da80fb14..afef34c684da7f 100644 --- a/EIPS/eip-draft-blake2b-f-precompile.md +++ b/EIPS/eip-draft-blake2b-f-precompile.md @@ -113,9 +113,7 @@ Each operation will cost `GFROUND * rounds`. ## Rationale -The most frequent concern with EIPs of this type is that the addition of specific functions at the protocol level is an infringement on Ethereum's "featureless" design. It is true that a more elegant solution to the issue is to simply improve the scalability characteristics of the network so as to make calculating functions requiring millions of gas practical for everyday use. In the meantime, however, I believe that certain operations are worth subsidising via precompiled contracts and there is significant precedent for this, most notably the inclusion of the SHA256 prcompiled contract, which is included largely to allow inter-operation with the Bitcoin blockchain. - -Additionally, BLAKE2b is an excellent candidate for precompilation because of the extremely asymetric efficiency which it exhibits. BLAKE2b is heavily optimized for modern 64-bit CPUs, specifically utilizing 24 and 63-bit rotations to allow parallelism through SIMD instructions and little-endian arithmetic. These characteristics provide exceptional speed on native CPUs: 3.08 cycles per byte, or 1 gibibyte per second on an Intel i5. +BLAKE2b is an excellent candidate for precompilation. It exhibits an extremely asymetric efficiency. BLAKE2b is heavily optimized for modern 64-bit CPUs, specifically utilizing 24 and 63-bit rotations to allow parallelism through SIMD instructions and little-endian arithmetic. These characteristics provide exceptional speed on native CPUs: 3.08 cycles per byte, or 1 gibibyte per second on an Intel i5. In contrast, the big-endian 32 byte semantics of the EVM are not conducive to efficient implementation of BLAKE2, and thus the gas cost associated with computing the hash on the EVM is disproportionate to the true cost of computing the function natively. From 5a293387b3db6733189af2413b59ca0eb997f28f Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Thu, 20 Jun 2019 15:44:35 -0400 Subject: [PATCH 09/39] Use 0x09 as the precompile address If a conflicting EIP is moving forward the EIP editor can assign a new address --- EIPS/eip-draft-blake2b-f-precompile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-draft-blake2b-f-precompile.md index afef34c684da7f..6070e793f71433 100644 --- a/EIPS/eip-draft-blake2b-f-precompile.md +++ b/EIPS/eip-draft-blake2b-f-precompile.md @@ -122,7 +122,7 @@ Implementation of only the core F compression function allows substantial flexib ## Backwards Compatibility -There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x0d` being empty. The likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value with negligible risk of collision. +There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x09` being empty. The likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value with negligible risk of collision. ## Test Cases From 5d203c4ae6ec24d6f7753971e6b3a35f116b609c Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Fri, 21 Jun 2019 08:20:14 -0400 Subject: [PATCH 10/39] Choosing an EIP number Contributing docs suggest EIPs be named `eip-draft-with-a-title` until an editor has been assigned, but discussing this work off-platform without a number is a problem. Assigning 152 as the issue number where the `F` precompile was originally raised (https://github.com/ethereum/EIPs/issues/152) --- EIPS/{eip-draft-blake2b-f-precompile.md => eip-152.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename EIPS/{eip-draft-blake2b-f-precompile.md => eip-152.md} (99%) diff --git a/EIPS/eip-draft-blake2b-f-precompile.md b/EIPS/eip-152.md similarity index 99% rename from EIPS/eip-draft-blake2b-f-precompile.md rename to EIPS/eip-152.md index 6070e793f71433..f19afaa99adeab 100644 --- a/EIPS/eip-draft-blake2b-f-precompile.md +++ b/EIPS/eip-152.md @@ -1,5 +1,5 @@ --- -eip: +eip: 152 title: Add Blake2 compression function `F` precompile author: Tjaden Hess , Matt Luongo (@mhluongo), Piotr Dyraga (@pdyraga) discussions-to: https://ethereum-magicians.org/t/blake2b-f-precompile/3157 From 6e7c49a91edc86ff4f2888b87dacb1812213629c Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Mon, 24 Jun 2019 07:04:04 -0400 Subject: [PATCH 11/39] Add a missing colon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks @axic 🙌 --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index f19afaa99adeab..b779828df0918e 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -6,7 +6,7 @@ discussions-to: https://ethereum-magicians.org/t/blake2b-f-precompile/3157 status: Draft type: Standards Track category: Core -created 2016-10-04 +created: 2016-10-04 requires: 2046 --- From ed06f26ccd6d8d830b9941d963ca65d8446b063b Mon Sep 17 00:00:00 2001 From: James Hancock Date: Sun, 23 Jun 2019 22:24:08 -0400 Subject: [PATCH 12/39] Spelling updates --- EIPS/eip-152.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index b779828df0918e..e2036090053147 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -113,7 +113,7 @@ Each operation will cost `GFROUND * rounds`. ## Rationale -BLAKE2b is an excellent candidate for precompilation. It exhibits an extremely asymetric efficiency. BLAKE2b is heavily optimized for modern 64-bit CPUs, specifically utilizing 24 and 63-bit rotations to allow parallelism through SIMD instructions and little-endian arithmetic. These characteristics provide exceptional speed on native CPUs: 3.08 cycles per byte, or 1 gibibyte per second on an Intel i5. +BLAKE2b is an excellent candidate for precompilation. It exhibits an extremely asymmetric efficiency. BLAKE2b is heavily optimized for modern 64-bit CPUs, specifically utilizing 24 and 63-bit rotations to allow parallelism through SIMD instructions and little-endian arithmetic. These characteristics provide exceptional speed on native CPUs: 3.08 cycles per byte, or 1 gibibyte per second on an Intel i5. In contrast, the big-endian 32 byte semantics of the EVM are not conducive to efficient implementation of BLAKE2, and thus the gas cost associated with computing the hash on the EVM is disproportionate to the true cost of computing the function natively. @@ -135,6 +135,13 @@ Test cases are in progress, and can be followed along in our [Golang Blake2 libr Implementations are in progress, and can be followed along in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f) as well as our fork of [go-ethereum](https://github.com/keep-network/go-ethereum). +## References + +For historic purposes discussion on this EIP also occurred in the following PRs. + + * [Original Issue](https://github.com/ethereum/EIPs/issues/152) + * [PR 2129](https://github.com/ethereum/EIPs/pull/2129) + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From f6dadde75c17e06c5e871247be94554a4b151f61 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Mon, 24 Jun 2019 07:17:04 -0400 Subject: [PATCH 13/39] Add @MadeOfTin to the authors list --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index e2036090053147..206dd7d95b9f99 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -1,7 +1,7 @@ --- eip: 152 title: Add Blake2 compression function `F` precompile -author: Tjaden Hess , Matt Luongo (@mhluongo), Piotr Dyraga (@pdyraga) +author: Tjaden Hess , Matt Luongo (@mhluongo), Piotr Dyraga (@pdyraga), James Hancock (@MadeOfTin) discussions-to: https://ethereum-magicians.org/t/blake2b-f-precompile/3157 status: Draft type: Standards Track From eb5486191c121564e76235993b0017b97551a306 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Mon, 24 Jun 2019 07:19:14 -0400 Subject: [PATCH 14/39] Prefer the original issue for discussion --- EIPS/eip-152.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 206dd7d95b9f99..d2e25ed25f7e38 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -2,7 +2,7 @@ eip: 152 title: Add Blake2 compression function `F` precompile author: Tjaden Hess , Matt Luongo (@mhluongo), Piotr Dyraga (@pdyraga), James Hancock (@MadeOfTin) -discussions-to: https://ethereum-magicians.org/t/blake2b-f-precompile/3157 +discussions-to: https://github.com/ethereum/EIPs/issues/152 status: Draft type: Standards Track category: Core @@ -137,9 +137,10 @@ Implementations are in progress, and can be followed along in our [Golang Blake2 ## References -For historic purposes discussion on this EIP also occurred in the following PRs. +For historic purposes discussion on this EIP also occurred in the following PRs and issues. * [Original Issue](https://github.com/ethereum/EIPs/issues/152) + * [Ethereum Magicians](https://ethereum-magicians.org/t/blake2b-f-precompile/3157) * [PR 2129](https://github.com/ethereum/EIPs/pull/2129) ## Copyright From 47ac2086229a168f0b41d9b52351bcda2a90ad3d Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Tue, 25 Jun 2019 09:00:08 -0400 Subject: [PATCH 15/39] Clarify the precompile's initial implementation --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index d2e25ed25f7e38..9ebf98baf203af 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -133,7 +133,7 @@ Test cases are in progress, and can be followed along in our [Golang Blake2 libr ## Implementation -Implementations are in progress, and can be followed along in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f) as well as our fork of [go-ethereum](https://github.com/keep-network/go-ethereum). +An initial implementation of the `F` function in Go, adapted from the standard library, can be found in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f). There's also an implementation of the precompile in our fork of [go-ethereum](https://github.com/keep-network/go-ethereum/pull/4). ## References From 29423a1d99b3bfd8f75c027d2616f7621f6f0331 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Tue, 25 Jun 2019 09:10:38 -0400 Subject: [PATCH 16/39] Make the precompile return value clear --- EIPS/eip-152.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 9ebf98baf203af..078b7ed2219c27 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -57,6 +57,10 @@ Loosely packing the data in equal 32-byte slots means an easier job for app deve [ 31 bytes padding | 1 byte for f ][ 28 bytes padding | 4 bytes for rounds] ``` +The precompile should compute the `F` function as [specified in the RFC](https://github.com/keep-network/go-ethereum/pull/4) and return the updated state vector `h`. + +### Example Usage in Solidity + The precompile can be wrapped easily in Solidity to provide a more development-friendly interface to `F`. ```solidity From 2f9384fc446710256b950aa7e94e5c682b99bfed Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Tue, 25 Jun 2019 13:15:18 -0400 Subject: [PATCH 17/39] Clean up references wording --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 078b7ed2219c27..1561075beec02b 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -141,7 +141,7 @@ An initial implementation of the `F` function in Go, adapted from the standard l ## References -For historic purposes discussion on this EIP also occurred in the following PRs and issues. +For referemce, further discussion on this EIP also occurred in the following PRs and issues * [Original Issue](https://github.com/ethereum/EIPs/issues/152) * [Ethereum Magicians](https://ethereum-magicians.org/t/blake2b-f-precompile/3157) From 7621447fe2cf49c7524df20e79cb443798b61904 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Tue, 25 Jun 2019 13:26:39 -0400 Subject: [PATCH 18/39] More rationale around this BLAKE2b approach --- EIPS/eip-152.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 1561075beec02b..bd3fca57fb0bfc 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -121,7 +121,23 @@ BLAKE2b is an excellent candidate for precompilation. It exhibits an extremely a In contrast, the big-endian 32 byte semantics of the EVM are not conducive to efficient implementation of BLAKE2, and thus the gas cost associated with computing the hash on the EVM is disproportionate to the true cost of computing the function natively. -Implementation of only the core F compression function allows substantial flexibility and extensibility while keeping changes at the protocol level to a minimum. This will allow functions like tree hashing, incremental hashing, and keyed, salted, and personalized hashing as well as variable length digests, none of which are currently available on the EVM. +An obvious implementation would be a direct BLAKE2b precompile. At first glance, a BLAKE2b precompile satifies most hashing and interoperability requirements on the EVM. Once we started digging in, however, it became clear that any BLAKE2b implementation would need specific features and internal modifications based on different projects' requirements and libraries. + +A [thread with the Zcash team](https://github.com/ethereum/EIPs/issues/152#issuecomment-499240310) makes the issue clear. + +> The minimal thing that is necessary for a working ZEC-ETH relay is an implementation of BLAKE2b Compression F in a precompile. + +> A BLAKE2b Compression Function F precompile would also suffice for the Filecoin and Handshake interop goals. + +> A full BLAKE2b precompile would suffice for a ZEC-ETH relay, provided that the implementation provided the parts of the BLAKE2 API that we need (personalization, maybe something else—I'm not sure). + +> I'm not 100% certain if a full BLAKE2b precompile would also suffice for the Filecoin and Handshake goals. It almost certainly could, provided that it supports all the API that they need. + +> BLAKE2s — whether the Compression Function F or the full hash — is only a nice-to-have for the purposes of a ZEC-ETH relay. + +From this and other conversations with teams in the space, we believe we should focus first on the `F` precompile as a strictly necessary piece for interoperability projects. A BLAKE2b precompile is a nice-to-have, and we support any efforts to add one-- but it's unclear whether complete requirements and a flexible API can be found in time for Istanbul. + +Implementation of only the core F compression function also allows substantial flexibility and extensibility while keeping changes at the protocol level to a minimum. This will allow functions like tree hashing, incremental hashing, and keyed, salted, and personalized hashing as well as variable length digests, none of which are currently available on the EVM. ## Backwards Compatibility From 94ebe0cc7cd4ada79a4ef4f5a44b5063c7476913 Mon Sep 17 00:00:00 2001 From: Matt Luongo Date: Wed, 26 Jun 2019 14:57:46 -0400 Subject: [PATCH 19/39] Fix a couple misspellings --- EIPS/eip-152.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index bd3fca57fb0bfc..ff591fee7e46e1 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -121,7 +121,7 @@ BLAKE2b is an excellent candidate for precompilation. It exhibits an extremely a In contrast, the big-endian 32 byte semantics of the EVM are not conducive to efficient implementation of BLAKE2, and thus the gas cost associated with computing the hash on the EVM is disproportionate to the true cost of computing the function natively. -An obvious implementation would be a direct BLAKE2b precompile. At first glance, a BLAKE2b precompile satifies most hashing and interoperability requirements on the EVM. Once we started digging in, however, it became clear that any BLAKE2b implementation would need specific features and internal modifications based on different projects' requirements and libraries. +An obvious implementation would be a direct BLAKE2b precompile. At first glance, a BLAKE2b precompile satisfies most hashing and interoperability requirements on the EVM. Once we started digging in, however, it became clear that any BLAKE2b implementation would need specific features and internal modifications based on different projects' requirements and libraries. A [thread with the Zcash team](https://github.com/ethereum/EIPs/issues/152#issuecomment-499240310) makes the issue clear. @@ -157,7 +157,7 @@ An initial implementation of the `F` function in Go, adapted from the standard l ## References -For referemce, further discussion on this EIP also occurred in the following PRs and issues +For reference, further discussion on this EIP also occurred in the following PRs and issues * [Original Issue](https://github.com/ethereum/EIPs/issues/152) * [Ethereum Magicians](https://ethereum-magicians.org/t/blake2b-f-precompile/3157) From 787c2a0ea0bd2b405847b6452464037050407cc3 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Thu, 27 Jun 2019 14:20:49 +0200 Subject: [PATCH 20/39] Updated the interface for F precompile - F precompile accepts now `abi.encodePacked` parameters taking exactly 213 bytes. This is safer and does not require left-padding data - `rounds` parameter is now the first one as the gas cost depends only on this parameter --- EIPS/eip-152.md | 90 ++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 54 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index ff591fee7e46e1..2acb5b6b0a83c1 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -34,27 +34,18 @@ Interoperability with Zcash could enable contracts like trustless atomic swaps b ## Specification -We propose adding a precompiled contract at address `0x09` wrapping the [BLAkE2b `F` compression function](https://tools.ietf.org/html/rfc7693#section-3.2). Rather than the ABI-encoded call structure proposed in [#152](https://github.com/ethereum/EIPs/issues/152), this design better matches other precompiles and works well with a standard `staticcall`. +We propose adding a precompiled contract at address `0x09` wrapping the [BLAkE2b `F` compression function](https://tools.ietf.org/html/rfc7693#section-3.2). -The precompile requires 6 inputs, corresponding to the inputs specified in the [BLAKE2b RFC](https://tools.ietf.org/html/rfc7693#section-3.2) +The precompile requires 6 inputs encoded with `abi.encodePacked` and taking exactly 213 bytes. The encoded inputs are corresponding to the ones specified in the [BLAKE2b RFC](https://tools.ietf.org/html/rfc7693#section-3.2) +- `rounds` - the number of rounds - `h` - the state vector - `m` - the message block vector - `t_0, t_1` - offset counters - `f` - the final block indicator flag -- `rounds` - the number of rounds - -Loosely packing the data in equal 32-byte slots means an easier job for app developers, and also appears to be compatible with how other precompiles accept input data. ``` -[ bytes32[0] | bytes32[1] ][ bytes32[2] | bytes32[3] | bytes32[4] | bytes32[5] ] -[ 64 bytes for h ][ 128 bytes for m ] - -[ bytes32[6] ][ bytes32[7] ] -[ 24 bytes padding | 8 bytes for t_0 ][ 24 bytes padding | 8 bytes for t_1 ] - -[ bytes32[8] ][ bytes32[9] ] -[ 31 bytes padding | 1 byte for f ][ 28 bytes padding | 4 bytes for rounds] +[4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] ``` The precompile should compute the `F` function as [specified in the RFC](https://github.com/keep-network/go-ethereum/pull/4) and return the updated state vector `h`. @@ -64,50 +55,41 @@ The precompile should compute the `F` function as [specified in the RFC](https:/ The precompile can be wrapped easily in Solidity to provide a more development-friendly interface to `F`. ```solidity - function F(bytes32[2] memory h, bytes32[4] memory m, uint64[2] memory t, bool f, uint32 rounds) public view returns (bytes32[2] memory) { - bytes32[2] memory output; +function F(uint32 rounds, bytes32[2] memory h, bytes32[4] memory m, uint64[2] memory t, bool f) public view returns (bytes32[2] memory) { + bytes32[2] memory output; - bytes32 _t0 = bytes32(uint256(t[0])); - bytes32 _t1 = bytes32(uint256(t[1])); + bytes memory args = abi.encodePacked(rounds, h[0], h[1], m[0], m[1], m[2], m[3], t[0], t[1], f); - bytes32 _f; - if (f) { - _f = hex"0000000000000000000000000000000000000000000000000000000000000001"; + assembly { + if iszero(staticcall(not(0), 0x09, add(args, 32), 0xd5, output, 0x40)) { + revert(0, 0) } - - bytes32 _rounds = bytes32(uint256(rounds)); - - bytes32[10] memory args = [ h[0], h[1], m[0], m[1], m[2], m[3], _t0, _t1, _f, _rounds ]; - - assembly { - if iszero(staticcall(not(0), 0x09, args, 0x140, output, 0x40)) { - revert(0, 0) - } - } - return output; - } - - function callF() public view returns (bytes32[2] memory) { - bytes32[2] memory h; - h[0] = hex"6a09e627f3bcc909bb67ae8484caa73b3c6ef372fe94b82ba54ff53a5f1d36f1"; - h[1] = hex"510e527fade682d19b05688c2b3e6c1f1f83d9abfb41bd6b5be0cd19137e2179"; - - bytes32[4] memory m; - m[0] = hex"278400340e6b05c5752592c52c4f121292eafc51cc01a997b4aed13409298fad"; - m[1] = hex"0d99ccc8f76453d9b3661e5c4d325d7751147db17489046d1682d50eefa4a1da"; - m[2] = hex"0000000000000000000000000000000000000000000000000000000000000000"; - m[3] = hex"0000000000000000000000000000000000000000000000000000000000000000"; - - uint64[2] memory t; - t[0] = 18446744073709551552; - t[1] = 18446744073709551615; - - bool f = true; - - uint32 rounds = 12; - - return F(h, m, t, f, rounds); - } + } + + return output; +} + +function callF() public view returns (bytes32[2] memory) { + bytes32[2] memory h; + h[0] = hex"6a09e627f3bcc909bb67ae8484caa73b3c6ef372fe94b82ba54ff53a5f1d36f2"; + h[1] = hex"510e527fade682d19b05688c2b3e6c1f1f83d9abfb41bd6b5be0cd19137e2179"; + + bytes32[4] memory m; + m[0] = hex"278400340e6b05c5752592c52c4f121292eafc51cc01a997b4aed13409298fad"; + m[1] = hex"0d99ccc8f76453d9b3661e5c4d325d7751147db17489046d1682d50eefa4a1da"; + m[2] = hex"0000000000000000000000000000000000000000000000000000000000000000"; + m[3] = hex"0000000000000000000000000000000000000000000000000000000000000000"; + + uint64[2] memory t; + t[0] = 18446744073709551552; // ffffffffffffffc0 + t[1] = 18446744073709551615; // ffffffffffffffff + + bool f = true; + + uint32 rounds = 12; + + return F(rounds, h, m, t, f); +} ``` ### Gas costs and benchmarks From 9c09e88006674e06a92463a39d3fc661ed5c0184 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Thu, 27 Jun 2019 15:11:28 +0200 Subject: [PATCH 21/39] Updated gas cost section proposing GFROUND=1 --- EIPS/eip-152.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 2acb5b6b0a83c1..41f34daffbabd4 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -94,10 +94,63 @@ function callF() public view returns (bytes32[2] memory) { ### Gas costs and benchmarks -Each operation will cost `GFROUND * rounds`. +Each operation will cost `GFROUND * rounds` gas, where `GFROUND = 1`. + +Assuming `ecrecover` precompile is perfectly priced, we executed a set of benchmarks comparing Blake2b F compression function precompile with `ecrecover` precompile. For benchmarks, we used 3,1 GHz Intel Core i7 64-bit machine. + +- `ecrecover` took `180.3` microseconds on average to execute. With the fixed gas price of `3000` for `ecrecover`, it is about `16.64` gas per microsecond of `ecrecover` work. + +``` +BenchmarkPrecompiledEcrecover/-Gas=3000-8 10000 180309 ns/op +``` + +- 12 rounds of `F` took `0.3686` microseconds on average, so the entire invocation with `12` rounds should cost `0.3686 * 16.64 = 6.133` gas, what gives `0.5111` gas per round. + +``` +BenchmarkPrecompiledBlake2F/testVectors2bX_0-Gas=12-8 3000000 352 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_3-Gas=12-8 5000000 342 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_70-Gas=12-8 5000000 328 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_140-Gas=12-8 5000000 329 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_230-Gas=12-8 5000000 332 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_300-Gas=12-8 5000000 335 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_370-Gas=12-8 3000000 424 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_440-Gas=12-8 3000000 413 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_510-Gas=12-8 3000000 417 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_580-Gas=12-8 3000000 414 ns/op +``` + +- Setting `1200` rounds instead of `12` brings down the gas cost even more. `1200` rounds of `F` took `25.66` microseconds on average, so the entire invocation with `1200` rounds should cost `25.66 * 16.64 = 426,98` gas, what gives `0.356` gas per round. +``` +BenchmarkPrecompiledBlake2F/testVectors2bX_0-Gas=1200-8 50000 25906 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_3-Gas=1200-8 50000 25427 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_70-Gas=1200-8 50000 26047 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_140-Gas=1200-8 50000 25386 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_230-Gas=1200-8 50000 25170 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_300-Gas=1200-8 50000 25957 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_370-Gas=1200-8 50000 26222 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_440-Gas=1200-8 50000 25337 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_510-Gas=1200-8 50000 25530 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_580-Gas=1200-8 50000 25623 ns/op +``` + +- For the case of `1` round, an average invocation time takes `0.1569` microsecond, so one round should cost `0.1569 * 16.64 = 2.610 gas`. However, in this scenario the call cost would totally overshadow the dynamic cost anyway. + +``` +BenchmarkPrecompiledBlake2F/testVectors2bX_0-Gas=1-8 10000000 159 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_3-Gas=1-8 10000000 162 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_70-Gas=1-8 10000000 155 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_140-Gas=1-8 10000000 161 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_230-Gas=1-8 10000000 161 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_300-Gas=1-8 10000000 154 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_370-Gas=1-8 10000000 155 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_440-Gas=1-8 10000000 155 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_510-Gas=1-8 10000000 149 ns/op +BenchmarkPrecompiledBlake2F/testVectors2bX_580-Gas=1-8 10000000 158 ns/op +``` + ## Rationale - + BLAKE2b is an excellent candidate for precompilation. It exhibits an extremely asymmetric efficiency. BLAKE2b is heavily optimized for modern 64-bit CPUs, specifically utilizing 24 and 63-bit rotations to allow parallelism through SIMD instructions and little-endian arithmetic. These characteristics provide exceptional speed on native CPUs: 3.08 cycles per byte, or 1 gibibyte per second on an Intel i5. From 9d354f320eb82bafcecd0895043d937cebc925e1 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Fri, 28 Jun 2019 12:06:54 +0200 Subject: [PATCH 22/39] Detailed benchmarks moved to appendix section --- EIPS/eip-152.md | 103 ++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 41f34daffbabd4..97f4f4281130bd 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -94,7 +94,58 @@ function callF() public view returns (bytes32[2] memory) { ### Gas costs and benchmarks -Each operation will cost `GFROUND * rounds` gas, where `GFROUND = 1`. +Each operation will cost `GFROUND * rounds` gas, where `GFROUND = 1`. Detailed benchmarks are presented in the benchmarks appendix section. + +## Rationale + + +BLAKE2b is an excellent candidate for precompilation. It exhibits an extremely asymmetric efficiency. BLAKE2b is heavily optimized for modern 64-bit CPUs, specifically utilizing 24 and 63-bit rotations to allow parallelism through SIMD instructions and little-endian arithmetic. These characteristics provide exceptional speed on native CPUs: 3.08 cycles per byte, or 1 gibibyte per second on an Intel i5. + +In contrast, the big-endian 32 byte semantics of the EVM are not conducive to efficient implementation of BLAKE2, and thus the gas cost associated with computing the hash on the EVM is disproportionate to the true cost of computing the function natively. + +An obvious implementation would be a direct BLAKE2b precompile. At first glance, a BLAKE2b precompile satisfies most hashing and interoperability requirements on the EVM. Once we started digging in, however, it became clear that any BLAKE2b implementation would need specific features and internal modifications based on different projects' requirements and libraries. + +A [thread with the Zcash team](https://github.com/ethereum/EIPs/issues/152#issuecomment-499240310) makes the issue clear. + +> The minimal thing that is necessary for a working ZEC-ETH relay is an implementation of BLAKE2b Compression F in a precompile. + +> A BLAKE2b Compression Function F precompile would also suffice for the Filecoin and Handshake interop goals. + +> A full BLAKE2b precompile would suffice for a ZEC-ETH relay, provided that the implementation provided the parts of the BLAKE2 API that we need (personalization, maybe something else—I'm not sure). + +> I'm not 100% certain if a full BLAKE2b precompile would also suffice for the Filecoin and Handshake goals. It almost certainly could, provided that it supports all the API that they need. + +> BLAKE2s — whether the Compression Function F or the full hash — is only a nice-to-have for the purposes of a ZEC-ETH relay. + +From this and other conversations with teams in the space, we believe we should focus first on the `F` precompile as a strictly necessary piece for interoperability projects. A BLAKE2b precompile is a nice-to-have, and we support any efforts to add one-- but it's unclear whether complete requirements and a flexible API can be found in time for Istanbul. + +Implementation of only the core F compression function also allows substantial flexibility and extensibility while keeping changes at the protocol level to a minimum. This will allow functions like tree hashing, incremental hashing, and keyed, salted, and personalized hashing as well as variable length digests, none of which are currently available on the EVM. + +## Backwards Compatibility + + +There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x09` being empty. The likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value with negligible risk of collision. + +## Test Cases + + + +Test cases are in progress, and can be followed along in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f) as well as our fork of [go-ethereum](https://github.com/keep-network/go-ethereum). + +## Implementation + + +An initial implementation of the `F` function in Go, adapted from the standard library, can be found in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f). There's also an implementation of the precompile in our fork of [go-ethereum](https://github.com/keep-network/go-ethereum/pull/4). + +## References + +For reference, further discussion on this EIP also occurred in the following PRs and issues + + * [Original Issue](https://github.com/ethereum/EIPs/issues/152) + * [Ethereum Magicians](https://ethereum-magicians.org/t/blake2b-f-precompile/3157) + * [PR 2129](https://github.com/ethereum/EIPs/pull/2129) + +## Appendix - benchmarks Assuming `ecrecover` precompile is perfectly priced, we executed a set of benchmarks comparing Blake2b F compression function precompile with `ecrecover` precompile. For benchmarks, we used 3,1 GHz Intel Core i7 64-bit machine. @@ -148,56 +199,6 @@ BenchmarkPrecompiledBlake2F/testVectors2bX_510-Gas=1-8 10000000 BenchmarkPrecompiledBlake2F/testVectors2bX_580-Gas=1-8 10000000 158 ns/op ``` - -## Rationale - - -BLAKE2b is an excellent candidate for precompilation. It exhibits an extremely asymmetric efficiency. BLAKE2b is heavily optimized for modern 64-bit CPUs, specifically utilizing 24 and 63-bit rotations to allow parallelism through SIMD instructions and little-endian arithmetic. These characteristics provide exceptional speed on native CPUs: 3.08 cycles per byte, or 1 gibibyte per second on an Intel i5. - -In contrast, the big-endian 32 byte semantics of the EVM are not conducive to efficient implementation of BLAKE2, and thus the gas cost associated with computing the hash on the EVM is disproportionate to the true cost of computing the function natively. - -An obvious implementation would be a direct BLAKE2b precompile. At first glance, a BLAKE2b precompile satisfies most hashing and interoperability requirements on the EVM. Once we started digging in, however, it became clear that any BLAKE2b implementation would need specific features and internal modifications based on different projects' requirements and libraries. - -A [thread with the Zcash team](https://github.com/ethereum/EIPs/issues/152#issuecomment-499240310) makes the issue clear. - -> The minimal thing that is necessary for a working ZEC-ETH relay is an implementation of BLAKE2b Compression F in a precompile. - -> A BLAKE2b Compression Function F precompile would also suffice for the Filecoin and Handshake interop goals. - -> A full BLAKE2b precompile would suffice for a ZEC-ETH relay, provided that the implementation provided the parts of the BLAKE2 API that we need (personalization, maybe something else—I'm not sure). - -> I'm not 100% certain if a full BLAKE2b precompile would also suffice for the Filecoin and Handshake goals. It almost certainly could, provided that it supports all the API that they need. - -> BLAKE2s — whether the Compression Function F or the full hash — is only a nice-to-have for the purposes of a ZEC-ETH relay. - -From this and other conversations with teams in the space, we believe we should focus first on the `F` precompile as a strictly necessary piece for interoperability projects. A BLAKE2b precompile is a nice-to-have, and we support any efforts to add one-- but it's unclear whether complete requirements and a flexible API can be found in time for Istanbul. - -Implementation of only the core F compression function also allows substantial flexibility and extensibility while keeping changes at the protocol level to a minimum. This will allow functions like tree hashing, incremental hashing, and keyed, salted, and personalized hashing as well as variable length digests, none of which are currently available on the EVM. - -## Backwards Compatibility - - -There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x09` being empty. The likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value with negligible risk of collision. - -## Test Cases - - - -Test cases are in progress, and can be followed along in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f) as well as our fork of [go-ethereum](https://github.com/keep-network/go-ethereum). - -## Implementation - - -An initial implementation of the `F` function in Go, adapted from the standard library, can be found in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f). There's also an implementation of the precompile in our fork of [go-ethereum](https://github.com/keep-network/go-ethereum/pull/4). - -## References - -For reference, further discussion on this EIP also occurred in the following PRs and issues - - * [Original Issue](https://github.com/ethereum/EIPs/issues/152) - * [Ethereum Magicians](https://ethereum-magicians.org/t/blake2b-f-precompile/3157) - * [PR 2129](https://github.com/ethereum/EIPs/pull/2129) - ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 7cd9f95f90a206e87be80906b4f824fee0f38efe Mon Sep 17 00:00:00 2001 From: pdyraga Date: Fri, 28 Jun 2019 12:24:06 +0200 Subject: [PATCH 23/39] Benchmark stats are compared against ecRecover as a baseline --- EIPS/eip-152.md | 96 ++++++++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 97f4f4281130bd..d61a36c8c8ed8d 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -147,58 +147,80 @@ For reference, further discussion on this EIP also occurred in the following PRs ## Appendix - benchmarks -Assuming `ecrecover` precompile is perfectly priced, we executed a set of benchmarks comparing Blake2b F compression function precompile with `ecrecover` precompile. For benchmarks, we used 3,1 GHz Intel Core i7 64-bit machine. - -- `ecrecover` took `180.3` microseconds on average to execute. With the fixed gas price of `3000` for `ecrecover`, it is about `16.64` gas per microsecond of `ecrecover` work. +Assuming ecRecover precompile is perfectly priced, we executed a set of benchmarks comparing Blake2b F compression function precompile with ecRecover precompile. For benchmarks, we used 3.1 GHz Intel Core i7 64-bit machine. ``` -BenchmarkPrecompiledEcrecover/-Gas=3000-8 10000 180309 ns/op +$ sysctl -n machdep.cpu.brand_string +Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz ``` -- 12 rounds of `F` took `0.3686` microseconds on average, so the entire invocation with `12` rounds should cost `0.3686 * 16.64 = 6.133` gas, what gives `0.5111` gas per round. +### 12 rounds + +An average gas price of F precompile call with 12 rounds compared to ecRecover should have been `6.74153` and it gives `0.5618` gas per round. ``` -BenchmarkPrecompiledBlake2F/testVectors2bX_0-Gas=12-8 3000000 352 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_3-Gas=12-8 5000000 342 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_70-Gas=12-8 5000000 328 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_140-Gas=12-8 5000000 329 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_230-Gas=12-8 5000000 332 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_300-Gas=12-8 5000000 335 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_370-Gas=12-8 3000000 424 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_440-Gas=12-8 3000000 413 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_510-Gas=12-8 3000000 417 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_580-Gas=12-8 3000000 414 ns/op +Name Gascost Time (ns) MGas/S Gasprice for 10MGas/S Gasprice for ECDSA eq +----------------------------------------- --------- ---------------- --------- ----------------------- ----------------------- +PrecompiledEcrecover/ 3000 152636 19.6546 1526.36 3000 +PrecompiledBlake2F/testVectors2bX_0 12 338 35.503 3.38 6.64326 +PrecompiledBlake2F/testVectors2bX_3 12 336 35.7143 3.36 6.60395 +PrecompiledBlake2F/testVectors2bX_70 12 362 33.1492 3.62 7.11497 +PrecompiledBlake2F/testVectors2bX_140 12 339 35.3982 3.39 6.66291 +PrecompiledBlake2F/testVectors2bX_230 12 339 35.3982 3.39 6.66291 +PrecompiledBlake2F/testVectors2bX_300 12 343 34.9854 3.43 6.74153 +PrecompiledBlake2F/testVectors2bX_370 12 336 35.7143 3.36 6.60395 +PrecompiledBlake2F/testVectors2bX_440 12 337 35.6083 3.37 6.6236 +PrecompiledBlake2F/testVectors2bX_510 12 345 34.7826 3.45 6.78084 +PrecompiledBlake2F/testVectors2bX_580 12 355 33.8028 3.55 6.97738 ``` -- Setting `1200` rounds instead of `12` brings down the gas cost even more. `1200` rounds of `F` took `25.66` microseconds on average, so the entire invocation with `1200` rounds should cost `25.66 * 16.64 = 426,98` gas, what gives `0.356` gas per round. +Columns + +* `MGas/S` - Shows what MGas per second was measured on that machine at that time +* `Gasprice for 10MGas/S` shows what the gasprice should have been, in order to reach 10 MGas/second +* `Gasprice for ECDSA eq` shows what the gasprice should have been, in order to have the same cost/cycle as ecRecover + +### 1200 rounds + +An average gas price of F precompile call with 1200 rounds compared to ecRecover should have been `436.1288` and it gives `0.3634` gas per round. + ``` -BenchmarkPrecompiledBlake2F/testVectors2bX_0-Gas=1200-8 50000 25906 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_3-Gas=1200-8 50000 25427 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_70-Gas=1200-8 50000 26047 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_140-Gas=1200-8 50000 25386 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_230-Gas=1200-8 50000 25170 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_300-Gas=1200-8 50000 25957 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_370-Gas=1200-8 50000 26222 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_440-Gas=1200-8 50000 25337 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_510-Gas=1200-8 50000 25530 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_580-Gas=1200-8 50000 25623 ns/op +Name Gascost Time (ns) MGas/S Gasprice for 10MGas/S Gasprice for ECDSA eq +----------------------------------------- --------- ---------------- --------- ----------------------- ----------------------- +PrecompiledEcrecover/ 3000 156152 19.212 1561.52 3000 +PrecompiledBlake2F/testVectors2bX_0 1200 22642 52.9989 226.42 434.999 +PrecompiledBlake2F/testVectors2bX_3 1200 22885 52.4361 228.85 439.668 +PrecompiledBlake2F/testVectors2bX_70 1200 22737 52.7774 227.37 436.824 +PrecompiledBlake2F/testVectors2bX_140 1200 22602 53.0926 226.02 434.231 +PrecompiledBlake2F/testVectors2bX_230 1200 22501 53.331 225.01 432.29 +PrecompiledBlake2F/testVectors2bX_300 1200 22435 53.4879 224.35 431.022 +PrecompiledBlake2F/testVectors2bX_370 1200 22901 52.3995 229.01 439.975 +PrecompiledBlake2F/testVectors2bX_440 1200 23134 51.8717 231.34 444.452 +PrecompiledBlake2F/testVectors2bX_510 1200 22608 53.0786 226.08 434.346 +PrecompiledBlake2F/testVectors2bX_580 1200 22563 53.1844 225.63 433.481 ``` -- For the case of `1` round, an average invocation time takes `0.1569` microsecond, so one round should cost `0.1569 * 16.64 = 2.610 gas`. However, in this scenario the call cost would totally overshadow the dynamic cost anyway. +### 1 round + +An average gas price of F precompile call with 1 round compared to ecRecover should have been `2.431701`. However, in this scenario the call cost would totally overshadow the dynamic cost anyway. ``` -BenchmarkPrecompiledBlake2F/testVectors2bX_0-Gas=1-8 10000000 159 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_3-Gas=1-8 10000000 162 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_70-Gas=1-8 10000000 155 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_140-Gas=1-8 10000000 161 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_230-Gas=1-8 10000000 161 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_300-Gas=1-8 10000000 154 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_370-Gas=1-8 10000000 155 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_440-Gas=1-8 10000000 155 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_510-Gas=1-8 10000000 149 ns/op -BenchmarkPrecompiledBlake2F/testVectors2bX_580-Gas=1-8 10000000 158 ns/op +Name Gascost Time (ns) MGas/S Gasprice for 10MGas/S Gasprice for ECDSA eq +----------------------------------------- --------- ---------------- ---------- ----------------------- ----------------------- +PrecompiledEcrecover/ 3000 157544 19.0423 1575.44 3000 +PrecompiledBlake2F/testVectors2bX_0 1 126 7.93651 1.26 2.39933 +PrecompiledBlake2F/testVectors2bX_3 1 127 7.87402 1.27 2.41837 +PrecompiledBlake2F/testVectors2bX_70 1 128 7.8125 1.28 2.43741 +PrecompiledBlake2F/testVectors2bX_140 1 125 8 1.25 2.38029 +PrecompiledBlake2F/testVectors2bX_230 1 128 7.8125 1.28 2.43741 +PrecompiledBlake2F/testVectors2bX_300 1 127 7.87402 1.27 2.41837 +PrecompiledBlake2F/testVectors2bX_370 1 131 7.63359 1.31 2.49454 +PrecompiledBlake2F/testVectors2bX_440 1 129 7.75194 1.29 2.45646 +PrecompiledBlake2F/testVectors2bX_510 1 125 8 1.25 2.38029 +PrecompiledBlake2F/testVectors2bX_580 1 131 7.63359 1.31 2.49454 ``` + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 73380484741f40ac6f93ebeedd91ab923febe9e3 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Fri, 28 Jun 2019 12:42:20 +0200 Subject: [PATCH 24/39] Clarification: f parameter is true if it is nonzero This rule is compatible with Solidity for boolean. --- EIPS/eip-152.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index d61a36c8c8ed8d..767a5f76d81bf5 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -48,6 +48,12 @@ The precompile requires 6 inputs encoded with `abi.encodePacked` and taking exac [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] ``` +`f` parameter is considered as `true` if it is `nonzero`. For example: +- `00000000` is `false` +- `00000001` is `true` +- `10000000` is `true` +- `11111111` is `true` + The precompile should compute the `F` function as [specified in the RFC](https://github.com/keep-network/go-ethereum/pull/4) and return the updated state vector `h`. ### Example Usage in Solidity From 534e4b37da74811ef6e9528fa625eba9e3863bd9 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Thu, 4 Jul 2019 15:46:34 +0200 Subject: [PATCH 25/39] Avoid referring to abi.encodePacked The specification should not be Solidity-specific. Instead of referring to abi.encodePacked we now just say "tightly encoded". --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 767a5f76d81bf5..79e00043135023 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -36,7 +36,7 @@ Interoperability with Zcash could enable contracts like trustless atomic swaps b We propose adding a precompiled contract at address `0x09` wrapping the [BLAkE2b `F` compression function](https://tools.ietf.org/html/rfc7693#section-3.2). -The precompile requires 6 inputs encoded with `abi.encodePacked` and taking exactly 213 bytes. The encoded inputs are corresponding to the ones specified in the [BLAKE2b RFC](https://tools.ietf.org/html/rfc7693#section-3.2) +The precompile requires 6 inputs tightly encoded, taking exactly 213 bytes, as explained below. The encoded inputs are corresponding to the ones specified in the [BLAKE2b RFC Section 3.2](https://tools.ietf.org/html/rfc7693#section-3.2): - `rounds` - the number of rounds - `h` - the state vector From ea28226a2fab3f77774fbfa3550f7fe145b455c9 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Thu, 4 Jul 2019 15:50:49 +0200 Subject: [PATCH 26/39] Fixed incorrect link "specified in the RFC" linked to the geth PR for F precompile instead of linking to the BLAKE2b RFC. --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 79e00043135023..f4c0954d5eaedc 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -54,7 +54,7 @@ The precompile requires 6 inputs tightly encoded, taking exactly 213 bytes, as e - `10000000` is `true` - `11111111` is `true` -The precompile should compute the `F` function as [specified in the RFC](https://github.com/keep-network/go-ethereum/pull/4) and return the updated state vector `h`. +The precompile should compute the `F` function as [specified in the RFC](https://tools.ietf.org/html/rfc7693#section-3.2) and return the updated state vector `h`. ### Example Usage in Solidity From 2e33d58fefb08d7c31e5fdb26e7c5722debc9d88 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Thu, 4 Jul 2019 15:56:53 +0200 Subject: [PATCH 27/39] Shortened the description about when parameter f is considered as true --- EIPS/eip-152.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index f4c0954d5eaedc..ccc7c1cf80d2b5 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -48,11 +48,7 @@ The precompile requires 6 inputs tightly encoded, taking exactly 213 bytes, as e [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] ``` -`f` parameter is considered as `true` if it is `nonzero`. For example: -- `00000000` is `false` -- `00000001` is `true` -- `10000000` is `true` -- `11111111` is `true` +`f` parameter is considered as `true` if at least 1 bit out of the 8 bits is set. The precompile should compute the `F` function as [specified in the RFC](https://tools.ietf.org/html/rfc7693#section-3.2) and return the updated state vector `h`. From 701280cb73d97c98314dfb9468ae6bcb30e51b7f Mon Sep 17 00:00:00 2001 From: pdyraga Date: Thu, 4 Jul 2019 15:57:59 +0200 Subject: [PATCH 28/39] Minor grammar improvement --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index ccc7c1cf80d2b5..2694e870ce2de5 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -48,7 +48,7 @@ The precompile requires 6 inputs tightly encoded, taking exactly 213 bytes, as e [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] ``` -`f` parameter is considered as `true` if at least 1 bit out of the 8 bits is set. +The boolean `f` parameter is considered as `true` if at least 1 bit out of the 8 bits is set. The precompile should compute the `F` function as [specified in the RFC](https://tools.ietf.org/html/rfc7693#section-3.2) and return the updated state vector `h`. From 64830d141087edc089a8d18a3f4d375215221216 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Tue, 13 Aug 2019 14:55:35 +0200 Subject: [PATCH 29/39] Updated information about endianness of F precompile inputs BLAKE2b is consistently little-endian. abi.encodePacked encodes each of its arguments in big-endian order. We need to be clear which parameters should go as little-endian (h, m, t) and which parameters should go as big-endian (rounds, f). --- EIPS/eip-152.md | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 2694e870ce2de5..2ca923c39b767b 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -38,17 +38,17 @@ We propose adding a precompiled contract at address `0x09` wrapping the [BLAkE2b The precompile requires 6 inputs tightly encoded, taking exactly 213 bytes, as explained below. The encoded inputs are corresponding to the ones specified in the [BLAKE2b RFC Section 3.2](https://tools.ietf.org/html/rfc7693#section-3.2): -- `rounds` - the number of rounds -- `h` - the state vector -- `m` - the message block vector -- `t_0, t_1` - offset counters -- `f` - the final block indicator flag +- `rounds` - the number of rounds - 32-bit unsigned big-endian word +- `h` - the state vector - 8 unsigned 64-bit little-endian words +- `m` - the message block vector - 16 unsigned 64-bit little-endian words +- `t_0, t_1` - offset counters - 2 unsigned 64-bit little-endian words +- `f` - the final block indicator flag - 8-bit unsigned big-endian word ``` [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] ``` -The boolean `f` parameter is considered as `true` if at least 1 bit out of the 8 bits is set. +The boolean f parameter is considered as true if at least 1 bit out of the 8 bits is set. The precompile should compute the `F` function as [specified in the RFC](https://tools.ietf.org/html/rfc7693#section-3.2) and return the updated state vector `h`. @@ -57,39 +57,42 @@ The precompile should compute the `F` function as [specified in the RFC](https:/ The precompile can be wrapped easily in Solidity to provide a more development-friendly interface to `F`. ```solidity -function F(uint32 rounds, bytes32[2] memory h, bytes32[4] memory m, uint64[2] memory t, bool f) public view returns (bytes32[2] memory) { +function F(uint32 rounds, bytes32[2] memory h, bytes32[4] memory m, bytes8[2] memory t, bool f) public view returns (bytes32[2] memory) { bytes32[2] memory output; bytes memory args = abi.encodePacked(rounds, h[0], h[1], m[0], m[1], m[2], m[3], t[0], t[1], f); assembly { - if iszero(staticcall(not(0), 0x09, add(args, 32), 0xd5, output, 0x40)) { - revert(0, 0) - } + if iszero(staticcall(not(0), 0x09, add(args, 32), 0xd5, output, 0x40)) { + revert(0, 0) + } } return output; } function callF() public view returns (bytes32[2] memory) { + uint32 rounds = 12; + bytes32[2] memory h; - h[0] = hex"6a09e627f3bcc909bb67ae8484caa73b3c6ef372fe94b82ba54ff53a5f1d36f2"; - h[1] = hex"510e527fade682d19b05688c2b3e6c1f1f83d9abfb41bd6b5be0cd19137e2179"; + h[0] = hex"48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5"; + h[1] = hex"d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b"; bytes32[4] memory m; - m[0] = hex"278400340e6b05c5752592c52c4f121292eafc51cc01a997b4aed13409298fad"; - m[1] = hex"0d99ccc8f76453d9b3661e5c4d325d7751147db17489046d1682d50eefa4a1da"; + m[0] = hex"6162630000000000000000000000000000000000000000000000000000000000"; + m[1] = hex"0000000000000000000000000000000000000000000000000000000000000000"; m[2] = hex"0000000000000000000000000000000000000000000000000000000000000000"; m[3] = hex"0000000000000000000000000000000000000000000000000000000000000000"; - uint64[2] memory t; - t[0] = 18446744073709551552; // ffffffffffffffc0 - t[1] = 18446744073709551615; // ffffffffffffffff + bytes8[2] memory t; + t[0] = hex"03000000"; + t[1] = hex"00000000"; bool f = true; - uint32 rounds = 12; - + // Expected output: + // ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1 + // 7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923 return F(rounds, h, m, t, f); } ``` From dcf86f6a60cc19a1352316906a8a83cace2adcc4 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Tue, 13 Aug 2019 14:57:06 +0200 Subject: [PATCH 30/39] Strict validation of f parameter --- EIPS/eip-152.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 2ca923c39b767b..b6df75838f8f6f 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -48,7 +48,9 @@ The precompile requires 6 inputs tightly encoded, taking exactly 213 bytes, as e [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] ``` -The boolean f parameter is considered as true if at least 1 bit out of the 8 bits is set. +The boolean `f` parameter is considered as `true` if set to `1`. +The boolean `f` parameter is considered as `false` if set to `0`. +All other values yield an invalid encoding of `f` error. The precompile should compute the `F` function as [specified in the RFC](https://tools.ietf.org/html/rfc7693#section-3.2) and return the updated state vector `h`. From e30104ccccf7675923b7f987d2604aadb55cf51a Mon Sep 17 00:00:00 2001 From: pdyraga Date: Tue, 13 Aug 2019 15:25:29 +0200 Subject: [PATCH 31/39] Initial test vectors for F precompile Test cases covered: - input length too short - input length too long - malformed f flag encoding - correct input, test vector from BLAKE2b RFC, Appendix A --- EIPS/eip-152.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index b6df75838f8f6f..eb47bc633e5610 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -137,7 +137,29 @@ There is very little risk of breaking backwards-compatibility with this EIP, the -Test cases are in progress, and can be followed along in our [Golang Blake2 library fork](https://github.com/keep-network/blake2-f) as well as our fork of [go-ethereum](https://github.com/keep-network/go-ethereum). +#### Test vector 0 +* input +`00000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +* output +error: input length for Blake2 F precompile should be exactly 213 bytes + +#### Test vector 1 +* input +`000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +* output +error: input length for Blake2 F precompile should be exactly 213 bytes + +#### Test vector 2 +* input +`0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002` +* output +error: incorrect final block indicator flag + +#### Test vector 3 +* input: +`0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +* output: +`ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923` ## Implementation From 65f1caa89409cda2c12342f4240090a162c87ff5 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Tue, 13 Aug 2019 16:21:10 +0200 Subject: [PATCH 32/39] Test vector for a non-final round --- EIPS/eip-152.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index eb47bc633e5610..d4b10fd450e2e3 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -161,6 +161,12 @@ error: incorrect final block indicator flag * output: `ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923` +#### Test vector 4 +* input: +`0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000` +* output: +`75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735` + ## Implementation From a40bc66010f4f7bc97103a89b8278f148c917d7c Mon Sep 17 00:00:00 2001 From: pdyraga Date: Tue, 13 Aug 2019 16:23:08 +0200 Subject: [PATCH 33/39] Test vector for the maximum number of rounds --- EIPS/eip-152.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index d4b10fd450e2e3..6bf4863f3544d9 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -167,6 +167,12 @@ error: incorrect final block indicator flag * output: `75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735` +#### Test vector 5 +* input: +`ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +* output: +`fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615` + ## Implementation From b8d33ba0901b98c4b4d9a47ec962895dc59dc667 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Tue, 13 Aug 2019 17:03:03 +0200 Subject: [PATCH 34/39] Test vector for a single round --- EIPS/eip-152.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 6bf4863f3544d9..f7e9cc96e9153e 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -168,6 +168,12 @@ error: incorrect final block indicator flag `75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735` #### Test vector 5 +* input: +`0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +* output: +`b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421` + +#### Test vector 6 * input: `ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` * output: From 7e2f8a1abba4fc4356b959d64cba73a726b378d0 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Fri, 16 Aug 2019 13:32:42 +0200 Subject: [PATCH 35/39] Added test vector for empty input --- EIPS/eip-152.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index f7e9cc96e9153e..588fcc2dc68f66 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -138,42 +138,42 @@ There is very little risk of breaking backwards-compatibility with this EIP, the #### Test vector 0 -* input -`00000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` -* output -error: input length for Blake2 F precompile should be exactly 213 bytes +* input: (empty) +* output: error "input length for Blake2 F precompile should be exactly 213 bytes" #### Test vector 1 -* input -`000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` -* output -error: input length for Blake2 F precompile should be exactly 213 bytes +* input: +`00000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +* output: error "input length for Blake2 F precompile should be exactly 213 bytes" #### Test vector 2 -* input -`0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002` -* output -error: incorrect final block indicator flag +* input: +`000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +* output: error "input length for Blake2 F precompile should be exactly 213 bytes" #### Test vector 3 +* input: +`0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002` +* output: error "incorrect final block indicator flag" + +#### Test vector 4 * input: `0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` -* output: -`ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923` +* output: `ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923` -#### Test vector 4 +#### Test vector 5 * input: `0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000` * output: `75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735` -#### Test vector 5 +#### Test vector 6 * input: `0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` * output: `b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421` -#### Test vector 6 +#### Test vector 7 * input: `ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` * output: From 817e12d744ac06432cfe0f2d9694b93347e62e69 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Fri, 16 Aug 2019 13:35:01 +0200 Subject: [PATCH 36/39] The final block indicator (8-bit word) does not have endianness --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 588fcc2dc68f66..0a9da7a85800dc 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -42,7 +42,7 @@ The precompile requires 6 inputs tightly encoded, taking exactly 213 bytes, as e - `h` - the state vector - 8 unsigned 64-bit little-endian words - `m` - the message block vector - 16 unsigned 64-bit little-endian words - `t_0, t_1` - offset counters - 2 unsigned 64-bit little-endian words -- `f` - the final block indicator flag - 8-bit unsigned big-endian word +- `f` - the final block indicator flag - 8-bit word ``` [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] From 2386c0ecd696aa7c0445698fcdf3473cd19554b4 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Fri, 16 Aug 2019 13:42:08 +0200 Subject: [PATCH 37/39] Clarify state vector encoding does not change in the output --- EIPS/eip-152.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index 0a9da7a85800dc..bcfbcdbb5d5a56 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -52,7 +52,7 @@ The boolean `f` parameter is considered as `true` if set to `1`. The boolean `f` parameter is considered as `false` if set to `0`. All other values yield an invalid encoding of `f` error. -The precompile should compute the `F` function as [specified in the RFC](https://tools.ietf.org/html/rfc7693#section-3.2) and return the updated state vector `h`. +The precompile should compute the `F` function as [specified in the RFC](https://tools.ietf.org/html/rfc7693#section-3.2) and return the updated state vector `h` with unchanged encoding (little-endian). ### Example Usage in Solidity From 1255c52242808970d92d2c74c261e00d203ab793 Mon Sep 17 00:00:00 2001 From: pdyraga Date: Fri, 16 Aug 2019 14:50:32 +0200 Subject: [PATCH 38/39] Put too short input test vector next to empty input test vector --- EIPS/eip-152.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index bcfbcdbb5d5a56..b92d9de3161f7b 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -143,12 +143,12 @@ There is very little risk of breaking backwards-compatibility with this EIP, the #### Test vector 1 * input: -`00000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +`00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` * output: error "input length for Blake2 F precompile should be exactly 213 bytes" #### Test vector 2 * input: -`000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +`000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` * output: error "input length for Blake2 F precompile should be exactly 213 bytes" #### Test vector 3 From 272c45f9f9305d7f84ccd1adb1b1d594ca38ff7a Mon Sep 17 00:00:00 2001 From: pdyraga Date: Tue, 20 Aug 2019 11:14:19 +0200 Subject: [PATCH 39/39] Added test vector for zero-rounds BLAKE2b case --- EIPS/eip-152.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-152.md b/EIPS/eip-152.md index b92d9de3161f7b..5b6c7cc5b8fd89 100644 --- a/EIPS/eip-152.md +++ b/EIPS/eip-152.md @@ -158,22 +158,28 @@ There is very little risk of breaking backwards-compatibility with this EIP, the #### Test vector 4 * input: +`0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` +* output: +`08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b` + +#### Test vector 5 +* input: `0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` * output: `ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923` -#### Test vector 5 +#### Test vector 6 * input: `0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000` * output: `75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735` -#### Test vector 6 +#### Test vector 7 * input: `0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` * output: `b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421` -#### Test vector 7 +#### Test vector 8 * input: `ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001` * output: