github.com/core-coin/go-core/v2@v2.1.9/consensus/cryptore/algorithm.go (about) 1 // Copyright 2017 by the Authors 2 // This file is part of the go-core library. 3 // 4 // The go-core library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-core library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-core library. If not, see <http://www.gnu.org/licenses/>. 16 17 package cryptore 18 19 import ( 20 "hash" 21 22 "golang.org/x/crypto/sha3" 23 ) 24 25 const ( 26 epochLength = 30000 // Blocks per epoch 27 ) 28 29 // hasher is a repetitive hasher allowing the same hash data structures to be 30 // reused between hash runs instead of requiring new ones to be created. 31 type hasher func(dest []byte, data []byte) 32 33 // makeHasher creates a repetitive hasher, allowing the same hash data structures to 34 // be reused between hash runs instead of requiring new ones to be created. The returned 35 // function is not thread safe! 36 func makeHasher(h hash.Hash) hasher { 37 // sha3.state supports Read to get the sum, use it to avoid the overhead of Sum. 38 // Read alters the state but we reset the hash before every operation. 39 type readerHash interface { 40 hash.Hash 41 Read([]byte) (int, error) 42 } 43 rh, ok := h.(readerHash) 44 if !ok { 45 panic("can't find Read method on hash") 46 } 47 outputLen := rh.Size() 48 return func(dest []byte, data []byte) { 49 rh.Reset() 50 rh.Write(data) 51 rh.Read(dest[:outputLen]) 52 } 53 } 54 55 // seedHash is the seed to use for generating a verification cache and the mining 56 // dataset. 57 func seedHash(block uint64) []byte { 58 seed := make([]byte, 32) 59 if block < epochLength { 60 return seed 61 } 62 SHA3 := makeHasher(sha3.New256()) 63 for i := 0; i < int(block/epochLength); i++ { 64 SHA3(seed, seed) 65 } 66 return seed 67 }