9 "gonum.org/v1/gonum/mat"
11 "github.com/vapor/crypto/sha3pool"
12 "github.com/vapor/protocol/bc"
16 matSize = 1 << 8 // Size of matrix
17 matNum = 1 << 8 // Number of matrix
20 func mulMatrix(headerhash []byte, cache []uint32) []uint8 {
21 ui32data := make([]uint32, matNum*matSize*matSize/4)
22 for i := 0; i < 128; i++ {
23 start := i * 1024 * 32
24 for j := 0; j < 512; j++ {
25 copy(ui32data[start+j*32:start+j*32+32], cache[start+j*64:start+j*64+32])
26 copy(ui32data[start+512*32+j*32:start+512*32+j*32+32], cache[start+j*64+32:start+j*64+64])
30 // Convert our destination slice to a int8 buffer
31 header := *(*reflect.SliceHeader)(unsafe.Pointer(&ui32data))
34 i8data := *(*[]int8)(unsafe.Pointer(&header))
36 f64data := make([]float64, matNum*matSize*matSize)
37 for i := 0; i < matNum*matSize*matSize; i++ {
38 f64data[i] = float64(i8data[i])
41 dataIdentity := make([]float64, matSize*matSize)
42 for i := 0; i < 256; i++ {
43 dataIdentity[i*257] = float64(1)
46 var tmp [matSize][matSize]float64
47 var maArr [4][matSize][matSize]float64
53 for k := 0; k < 4; k++ {
57 ma := mat.NewDense(matSize, matSize, dataIdentity)
58 mc := mat.NewDense(matSize, matSize, make([]float64, matSize*matSize))
61 sha3pool.Sum256(sequence[:], headerhash[i*8:(i+1)*8])
63 for j := 0; j < 2; j++ {
64 for k := 0; k < 32; k++ {
65 index := int(sequence[k])
66 mb := mat.NewDense(matSize, matSize, f64data[index*matSize*matSize:(index+1)*matSize*matSize])
69 for row := 0; row < matSize; row++ {
70 for col := 0; col < matSize; col++ {
71 i32v := int32(mc.At(row, col))
72 i8v := int8((i32v & 0xff) +
74 mc.Set(row, col, float64(i8v))
81 for row := 0; row < matSize; row++ {
82 for col := 0; col < matSize; col++ {
83 maArr[i][row][col] = ma.At(row, col)
90 for i := 0; i < 4; i++ {
91 for row := 0; row < matSize; row++ {
92 for col := 0; col < matSize; col++ {
93 i32vtmp := int32(tmp[row][col])
94 i32vma := int32(maArr[i][row][col])
95 i8v := int8(int32(i32vtmp+i32vma) & 0xff)
96 tmp[row][col] = float64(i8v)
101 result := make([]uint8, 0)
102 for i := 0; i < matSize; i++ {
103 for j := 0; j < matSize; j++ {
104 result = append(result, uint8(tmp[i][j]))
110 // hashMatrix hash result of mulMatrix
111 func hashMatrix(result []uint8) *bc.Hash {
112 var mat8 [matSize][matSize]uint8
113 for i := 0; i < matSize; i++ {
114 for j := 0; j < matSize; j++ {
115 mat8[i][j] = result[i*matSize+j]
119 var mat32 [matSize][matSize / 4]uint32
121 for i := 0; i < matSize; i++ {
122 for j := 0; j < matSize/4; j++ {
123 mat32[i][j] = ((uint32(mat8[i][j+192])) << 24) |
124 ((uint32(mat8[i][j+128])) << 16) |
125 ((uint32(mat8[i][j+64])) << 8) |
126 ((uint32(mat8[i][j])) << 0)
130 for k := matSize; k > 1; k = k / 2 {
131 for j := 0; j < k/2; j++ {
132 for i := 0; i < matSize/4; i++ {
133 mat32[j][i] = fnv(mat32[j][i], mat32[j+k/2][i])
138 ui32data := make([]uint32, 0)
139 for i := 0; i < matSize/4; i++ {
140 ui32data = append(ui32data, mat32[0][i])
143 // Convert our destination slice to a byte buffer
144 header := *(*reflect.SliceHeader)(unsafe.Pointer(&ui32data))
147 dataBytes := *(*[]byte)(unsafe.Pointer(&header))
150 sha3pool.Sum256(h[:], dataBytes)
151 bcHash := bc.NewHash(h)
155 func fnv(a, b uint32) uint32 {
156 return a*0x01000193 ^ b