Skip to content

hashimoto

Source (upstream pre-purge) Current
File consensus/ethash/algorithm.go algorithm.go
Symbol hashimoto hashimoto
Ref dde2da0ef~1 etc/v1.17.3-full-node

ADAPT: crypto.Keccak512 removed in #27178, replaced with sha3.NewLegacyKeccak512()

3-way merge — purge → getc ← upstream

pre-purgefork-only
// hashimoto aggregates data from the full dataset in order to produce our final
// value for a particular header hash and nonce.
func hashimoto(hash []byte, nonce uint64, size uint64, lookup func(index uint32) []uint32) ([]byte, []byte) {
// Calculate the number of theoretical rows (we use one buffer nonetheless)
rows := uint32(size / mixBytes)
// Combine header+nonce into a 40 byte seed
seed := make([]byte, 40)
copy(seed, hash)
binary.LittleEndian.PutUint64(seed[32:], nonce)
keccak512Hasher := sha3.NewLegacyKeccak512()
keccak512Hasher.Write(seed)
seed = keccak512Hasher.Sum(nil)
seedHead := binary.LittleEndian.Uint32(seed)
// Start the mix with replicated seed
mix := make([]uint32, mixBytes/4)
for i := 0; i < len(mix); i++ {
mix[i] = binary.LittleEndian.Uint32(seed[i%16*4:])
}
// Mix in random dataset nodes
temp := make([]uint32, len(mix))
for i := 0; i < loopAccesses; i++ {
parent := fnv(uint32(i)^seedHead, mix[i%len(mix)]) % rows
for j := uint32(0); j < mixBytes/hashBytes; j++ {
copy(temp[j*hashWords:], lookup(2*parent+j))
}
fnvHash(mix, temp)
}
// Compress mix
for i := 0; i < len(mix); i += 4 {
mix[i/4] = fnv(fnv(fnv(mix[i], mix[i+1]), mix[i+2]), mix[i+3])
}
mix = mix[:len(mix)/4]
digest := make([]byte, common.HashLength)
for i, val := range mix {
binary.LittleEndian.PutUint32(digest[i*4:], val)
}
return digest, crypto.Keccak256(append(seed, digest...))
}
core-geth validation — +3 -1 | | | |---|---| | File | [`algorithm.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/consensus/ethash/algorithm.go) | | Symbol | `hashimoto` | | Ref | `v1.12.20` |
--- a/core-geth/consensus/ethash/algorithm.go
+++ b/etc/consensus/ethash/algorithm.go
@@ -9,7 +9,9 @@
    copy(seed, hash)
    binary.LittleEndian.PutUint64(seed[32:], nonce)

-   seed = crypto.Keccak512(seed)
+   keccak512Hasher := sha3.NewLegacyKeccak512()
+   keccak512Hasher.Write(seed)
+   seed = keccak512Hasher.Sum(nil)
    seedHead := binary.LittleEndian.Uint32(seed)

    // Start the mix with replicated seed

← Consensus & Ethash