Skip to content

Commit

Permalink
core/vm, crypto/blake2b: add SSE, AVX and AVX2 code
Browse files Browse the repository at this point in the history
  • Loading branch information
karalabe committed Aug 21, 2019
1 parent 2890f06 commit 1bccafe
Show file tree
Hide file tree
Showing 14 changed files with 2,560 additions and 164 deletions.
53 changes: 25 additions & 28 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,63 +438,60 @@ func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) {
type blake2F struct{}

func (c *blake2F) RequiredGas(input []byte) uint64 {
// If the input is malformed, we can't calculate the gas, return 0 and let the
// actual call choke and fault.
if len(input) != blake2FInputLength {
// Input is malformed, we can't read the number of rounds.
// Precompile can't be executed so we set its price to 0.
return 0
}

rounds := binary.BigEndian.Uint32(input[0:4])
return uint64(rounds)
return uint64(binary.BigEndian.Uint32(input[0:4]))
}

const blake2FInputLength = 213
const blake2FFinalBlockBytes = byte(1)
const blake2FNonFinalBlockBytes = byte(0)

var errBlake2FIncorrectInputLength = errors.New(
"input length for Blake2 F precompile should be exactly 213 bytes",
const (
blake2FInputLength = 213
blake2FFinalBlockBytes = byte(1)
blake2FNonFinalBlockBytes = byte(0)
)

var errBlake2FIncorrectFinalBlockIndicator = errors.New(
"incorrect final block indicator flag",
var (
errBlake2FInvalidInputLength = errors.New("invalid input length")
errBlake2FInvalidFinalFlag = errors.New("invalid final flag")
)

func (c *blake2F) Run(input []byte) ([]byte, error) {
// Make sure the input is valid (correct lenth and final flag)
if len(input) != blake2FInputLength {
return nil, errBlake2FIncorrectInputLength
return nil, errBlake2FInvalidInputLength
}
if input[212] != blake2FNonFinalBlockBytes && input[212] != blake2FFinalBlockBytes {
return nil, errBlake2FIncorrectFinalBlockIndicator
return nil, errBlake2FInvalidFinalFlag
}
// Parse the input into the Blake2b call parameters
var (
rounds = binary.BigEndian.Uint32(input[0:4])
final = (input[212] == blake2FFinalBlockBytes)

rounds := binary.BigEndian.Uint32(input[0:4])

var h [8]uint64
h [8]uint64
m [16]uint64
t [2]uint64
)
for i := 0; i < 8; i++ {
offset := 4 + i*8
h[i] = binary.LittleEndian.Uint64(input[offset : offset+8])
}

var m [16]uint64
for i := 0; i < 16; i++ {
offset := 68 + i*8
m[i] = binary.LittleEndian.Uint64(input[offset : offset+8])
}

var t [2]uint64
t[0] = binary.LittleEndian.Uint64(input[196:204])
t[1] = binary.LittleEndian.Uint64(input[204:212])

f := (input[212] == blake2FFinalBlockBytes)
// Execute the compression function, extract and return the result
blake2b.F(&h, m, t, final, rounds)

blake2b.F(&h, m, t, f, rounds)

var output [64]byte
output := make([]byte, 64)
for i := 0; i < 8; i++ {
offset := i * 8
binary.LittleEndian.PutUint64(output[offset:offset+8], h[i])
}

return output[:], nil
return output, nil
}
13 changes: 9 additions & 4 deletions core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,22 +349,22 @@ var bn256PairingTests = []precompiledTest{
var blake2FMalformedInputTests = []precompiledFailureTest{
{
input: "",
expectedError: errBlake2FIncorrectInputLength,
expectedError: errBlake2FInvalidInputLength,
name: "vector 0: empty input",
},
{
input: "00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
expectedError: errBlake2FIncorrectInputLength,
expectedError: errBlake2FInvalidInputLength,
name: "vector 1: less than 213 bytes input",
},
{
input: "000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
expectedError: errBlake2FIncorrectInputLength,
expectedError: errBlake2FInvalidInputLength,
name: "vector 2: more than 213 bytes input",
},
{
input: "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002",
expectedError: errBlake2FIncorrectFinalBlockIndicator,
expectedError: errBlake2FInvalidFinalFlag,
name: "vector 3: malformed final block indicator flag",
},
}
Expand All @@ -391,6 +391,11 @@ var blake2FTests = []precompiledTest{
expected: "b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421",
name: "vector 7",
},
{
input: "007A120048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
expected: "6d2ce9e534d50e18ff866ae92d70cceba79bbcd14c63819fe48752c8aca87a4bb7dcc230d22a4047f0486cfcfb50a17b24b2899eb8fca370f22240adb5170189",
name: "vector 8",
},
}

func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
Expand Down
Loading

0 comments on commit 1bccafe

Please sign in to comment.