diff options
Diffstat (limited to 'dagger.go')
-rw-r--r-- | dagger.go | 199 |
1 files changed, 101 insertions, 98 deletions
@@ -1,142 +1,145 @@ package main import ( - "math/big" - "math/rand" - "time" - "github.com/obscuren/sha3" - "hash" - "github.com/ethereum/ethutil-go" + "github.com/ethereum/ethutil-go" + "github.com/obscuren/sha3" + "hash" + "math/big" + "math/rand" + "time" ) type Dagger struct { - hash *big.Int - xn *big.Int + hash *big.Int + xn *big.Int } var Found bool + func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) + r := rand.New(rand.NewSource(time.Now().UnixNano())) - for i := 0; i < 1000; i++ { - rnd := r.Int63() + for i := 0; i < 1000; i++ { + rnd := r.Int63() - if dag.Eval(big.NewInt(rnd)).Cmp(obj) < 0 { - // Post back result on the channel - resChan <- rnd - // Notify other threads we've found a valid nonce - Found = true - } + if dag.Eval(big.NewInt(rnd)).Cmp(obj) < 0 { + // Post back result on the channel + resChan <- rnd + // Notify other threads we've found a valid nonce + Found = true + } - // Break out if found - if Found { break } - } + // Break out if found + if Found { + break + } + } - resChan <- 0 + resChan <- 0 } func (dag *Dagger) Search(hash, diff *big.Int) *big.Int { - // TODO fix multi threading. Somehow it results in the wrong nonce - amountOfRoutines := 1 + // TODO fix multi threading. Somehow it results in the wrong nonce + amountOfRoutines := 1 - dag.hash = hash + dag.hash = hash - obj := ethutil.BigPow(2, 256) - obj = obj.Div(obj, diff) + obj := ethutil.BigPow(2, 256) + obj = obj.Div(obj, diff) - Found = false - resChan := make(chan int64, 3) - var res int64 + Found = false + resChan := make(chan int64, 3) + var res int64 - for k := 0; k < amountOfRoutines; k++ { - go dag.Find(obj, resChan) - } + for k := 0; k < amountOfRoutines; k++ { + go dag.Find(obj, resChan) + } - // Wait for each go routine to finish - for k := 0; k < amountOfRoutines; k++ { - // Get the result from the channel. 0 = quit - if r := <- resChan; r != 0 { - res = r - } - } + // Wait for each go routine to finish + for k := 0; k < amountOfRoutines; k++ { + // Get the result from the channel. 0 = quit + if r := <-resChan; r != 0 { + res = r + } + } - return big.NewInt(res) + return big.NewInt(res) } func DaggerVerify(hash, diff, nonce *big.Int) bool { - dagger := &Dagger{} - dagger.hash = hash + dagger := &Dagger{} + dagger.hash = hash - obj := ethutil.BigPow(2, 256) - obj = obj.Div(obj, diff) + obj := ethutil.BigPow(2, 256) + obj = obj.Div(obj, diff) - return dagger.Eval(nonce).Cmp(obj) < 0 + return dagger.Eval(nonce).Cmp(obj) < 0 } func (dag *Dagger) Node(L uint64, i uint64) *big.Int { - if L == i { - return dag.hash - } - - var m *big.Int - if L == 9 { - m = big.NewInt(16) - } else { - m = big.NewInt(3) - } - - sha := sha3.NewKeccak256() - sha.Reset() - d := sha3.NewKeccak256() - b := new(big.Int) - ret := new(big.Int) - - for k := 0; k < int(m.Uint64()); k++ { - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(big.NewInt(int64(L)).Bytes()) - d.Write(big.NewInt(int64(i)).Bytes()) - d.Write(big.NewInt(int64(k)).Bytes()) - - b.SetBytes(Sum(d)) - pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1) - sha.Write(dag.Node(L - 1, pk).Bytes()) - } - - ret.SetBytes(Sum(sha)) - - return ret + if L == i { + return dag.hash + } + + var m *big.Int + if L == 9 { + m = big.NewInt(16) + } else { + m = big.NewInt(3) + } + + sha := sha3.NewKeccak256() + sha.Reset() + d := sha3.NewKeccak256() + b := new(big.Int) + ret := new(big.Int) + + for k := 0; k < int(m.Uint64()); k++ { + d.Reset() + d.Write(dag.hash.Bytes()) + d.Write(dag.xn.Bytes()) + d.Write(big.NewInt(int64(L)).Bytes()) + d.Write(big.NewInt(int64(i)).Bytes()) + d.Write(big.NewInt(int64(k)).Bytes()) + + b.SetBytes(Sum(d)) + pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1) + sha.Write(dag.Node(L-1, pk).Bytes()) + } + + ret.SetBytes(Sum(sha)) + + return ret } func Sum(sha hash.Hash) []byte { - in := make([]byte, 32) - return sha.Sum(in) + in := make([]byte, 32) + return sha.Sum(in) } func (dag *Dagger) Eval(N *big.Int) *big.Int { - pow := ethutil.BigPow(2, 26) - dag.xn = N.Div(N, pow) + pow := ethutil.BigPow(2, 26) + dag.xn = N.Div(N, pow) - sha := sha3.NewKeccak256() - sha.Reset() - ret := new(big.Int) + sha := sha3.NewKeccak256() + sha.Reset() + ret := new(big.Int) - for k := 0; k < 4; k++ { - d := sha3.NewKeccak256() - b := new(big.Int) + for k := 0; k < 4; k++ { + d := sha3.NewKeccak256() + b := new(big.Int) - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(N.Bytes()) - d.Write(big.NewInt(int64(k)).Bytes()) + d.Reset() + d.Write(dag.hash.Bytes()) + d.Write(dag.xn.Bytes()) + d.Write(N.Bytes()) + d.Write(big.NewInt(int64(k)).Bytes()) - b.SetBytes(Sum(d)) - pk := (b.Uint64() & 0x1ffffff) + b.SetBytes(Sum(d)) + pk := (b.Uint64() & 0x1ffffff) - sha.Write(dag.Node(9, pk).Bytes()) - } + sha.Write(dag.Node(9, pk).Bytes()) + } - return ret.SetBytes(Sum(sha)) + return ret.SetBytes(Sum(sha)) } |