/
seed.go
65 lines (52 loc) · 1.38 KB
/
seed.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package go_algorithm
import (
"encoding/binary"
"unsafe"
"github.com/bytom-gm/crypto/scrypt"
"github.com/bytom-gm/crypto/sha3pool"
"github.com/bytom-gm/protocol/bc"
)
func calcSeed(blockHashs []*bc.Hash) []byte {
data := []byte{}
for _, blockHash := range blockHashs {
data = append(data, blockHash.Bytes()...)
}
var s [32]byte
sha3pool.Sum256(s[:], data)
return s[:]
}
func extendBytes(seed []byte, round int) []byte {
extSeed := make([]byte, len(seed)*(round+1))
copy(extSeed, seed)
for i := 0; i < round; i++ {
var h [32]byte
sha3pool.Sum256(h[:], extSeed[i*32:(i+1)*32])
copy(extSeed[(i+1)*32:(i+2)*32], h[:])
}
return extSeed
}
func calcSeedCache(seed []byte) (cache []uint32) {
extSeed := extendBytes(seed, 3)
v := make([]uint32, 32*1024)
// Swap the byte order on big endian systems
if !isLittleEndian() {
swap(extSeed)
}
for i := 0; i < 128; i++ {
scrypt.Smix(extSeed, v)
cache = append(cache, v...)
}
return cache
}
// isLittleEndian returns whether the local system is running in little or big
// endian byte order.
func isLittleEndian() bool {
n := uint32(0x01020304)
return *(*byte)(unsafe.Pointer(&n)) == 0x04
}
// swap changes the byte order of the buffer assuming a uint32 representation.
func swap(buffer []byte) {
for i := 0; i < len(buffer); i += 4 {
binary.BigEndian.PutUint32(buffer[i:], binary.LittleEndian.Uint32(buffer[i:]))
}
}