github.com/cryptoecc/eth-ecc@v0.0.3/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/cryptoecc/ETH-ECC/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 src := rand.NewSource(hSeed) 111 rnd := rand.New(src) 112 rnd.Seed(hSeed) 113 rnd.Shuffle(len(colOrder), func(i, j int) { 114 colOrder[i],colOrder[j] = colOrder[j], colOrder[i] 115 }) 116 hSeed-- 117 118 for j := 0; j < parameters.n; j++ { 119 index := (colOrder[j]/parameters.wr + k*i) 120 H[index][j] = 1 121 } 122 } 123 124 return H 125 } 126 127 //generateQ generate colInRow and rowInCol matrix using H matrix 128 func generateQ(parameters Parameters, H [][]int) ([][]int, [][]int) { 129 colInRow := make([][]int, parameters.wr) 130 for i := 0; i < parameters.wr; i++ { 131 colInRow[i] = make([]int, parameters.m) 132 } 133 134 rowInCol := make([][]int, parameters.wc) 135 for i := 0; i < parameters.wc; i++ { 136 rowInCol[i] = make([]int, parameters.n) 137 } 138 139 rowIndex := 0 140 colIndex := 0 141 142 for i := 0; i < parameters.m; i++ { 143 for j := 0; j < parameters.n; j++ { 144 if H[i][j] == 1 { 145 colInRow[colIndex%parameters.wr][i] = j 146 colIndex++ 147 148 rowInCol[rowIndex/parameters.n][j] = i 149 rowIndex++ 150 } 151 } 152 } 153 154 return colInRow, rowInCol 155 } 156 157 //generateHv generate hashvector 158 //It needs to compare with origin C++ implementation Especially when sha256 function is used 159 func generateHv(parameters Parameters, encryptedHeaderWithNonce []byte) []int { 160 hashVector := make([]int, parameters.n) 161 162 /* 163 if parameters.n <= 256 { 164 tmpHashVector = sha256.Sum256(headerWithNonce) 165 } else { 166 /* 167 This section is for a case in which the size of a hash vector is larger than 256. 168 This section will be implemented soon. 169 } 170 transform the constructed hexadecimal array into an binary array 171 ex) FE01 => 11111110000 0001 172 */ 173 174 for i := 0; i < parameters.n/8; i++ { 175 decimal := int(encryptedHeaderWithNonce[i]) 176 for j := 7; j >= 0; j-- { 177 hashVector[j+8*(i)] = decimal % 2 178 decimal /= 2 179 } 180 } 181 182 //outputWord := hashVector[:parameters.n] 183 return hashVector 184 }