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.Keccak512removed in #27178, replaced withsha3.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