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