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  }