github.com/cryptoecc/eth-ecc@v0.0.3/consensus/ethash/LDPC_utils.go (about) 1 package ethash 2 3 import ( 4 crand "crypto/rand" 5 "math" 6 "math/big" 7 "math/rand" 8 ) 9 10 //Parameters for matrix and seed 11 const ( 12 BigInfinity = 1000000.0 13 Inf = 64.0 14 MaxNonce = 1<<32 - 1 15 16 // These parameters are only used for the decoding function. 17 maxIter = 20 // The maximum number of iteration in the decoder 18 crossErr = 0.01 // A transisient error probability. This is also fixed as a small value 19 ) 20 21 type Parameters struct { 22 n int //256 23 m int //34 24 wc int 25 wr int 26 seed int 27 } 28 29 // setParameters sets n, wc, wr, m, seed return parameters and difficulty level 30 func setParameters(hash []byte) Parameters { 31 parameters := Parameters{ 32 n: 256, 33 wc: 3, 34 wr: 4, 35 } 36 parameters.m = int(parameters.n * parameters.wc / parameters.wr) 37 38 var arrayHash [32]byte 39 copy(arrayHash[:], hash[:32]) 40 parameters.seed = generateSeed(arrayHash) 41 42 return parameters 43 } 44 45 //generateRandomNonce generate 64bit random nonce with similar way of ethereum block nonce 46 func generateRandomNonce() uint64 { 47 seed, _ := crand.Int(crand.Reader, big.NewInt(math.MaxInt64)) 48 source := rand.New(rand.NewSource(seed.Int64())) 49 50 return uint64(source.Int63()) 51 } 52 53 func funcF(x float64) float64 { 54 if x >= BigInfinity { 55 return 1.0 / BigInfinity 56 } else if x <= (1.0 / BigInfinity) { 57 return BigInfinity 58 } else { 59 return math.Log((math.Exp(x) + 1) / (math.Exp(x) - 1)) 60 } 61 } 62 63 func infinityTest(x float64) float64 { 64 if x >= Inf { 65 return Inf 66 } else if x <= -Inf { 67 return -Inf 68 } else { 69 return x 70 } 71 } 72 73 //generateSeed generate seed using previous hash vector 74 func generateSeed(phv [32]byte) int { 75 sum := 0 76 for i := 0; i < len(phv); i++ { 77 sum += int(phv[i]) 78 } 79 return sum 80 } 81 82 //generateH generate H matrix using parameters 83 //generateH Cannot be sure rand is same with original implementation of C++ 84 func generateH(parameters Parameters) [][]int { 85 var H [][]int 86 var hSeed int64 87 var colOrder []int 88 89 hSeed = int64(parameters.seed) 90 k := parameters.m / parameters.wc 91 92 H = make([][]int, parameters.m) 93 for i := range H { 94 H[i] = make([]int, parameters.n) 95 } 96 97 for i := 0; i < k; i++ { 98 for j := i * parameters.wr; j < (i+1)*parameters.wr; j++ { 99 H[i][j] = 1 100 } 101 } 102 103 for i := 1; i < parameters.wc; i++ { 104 colOrder = nil 105 for j := 0; j < parameters.n; j++ { 106 colOrder = append(colOrder, j) 107 } 108 109 rand.Seed(hSeed) 110 rand.Shuffle(len(colOrder), func(i, j int) { 111 colOrder[i], colOrder[j] = colOrder[j], colOrder[i] 112 }) 113 hSeed-- 114 115 for j := 0; j < parameters.n; j++ { 116 index := (colOrder[j]/parameters.wr + k*i) 117 H[index][j] = 1 118 } 119 } 120 121 return H 122 } 123 124 //generateQ generate colInRow and rowInCol matrix using H matrix 125 func generateQ(parameters Parameters, H [][]int) ([][]int, [][]int) { 126 colInRow := make([][]int, parameters.wr) 127 for i := 0; i < parameters.wr; i++ { 128 colInRow[i] = make([]int, parameters.m) 129 } 130 131 rowInCol := make([][]int, parameters.wc) 132 for i := 0; i < parameters.wc; i++ { 133 rowInCol[i] = make([]int, parameters.n) 134 } 135 136 rowIndex := 0 137 colIndex := 0 138 139 for i := 0; i < parameters.m; i++ { 140 for j := 0; j < parameters.n; j++ { 141 if H[i][j] == 1 { 142 colInRow[colIndex%parameters.wr][i] = j 143 colIndex++ 144 145 rowInCol[rowIndex/parameters.n][j] = i 146 rowIndex++ 147 } 148 } 149 } 150 151 return colInRow, rowInCol 152 } 153 154 //generateHv generate hashvector 155 //It needs to compare with origin C++ implementation Especially when sha256 function is used 156 func generateHv(parameters Parameters, encryptedHeaderWithNonce []byte) []int { 157 hashVector := make([]int, parameters.n) 158 159 /* 160 if parameters.n <= 256 { 161 tmpHashVector = sha256.Sum256(headerWithNonce) 162 } else { 163 /* 164 This section is for a case in which the size of a hash vector is larger than 256. 165 This section will be implemented soon. 166 } 167 transform the constructed hexadecimal array into an binary array 168 ex) FE01 => 11111110000 0001 169 */ 170 171 for i := 0; i < parameters.n/8; i++ { 172 decimal := int(encryptedHeaderWithNonce[i]) 173 for j := 7; j >= 0; j-- { 174 hashVector[j+8*(i)] = decimal % 2 175 decimal /= 2 176 } 177 } 178 179 //outputWord := hashVector[:parameters.n] 180 return hashVector 181 }