aboutsummaryrefslogtreecommitdiffstats
path: root/dagger.go
blob: 750a781b045c2f9e4c6fb1c7b4a0f092c46142dd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main

import (
  "math/big"
  "fmt"
  "math/rand"
  "time"
  "github.com/obscuren/sha3"
)

type Dagger struct {
  hash *big.Int
  xn *big.Int
}

func (dag *Dagger) Search(diff *big.Int) *big.Int {
  dag.hash = big.NewInt(0)

  obj := BigPow(2, 256)
  obj = obj.Div(obj, diff)

  fmt.Println("diff", diff, "< objective", obj)

  r := rand.New(rand.NewSource(time.Now().UnixNano()))
  rnd := big.NewInt(r.Int63())
  fmt.Println("init rnd =", rnd)

  for i := 0; i < 1000; i++ {
    if dag.Eval(rnd).Cmp(obj) < 0 {
      fmt.Println("Found result! i = ", i)
      return rnd
    }

    rnd = rnd.Add(rnd, big.NewInt(1))
  }

  return big.NewInt(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.NewKeccak224()
  sha.Reset()
  d := sha3.NewKeccak224()
  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(d.Sum(nil))
    pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1)
    sha.Write(dag.Node(L - 1, pk).Bytes())
  }

  ret.SetBytes(sha.Sum(nil))

  return ret
}

func (dag *Dagger) Eval(N *big.Int) *big.Int {
  pow := BigPow(2, 26)
  dag.xn = N.Div(N, pow)

  sha := sha3.NewKeccak224()
  sha.Reset()
  ret := new(big.Int)

  doneChan := make(chan bool, 3)

  for k := 0; k < 4; k++ {
    go func(_k int) {
      d := sha3.NewKeccak224()
      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())

      b.SetBytes(d.Sum(nil))
      pk := (b.Uint64() & 0x1ffffff)

      sha.Write(dag.Node(9, pk).Bytes())
      doneChan <- true
    }(k)
  }

  for k := 0; k < 4; k++ {
    <- doneChan
  }

  return ret.SetBytes(sha.Sum(nil))
}