mirror of https://github.com/ethereum/go-ethereum
parent
032ab66529
commit
fed3e6a808
@ -1,12 +0,0 @@ |
|||||||
package ar |
|
||||||
|
|
||||||
import ( |
|
||||||
"math/big" |
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/trie" |
|
||||||
) |
|
||||||
|
|
||||||
type Block interface { |
|
||||||
Trie() *trie.Trie |
|
||||||
Diff() *big.Int |
|
||||||
} |
|
@ -1,54 +0,0 @@ |
|||||||
package ar |
|
||||||
|
|
||||||
import "math/big" |
|
||||||
|
|
||||||
const lenops int64 = 9 |
|
||||||
|
|
||||||
type OpsFunc func(a, b *big.Int) *big.Int |
|
||||||
|
|
||||||
var ops [lenops]OpsFunc |
|
||||||
|
|
||||||
func init() { |
|
||||||
ops[0] = Add |
|
||||||
ops[1] = Mul |
|
||||||
ops[2] = Mod |
|
||||||
ops[3] = Xor |
|
||||||
ops[4] = And |
|
||||||
ops[5] = Or |
|
||||||
ops[6] = Sub1 |
|
||||||
ops[7] = XorSub |
|
||||||
ops[8] = Rsh |
|
||||||
} |
|
||||||
|
|
||||||
func Add(x, y *big.Int) *big.Int { |
|
||||||
return new(big.Int).Add(x, y) |
|
||||||
} |
|
||||||
func Mul(x, y *big.Int) *big.Int { |
|
||||||
return new(big.Int).Mul(x, y) |
|
||||||
} |
|
||||||
func Mod(x, y *big.Int) *big.Int { |
|
||||||
return new(big.Int).Mod(x, y) |
|
||||||
} |
|
||||||
func Xor(x, y *big.Int) *big.Int { |
|
||||||
return new(big.Int).Xor(x, y) |
|
||||||
} |
|
||||||
func And(x, y *big.Int) *big.Int { |
|
||||||
return new(big.Int).And(x, y) |
|
||||||
} |
|
||||||
func Or(x, y *big.Int) *big.Int { |
|
||||||
return new(big.Int).Or(x, y) |
|
||||||
} |
|
||||||
func Sub1(x, y *big.Int) *big.Int { |
|
||||||
a := big.NewInt(-1) |
|
||||||
a.Sub(a, x) |
|
||||||
|
|
||||||
return a |
|
||||||
} |
|
||||||
func XorSub(x, y *big.Int) *big.Int { |
|
||||||
t := Sub1(x, nil) |
|
||||||
|
|
||||||
return t.Xor(t, y) |
|
||||||
} |
|
||||||
func Rsh(x, y *big.Int) *big.Int { |
|
||||||
return new(big.Int).Rsh(x, uint(y.Uint64()%64)) |
|
||||||
} |
|
@ -1,122 +0,0 @@ |
|||||||
package ar |
|
||||||
|
|
||||||
import ( |
|
||||||
"math/big" |
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethutil" |
|
||||||
) |
|
||||||
|
|
||||||
type Entry struct { |
|
||||||
op OpsFunc |
|
||||||
i, j *big.Int |
|
||||||
} |
|
||||||
|
|
||||||
type Tape struct { |
|
||||||
tape []Entry |
|
||||||
block Block |
|
||||||
} |
|
||||||
|
|
||||||
func NewTape(block Block) *Tape { |
|
||||||
return &Tape{nil, block} |
|
||||||
} |
|
||||||
|
|
||||||
func (self *Tape) gen(w, h int64, gen NumberGenerator) { |
|
||||||
self.tape = nil |
|
||||||
|
|
||||||
for v := int64(0); v < h; v++ { |
|
||||||
op := ops[gen.rand64(lenops).Int64()] |
|
||||||
r := gen.rand64(100).Uint64() |
|
||||||
|
|
||||||
var j *big.Int |
|
||||||
if r < 20 && v > 20 { |
|
||||||
j = self.tape[len(self.tape)-1].i |
|
||||||
} else { |
|
||||||
j = gen.rand64(w) |
|
||||||
} |
|
||||||
|
|
||||||
i := gen.rand64(w) |
|
||||||
self.tape = append(self.tape, Entry{op, i, j}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
func (self *Tape) runTape(w, h int64, gen NumberGenerator) *big.Int { |
|
||||||
var mem []*big.Int |
|
||||||
for i := int64(0); i < w; i++ { |
|
||||||
mem = append(mem, gen.rand(ethutil.BigPow(2, 64))) |
|
||||||
} |
|
||||||
|
|
||||||
set := func(i, j int) Entry { |
|
||||||
entry := self.tape[i*100+j] |
|
||||||
mem[entry.i.Uint64()] = entry.op(entry.i, entry.j) |
|
||||||
|
|
||||||
return entry |
|
||||||
} |
|
||||||
|
|
||||||
dir := true |
|
||||||
for i := 0; i < int(h)/100; i++ { |
|
||||||
var entry Entry |
|
||||||
if dir { |
|
||||||
for j := 0; j < 100; j++ { |
|
||||||
entry = set(i, j) |
|
||||||
} |
|
||||||
} else { |
|
||||||
for j := 99; i >= 0; j-- { |
|
||||||
entry = set(i, j) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
t := mem[entry.i.Uint64()] |
|
||||||
if big.NewInt(2).Cmp(new(big.Int).Mod(t, big.NewInt(37))) < 0 { |
|
||||||
dir = !dir |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return Sha3(mem) |
|
||||||
} |
|
||||||
|
|
||||||
func (self *Tape) Verify(header, nonce []byte) bool { |
|
||||||
n := ethutil.BigD(nonce) |
|
||||||
|
|
||||||
var w int64 = 10000 |
|
||||||
var h int64 = 150000 |
|
||||||
gen := Rnd(Sha3([]interface{}{header, new(big.Int).Div(n, big.NewInt(1000))})) |
|
||||||
self.gen(w, h, gen) |
|
||||||
|
|
||||||
gen = Rnd(Sha3([]interface{}{header, new(big.Int).Mod(n, big.NewInt(1000))})) |
|
||||||
hash := self.runTape(w, h, gen) |
|
||||||
|
|
||||||
it := self.block.Trie().Iterator() |
|
||||||
next := it.Next(string(new(big.Int).Mod(hash, ethutil.BigPow(2, 160)).Bytes())) |
|
||||||
|
|
||||||
req := ethutil.BigPow(2, 256) |
|
||||||
req.Div(req, self.block.Diff()) |
|
||||||
return Sha3([]interface{}{hash, next}).Cmp(req) < 0 |
|
||||||
} |
|
||||||
|
|
||||||
func (self *Tape) Run(header []byte) []byte { |
|
||||||
nonce := big.NewInt(0) |
|
||||||
var w int64 = 10000 |
|
||||||
var h int64 = 150000 |
|
||||||
|
|
||||||
req := ethutil.BigPow(2, 256) |
|
||||||
req.Div(req, self.block.Diff()) |
|
||||||
|
|
||||||
for { |
|
||||||
if new(big.Int).Mod(nonce, b(1000)).Cmp(b(0)) == 0 { |
|
||||||
gen := Rnd(Sha3([]interface{}{header, new(big.Int).Div(nonce, big.NewInt(1000))})) |
|
||||||
self.gen(w, h, gen) |
|
||||||
} |
|
||||||
|
|
||||||
gen := Rnd(Sha3([]interface{}{header, new(big.Int).Mod(nonce, big.NewInt(1000))})) |
|
||||||
hash := self.runTape(w, h, gen) |
|
||||||
|
|
||||||
it := self.block.Trie().Iterator() |
|
||||||
next := it.Next(string(new(big.Int).Mod(hash, ethutil.BigPow(2, 160)).Bytes())) |
|
||||||
|
|
||||||
if Sha3([]interface{}{hash, next}).Cmp(req) < 0 { |
|
||||||
return nonce.Bytes() |
|
||||||
} else { |
|
||||||
nonce.Add(nonce, ethutil.Big1) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,47 +0,0 @@ |
|||||||
package ar |
|
||||||
|
|
||||||
import ( |
|
||||||
"fmt" |
|
||||||
"math/big" |
|
||||||
"testing" |
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb" |
|
||||||
"github.com/ethereum/go-ethereum/trie" |
|
||||||
) |
|
||||||
|
|
||||||
type TestBlock struct { |
|
||||||
trie *trie.Trie |
|
||||||
} |
|
||||||
|
|
||||||
func NewTestBlock() *TestBlock { |
|
||||||
db, _ := ethdb.NewMemDatabase() |
|
||||||
return &TestBlock{ |
|
||||||
trie: trie.New(db, ""), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
func (self *TestBlock) Diff() *big.Int { |
|
||||||
return b(10) |
|
||||||
} |
|
||||||
|
|
||||||
func (self *TestBlock) Trie() *trie.Trie { |
|
||||||
return self.trie |
|
||||||
} |
|
||||||
|
|
||||||
func (self *TestBlock) Hash() []byte { |
|
||||||
a := make([]byte, 32) |
|
||||||
a[0] = 10 |
|
||||||
a[1] = 2 |
|
||||||
return a |
|
||||||
} |
|
||||||
|
|
||||||
func TestPow(t *testing.T) { |
|
||||||
entry := make([]byte, 32) |
|
||||||
entry[0] = 255 |
|
||||||
|
|
||||||
block := NewTestBlock() |
|
||||||
|
|
||||||
pow := NewTape(block) |
|
||||||
nonce := pow.Run(block.Hash()) |
|
||||||
fmt.Println("Found nonce", nonce) |
|
||||||
} |
|
@ -1,66 +0,0 @@ |
|||||||
package ar |
|
||||||
|
|
||||||
import ( |
|
||||||
"math/big" |
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto" |
|
||||||
"github.com/ethereum/go-ethereum/ethutil" |
|
||||||
) |
|
||||||
|
|
||||||
var b = big.NewInt |
|
||||||
|
|
||||||
type Node interface { |
|
||||||
Big() *big.Int |
|
||||||
} |
|
||||||
|
|
||||||
type ByteNode []byte |
|
||||||
|
|
||||||
func (self ByteNode) Big() *big.Int { |
|
||||||
return ethutil.BigD(ethutil.Encode([]byte(self))) |
|
||||||
} |
|
||||||
|
|
||||||
func Sha3(v interface{}) *big.Int { |
|
||||||
if b, ok := v.(*big.Int); ok { |
|
||||||
return ethutil.BigD(crypto.Sha3(b.Bytes())) |
|
||||||
} else if b, ok := v.([]interface{}); ok { |
|
||||||
return ethutil.BigD(crypto.Sha3(ethutil.Encode(b))) |
|
||||||
} else if s, ok := v.([]*big.Int); ok { |
|
||||||
v := make([]interface{}, len(s)) |
|
||||||
for i, b := range s { |
|
||||||
v[i] = b |
|
||||||
} |
|
||||||
|
|
||||||
return ethutil.BigD(crypto.Sha3(ethutil.Encode(v))) |
|
||||||
} |
|
||||||
|
|
||||||
return nil |
|
||||||
} |
|
||||||
|
|
||||||
type NumberGenerator interface { |
|
||||||
rand(r *big.Int) *big.Int |
|
||||||
rand64(r int64) *big.Int |
|
||||||
} |
|
||||||
|
|
||||||
type rnd struct { |
|
||||||
seed *big.Int |
|
||||||
} |
|
||||||
|
|
||||||
func Rnd(s *big.Int) rnd { |
|
||||||
return rnd{s} |
|
||||||
} |
|
||||||
|
|
||||||
func (self rnd) rand(r *big.Int) *big.Int { |
|
||||||
o := b(0).Mod(self.seed, r) |
|
||||||
|
|
||||||
self.seed.Div(self.seed, r) |
|
||||||
|
|
||||||
if self.seed.Cmp(ethutil.BigPow(2, 64)) < 0 { |
|
||||||
self.seed = Sha3(self.seed) |
|
||||||
} |
|
||||||
|
|
||||||
return o |
|
||||||
} |
|
||||||
|
|
||||||
func (self rnd) rand64(r int64) *big.Int { |
|
||||||
return self.rand(b(r)) |
|
||||||
} |
|
Loading…
Reference in new issue