forked from tuneinsight/lattigo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
prng_sol.go
68 lines (57 loc) · 1.31 KB
/
prng_sol.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
66
67
68
package utils
import (
"github.com/ethereum/go-ethereum/crypto"
solsha3 "github.com/miguelmota/go-solidity-sha3"
)
const sha3Size = 32
type SolPRNG struct {
seed []byte
salt uint32
hash func(data ...[]byte) []byte
}
func NewSolPRNG(seed []byte, salt uint32) *SolPRNG {
prng := new(SolPRNG)
prng.seed = seed
prng.salt = salt
prng.hash = crypto.Keccak256
return prng
}
func (prng *SolPRNG) Read(sum []byte) (n int, err error) {
n = len(sum)
iv := prng.hash(prng.seed, ConvertU32toBytes32(prng.salt))
i := 0
for ; i <= n-sha3Size; i = i + sha3Size {
hash := prng.hash(iv)
iv = hash
copy(sum[i:i+sha3Size], hash)
}
remain := n - i
if remain > 0 {
hash := prng.hash(iv)
iv = hash
copy(sum[i:i+remain], hash[:remain])
}
copy(prng.seed, iv)
return
}
func ConvertU32toBytes32(num uint32) []byte {
byte4 := solsha3.Uint32(num)
prefixBytes := make([]byte, 28)
return append(prefixBytes, byte4...)
}
func ConvertBytesToBytes32(byteArray []byte) [32]byte {
offset := 32 - len(byteArray)
if offset <= 0 {
return bytesTobytes32(byteArray[:32])
}
prefixArray := make([]byte, offset)
resBytes := append(byteArray, prefixArray...)
return bytesTobytes32(resBytes)
}
func bytesTobytes32(byte32Array []byte) [32]byte {
res := [32]byte{}
for i := 0; i < 32; i++ {
res[i] = byte32Array[i]
}
return res
}