From 50659f4b480fb9446cfb40955331a7a044353ff8 Mon Sep 17 00:00:00 2001
From: Gustav Simonsson <gustav.simonsson@gmail.com>
Date: Tue, 5 May 2015 07:50:04 +0200
Subject: [PATCH] Update ethash Godeps files

---
 Godeps/Godeps.json                            |    4 +-
 .../github.com/ethereum/ethash/.travis.yml    |   19 +-
 .../src/github.com/ethereum/ethash/README.md  |   17 +-
 .../github.com/ethereum/ethash/appveyor.yml   |   43 +
 .../src/github.com/ethereum/ethash/ethash.go  |  576 +++----
 .../github.com/ethereum/ethash/ethash_test.go |  176 ++
 .../src/github.com/ethereum/ethash/ethashc.go |   24 +
 .../src/github.com/ethereum/ethash/setup.py   |   47 +-
 .../ethash/src/benchmark/CMakeLists.txt       |   46 +-
 .../ethash/src/benchmark/benchmark.cpp        |   63 +-
 .../ethash/src/libethash-cl/CMakeLists.txt    |    2 +-
 .../src/libethash-cl/ethash_cl_miner.cpp      |  143 +-
 .../ethash/src/libethash-cl/ethash_cl_miner.h |   26 +-
 .../libethash-cl/ethash_cl_miner_kernel.cl    |    5 +-
 .../ethash/src/libethash/CMakeLists.txt       |    5 +-
 .../ethash/src/libethash/data_sizes.h         | 1476 ++++++++---------
 .../ethereum/ethash/src/libethash/endian.h    |   74 +-
 .../ethereum/ethash/src/libethash/ethash.h    |  215 ++-
 .../ethereum/ethash/src/libethash/fnv.h       |    7 +-
 .../ethereum/ethash/src/libethash/internal.c  |  630 ++++---
 .../ethereum/ethash/src/libethash/internal.h  |  149 +-
 .../ethereum/ethash/src/libethash/io.c        |  129 +-
 .../ethereum/ethash/src/libethash/io.h        |  197 ++-
 .../ethereum/ethash/src/libethash/io_posix.c  |  102 +-
 .../ethereum/ethash/src/libethash/io_win32.c  |  103 +-
 .../ethereum/ethash/src/libethash/mmap.h      |   47 +
 .../ethash/src/libethash/mmap_win32.c         |   84 +
 .../ethereum/ethash/src/libethash/sha3.c      |  194 +--
 .../ethereum/ethash/src/libethash/sha3.h      |   12 +-
 .../ethash/src/libethash/sha3_cryptopp.cpp    |   14 +-
 .../ethash/src/libethash/sha3_cryptopp.h      |    7 +-
 .../ethereum/ethash/src/libethash/util.h      |    2 +-
 .../src/libethash/{util.c => util_win32.c}    |    9 +-
 .../ethereum/ethash/src/python/core.c         |   79 +-
 .../ethereum/ethash/test/c/CMakeLists.txt     |   13 +-
 .../ethereum/ethash/test/c/test.cpp           |  879 ++++++----
 .../github.com/ethereum/ethash/test/c/test.sh |   13 +
 .../ethereum/ethash/test/go/ethash_test.go    |   82 -
 .../github.com/ethereum/ethash/test/test.sh   |    9 +-
 39 files changed, 3369 insertions(+), 2353 deletions(-)
 create mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/appveyor.yml
 create mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/ethash_test.go
 create mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/ethashc.go
 create mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/mmap.h
 create mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/mmap_win32.c
 rename Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/{util.c => util_win32.c} (85%)
 delete mode 100644 Godeps/_workspace/src/github.com/ethereum/ethash/test/go/ethash_test.go

diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index 41cb28a12..9dadd49c9 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -17,8 +17,8 @@
 		},
 		{
 			"ImportPath": "github.com/ethereum/ethash",
-			"Comment": "v23.1-82-g908aad3",
-			"Rev": "908aad345c9fbf3ab9bbb94031dc02d0d90df1b8"
+			"Comment": "v23.1-192-g4faa4cb",
+			"Rev": "4faa4cb42ae7f0ea6b4aa2c90cb9170fdcbb915a"
 		},
 		{
 			"ImportPath": "github.com/howeyc/fsnotify",
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/.travis.yml b/Godeps/_workspace/src/github.com/ethereum/ethash/.travis.yml
index 30e944a68..b83b02bf3 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/.travis.yml
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/.travis.yml
@@ -1,14 +1,23 @@
-# making our travis.yml play well with C++11 by obtaining g++4.8
-# Taken from this file:
-# https://github.com/beark/ftl/blob/master/.travis.yml
+language: go
+go:
+  - 1.4.2
+
 before_install:
+  # for g++4.8 and C++11
   - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
+
+  # Set up go-ethereum
   - sudo apt-get update -y -qq
+  - sudo apt-get install -yqq libgmp3-dev 
+  - git clone --depth=10 https://github.com/ethereum/go-ethereum ${GOPATH}/src/github.com/ethereum/go-ethereum
+  # use canned dependencies from the go-ethereum repository
+  - export GOPATH=$GOPATH:$GOPATH/src/github.com/ethereum/go-ethereum/Godeps/_workspace/
+  - echo $GOPATH
 
 install:
+  # need to explicitly request version 1.48 since by default we get 1.46 which does not work with C++11
   - sudo apt-get install -qq --yes --force-yes g++-4.8
   - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50
-  # need to explicitly request version 1.48 since by default we get 1.46 which does not work with C++11
-  - sudo apt-get install -qq wget cmake bash libboost-test1.48-dev libboost-system1.48-dev libboost-filesystem1.48-dev nodejs python-pip python-dev
+  - sudo apt-get install -qq wget cmake bash libboost-test1.48-dev libboost-system1.48-dev libboost-filesystem1.48-dev nodejs python-pip python-dev valgrind
   - sudo pip install virtualenv -q
 script: "./test/test.sh"
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/README.md b/Godeps/_workspace/src/github.com/ethereum/ethash/README.md
index 8b9e015cf..2b2c3b544 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/README.md
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/README.md
@@ -1,7 +1,22 @@
 [![Build Status](https://travis-ci.org/ethereum/ethash.svg?branch=master)](https://travis-ci.org/ethereum/ethash)
-
+[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/debris/ethash?branch=master&svg=true)](https://ci.appveyor.com/project/debris/ethash-nr37r/branch/master)
 
 # Ethash
 
 For details on this project, please see the Ethereum wiki:
 https://github.com/ethereum/wiki/wiki/Ethash
+
+### Coding Style for C++ code:
+
+Follow the same exact style as in [cpp-ethereum](https://github.com/ethereum/cpp-ethereum/blob/develop/CodingStandards.txt)
+
+### Coding Style for C code:
+
+The main thing above all is code consistency.
+
+- Tabs for indentation. A tab is 4 spaces
+- Try to stick to the [K&R](http://en.wikipedia.org/wiki/Indent_style#K.26R_style),
+  especially for the C code.
+- Keep the line lengths reasonable. No hard limit on 80 characters but don't go further
+  than 110. Some people work with multiple buffers next to each other.
+  Make them like you :)
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/appveyor.yml b/Godeps/_workspace/src/github.com/ethereum/ethash/appveyor.yml
new file mode 100644
index 000000000..ac36a0626
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/appveyor.yml
@@ -0,0 +1,43 @@
+version: 1.0.0.{build}
+
+environment:
+    BOOST_ROOT: "c:/projects/ethash/deps/boost"
+
+branches:
+    only:
+        - master
+        - develop
+
+os: Windows Server 2012 R2
+
+clone_folder: c:\projects\ethash
+
+#platform: Any CPU
+#configuration: Debug
+
+install:
+    # by default, all script lines are interpreted as batch
+
+# scripts to run before build
+before_build:
+    - echo "Downloading boost..."
+    - mkdir c:\projects\ethash\deps
+    - cd c:\projects\ethash\deps
+    - curl -O https://build.ethdev.com/builds/windows-precompiled/boost.tar.gz
+    - echo "Unzipping boost..."
+    - 7z x boost.tar.gz > nul
+    - 7z x boost.tar > nul
+    - ls
+    - echo "Running cmake..."
+    - cd c:\projects\ethash
+    - cmake .
+
+build:
+    project: ALL_BUILD.vcxproj      # path to Visual Studio solution or project
+
+after_build:
+    - echo "Running tests..."
+    - cd c:\projects\ethash\test\c\Debug
+    - Test.exe
+    - echo "Finished!"
+
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go
index 74285a33c..1ee980765 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go
@@ -1,32 +1,22 @@
-/*
-###################################################################################
-###################################################################################
-####################                                           ####################
-####################  EDIT AND YOU SHALL FEEL MY WRATH - jeff  ####################
-####################                                           ####################
-###################################################################################
-###################################################################################
-*/
-
 package ethash
 
 /*
-#cgo CFLAGS: -std=gnu99 -Wall
-#include "src/libethash/util.c"
-#include "src/libethash/internal.c"
-#include "src/libethash/sha3.c"
+#include "src/libethash/internal.h"
+
+int ethashGoCallback_cgo(unsigned);
 */
 import "C"
 
 import (
-	"bytes"
-	"encoding/binary"
+	"errors"
 	"fmt"
 	"io/ioutil"
 	"math/big"
 	"math/rand"
 	"os"
-	"path"
+	"os/user"
+	"path/filepath"
+	"runtime"
 	"sync"
 	"time"
 	"unsafe"
@@ -38,318 +28,267 @@ import (
 	"github.com/ethereum/go-ethereum/pow"
 )
 
-var minDifficulty = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0))
-
-type ParamsAndCache struct {
-	params *C.ethash_params
-	cache  *C.ethash_cache
-	Epoch  uint64
-}
-
-type DAG struct {
-	dag            unsafe.Pointer // full GB of memory for dag
-	file           bool
-	paramsAndCache *ParamsAndCache
-}
-
-type Ethash struct {
-	turbo          bool
-	HashRate       int64
-	chainManager   pow.ChainManager
-	dag            *DAG
-	paramsAndCache *ParamsAndCache
-	ret            *C.ethash_return_value
-	dagMutex       *sync.RWMutex
-	cacheMutex     *sync.RWMutex
-}
+var (
+	minDifficulty = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0))
+	sharedLight   = new(Light)
+)
 
-func parseNonce(nonce []byte) (uint64, error) {
-	nonceBuf := bytes.NewBuffer(nonce)
-	nonceInt, err := binary.ReadUvarint(nonceBuf)
-	if err != nil {
-		return 0, err
-	}
-	return nonceInt, nil
-}
+const (
+	epochLength         uint64     = 30000
+	cacheSizeForTesting C.uint64_t = 1024
+	dagSizeForTesting   C.uint64_t = 1024 * 32
+)
 
-const epochLength uint64 = 30000
+var DefaultDir = defaultDir()
 
-func makeParamsAndCache(chainManager pow.ChainManager, blockNum uint64) (*ParamsAndCache, error) {
-	if blockNum >= epochLength*2048 {
-		return nil, fmt.Errorf("block number is out of bounds (value %v, limit is %v)", blockNum, epochLength*2048)
+func defaultDir() string {
+	home := os.Getenv("HOME")
+	if user, err := user.Current(); err == nil {
+		home = user.HomeDir
 	}
-	paramsAndCache := &ParamsAndCache{
-		params: new(C.ethash_params),
-		cache:  new(C.ethash_cache),
-		Epoch:  blockNum / epochLength,
+	if runtime.GOOS == "windows" {
+		return filepath.Join(home, "AppData", "Ethash")
 	}
-	C.ethash_params_init(paramsAndCache.params, C.uint32_t(uint32(blockNum)))
-	paramsAndCache.cache.mem = C.malloc(C.size_t(paramsAndCache.params.cache_size))
-
-	seedHash, err := GetSeedHash(blockNum)
-	if err != nil {
-		return nil, err
-	}
-
-	glog.V(logger.Info).Infof("Making cache for epoch: %d (%v) (%x)\n", paramsAndCache.Epoch, blockNum, seedHash)
-	start := time.Now()
-	C.ethash_mkcache(paramsAndCache.cache, paramsAndCache.params, (*C.ethash_blockhash_t)(unsafe.Pointer(&seedHash[0])))
+	return filepath.Join(home, ".ethash")
+}
 
-	if glog.V(logger.Info) {
-		glog.Infoln("Took:", time.Since(start))
-	}
+// cache wraps an ethash_light_t with some metadata
+// and automatic memory management.
+type cache struct {
+	epoch uint64
+	test  bool
 
-	return paramsAndCache, nil
+	gen sync.Once // ensures cache is only generated once.
+	ptr *C.struct_ethash_light
 }
 
-func (pow *Ethash) UpdateCache(blockNum uint64, force bool) error {
-	pow.cacheMutex.Lock()
-	defer pow.cacheMutex.Unlock()
-
-	thisEpoch := blockNum / epochLength
-	if force || pow.paramsAndCache.Epoch != thisEpoch {
-		var err error
-		pow.paramsAndCache, err = makeParamsAndCache(pow.chainManager, blockNum)
-		if err != nil {
-			panic(err)
+// generate creates the actual cache. it can be called from multiple
+// goroutines. the first call will generate the cache, subsequent
+// calls wait until it is generated.
+func (cache *cache) generate() {
+	cache.gen.Do(func() {
+		started := time.Now()
+		seedHash := makeSeedHash(cache.epoch)
+		glog.V(logger.Debug).Infof("Generating cache for epoch %d (%x)", cache.epoch, seedHash)
+		size := C.ethash_get_cachesize(C.uint64_t(cache.epoch * epochLength))
+		if cache.test {
+			size = cacheSizeForTesting
 		}
-	}
-
-	return nil
+		cache.ptr = C.ethash_light_new_internal(size, (*C.ethash_h256_t)(unsafe.Pointer(&seedHash[0])))
+		runtime.SetFinalizer(cache, freeCache)
+		glog.V(logger.Debug).Infof("Done generating cache for epoch %d, it took %v", cache.epoch, time.Since(started))
+	})
 }
 
-func makeDAG(p *ParamsAndCache) *DAG {
-	d := &DAG{
-		dag:            C.malloc(C.size_t(p.params.full_size)),
-		file:           false,
-		paramsAndCache: p,
-	}
+func freeCache(cache *cache) {
+	C.ethash_light_delete(cache.ptr)
+	cache.ptr = nil
+}
 
-	donech := make(chan string)
-	go func() {
-		t := time.NewTicker(5 * time.Second)
-		tstart := time.Now()
-	done:
-		for {
-			select {
-			case <-t.C:
-				glog.V(logger.Info).Infof("... still generating DAG (%v) ...\n", time.Since(tstart).Seconds())
-			case str := <-donech:
-				glog.V(logger.Info).Infof("... %s ...\n", str)
-				break done
-			}
-		}
-	}()
-	C.ethash_compute_full_data(d.dag, p.params, p.cache)
-	donech <- "DAG generation completed"
-	return d
+// Light implements the Verify half of the proof of work.
+// It uses a small in-memory cache to verify the nonces
+// found by Full.
+type Light struct {
+	test    bool       // if set use a smaller cache size
+	mu      sync.Mutex // protects current
+	current *cache     // last cache which was generated.
+	// TODO: keep multiple caches.
 }
 
-func (pow *Ethash) writeDagToDisk(dag *DAG, epoch uint64) *os.File {
-	if epoch > 2048 {
-		panic(fmt.Errorf("Epoch must be less than 2048 (is %v)", epoch))
+// Verify checks whether the block's nonce is valid.
+func (l *Light) Verify(block pow.Block) bool {
+	// TODO: do ethash_quick_verify before getCache in order
+	// to prevent DOS attacks.
+	var (
+		blockNum   = block.NumberU64()
+		difficulty = block.Difficulty()
+		cache      = l.getCache(blockNum)
+		dagSize    = C.ethash_get_datasize(C.uint64_t(blockNum))
+	)
+	if l.test {
+		dagSize = dagSizeForTesting
 	}
-	data := C.GoBytes(unsafe.Pointer(dag.dag), C.int(dag.paramsAndCache.params.full_size))
-	file, err := os.Create("/tmp/dag")
-	if err != nil {
-		panic(err)
+	if blockNum >= epochLength*2048 {
+		glog.V(logger.Debug).Infof("block number %d too high, limit is %d", epochLength*2048)
+		return false
 	}
+	// Recompute the hash using the cache.
+	hash := hashToH256(block.HashNoNonce())
+	ret := C.ethash_light_compute_internal(cache.ptr, dagSize, hash, C.uint64_t(block.Nonce()))
+	if !ret.success {
+		return false
+	}
+	// Make sure cache is live until after the C call.
+	// This is important because a GC might happen and execute
+	// the finalizer before the call completes.
+	_ = cache
+	// The actual check.
+	target := new(big.Int).Div(minDifficulty, difficulty)
+	return h256ToHash(ret.result).Big().Cmp(target) <= 0
+}
 
-	dataEpoch := make([]byte, 8)
-	binary.BigEndian.PutUint64(dataEpoch, epoch)
-
-	file.Write(dataEpoch)
-	file.Write(data)
+func h256ToHash(in C.struct_ethash_h256) common.Hash {
+	return *(*common.Hash)(unsafe.Pointer(&in.b))
+}
 
-	return file
+func hashToH256(in common.Hash) C.struct_ethash_h256 {
+	return C.struct_ethash_h256{b: *(*[32]C.uint8_t)(unsafe.Pointer(&in[0]))}
 }
 
-func (pow *Ethash) UpdateDAG() {
-	blockNum := pow.chainManager.CurrentBlock().NumberU64()
-	if blockNum >= epochLength*2048 {
-		// This will crash in the 2030s or 2040s
-		panic(fmt.Errorf("Current block number is out of bounds (value %v, limit is %v)", blockNum, epochLength*2048))
+func (l *Light) getCache(blockNum uint64) *cache {
+	var c *cache
+	epoch := blockNum / epochLength
+	// Update or reuse the last cache.
+	l.mu.Lock()
+	if l.current != nil && l.current.epoch == epoch {
+		c = l.current
+	} else {
+		c = &cache{epoch: epoch, test: l.test}
+		l.current = c
 	}
+	l.mu.Unlock()
+	// Wait for the cache to finish generating.
+	c.generate()
+	return c
+}
 
-	pow.dagMutex.Lock()
-	defer pow.dagMutex.Unlock()
-	thisEpoch := blockNum / epochLength
-	if pow.dag == nil || pow.dag.paramsAndCache.Epoch != thisEpoch {
-		if pow.dag != nil && pow.dag.dag != nil {
-			C.free(pow.dag.dag)
-			pow.dag.dag = nil
-		}
+// dag wraps an ethash_full_t with some metadata
+// and automatic memory management.
+type dag struct {
+	epoch uint64
+	test  bool
+	dir   string
 
-		if pow.dag != nil && pow.dag.paramsAndCache.cache.mem != nil {
-			C.free(pow.dag.paramsAndCache.cache.mem)
-			pow.dag.paramsAndCache.cache.mem = nil
-		}
+	gen sync.Once // ensures DAG is only generated once.
+	ptr *C.struct_ethash_full
+}
 
-		// Make the params and cache for the DAG
-		paramsAndCache, err := makeParamsAndCache(pow.chainManager, blockNum)
-		if err != nil {
-			panic(err)
+// generate creates the actual DAG. it can be called from multiple
+// goroutines. the first call will generate the DAG, subsequent
+// calls wait until it is generated.
+func (d *dag) generate() {
+	d.gen.Do(func() {
+		var (
+			started   = time.Now()
+			seedHash  = makeSeedHash(d.epoch)
+			blockNum  = C.uint64_t(d.epoch * epochLength)
+			cacheSize = C.ethash_get_cachesize(blockNum)
+			dagSize   = C.ethash_get_datasize(blockNum)
+		)
+		if d.test {
+			cacheSize = cacheSizeForTesting
+			dagSize = dagSizeForTesting
 		}
-
-		// TODO: On non-SSD disks, loading the DAG from disk takes longer than generating it in memory
-		pow.paramsAndCache = paramsAndCache
-		path := path.Join("/", "tmp", "dag")
-		pow.dag = nil
-		glog.V(logger.Info).Infoln("Retrieving DAG")
-		start := time.Now()
-
-		file, err := os.Open(path)
-		if err != nil {
-			glog.V(logger.Info).Infof("No DAG found. Generating new DAG in '%s' (this takes a while)...\n", path)
-			pow.dag = makeDAG(paramsAndCache)
-			file = pow.writeDagToDisk(pow.dag, thisEpoch)
-			pow.dag.file = true
-		} else {
-			data, err := ioutil.ReadAll(file)
-			if err != nil {
-				glog.V(logger.Info).Infof("DAG load err: %v\n", err)
-			}
-
-			if len(data) < 8 {
-				glog.V(logger.Info).Infof("DAG in '%s' is less than 8 bytes, it must be corrupted. Generating new DAG (this takes a while)...\n", path)
-				pow.dag = makeDAG(paramsAndCache)
-				file = pow.writeDagToDisk(pow.dag, thisEpoch)
-				pow.dag.file = true
-			} else {
-				dataEpoch := binary.BigEndian.Uint64(data[0:8])
-				if dataEpoch < thisEpoch {
-					glog.V(logger.Info).Infof("DAG in '%s' is stale. Generating new DAG (this takes a while)...\n", path)
-					pow.dag = makeDAG(paramsAndCache)
-					file = pow.writeDagToDisk(pow.dag, thisEpoch)
-					pow.dag.file = true
-				} else if dataEpoch > thisEpoch {
-					// FIXME
-					panic(fmt.Errorf("Saved DAG in '%s' reports to be from future epoch %v (current epoch is %v)\n", path, dataEpoch, thisEpoch))
-				} else if len(data) != (int(paramsAndCache.params.full_size) + 8) {
-					glog.V(logger.Info).Infof("DAG in '%s' is corrupted. Generating new DAG (this takes a while)...\n", path)
-					pow.dag = makeDAG(paramsAndCache)
-					file = pow.writeDagToDisk(pow.dag, thisEpoch)
-					pow.dag.file = true
-				} else {
-					data = data[8:]
-					pow.dag = &DAG{
-						dag:            unsafe.Pointer(&data[0]),
-						file:           true,
-						paramsAndCache: paramsAndCache,
-					}
-				}
-			}
+		if d.dir == "" {
+			d.dir = DefaultDir
 		}
-		glog.V(logger.Info).Infoln("Took:", time.Since(start))
-
-		file.Close()
-	}
-}
-
-func New(chainManager pow.ChainManager) *Ethash {
-	paramsAndCache, err := makeParamsAndCache(chainManager, chainManager.CurrentBlock().NumberU64())
-	if err != nil {
-		panic(err)
-	}
-
-	return &Ethash{
-		turbo:          true,
-		paramsAndCache: paramsAndCache,
-		chainManager:   chainManager,
-		dag:            nil,
-		cacheMutex:     new(sync.RWMutex),
-		dagMutex:       new(sync.RWMutex),
-	}
+		glog.V(logger.Info).Infof("Generating DAG for epoch %d (%x)", d.epoch, seedHash)
+		// Generate a temporary cache.
+		// TODO: this could share the cache with Light
+		cache := C.ethash_light_new_internal(cacheSize, (*C.ethash_h256_t)(unsafe.Pointer(&seedHash[0])))
+		defer C.ethash_light_delete(cache)
+		// Generate the actual DAG.
+		d.ptr = C.ethash_full_new_internal(
+			C.CString(d.dir),
+			hashToH256(seedHash),
+			dagSize,
+			cache,
+			(C.ethash_callback_t)(unsafe.Pointer(C.ethashGoCallback_cgo)),
+		)
+		if d.ptr == nil {
+			panic("ethash_full_new IO or memory error")
+		}
+		runtime.SetFinalizer(d, freeDAG)
+		glog.V(logger.Info).Infof("Done generating DAG for epoch %d, it took %v", d.epoch, time.Since(started))
+	})
 }
 
-func (pow *Ethash) DAGSize() uint64 {
-	return uint64(pow.dag.paramsAndCache.params.full_size)
+func freeDAG(h *dag) {
+	C.ethash_full_delete(h.ptr)
+	h.ptr = nil
 }
 
-func (pow *Ethash) CacheSize() uint64 {
-	return uint64(pow.paramsAndCache.params.cache_size)
+//export ethashGoCallback
+func ethashGoCallback(percent C.unsigned) C.int {
+	glog.V(logger.Info).Infof("Still generating DAG: %d%%", percent)
+	return 0
 }
 
-func GetSeedHash(blockNum uint64) ([]byte, error) {
+// MakeDAG pre-generates a DAG file for the given block number in the
+// given directory. If dir is the empty string, the default directory
+// is used.
+func MakeDAG(blockNum uint64, dir string) error {
+	d := &dag{epoch: blockNum / epochLength, dir: dir}
 	if blockNum >= epochLength*2048 {
-		return nil, fmt.Errorf("block number is out of bounds (value %v, limit is %v)", blockNum, epochLength*2048)
-	}
-
-	epoch := blockNum / epochLength
-	seedHash := make([]byte, 32)
-	var i uint64
-	for i = 0; i < 32; i++ {
-		seedHash[i] = 0
+		return fmt.Errorf("block number too high, limit is %d", epochLength*2048)
 	}
-	for i = 0; i < epoch; i++ {
-		seedHash = crypto.Sha3(seedHash)
+	d.generate()
+	if d.ptr == nil {
+		return errors.New("failed")
 	}
-	return seedHash, nil
+	return nil
 }
 
-func (pow *Ethash) Stop() {
-	pow.cacheMutex.Lock()
-	pow.dagMutex.Lock()
-	defer pow.dagMutex.Unlock()
-	defer pow.cacheMutex.Unlock()
+// Full implements the Search half of the proof of work.
+type Full struct {
+	Dir string // use this to specify a non-default DAG directory
 
-	if pow.paramsAndCache.cache != nil {
-		C.free(pow.paramsAndCache.cache.mem)
-	}
-	if pow.dag.dag != nil && !pow.dag.file {
-		C.free(pow.dag.dag)
-	}
-	if pow.dag != nil && pow.dag.paramsAndCache != nil && pow.dag.paramsAndCache.cache.mem != nil {
-		C.free(pow.dag.paramsAndCache.cache.mem)
-		pow.dag.paramsAndCache.cache.mem = nil
-	}
-	pow.dag.dag = nil
+	test     bool // if set use a smaller DAG size
+	turbo    bool
+	hashRate int64
+
+	mu      sync.Mutex // protects dag
+	current *dag       // current full DAG
 }
 
-func (pow *Ethash) Search(block pow.Block, stop <-chan struct{}) (uint64, []byte, []byte) {
-	pow.UpdateDAG()
+func (pow *Full) getDAG(blockNum uint64) (d *dag) {
+	epoch := blockNum / epochLength
+	pow.mu.Lock()
+	if pow.current != nil && pow.current.epoch == epoch {
+		d = pow.current
+	} else {
+		d = &dag{epoch: epoch, test: pow.test, dir: pow.Dir}
+		pow.current = d
+	}
+	pow.mu.Unlock()
+	// wait for it to finish generating.
+	d.generate()
+	return d
+}
 
-	pow.dagMutex.RLock()
-	defer pow.dagMutex.RUnlock()
+func (pow *Full) Search(block pow.Block, stop <-chan struct{}) (nonce uint64, mixDigest []byte) {
+	dag := pow.getDAG(block.NumberU64())
 
 	r := rand.New(rand.NewSource(time.Now().UnixNano()))
-	miningHash := block.HashNoNonce()
 	diff := block.Difficulty()
 
 	i := int64(0)
 	starti := i
 	start := time.Now().UnixNano()
 
-	nonce := uint64(r.Int63())
-	cMiningHash := (*C.ethash_blockhash_t)(unsafe.Pointer(&miningHash[0]))
+	nonce = uint64(r.Int63())
+	hash := hashToH256(block.HashNoNonce())
 	target := new(big.Int).Div(minDifficulty, diff)
-
-	var ret C.ethash_return_value
 	for {
 		select {
 		case <-stop:
-			pow.HashRate = 0
-			return 0, nil, nil
+			pow.hashRate = 0
+			return 0, nil
 		default:
 			i++
 
 			elapsed := time.Now().UnixNano() - start
 			hashes := ((float64(1e9) / float64(elapsed)) * float64(i-starti)) / 1000
-			pow.HashRate = int64(hashes)
+			pow.hashRate = int64(hashes)
 
-			C.ethash_full(&ret, pow.dag.dag, pow.dag.paramsAndCache.params, cMiningHash, C.uint64_t(nonce))
-			result := common.Bytes2Big(C.GoBytes(unsafe.Pointer(&ret.result), C.int(32)))
+			ret := C.ethash_full_compute(dag.ptr, hash, C.uint64_t(nonce))
+			result := h256ToHash(ret.result).Big()
 
 			// TODO: disagrees with the spec https://github.com/ethereum/wiki/wiki/Ethash#mining
-			if result.Cmp(target) <= 0 {
-				mixDigest := C.GoBytes(unsafe.Pointer(&ret.mix_hash), C.int(32))
-				seedHash, err := GetSeedHash(block.NumberU64()) // This seedhash is useless
-				if err != nil {
-					panic(err)
-				}
-				return nonce, mixDigest, seedHash
+			if ret.success && result.Cmp(target) <= 0 {
+				mixDigest = C.GoBytes(unsafe.Pointer(&ret.mix_hash), C.int(32))
+				return nonce, mixDigest
 			}
-
 			nonce += 1
 		}
 
@@ -357,82 +296,57 @@ func (pow *Ethash) Search(block pow.Block, stop <-chan struct{}) (uint64, []byte
 			time.Sleep(20 * time.Microsecond)
 		}
 	}
-
 }
 
-func (pow *Ethash) Verify(block pow.Block) bool {
-
-	return pow.verify(block.HashNoNonce(), block.MixDigest(), block.Difficulty(), block.NumberU64(), block.Nonce())
+func (pow *Full) GetHashrate() int64 {
+	// TODO: this needs to use an atomic operation.
+	return pow.hashRate
 }
 
-func (pow *Ethash) verify(hash common.Hash, mixDigest common.Hash, difficulty *big.Int, blockNum uint64, nonce uint64) bool {
-	// Make sure the block num is valid
-	if blockNum >= epochLength*2048 {
-		glog.V(logger.Info).Infoln(fmt.Sprintf("Block number exceeds limit, invalid (value is %v, limit is %v)",
-			blockNum, epochLength*2048))
-		return false
-	}
-
-	// First check: make sure header, mixDigest, nonce are correct without hitting the cache
-	// This is to prevent DOS attacks
-	chash := (*C.ethash_blockhash_t)(unsafe.Pointer(&hash[0]))
-	cnonce := C.uint64_t(nonce)
-	target := new(big.Int).Div(minDifficulty, difficulty)
-
-	var pAc *ParamsAndCache
-	// If its an old block (doesn't use the current cache)
-	// get the cache for it but don't update (so we don't need the mutex)
-	// Otherwise, it's the current block or a future block.
-	// If current, updateCache will do nothing.
-	if blockNum/epochLength < pow.paramsAndCache.Epoch {
-		var err error
-		// If we can't make the params for some reason, this block is invalid
-		pAc, err = makeParamsAndCache(pow.chainManager, blockNum)
-		if err != nil {
-			glog.V(logger.Info).Infoln("big fucking eror", err)
-			return false
-		}
-	} else {
-		pow.UpdateCache(blockNum, false)
-		pow.cacheMutex.RLock()
-		defer pow.cacheMutex.RUnlock()
-		pAc = pow.paramsAndCache
-	}
-
-	ret := new(C.ethash_return_value)
-
-	C.ethash_light(ret, pAc.cache, pAc.params, chash, cnonce)
+func (pow *Full) Turbo(on bool) {
+	// TODO: this needs to use an atomic operation.
+	pow.turbo = on
+}
 
-	result := common.Bytes2Big(C.GoBytes(unsafe.Pointer(&ret.result), C.int(32)))
-	return result.Cmp(target) <= 0
+// Ethash combines block verification with Light and
+// nonce searching with Full into a single proof of work.
+type Ethash struct {
+	*Light
+	*Full
 }
 
-func (pow *Ethash) GetHashrate() int64 {
-	return pow.HashRate
+// New creates an instance of the proof of work.
+// A single instance of Light is shared across all instances
+// created with New.
+func New() *Ethash {
+	return &Ethash{sharedLight, &Full{turbo: true}}
 }
 
-func (pow *Ethash) Turbo(on bool) {
-	pow.turbo = on
+// NewForTesting creates a proof of work for use in unit tests.
+// It uses a smaller DAG and cache size to keep test times low.
+// DAG files are stored in a temporary directory.
+//
+// Nonces found by a testing instance are not verifiable with a
+// regular-size cache.
+func NewForTesting() (*Ethash, error) {
+	dir, err := ioutil.TempDir("", "ethash-test")
+	if err != nil {
+		return nil, err
+	}
+	return &Ethash{&Light{test: true}, &Full{Dir: dir, test: true}}, nil
 }
 
-func (pow *Ethash) FullHash(nonce uint64, miningHash []byte) []byte {
-	pow.UpdateDAG()
-	pow.dagMutex.Lock()
-	defer pow.dagMutex.Unlock()
-	cMiningHash := (*C.ethash_blockhash_t)(unsafe.Pointer(&miningHash[0]))
-	cnonce := C.uint64_t(nonce)
-	ret := new(C.ethash_return_value)
-	// pow.hash is the output/return of ethash_full
-	C.ethash_full(ret, pow.dag.dag, pow.paramsAndCache.params, cMiningHash, cnonce)
-	ghash_full := C.GoBytes(unsafe.Pointer(&ret.result), 32)
-	return ghash_full
+func GetSeedHash(blockNum uint64) ([]byte, error) {
+	if blockNum >= epochLength*2048 {
+		return nil, fmt.Errorf("block number too high, limit is %d", epochLength*2048)
+	}
+	sh := makeSeedHash(blockNum / epochLength)
+	return sh[:], nil
 }
 
-func (pow *Ethash) LightHash(nonce uint64, miningHash []byte) []byte {
-	cMiningHash := (*C.ethash_blockhash_t)(unsafe.Pointer(&miningHash[0]))
-	cnonce := C.uint64_t(nonce)
-	ret := new(C.ethash_return_value)
-	C.ethash_light(ret, pow.paramsAndCache.cache, pow.paramsAndCache.params, cMiningHash, cnonce)
-	ghash_light := C.GoBytes(unsafe.Pointer(&ret.result), 32)
-	return ghash_light
+func makeSeedHash(epoch uint64) (sh common.Hash) {
+	for ; epoch > 0; epoch-- {
+		sh = crypto.Sha3Hash(sh[:])
+	}
+	return sh
 }
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/ethash_test.go b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash_test.go
new file mode 100644
index 000000000..42be77b94
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/ethash_test.go
@@ -0,0 +1,176 @@
+package ethash
+
+import (
+	"bytes"
+	"crypto/rand"
+	"encoding/hex"
+	"log"
+	"math/big"
+	"os"
+	"sync"
+	"testing"
+
+	"github.com/ethereum/go-ethereum/common"
+)
+
+func init() {
+	// glog.SetV(6)
+	// glog.SetToStderr(true)
+}
+
+type testBlock struct {
+	difficulty  *big.Int
+	hashNoNonce common.Hash
+	nonce       uint64
+	mixDigest   common.Hash
+	number      uint64
+}
+
+func (b *testBlock) Difficulty() *big.Int     { return b.difficulty }
+func (b *testBlock) HashNoNonce() common.Hash { return b.hashNoNonce }
+func (b *testBlock) Nonce() uint64            { return b.nonce }
+func (b *testBlock) MixDigest() common.Hash   { return b.mixDigest }
+func (b *testBlock) NumberU64() uint64        { return b.number }
+
+var validBlocks = []*testBlock{
+	// from proof of concept nine testnet, epoch 0
+	{
+		number:      22,
+		hashNoNonce: common.HexToHash("372eca2454ead349c3df0ab5d00b0b706b23e49d469387db91811cee0358fc6d"),
+		difficulty:  big.NewInt(132416),
+		nonce:       0x495732e0ed7a801c,
+	},
+	// from proof of concept nine testnet, epoch 1
+	{
+		number:      30001,
+		hashNoNonce: common.HexToHash("7e44356ee3441623bc72a683fd3708fdf75e971bbe294f33e539eedad4b92b34"),
+		difficulty:  big.NewInt(1532671),
+		nonce:       0x318df1c8adef7e5e,
+	},
+	// from proof of concept nine testnet, epoch 2
+	{
+		number:      60000,
+		hashNoNonce: common.HexToHash("5fc898f16035bf5ac9c6d9077ae1e3d5fc1ecc3c9fd5bee8bb00e810fdacbaa0"),
+		difficulty:  big.NewInt(2467358),
+		nonce:       0x50377003e5d830ca,
+	},
+}
+
+func TestEthashVerifyValid(t *testing.T) {
+	eth := New()
+	for i, block := range validBlocks {
+		if !eth.Verify(block) {
+			t.Errorf("block %d (%x) did not validate.", i, block.hashNoNonce[:6])
+		}
+	}
+}
+
+func TestEthashConcurrentVerify(t *testing.T) {
+	eth, err := NewForTesting()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(eth.Full.Dir)
+
+	block := &testBlock{difficulty: big.NewInt(10)}
+	nonce, _ := eth.Search(block, nil)
+	block.nonce = nonce
+
+	// Verify the block concurrently to check for data races.
+	var wg sync.WaitGroup
+	wg.Add(100)
+	for i := 0; i < 100; i++ {
+		go func() {
+			if !eth.Verify(block) {
+				t.Error("Block could not be verified")
+			}
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+}
+
+func TestEthashConcurrentSearch(t *testing.T) {
+	eth, err := NewForTesting()
+	if err != nil {
+		t.Fatal(err)
+	}
+	eth.Turbo(true)
+	defer os.RemoveAll(eth.Full.Dir)
+
+	// launch n searches concurrently.
+	var (
+		block   = &testBlock{difficulty: big.NewInt(35000)}
+		nsearch = 10
+		wg      = new(sync.WaitGroup)
+		found   = make(chan uint64)
+		stop    = make(chan struct{})
+	)
+	rand.Read(block.hashNoNonce[:])
+	wg.Add(nsearch)
+	for i := 0; i < nsearch; i++ {
+		go func() {
+			nonce, _ := eth.Search(block, stop)
+			select {
+			case found <- nonce:
+			case <-stop:
+			}
+			wg.Done()
+		}()
+	}
+
+	// wait for one of them to find the nonce
+	nonce := <-found
+	// stop the others
+	close(stop)
+	wg.Wait()
+
+	if block.nonce = nonce; !eth.Verify(block) {
+		t.Error("Block could not be verified")
+	}
+}
+
+func TestEthashSearchAcrossEpoch(t *testing.T) {
+	eth, err := NewForTesting()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(eth.Full.Dir)
+
+	for i := epochLength - 40; i < epochLength+40; i++ {
+		block := &testBlock{number: i, difficulty: big.NewInt(90)}
+		rand.Read(block.hashNoNonce[:])
+		nonce, _ := eth.Search(block, nil)
+		block.nonce = nonce
+		if !eth.Verify(block) {
+			t.Fatalf("Block could not be verified")
+		}
+	}
+}
+
+func TestGetSeedHash(t *testing.T) {
+	seed0, err := GetSeedHash(0)
+	if err != nil {
+		t.Errorf("Failed to get seedHash for block 0: %v", err)
+	}
+	if bytes.Compare(seed0, make([]byte, 32)) != 0 {
+		log.Printf("seedHash for block 0 should be 0s, was: %v\n", seed0)
+	}
+	seed1, err := GetSeedHash(30000)
+	if err != nil {
+		t.Error(err)
+	}
+
+	// From python:
+	// > from pyethash import get_seedhash
+	// > get_seedhash(30000)
+	expectedSeed1, err := hex.DecodeString("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")
+	if err != nil {
+		t.Error(err)
+	}
+
+	if bytes.Compare(seed1, expectedSeed1) != 0 {
+		log.Printf("seedHash for block 1 should be: %v,\nactual value: %v\n", expectedSeed1, seed1)
+	}
+
+}
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/ethashc.go b/Godeps/_workspace/src/github.com/ethereum/ethash/ethashc.go
new file mode 100644
index 000000000..9c208b3f2
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/ethashc.go
@@ -0,0 +1,24 @@
+package ethash
+
+/*
+#cgo CFLAGS: -std=gnu99 -Wall
+#cgo LDFLAGS: -lm
+
+#include "src/libethash/internal.c"
+#include "src/libethash/sha3.c"
+#include "src/libethash/io.c"
+
+#ifdef _WIN32
+#	include "src/libethash/util_win32.c"
+#	include "src/libethash/io_win32.c"
+#	include "src/libethash/mmap_win32.c"
+#else
+#	include "src/libethash/io_posix.c"
+#endif
+
+// 'gateway function' for calling back into go.
+extern int ethashGoCallback(unsigned);
+int ethashGoCallback_cgo(unsigned percent) { return ethashGoCallback(percent); }
+
+*/
+import "C"
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/setup.py b/Godeps/_workspace/src/github.com/ethereum/ethash/setup.py
index 6a6b93839..18aa20f6d 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/setup.py
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/setup.py
@@ -1,23 +1,36 @@
 #!/usr/bin/env python
+import os
 from distutils.core import setup, Extension
-
+sources = [
+    'src/python/core.c',
+    'src/libethash/io.c',
+    'src/libethash/internal.c',
+    'src/libethash/sha3.c']
+if os.name == 'nt':
+    sources += [
+        'src/libethash/util_win32.c',
+        'src/libethash/io_win32.c',
+        'src/libethash/mmap_win32.c',
+    ]
+else:
+    sources += [
+        'src/libethash/io_posix.c'
+    ]
+depends = [
+    'src/libethash/ethash.h',
+    'src/libethash/compiler.h',
+    'src/libethash/data_sizes.h',
+    'src/libethash/endian.h',
+    'src/libethash/ethash.h',
+    'src/libethash/io.h',
+    'src/libethash/fnv.h',
+    'src/libethash/internal.h',
+    'src/libethash/sha3.h',
+    'src/libethash/util.h',
+]
 pyethash = Extension('pyethash',
-                     sources=[
-                         'src/python/core.c',
-                         'src/libethash/util.c',
-                         'src/libethash/internal.c',
-                         'src/libethash/sha3.c'],
-                     depends=[
-                         'src/libethash/ethash.h',
-                         'src/libethash/compiler.h',
-                         'src/libethash/data_sizes.h',
-                         'src/libethash/endian.h',
-                         'src/libethash/ethash.h',
-                         'src/libethash/fnv.h',
-                         'src/libethash/internal.h',
-                         'src/libethash/sha3.h',
-                         'src/libethash/util.h'
-                     ],
+                     sources=sources,
+                     depends=depends,
                      extra_compile_args=["-Isrc/", "-std=gnu99", "-Wall"])
 
 setup(
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/CMakeLists.txt b/Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/CMakeLists.txt
index 840fe5146..3df4ab596 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/CMakeLists.txt
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/CMakeLists.txt
@@ -3,56 +3,56 @@ include_directories(..)
 set(CMAKE_BUILD_TYPE Release)
 
 if (MSVC)
-	add_definitions("/openmp")
+  add_definitions("/openmp")
 endif()
 
 # enable C++11, should probably be a bit more specific about compiler
 if (NOT MSVC)
-    SET(CMAKE_CXX_FLAGS "-std=c++11")
+  SET(CMAKE_CXX_FLAGS "-std=c++11")
 endif()
 
 if (NOT MPI_FOUND)
-    find_package(MPI)
+  find_package(MPI)
 endif()
 
 if (NOT CRYPTOPP_FOUND)
-	find_package(CryptoPP 5.6.2)
+  find_package(CryptoPP 5.6.2)
 endif()
 
 if (CRYPTOPP_FOUND)
-	add_definitions(-DWITH_CRYPTOPP)
+  add_definitions(-DWITH_CRYPTOPP)
+  find_package (Threads REQUIRED)
 endif()
 
 if (NOT OpenCL_FOUND)
-	find_package(OpenCL)
+  find_package(OpenCL)
 endif()
 if (OpenCL_FOUND)
-	add_definitions(-DWITH_OPENCL)
-	include_directories(${OpenCL_INCLUDE_DIRS})
-	list(APPEND FILES ethash_cl_miner.cpp ethash_cl_miner.h)
+  add_definitions(-DWITH_OPENCL)
+  include_directories(${OpenCL_INCLUDE_DIRS})
+  list(APPEND FILES ethash_cl_miner.cpp ethash_cl_miner.h)
 endif()
 
 if (MPI_FOUND)
-    include_directories(${MPI_INCLUDE_PATH})
-    add_executable (Benchmark_MPI_FULL benchmark.cpp)
-    target_link_libraries (Benchmark_MPI_FULL ${ETHHASH_LIBS} ${MPI_LIBRARIES})
-    SET_TARGET_PROPERTIES(Benchmark_MPI_FULL PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${MPI_COMPILE_FLAGS} -DFULL -DMPI")
+  include_directories(${MPI_INCLUDE_PATH})
+  add_executable (Benchmark_MPI_FULL benchmark.cpp)
+  target_link_libraries (Benchmark_MPI_FULL ${ETHHASH_LIBS} ${MPI_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+  SET_TARGET_PROPERTIES(Benchmark_MPI_FULL PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${MPI_COMPILE_FLAGS} -DFULL -DMPI")
 
-    add_executable (Benchmark_MPI_LIGHT benchmark.cpp)
-    target_link_libraries (Benchmark_MPI_LIGHT ${ETHHASH_LIBS} ${MPI_LIBRARIES})
-    SET_TARGET_PROPERTIES(Benchmark_MPI_LIGHT PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${MPI_COMPILE_FLAGS} -DMPI")
+  add_executable (Benchmark_MPI_LIGHT benchmark.cpp)
+  target_link_libraries (Benchmark_MPI_LIGHT ${ETHHASH_LIBS} ${MPI_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+  SET_TARGET_PROPERTIES(Benchmark_MPI_LIGHT PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${MPI_COMPILE_FLAGS} -DMPI")
 endif()
 
 add_executable (Benchmark_FULL benchmark.cpp)
-target_link_libraries (Benchmark_FULL ${ETHHASH_LIBS})
+target_link_libraries (Benchmark_FULL ${ETHHASH_LIBS} ${CMAKE_THREAD_LIBS_INIT})
 SET_TARGET_PROPERTIES(Benchmark_FULL PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -DFULL")
 
 add_executable (Benchmark_LIGHT benchmark.cpp)
-target_link_libraries (Benchmark_LIGHT ${ETHHASH_LIBS})
+target_link_libraries (Benchmark_LIGHT ${ETHHASH_LIBS} ${CMAKE_THREAD_LIBS_INIT})
 
 if (OpenCL_FOUND)
-	add_executable (Benchmark_CL benchmark.cpp)
-	target_link_libraries (Benchmark_CL ${ETHHASH_LIBS} ethash-cl)
-	SET_TARGET_PROPERTIES(Benchmark_CL PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -DOPENCL")
-endif()
-
+  add_executable (Benchmark_CL benchmark.cpp)
+  target_link_libraries (Benchmark_CL ${ETHHASH_LIBS} ethash-cl ${CMAKE_THREAD_LIBS_INIT})
+  SET_TARGET_PROPERTIES(Benchmark_CL PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -DOPENCL")
+endif()
\ No newline at end of file
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/benchmark.cpp b/Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/benchmark.cpp
index 2635c8038..1a648edf4 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/benchmark.cpp
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/benchmark.cpp
@@ -96,6 +96,11 @@ static std::string bytesToHexString(uint8_t const* bytes, unsigned size)
 	return str;
 }
 
+static std::string bytesToHexString(ethash_h256_t const *hash, unsigned size)
+{
+	return bytesToHexString((uint8_t*)hash, size);
+}
+
 extern "C" int main(void)
 {
 	// params for ethash
@@ -106,12 +111,12 @@ extern "C" int main(void)
 	//params.full_size = 8209 * 4096;	// 8MBish;
 	//params.cache_size = 8209*4096;
 	//params.cache_size = 2053*4096;
-	ethash_blockhash_t seed;
-	ethash_blockhash_t previous_hash;
+	ethash_h256_t seed;
+	ethash_h256_t previous_hash;
 
 	memcpy(&seed, hexStringToBytes("9410b944535a83d9adf6bbdcc80e051f30676173c16ca0d32d6f1263fc246466").data(), 32);
 	memcpy(&previous_hash, hexStringToBytes("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").data(), 32);
-	
+
 	// allocate page aligned buffer for dataset
 #ifdef FULL
 	void* full_mem_buf = malloc(params.full_size + 4095);
@@ -122,24 +127,24 @@ extern "C" int main(void)
 
 	ethash_cache cache;
 	cache.mem = cache_mem;
-	
+
 	// compute cache or full data
 	{
 		auto startTime = high_resolution_clock::now();
-		ethash_mkcache(&cache, &params, seed);
+		ethash_mkcache(&cache, &params, &seed);
 		auto time = std::chrono::duration_cast<std::chrono::milliseconds>(high_resolution_clock::now() - startTime).count();
 
-		ethash_blockhash_t cache_hash;
+		ethash_h256_t cache_hash;
 		SHA3_256(&cache_hash, (uint8_t const*)cache_mem, params.cache_size);
-		debugf("ethash_mkcache: %ums, sha3: %s\n", (unsigned)((time*1000)/CLOCKS_PER_SEC), bytesToHexString(cache_hash,sizeof(cache_hash)).data());
+		debugf("ethash_mkcache: %ums, sha3: %s\n", (unsigned)((time*1000)/CLOCKS_PER_SEC), bytesToHexString(&cache_hash, sizeof(cache_hash)).data());
 
 		// print a couple of test hashes
 		{
 			auto startTime = high_resolution_clock::now();
 			ethash_return_value hash;
-			ethash_light(&hash, &cache, &params, previous_hash, 0);
+			ethash_light(&hash, &cache, &params, &previous_hash, 0);
 			auto time = std::chrono::duration_cast<std::chrono::milliseconds>(high_resolution_clock::now() - startTime).count();
-			debugf("ethash_light test: %ums, %s\n", (unsigned)time, bytesToHexString(hash.result, 32).data());
+			debugf("ethash_light test: %ums, %s\n", (unsigned)time, bytesToHexString(&hash.result, 32).data());
 		}
 
 		#ifdef FULL
@@ -154,34 +159,34 @@ extern "C" int main(void)
 	ethash_cl_miner miner;
 	{
 		auto startTime = high_resolution_clock::now();
-		if (!miner.init(params, seed))
+		if (!miner.init(params, &seed))
 			exit(-1);
 		auto time = std::chrono::duration_cast<std::chrono::milliseconds>(high_resolution_clock::now() - startTime).count();
-        debugf("ethash_cl_miner init: %ums\n", (unsigned)time);
+		debugf("ethash_cl_miner init: %ums\n", (unsigned)time);
 	}
 #endif
 
 
 #ifdef FULL
-    {
-        auto startTime = high_resolution_clock::now();
+	{
+		auto startTime = high_resolution_clock::now();
 		ethash_return_value hash;
-        ethash_full(&hash, full_mem, &params, previous_hash, 0);
-        auto time = std::chrono::duration_cast<std::chrono::milliseconds>(high_resolution_clock::now() - startTime).count();
-        debugf("ethash_full test: %uns, %s\n", (unsigned)time);
-    }
+		ethash_full(&hash, full_mem, &params, &previous_hash, 0);
+		auto time = std::chrono::duration_cast<std::chrono::milliseconds>(high_resolution_clock::now() - startTime).count();
+		debugf("ethash_full test: %uns\n", (unsigned)time);
+	}
 #endif
 
 #ifdef OPENCL
 	// validate 1024 hashes against CPU
-	miner.hash(g_hashes, previous_hash, 0, 1024);
+	miner.hash(g_hashes, (uint8_t*)&previous_hash, 0, 1024);
 	for (unsigned i = 0; i != 1024; ++i)
 	{
 		ethash_return_value hash;
-		ethash_light(&hash, &cache, &params, previous_hash, i);
-		if (memcmp(hash.result, g_hashes + 32*i, 32) != 0)
+		ethash_light(&hash, &cache, &params, &previous_hash, i);
+		if (memcmp(&hash.result, g_hashes + 32*i, 32) != 0)
 		{
-			debugf("nonce %u failed: %s %s\n", i, bytesToHexString(g_hashes + 32*i, 32).c_str(), bytesToHexString(hash.result, 32).c_str());
+			debugf("nonce %u failed: %s %s\n", i, bytesToHexString(g_hashes + 32*i, 32).c_str(), bytesToHexString(&hash.result, 32).c_str());
 			static unsigned c = 0;
 			if (++c == 16)
 			{
@@ -189,14 +194,14 @@ extern "C" int main(void)
 			}
 		}
 	}
-	
+
 	// ensure nothing else is going on
 	miner.finish();
 #endif
 
 	auto startTime = high_resolution_clock::now();
 	unsigned hash_count = trials;
-	
+
 	#ifdef OPENCL
 	{
 		struct search_hook : ethash_cl_miner::search_hook
@@ -220,14 +225,14 @@ extern "C" int main(void)
 		search_hook hook;
 		hook.hash_count = 0;
 
-		miner.search(previous_hash, 0x000000ffffffffff, hook);
+		miner.search((uint8_t*)&previous_hash, 0x000000ffffffffff, hook);
 
 		for (unsigned i = 0; i != hook.nonce_vec.size(); ++i)
 		{
 			uint64_t nonce = hook.nonce_vec[i];
 			ethash_return_value hash;
-			ethash_light(&hash, &cache, &params, previous_hash, nonce);
-			debugf("found: %.8x%.8x -> %s\n", unsigned(nonce>>32), unsigned(nonce), bytesToHexString(hash.result, 32).c_str());
+			ethash_light(&hash, &cache, &params, &previous_hash, nonce);
+			debugf("found: %.8x%.8x -> %s\n", unsigned(nonce>>32), unsigned(nonce), bytesToHexString(&hash.result, 32).c_str());
 		}
 
 		hash_count = hook.hash_count;
@@ -239,9 +244,9 @@ extern "C" int main(void)
 		{
 			ethash_return_value hash;
 			#ifdef FULL
-				ethash_full(&hash, full_mem, &params, previous_hash, nonce);
+				ethash_full(&hash, full_mem, &params, &previous_hash, nonce);
 			#else
-				ethash_light(&hash, &cache, &params, previous_hash, nonce);
+				ethash_light(&hash, &cache, &params, &previous_hash, nonce);
 			#endif // FULL
 		}
 	}
@@ -249,7 +254,7 @@ extern "C" int main(void)
 	auto time = std::chrono::duration_cast<std::chrono::microseconds>(high_resolution_clock::now() - startTime).count();
 	debugf("Search took: %ums\n", (unsigned)time/1000);
 
-	unsigned read_size = ACCESSES * MIX_BYTES;
+	unsigned read_size = ETHASH_ACCESSES * ETHASH_MIX_BYTES;
 #if defined(OPENCL) || defined(FULL)
 	debugf(
 		"hashrate: %8.2f Mh/s, bw: %8.2f GB/s\n",
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt
index 30fa7ed4b..3cfe1644d 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt
@@ -13,7 +13,7 @@ if (NOT MSVC)
     set(CMAKE_CXX_FLAGS                "-Wall -std=c++11")
     set(CMAKE_CXX_FLAGS_DEBUG          "-O0 -g")
     set(CMAKE_CXX_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
-    set(CMAKE_CXX_FLAGS_RELEASE        "-O4 -DNDEBUG")
+    set(CMAKE_CXX_FLAGS_RELEASE        "-O3 -DNDEBUG")
     set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
 
     # Compiler-specific C++11 activation.
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp
index bf7bb2128..65f15d7ca 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp
@@ -24,12 +24,15 @@
 
 #include <cstdio>
 #include <cstdlib>
+#include <iostream>
 #include <assert.h>
 #include <queue>
 #include <vector>
+#include <libethash/util.h>
+#include <libethash/ethash.h>
+#include <libethash/internal.h>
 #include "ethash_cl_miner.h"
 #include "ethash_cl_miner_kernel.h"
-#include <libethash/util.h>
 
 #define ETHASH_BYTES 32
 
@@ -42,6 +45,8 @@
 #undef min
 #undef max
 
+using namespace std;
+
 static void add_definition(std::string& source, char const* id, unsigned value)
 {
 	char buf[256];
@@ -49,52 +54,108 @@ static void add_definition(std::string& source, char const* id, unsigned value)
 	source.insert(source.begin(), buf, buf + strlen(buf));
 }
 
+ethash_cl_miner::search_hook::~search_hook() {}
+
 ethash_cl_miner::ethash_cl_miner()
 :	m_opencl_1_1()
 {
 }
 
-bool ethash_cl_miner::init(ethash_params const& params, ethash_blockhash_t const *seed, unsigned workgroup_size)
+std::string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _deviceId)
+{
+	std::vector<cl::Platform> platforms;
+	cl::Platform::get(&platforms);
+	if (platforms.empty())
+	{
+		cout << "No OpenCL platforms found." << endl;
+		return std::string();
+	}
+
+	// get GPU device of the selected platform
+	std::vector<cl::Device> devices;
+	unsigned platform_num = std::min<unsigned>(_platformId, platforms.size() - 1);
+	platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices);
+	if (devices.empty())
+	{
+		cout << "No OpenCL devices found." << endl;
+		return std::string();
+	}
+
+	// use selected default device
+	unsigned device_num = std::min<unsigned>(_deviceId, devices.size() - 1);
+	cl::Device& device = devices[device_num];
+	std::string device_version = device.getInfo<CL_DEVICE_VERSION>();
+
+	return "{ \"platform\": \"" + platforms[platform_num].getInfo<CL_PLATFORM_NAME>() + "\", \"device\": \"" + device.getInfo<CL_DEVICE_NAME>() + "\", \"version\": \"" + device_version + "\" }";
+}
+
+unsigned ethash_cl_miner::get_num_devices(unsigned _platformId)
+{
+	std::vector<cl::Platform> platforms;
+	cl::Platform::get(&platforms);
+	if (platforms.empty())
+	{
+		cout << "No OpenCL platforms found." << endl;
+		return 0;
+	}
+
+	std::vector<cl::Device> devices;
+	unsigned platform_num = std::min<unsigned>(_platformId, platforms.size() - 1);
+	platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices);
+	if (devices.empty())
+	{
+		cout << "No OpenCL devices found." << endl;
+		return 0;
+	}
+	return devices.size();
+}
+
+void ethash_cl_miner::finish()
+{
+	if (m_queue())
+		m_queue.finish();
+}
+
+bool ethash_cl_miner::init(uint64_t block_number, std::function<void(void*)> _fillDAG, unsigned workgroup_size, unsigned _platformId, unsigned _deviceId)
 {
 	// store params
-	m_params = params;
+	m_fullSize = ethash_get_datasize(block_number);
 
 	// get all platforms
-    std::vector<cl::Platform> platforms;
-    cl::Platform::get(&platforms);
+	std::vector<cl::Platform> platforms;
+	cl::Platform::get(&platforms);
 	if (platforms.empty())
 	{
-		debugf("No OpenCL platforms found.\n");
+		cout << "No OpenCL platforms found." << endl;
 		return false;
 	}
 
-	// use default platform
-	debugf("Using platform: %s\n", platforms[0].getInfo<CL_PLATFORM_NAME>().c_str());
+	// use selected platform
+	_platformId = std::min<unsigned>(_platformId, platforms.size() - 1);
 
-    // get GPU device of the default platform
-    std::vector<cl::Device> devices;
-    platforms[0].getDevices(CL_DEVICE_TYPE_ALL, &devices);
-    if (devices.empty())
+	cout << "Using platform: " << platforms[_platformId].getInfo<CL_PLATFORM_NAME>().c_str() << endl;
+
+	// get GPU device of the default platform
+	std::vector<cl::Device> devices;
+	platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices);
+	if (devices.empty())
 	{
-		debugf("No OpenCL devices found.\n");
+		cout << "No OpenCL devices found." << endl;
 		return false;
 	}
 
-	// use default device
-	unsigned device_num = 0;
-	cl::Device& device = devices[device_num];
+	// use selected device
+	cl::Device& device = devices[std::min<unsigned>(_deviceId, devices.size() - 1)];
 	std::string device_version = device.getInfo<CL_DEVICE_VERSION>();
-	debugf("Using device: %s (%s)\n", device.getInfo<CL_DEVICE_NAME>().c_str(),device_version.c_str());
+	cout << "Using device: " << device.getInfo<CL_DEVICE_NAME>().c_str() << "(" << device_version.c_str() << ")" << endl;
 
 	if (strncmp("OpenCL 1.0", device_version.c_str(), 10) == 0)
 	{
-		debugf("OpenCL 1.0 is not supported.\n");
+		cout << "OpenCL 1.0 is not supported." << endl;
 		return false;
 	}
 	if (strncmp("OpenCL 1.1", device_version.c_str(), 10) == 0)
-	{
 		m_opencl_1_1 = true;
-	}
 
 	// create context
 	m_context = cl::Context(std::vector<cl::Device>(&device, &device + 1));
@@ -106,8 +167,8 @@ bool ethash_cl_miner::init(ethash_params const& params, ethash_blockhash_t const
 	// patch source code
 	std::string code(ETHASH_CL_MINER_KERNEL, ETHASH_CL_MINER_KERNEL + ETHASH_CL_MINER_KERNEL_SIZE);
 	add_definition(code, "GROUP_SIZE", m_workgroup_size);
-	add_definition(code, "DAG_SIZE", (unsigned)(params.full_size / MIX_BYTES));
-	add_definition(code, "ACCESSES", ACCESSES);
+	add_definition(code, "DAG_SIZE", (unsigned)(m_fullSize / ETHASH_MIX_BYTES));
+	add_definition(code, "ACCESSES", ETHASH_ACCESSES);
 	add_definition(code, "MAX_OUTPUTS", c_max_search_results);
 	//debugf("%s", code.c_str());
 
@@ -122,31 +183,25 @@ bool ethash_cl_miner::init(ethash_params const& params, ethash_blockhash_t const
 	}
 	catch (cl::Error err)
 	{
-		debugf("%s\n", program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device).c_str());
+		cout << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device).c_str();
 		return false;
 	}
 	m_hash_kernel = cl::Kernel(program, "ethash_hash");
 	m_search_kernel = cl::Kernel(program, "ethash_search");
 
 	// create buffer for dag
-	m_dag = cl::Buffer(m_context, CL_MEM_READ_ONLY, params.full_size);
-	
+	m_dag = cl::Buffer(m_context, CL_MEM_READ_ONLY, m_fullSize);
+
 	// create buffer for header
 	m_header = cl::Buffer(m_context, CL_MEM_READ_ONLY, 32);
 
 	// compute dag on CPU
 	{
-		void* cache_mem = malloc(params.cache_size + 63);
-		ethash_cache cache;
-		cache.mem = (void*)(((uintptr_t)cache_mem + 63) & ~63);
-		ethash_mkcache(&cache, &params, seed);
-
 		// if this throws then it's because we probably need to subdivide the dag uploads for compatibility
-		void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, params.full_size);
-		ethash_compute_full_data(dag_ptr, &params, &cache);
+		void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, m_fullSize);
+		// memcpying 1GB: horrible... really. horrible. but necessary since we can't mmap *and* gpumap.
+		_fillDAG(dag_ptr);
 		m_queue.enqueueUnmapMemObject(m_dag, dag_ptr);
-
-		free(cache_mem);
 	}
 
 	// create mining buffers
@@ -167,7 +222,7 @@ void ethash_cl_miner::hash(uint8_t* ret, uint8_t const* header, uint64_t nonce,
 		unsigned buf;
 	};
 	std::queue<pending_batch> pending;
-	
+
 	// update header constant buffer
 	m_queue.enqueueWriteBuffer(m_header, true, 0, 32, header);
 
@@ -191,8 +246,8 @@ void ethash_cl_miner::hash(uint8_t* ret, uint8_t const* header, uint64_t nonce,
 		// how many this batch
 		if (i < count)
 		{
-			unsigned const this_count = std::min(count - i, c_hash_batch_size);
-			unsigned const batch_count = std::max(this_count, m_workgroup_size);
+			unsigned const this_count = std::min<unsigned>(count - i, c_hash_batch_size);
+			unsigned const batch_count = std::max<unsigned>(this_count, m_workgroup_size);
 
 			// supply output hash buffer to kernel
 			m_hash_kernel.setArg(0, m_hash_buf[buf]);
@@ -205,7 +260,7 @@ void ethash_cl_miner::hash(uint8_t* ret, uint8_t const* header, uint64_t nonce,
 				cl::NDRange(m_workgroup_size)
 				);
 			m_queue.flush();
-		
+
 			pending.push({i, this_count, buf});
 			i += this_count;
 			buf = (buf + 1) % c_num_buffers;
@@ -245,7 +300,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
 		m_queue.enqueueWriteBuffer(m_search_buf[i], false, 0, 4, &c_zero);
 	}
 
-#if CL_VERSION_1_2
+#if CL_VERSION_1_2 && 0
 	cl::Event pre_return_event;
 	if (!m_opencl_1_1)
 	{
@@ -284,7 +339,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
 
 		// execute it!
 		m_queue.enqueueNDRangeKernel(m_search_kernel, cl::NullRange, c_search_batch_size, m_workgroup_size);
-		
+
 		pending.push({start_nonce, buf});
 		buf = (buf + 1) % c_num_buffers;
 
@@ -295,16 +350,16 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
 
 			// could use pinned host pointer instead
 			uint32_t* results = (uint32_t*)m_queue.enqueueMapBuffer(m_search_buf[batch.buf], true, CL_MAP_READ, 0, (1+c_max_search_results) * sizeof(uint32_t));
-			unsigned num_found = std::min(results[0], c_max_search_results);
+			unsigned num_found = std::min<unsigned>(results[0], c_max_search_results);
 
 			uint64_t nonces[c_max_search_results];
 			for (unsigned i = 0; i != num_found; ++i)
 			{
 				nonces[i] = batch.start_nonce + results[i+1];
 			}
-			
+
 			m_queue.enqueueUnmapMemObject(m_search_buf[batch.buf], results);
-			
+
 			bool exit = num_found && hook.found(nonces, num_found);
 			exit |= hook.searched(batch.start_nonce, c_search_batch_size); // always report searched before exit
 			if (exit)
@@ -319,7 +374,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
 	}
 
 	// not safe to return until this is ready
-#if CL_VERSION_1_2
+#if CL_VERSION_1_2 && 0
 	if (!m_opencl_1_1)
 	{
 		pre_return_event.wait();
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h
index af614b3e4..23868b2c7 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h
@@ -1,9 +1,19 @@
 #pragma once
 
-#define __CL_ENABLE_EXCEPTIONS 
+#define __CL_ENABLE_EXCEPTIONS
 #define CL_USE_DEPRECATED_OPENCL_2_0_APIS
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#include "cl.hpp"
+#pragma clang diagnostic pop
+#else
 #include "cl.hpp"
+#endif
+
 #include <time.h>
+#include <functional>
 #include <libethash/ethash.h>
 
 class ethash_cl_miner
@@ -11,6 +21,8 @@ class ethash_cl_miner
 public:
 	struct search_hook
 	{
+		virtual ~search_hook(); // always a virtual destructor for a class with virtuals.
+
 		// reports progress, return true to abort
 		virtual bool found(uint64_t const* nonces, uint32_t count) = 0;
 		virtual bool searched(uint64_t start_nonce, uint32_t count) = 0;
@@ -19,19 +31,19 @@ public:
 public:
 	ethash_cl_miner();
 
-	bool init(ethash_params const& params, ethash_blockhash_t const *seed, unsigned workgroup_size = 64);
+	bool init(uint64_t block_number, std::function<void(void*)> _fillDAG, unsigned workgroup_size = 64, unsigned _platformId = 0, unsigned _deviceId = 0);
+	static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0);
+	static unsigned get_num_devices(unsigned _platformId = 0);
+
 
 	void finish();
 	void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count);
 	void search(uint8_t const* header, uint64_t target, search_hook& hook);
 
 private:
-	static unsigned const c_max_search_results = 63;
-	static unsigned const c_num_buffers = 2;
-	static unsigned const c_hash_batch_size = 1024;
-	static unsigned const c_search_batch_size = 1024*256;
+	enum { c_max_search_results = 63, c_num_buffers = 2, c_hash_batch_size = 1024, c_search_batch_size = 1024*256 };
 
-	ethash_params m_params;
+	uint64_t m_fullSize;
 	cl::Context m_context;
 	cl::CommandQueue m_queue;
 	cl::Kernel m_hash_kernel;
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner_kernel.cl b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner_kernel.cl
index ee21a331e..3c8b9dc92 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner_kernel.cl
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner_kernel.cl
@@ -415,8 +415,7 @@ __kernel void ethash_search_simple(
 {
 	uint const gid = get_global_id(0);
 	hash32_t hash = compute_hash_simple(g_header, g_dag, start_nonce + gid, isolate);
-
-	if (hash.ulongs[countof(hash.ulongs)-1] < target)
+	if (as_ulong(as_uchar8(hash.ulongs[0]).s76543210) < target)
 	{
 		uint slot = min(MAX_OUTPUTS, atomic_inc(&g_output[0]) + 1);
 		g_output[slot] = gid;
@@ -453,7 +452,7 @@ __kernel void ethash_search(
 	uint const gid = get_global_id(0);
 	hash32_t hash = compute_hash(share, g_header, g_dag, start_nonce + gid, isolate);
 
-	if (hash.ulongs[countof(hash.ulongs)-1] < target)
+	if (as_ulong(as_uchar8(hash.ulongs[0]).s76543210) < target)
 	{
 		uint slot = min(MAX_OUTPUTS, atomic_inc(&g_output[0]) + 1);
 		g_output[slot] = gid;
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/CMakeLists.txt b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/CMakeLists.txt
index c92240086..a65621c3e 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/CMakeLists.txt
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/CMakeLists.txt
@@ -10,8 +10,7 @@ if (NOT MSVC)
 	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
 endif()
 
-set(FILES 	util.c
-          	util.h
+set(FILES 	util.h
           	io.c
           	internal.c
           	ethash.h
@@ -21,7 +20,7 @@ set(FILES 	util.c
           	data_sizes.h)
 
 if (MSVC)
-	list(APPEND FILES io_win32.c)
+	list(APPEND FILES util_win32.c io_win32.c mmap_win32.c)
 else()
 	list(APPEND FILES io_posix.c)
 endif()
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/data_sizes.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/data_sizes.h
index cf52ae4f8..83cc30bcb 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/data_sizes.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/data_sizes.h
@@ -49,416 +49,416 @@ extern "C" {
 
 
 static const uint64_t dag_sizes[2048] = {
-        1073739904U, 1082130304U, 1090514816U, 1098906752U, 1107293056U,
-        1115684224U, 1124070016U, 1132461952U, 1140849536U, 1149232768U,
-        1157627776U, 1166013824U, 1174404736U, 1182786944U, 1191180416U,
-        1199568512U, 1207958912U, 1216345216U, 1224732032U, 1233124736U,
-        1241513344U, 1249902464U, 1258290304U, 1266673792U, 1275067264U,
-        1283453312U, 1291844992U, 1300234112U, 1308619904U, 1317010048U,
-        1325397376U, 1333787776U, 1342176128U, 1350561664U, 1358954368U,
-        1367339392U, 1375731584U, 1384118144U, 1392507008U, 1400897408U,
-        1409284736U, 1417673344U, 1426062464U, 1434451072U, 1442839168U,
-        1451229056U, 1459615616U, 1468006016U, 1476394112U, 1484782976U,
-        1493171584U, 1501559168U, 1509948032U, 1518337664U, 1526726528U,
-        1535114624U, 1543503488U, 1551892096U, 1560278656U, 1568669056U,
-        1577056384U, 1585446272U, 1593831296U, 1602219392U, 1610610304U,
-        1619000192U, 1627386752U, 1635773824U, 1644164224U, 1652555648U,
-        1660943488U, 1669332608U, 1677721216U, 1686109312U, 1694497664U,
-        1702886272U, 1711274624U, 1719661184U, 1728047744U, 1736434816U,
-        1744829056U, 1753218944U, 1761606272U, 1769995904U, 1778382464U,
-        1786772864U, 1795157888U, 1803550592U, 1811937664U, 1820327552U,
-        1828711552U, 1837102976U, 1845488768U, 1853879936U, 1862269312U,
-        1870656896U, 1879048064U, 1887431552U, 1895825024U, 1904212096U,
-        1912601216U, 1920988544U, 1929379456U, 1937765504U, 1946156672U,
-        1954543232U, 1962932096U, 1971321728U, 1979707264U, 1988093056U,
-        1996487552U, 2004874624U, 2013262208U, 2021653888U, 2030039936U,
-        2038430848U, 2046819968U, 2055208576U, 2063596672U, 2071981952U,
-        2080373632U, 2088762752U, 2097149056U, 2105539712U, 2113928576U,
-        2122315136U, 2130700672U, 2139092608U, 2147483264U, 2155872128U,
-        2164257664U, 2172642176U, 2181035392U, 2189426048U, 2197814912U,
-        2206203008U, 2214587264U, 2222979712U, 2231367808U, 2239758208U,
-        2248145024U, 2256527744U, 2264922752U, 2273312128U, 2281701248U,
-        2290086272U, 2298476672U, 2306867072U, 2315251072U, 2323639168U,
-        2332032128U, 2340420224U, 2348808064U, 2357196416U, 2365580416U,
-        2373966976U, 2382363008U, 2390748544U, 2399139968U, 2407530368U,
-        2415918976U, 2424307328U, 2432695424U, 2441084288U, 2449472384U,
-        2457861248U, 2466247808U, 2474637184U, 2483026816U, 2491414144U,
-        2499803776U, 2508191872U, 2516582272U, 2524970368U, 2533359232U,
-        2541743488U, 2550134144U, 2558525056U, 2566913408U, 2575301504U,
-        2583686528U, 2592073856U, 2600467328U, 2608856192U, 2617240448U,
-        2625631616U, 2634022016U, 2642407552U, 2650796416U, 2659188352U,
-        2667574912U, 2675965312U, 2684352896U, 2692738688U, 2701130624U,
-        2709518464U, 2717907328U, 2726293376U, 2734685056U, 2743073152U,
-        2751462016U, 2759851648U, 2768232832U, 2776625536U, 2785017728U,
-        2793401984U, 2801794432U, 2810182016U, 2818571648U, 2826959488U,
-        2835349376U, 2843734144U, 2852121472U, 2860514432U, 2868900992U,
-        2877286784U, 2885676928U, 2894069632U, 2902451584U, 2910843008U,
-        2919234688U, 2927622784U, 2936011648U, 2944400768U, 2952789376U,
-        2961177728U, 2969565568U, 2977951616U, 2986338944U, 2994731392U,
-        3003120256U, 3011508352U, 3019895936U, 3028287104U, 3036675968U,
-        3045063808U, 3053452928U, 3061837696U, 3070228352U, 3078615424U,
-        3087003776U, 3095394944U, 3103782272U, 3112173184U, 3120562048U,
-        3128944768U, 3137339264U, 3145725056U, 3154109312U, 3162505088U,
-        3170893184U, 3179280256U, 3187669376U, 3196056704U, 3204445568U,
-        3212836736U, 3221224064U, 3229612928U, 3238002304U, 3246391168U,
-        3254778496U, 3263165824U, 3271556224U, 3279944576U, 3288332416U,
-        3296719232U, 3305110912U, 3313500032U, 3321887104U, 3330273152U,
-        3338658944U, 3347053184U, 3355440512U, 3363827072U, 3372220288U,
-        3380608384U, 3388997504U, 3397384576U, 3405774208U, 3414163072U,
-        3422551936U, 3430937984U, 3439328384U, 3447714176U, 3456104576U,
-        3464493952U, 3472883584U, 3481268864U, 3489655168U, 3498048896U,
-        3506434432U, 3514826368U, 3523213952U, 3531603584U, 3539987072U,
-        3548380288U, 3556763264U, 3565157248U, 3573545344U, 3581934464U,
-        3590324096U, 3598712704U, 3607098752U, 3615488384U, 3623877248U,
-        3632265856U, 3640646528U, 3649043584U, 3657430144U, 3665821568U,
-        3674207872U, 3682597504U, 3690984832U, 3699367808U, 3707764352U,
-        3716152448U, 3724541056U, 3732925568U, 3741318016U, 3749706368U,
-        3758091136U, 3766481536U, 3774872704U, 3783260032U, 3791650432U,
-        3800036224U, 3808427648U, 3816815488U, 3825204608U, 3833592704U,
-        3841981568U, 3850370432U, 3858755968U, 3867147904U, 3875536256U,
-        3883920512U, 3892313728U, 3900702592U, 3909087872U, 3917478784U,
-        3925868416U, 3934256512U, 3942645376U, 3951032192U, 3959422336U,
-        3967809152U, 3976200064U, 3984588416U, 3992974976U, 4001363584U,
-        4009751168U, 4018141312U, 4026530432U, 4034911616U, 4043308928U,
-        4051695488U, 4060084352U, 4068472448U, 4076862848U, 4085249408U,
-        4093640576U, 4102028416U, 4110413696U, 4118805632U, 4127194496U,
-        4135583104U, 4143971968U, 4152360832U, 4160746112U, 4169135744U,
-        4177525888U, 4185912704U, 4194303616U, 4202691968U, 4211076736U,
-        4219463552U, 4227855488U, 4236246656U, 4244633728U, 4253022848U,
-        4261412224U, 4269799808U, 4278184832U, 4286578048U, 4294962304U,
-        4303349632U, 4311743104U, 4320130432U, 4328521088U, 4336909184U,
-        4345295488U, 4353687424U, 4362073472U, 4370458496U, 4378852736U,
-        4387238528U, 4395630208U, 4404019072U, 4412407424U, 4420790656U,
-        4429182848U, 4437571456U, 4445962112U, 4454344064U, 4462738048U,
-        4471119232U, 4479516544U, 4487904128U, 4496289664U, 4504682368U,
-        4513068416U, 4521459584U, 4529846144U, 4538232704U, 4546619776U,
-        4555010176U, 4563402112U, 4571790208U, 4580174464U, 4588567936U,
-        4596957056U, 4605344896U, 4613734016U, 4622119808U, 4630511488U,
-        4638898816U, 4647287936U, 4655675264U, 4664065664U, 4672451968U,
-        4680842624U, 4689231488U, 4697620352U, 4706007424U, 4714397056U,
-        4722786176U, 4731173248U, 4739562368U, 4747951744U, 4756340608U,
-        4764727936U, 4773114496U, 4781504384U, 4789894784U, 4798283648U,
-        4806667648U, 4815059584U, 4823449472U, 4831835776U, 4840226176U,
-        4848612224U, 4857003392U, 4865391488U, 4873780096U, 4882169728U,
-        4890557312U, 4898946944U, 4907333248U, 4915722368U, 4924110976U,
-        4932499328U, 4940889728U, 4949276032U, 4957666432U, 4966054784U,
-        4974438016U, 4982831488U, 4991221376U, 4999607168U, 5007998848U,
-        5016386432U, 5024763776U, 5033164672U, 5041544576U, 5049941888U,
-        5058329728U, 5066717056U, 5075107456U, 5083494272U, 5091883904U,
-        5100273536U, 5108662144U, 5117048192U, 5125436032U, 5133827456U,
-        5142215296U, 5150605184U, 5158993024U, 5167382144U, 5175769472U,
-        5184157568U, 5192543872U, 5200936064U, 5209324928U, 5217711232U,
-        5226102656U, 5234490496U, 5242877312U, 5251263872U, 5259654016U,
-        5268040832U, 5276434304U, 5284819328U, 5293209728U, 5301598592U,
-        5309986688U, 5318374784U, 5326764416U, 5335151488U, 5343542144U,
-        5351929472U, 5360319872U, 5368706944U, 5377096576U, 5385484928U,
-        5393871232U, 5402263424U, 5410650496U, 5419040384U, 5427426944U,
-        5435816576U, 5444205952U, 5452594816U, 5460981376U, 5469367936U,
-        5477760896U, 5486148736U, 5494536832U, 5502925952U, 5511315328U,
-        5519703424U, 5528089984U, 5536481152U, 5544869504U, 5553256064U,
-        5561645696U, 5570032768U, 5578423936U, 5586811264U, 5595193216U,
-        5603585408U, 5611972736U, 5620366208U, 5628750464U, 5637143936U,
-        5645528192U, 5653921408U, 5662310272U, 5670694784U, 5679082624U,
-        5687474048U, 5695864448U, 5704251008U, 5712641408U, 5721030272U,
-        5729416832U, 5737806208U, 5746194304U, 5754583936U, 5762969984U,
-        5771358592U, 5779748224U, 5788137856U, 5796527488U, 5804911232U,
-        5813300608U, 5821692544U, 5830082176U, 5838468992U, 5846855552U,
-        5855247488U, 5863636096U, 5872024448U, 5880411008U, 5888799872U,
-        5897186432U, 5905576832U, 5913966976U, 5922352768U, 5930744704U,
-        5939132288U, 5947522432U, 5955911296U, 5964299392U, 5972688256U,
-        5981074304U, 5989465472U, 5997851008U, 6006241408U, 6014627968U,
-        6023015552U, 6031408256U, 6039796096U, 6048185216U, 6056574848U,
-        6064963456U, 6073351808U, 6081736064U, 6090128768U, 6098517632U,
-        6106906496U, 6115289216U, 6123680896U, 6132070016U, 6140459648U,
-        6148849024U, 6157237376U, 6165624704U, 6174009728U, 6182403712U,
-        6190792064U, 6199176064U, 6207569792U, 6215952256U, 6224345216U,
-        6232732544U, 6241124224U, 6249510272U, 6257899136U, 6266287744U,
-        6274676864U, 6283065728U, 6291454336U, 6299843456U, 6308232064U,
-        6316620928U, 6325006208U, 6333395584U, 6341784704U, 6350174848U,
-        6358562176U, 6366951296U, 6375337856U, 6383729536U, 6392119168U,
-        6400504192U, 6408895616U, 6417283456U, 6425673344U, 6434059136U,
-        6442444672U, 6450837376U, 6459223424U, 6467613056U, 6476004224U,
-        6484393088U, 6492781952U, 6501170048U, 6509555072U, 6517947008U,
-        6526336384U, 6534725504U, 6543112832U, 6551500672U, 6559888768U,
-        6568278656U, 6576662912U, 6585055616U, 6593443456U, 6601834112U,
-        6610219648U, 6618610304U, 6626999168U, 6635385472U, 6643777408U,
-        6652164224U, 6660552832U, 6668941952U, 6677330048U, 6685719424U,
-        6694107776U, 6702493568U, 6710882176U, 6719274112U, 6727662976U,
-        6736052096U, 6744437632U, 6752825984U, 6761213824U, 6769604224U,
-        6777993856U, 6786383488U, 6794770816U, 6803158144U, 6811549312U,
-        6819937664U, 6828326528U, 6836706176U, 6845101696U, 6853491328U,
-        6861880448U, 6870269312U, 6878655104U, 6887046272U, 6895433344U,
-        6903822208U, 6912212864U, 6920596864U, 6928988288U, 6937377152U,
-        6945764992U, 6954149248U, 6962544256U, 6970928768U, 6979317376U,
-        6987709312U, 6996093824U, 7004487296U, 7012875392U, 7021258624U,
-        7029652352U, 7038038912U, 7046427776U, 7054818944U, 7063207808U,
-        7071595136U, 7079980928U, 7088372608U, 7096759424U, 7105149824U,
-        7113536896U, 7121928064U, 7130315392U, 7138699648U, 7147092352U,
-        7155479168U, 7163865728U, 7172249984U, 7180648064U, 7189036672U,
-        7197424768U, 7205810816U, 7214196608U, 7222589824U, 7230975104U,
-        7239367552U, 7247755904U, 7256145536U, 7264533376U, 7272921472U,
-        7281308032U, 7289694848U, 7298088832U, 7306471808U, 7314864512U,
-        7323253888U, 7331643008U, 7340029568U, 7348419712U, 7356808832U,
-        7365196672U, 7373585792U, 7381973888U, 7390362752U, 7398750592U,
-        7407138944U, 7415528576U, 7423915648U, 7432302208U, 7440690304U,
-        7449080192U, 7457472128U, 7465860992U, 7474249088U, 7482635648U,
-        7491023744U, 7499412608U, 7507803008U, 7516192384U, 7524579968U,
-        7532967296U, 7541358464U, 7549745792U, 7558134656U, 7566524032U,
-        7574912896U, 7583300992U, 7591690112U, 7600075136U, 7608466816U,
-        7616854912U, 7625244544U, 7633629824U, 7642020992U, 7650410368U,
-        7658794112U, 7667187328U, 7675574912U, 7683961984U, 7692349568U,
-        7700739712U, 7709130368U, 7717519232U, 7725905536U, 7734295424U,
-        7742683264U, 7751069056U, 7759457408U, 7767849088U, 7776238208U,
-        7784626816U, 7793014912U, 7801405312U, 7809792128U, 7818179968U,
-        7826571136U, 7834957184U, 7843347328U, 7851732352U, 7860124544U,
-        7868512384U, 7876902016U, 7885287808U, 7893679744U, 7902067072U,
-        7910455936U, 7918844288U, 7927230848U, 7935622784U, 7944009344U,
-        7952400256U, 7960786048U, 7969176704U, 7977565312U, 7985953408U,
-        7994339968U, 8002730368U, 8011119488U, 8019508096U, 8027896192U,
-        8036285056U, 8044674688U, 8053062272U, 8061448832U, 8069838464U,
-        8078227328U, 8086616704U, 8095006592U, 8103393664U, 8111783552U,
-        8120171392U, 8128560256U, 8136949376U, 8145336704U, 8153726848U,
-        8162114944U, 8170503296U, 8178891904U, 8187280768U, 8195669632U,
-        8204058496U, 8212444544U, 8220834176U, 8229222272U, 8237612672U,
-        8246000768U, 8254389376U, 8262775168U, 8271167104U, 8279553664U,
-        8287944064U, 8296333184U, 8304715136U, 8313108352U, 8321497984U,
-        8329885568U, 8338274432U, 8346663296U, 8355052928U, 8363441536U,
-        8371828352U, 8380217984U, 8388606592U, 8396996224U, 8405384576U,
-        8413772672U, 8422161536U, 8430549376U, 8438939008U, 8447326592U,
-        8455715456U, 8464104832U, 8472492928U, 8480882048U, 8489270656U,
-        8497659776U, 8506045312U, 8514434944U, 8522823808U, 8531208832U,
-        8539602304U, 8547990656U, 8556378752U, 8564768384U, 8573154176U,
-        8581542784U, 8589933952U, 8598322816U, 8606705024U, 8615099264U,
-        8623487872U, 8631876992U, 8640264064U, 8648653952U, 8657040256U,
-        8665430656U, 8673820544U, 8682209152U, 8690592128U, 8698977152U,
-        8707374464U, 8715763328U, 8724151424U, 8732540032U, 8740928384U,
-        8749315712U, 8757704576U, 8766089344U, 8774480768U, 8782871936U,
-        8791260032U, 8799645824U, 8808034432U, 8816426368U, 8824812928U,
-        8833199488U, 8841591424U, 8849976448U, 8858366336U, 8866757248U,
-        8875147136U, 8883532928U, 8891923328U, 8900306816U, 8908700288U,
-        8917088384U, 8925478784U, 8933867392U, 8942250368U, 8950644608U,
-        8959032704U, 8967420544U, 8975809664U, 8984197504U, 8992584064U,
-        9000976256U, 9009362048U, 9017752448U, 9026141312U, 9034530688U,
-        9042917504U, 9051307904U, 9059694208U, 9068084864U, 9076471424U,
-        9084861824U, 9093250688U, 9101638528U, 9110027648U, 9118416512U,
-        9126803584U, 9135188096U, 9143581312U, 9151969664U, 9160356224U,
-        9168747136U, 9177134464U, 9185525632U, 9193910144U, 9202302848U,
-        9210690688U, 9219079552U, 9227465344U, 9235854464U, 9244244864U,
-        9252633472U, 9261021824U, 9269411456U, 9277799296U, 9286188928U,
-        9294574208U, 9302965888U, 9311351936U, 9319740032U, 9328131968U,
-        9336516736U, 9344907392U, 9353296768U, 9361685888U, 9370074752U,
-        9378463616U, 9386849408U, 9395239808U, 9403629184U, 9412016512U,
-        9420405376U, 9428795008U, 9437181568U, 9445570688U, 9453960832U,
-        9462346624U, 9470738048U, 9479121536U, 9487515008U, 9495903616U,
-        9504289664U, 9512678528U, 9521067904U, 9529456256U, 9537843584U,
-        9546233728U, 9554621312U, 9563011456U, 9571398784U, 9579788672U,
-        9588178304U, 9596567168U, 9604954496U, 9613343104U, 9621732992U,
-        9630121856U, 9638508416U, 9646898816U, 9655283584U, 9663675776U,
-        9672061312U, 9680449664U, 9688840064U, 9697230464U, 9705617536U,
-        9714003584U, 9722393984U, 9730772608U, 9739172224U, 9747561088U,
-        9755945344U, 9764338816U, 9772726144U, 9781116544U, 9789503872U,
-        9797892992U, 9806282624U, 9814670464U, 9823056512U, 9831439232U,
-        9839833984U, 9848224384U, 9856613504U, 9865000576U, 9873391232U,
-        9881772416U, 9890162816U, 9898556288U, 9906940544U, 9915333248U,
-        9923721088U, 9932108672U, 9940496512U, 9948888448U, 9957276544U,
-        9965666176U, 9974048384U, 9982441088U, 9990830464U, 9999219584U,
-        10007602816U, 10015996544U, 10024385152U, 10032774016U, 10041163648U,
-        10049548928U, 10057940096U, 10066329472U, 10074717824U, 10083105152U,
-        10091495296U, 10099878784U, 10108272256U, 10116660608U, 10125049216U,
-        10133437312U, 10141825664U, 10150213504U, 10158601088U, 10166991232U,
-        10175378816U, 10183766144U, 10192157312U, 10200545408U, 10208935552U,
-        10217322112U, 10225712768U, 10234099328U, 10242489472U, 10250876032U,
-        10259264896U, 10267656064U, 10276042624U, 10284429184U, 10292820352U,
-        10301209472U, 10309598848U, 10317987712U, 10326375296U, 10334763392U,
-        10343153536U, 10351541632U, 10359930752U, 10368318592U, 10376707456U,
-        10385096576U, 10393484672U, 10401867136U, 10410262144U, 10418647424U,
-        10427039104U, 10435425664U, 10443810176U, 10452203648U, 10460589952U,
-        10468982144U, 10477369472U, 10485759104U, 10494147712U, 10502533504U,
-        10510923392U, 10519313536U, 10527702656U, 10536091264U, 10544478592U,
-        10552867712U, 10561255808U, 10569642368U, 10578032768U, 10586423168U,
-        10594805632U, 10603200128U, 10611588992U, 10619976064U, 10628361344U,
-        10636754048U, 10645143424U, 10653531776U, 10661920384U, 10670307968U,
-        10678696832U, 10687086464U, 10695475072U, 10703863168U, 10712246144U,
-        10720639616U, 10729026688U, 10737414784U, 10745806208U, 10754190976U,
-        10762581376U, 10770971264U, 10779356288U, 10787747456U, 10796135552U,
-        10804525184U, 10812915584U, 10821301888U, 10829692288U, 10838078336U,
-        10846469248U, 10854858368U, 10863247232U, 10871631488U, 10880023424U,
-        10888412032U, 10896799616U, 10905188992U, 10913574016U, 10921964672U,
-        10930352768U, 10938742912U, 10947132544U, 10955518592U, 10963909504U,
-        10972298368U, 10980687488U, 10989074816U, 10997462912U, 11005851776U,
-        11014241152U, 11022627712U, 11031017344U, 11039403904U, 11047793024U,
-        11056184704U, 11064570752U, 11072960896U, 11081343872U, 11089737856U,
-        11098128256U, 11106514816U, 11114904448U, 11123293568U, 11131680128U,
-        11140065152U, 11148458368U, 11156845696U, 11165236864U, 11173624192U,
-        11182013824U, 11190402688U, 11198790784U, 11207179136U, 11215568768U,
-        11223957376U, 11232345728U, 11240734592U, 11249122688U, 11257511296U,
-        11265899648U, 11274285952U, 11282675584U, 11291065472U, 11299452544U,
-        11307842432U, 11316231296U, 11324616832U, 11333009024U, 11341395584U,
-        11349782656U, 11358172288U, 11366560384U, 11374950016U, 11383339648U,
-        11391721856U, 11400117376U, 11408504192U, 11416893568U, 11425283456U,
-        11433671552U, 11442061184U, 11450444672U, 11458837888U, 11467226752U,
-        11475611776U, 11484003968U, 11492392064U, 11500780672U, 11509169024U,
-        11517550976U, 11525944448U, 11534335616U, 11542724224U, 11551111808U,
-        11559500672U, 11567890304U, 11576277376U, 11584667008U, 11593056128U,
-        11601443456U, 11609830016U, 11618221952U, 11626607488U, 11634995072U,
-        11643387776U, 11651775104U, 11660161664U, 11668552576U, 11676940928U,
-        11685330304U, 11693718656U, 11702106496U, 11710496128U, 11718882688U,
-        11727273088U, 11735660416U, 11744050048U, 11752437376U, 11760824704U,
-        11769216128U, 11777604736U, 11785991296U, 11794381952U, 11802770048U,
-        11811157888U, 11819548544U, 11827932544U, 11836324736U, 11844713344U,
-        11853100928U, 11861486464U, 11869879936U, 11878268032U, 11886656896U,
-        11895044992U, 11903433088U, 11911822976U, 11920210816U, 11928600448U,
-        11936987264U, 11945375872U, 11953761152U, 11962151296U, 11970543488U,
-        11978928512U, 11987320448U, 11995708288U, 12004095104U, 12012486272U,
-        12020875136U, 12029255552U, 12037652096U, 12046039168U, 12054429568U,
-        12062813824U, 12071206528U, 12079594624U, 12087983744U, 12096371072U,
-        12104759936U, 12113147264U, 12121534592U, 12129924992U, 12138314624U,
-        12146703232U, 12155091584U, 12163481216U, 12171864704U, 12180255872U,
-        12188643968U, 12197034112U, 12205424512U, 12213811328U, 12222199424U,
-        12230590336U, 12238977664U, 12247365248U, 12255755392U, 12264143488U,
-        12272531584U, 12280920448U, 12289309568U, 12297694592U, 12306086528U,
-        12314475392U, 12322865024U, 12331253632U, 12339640448U, 12348029312U,
-        12356418944U, 12364805248U, 12373196672U, 12381580928U, 12389969024U,
-        12398357632U, 12406750592U, 12415138432U, 12423527552U, 12431916416U,
-        12440304512U, 12448692352U, 12457081216U, 12465467776U, 12473859968U,
-        12482245504U, 12490636672U, 12499025536U, 12507411584U, 12515801728U,
-        12524190592U, 12532577152U, 12540966272U, 12549354368U, 12557743232U,
-        12566129536U, 12574523264U, 12582911872U, 12591299456U, 12599688064U,
-        12608074624U, 12616463488U, 12624845696U, 12633239936U, 12641631616U,
-        12650019968U, 12658407296U, 12666795136U, 12675183232U, 12683574656U,
-        12691960192U, 12700350592U, 12708740224U, 12717128576U, 12725515904U,
-        12733906816U, 12742295168U, 12750680192U, 12759071872U, 12767460736U,
-        12775848832U, 12784236928U, 12792626816U, 12801014656U, 12809404288U,
-        12817789312U, 12826181504U, 12834568832U, 12842954624U, 12851345792U,
-        12859732352U, 12868122496U, 12876512128U, 12884901248U, 12893289088U,
-        12901672832U, 12910067584U, 12918455168U, 12926842496U, 12935232896U,
-        12943620736U, 12952009856U, 12960396928U, 12968786816U, 12977176192U,
-        12985563776U, 12993951104U, 13002341504U, 13010730368U, 13019115392U,
-        13027506304U, 13035895168U, 13044272512U, 13052673152U, 13061062528U,
-        13069446272U, 13077838976U, 13086227072U, 13094613632U, 13103000192U,
-        13111393664U, 13119782528U, 13128157568U, 13136559232U, 13144945024U,
-        13153329536U, 13161724288U, 13170111872U, 13178502784U, 13186884736U,
-        13195279744U, 13203667072U, 13212057472U, 13220445824U, 13228832128U,
-        13237221248U, 13245610624U, 13254000512U, 13262388352U, 13270777472U,
-        13279166336U, 13287553408U, 13295943296U, 13304331904U, 13312719488U,
-        13321108096U, 13329494656U, 13337885824U, 13346274944U, 13354663808U,
-        13363051136U, 13371439232U, 13379825024U, 13388210816U, 13396605056U,
-        13404995456U, 13413380224U, 13421771392U, 13430159744U, 13438546048U,
-        13446937216U, 13455326848U, 13463708288U, 13472103808U, 13480492672U,
-        13488875648U, 13497269888U, 13505657728U, 13514045312U, 13522435712U,
-        13530824576U, 13539210112U, 13547599232U, 13555989376U, 13564379008U,
-        13572766336U, 13581154432U, 13589544832U, 13597932928U, 13606320512U,
-        13614710656U, 13623097472U, 13631477632U, 13639874944U, 13648264064U,
-        13656652928U, 13665041792U, 13673430656U, 13681818496U, 13690207616U,
-        13698595712U, 13706982272U, 13715373184U, 13723762048U, 13732150144U,
-        13740536704U, 13748926592U, 13757316224U, 13765700992U, 13774090112U,
-        13782477952U, 13790869376U, 13799259008U, 13807647872U, 13816036736U,
-        13824425344U, 13832814208U, 13841202304U, 13849591424U, 13857978752U,
-        13866368896U, 13874754688U, 13883145344U, 13891533184U, 13899919232U,
-        13908311168U, 13916692096U, 13925085056U, 13933473152U, 13941866368U,
-        13950253696U, 13958643584U, 13967032192U, 13975417216U, 13983807616U,
-        13992197504U, 14000582272U, 14008973696U, 14017363072U, 14025752192U,
-        14034137984U, 14042528384U, 14050918016U, 14059301504U, 14067691648U,
-        14076083584U, 14084470144U, 14092852352U, 14101249664U, 14109635968U,
-        14118024832U, 14126407552U, 14134804352U, 14143188608U, 14151577984U,
-        14159968384U, 14168357248U, 14176741504U, 14185127296U, 14193521024U,
-        14201911424U, 14210301824U, 14218685056U, 14227067264U, 14235467392U,
-        14243855488U, 14252243072U, 14260630144U, 14269021568U, 14277409408U,
-        14285799296U, 14294187904U, 14302571392U, 14310961792U, 14319353728U,
-        14327738752U, 14336130944U, 14344518784U, 14352906368U, 14361296512U,
-        14369685376U, 14378071424U, 14386462592U, 14394848128U, 14403230848U,
-        14411627392U, 14420013952U, 14428402304U, 14436793472U, 14445181568U,
-        14453569664U, 14461959808U, 14470347904U, 14478737024U, 14487122816U,
-        14495511424U, 14503901824U, 14512291712U, 14520677504U, 14529064832U,
-        14537456768U, 14545845632U, 14554234496U, 14562618496U, 14571011456U,
-        14579398784U, 14587789184U, 14596172672U, 14604564608U, 14612953984U,
-        14621341312U, 14629724288U, 14638120832U, 14646503296U, 14654897536U,
-        14663284864U, 14671675264U, 14680061056U, 14688447616U, 14696835968U,
-        14705228416U, 14713616768U, 14722003328U, 14730392192U, 14738784128U,
-        14747172736U, 14755561088U, 14763947648U, 14772336512U, 14780725376U,
-        14789110144U, 14797499776U, 14805892736U, 14814276992U, 14822670208U,
-        14831056256U, 14839444352U, 14847836032U, 14856222848U, 14864612992U,
-        14872997504U, 14881388672U, 14889775744U, 14898165376U, 14906553472U,
-        14914944896U, 14923329664U, 14931721856U, 14940109696U, 14948497024U,
-        14956887424U, 14965276544U, 14973663616U, 14982053248U, 14990439808U,
-        14998830976U, 15007216768U, 15015605888U, 15023995264U, 15032385152U,
-        15040768384U, 15049154944U, 15057549184U, 15065939072U, 15074328448U,
-        15082715008U, 15091104128U, 15099493504U, 15107879296U, 15116269184U,
-        15124659584U, 15133042304U, 15141431936U, 15149824384U, 15158214272U,
-        15166602368U, 15174991232U, 15183378304U, 15191760512U, 15200154496U,
-        15208542592U, 15216931712U, 15225323392U, 15233708416U, 15242098048U,
-        15250489216U, 15258875264U, 15267265408U, 15275654528U, 15284043136U,
-        15292431488U, 15300819584U, 15309208192U, 15317596544U, 15325986176U,
-        15334374784U, 15342763648U, 15351151744U, 15359540608U, 15367929728U,
-        15376318336U, 15384706432U, 15393092992U, 15401481856U, 15409869952U,
-        15418258816U, 15426649984U, 15435037568U, 15443425664U, 15451815296U,
-        15460203392U, 15468589184U, 15476979328U, 15485369216U, 15493755776U,
-        15502146944U, 15510534272U, 15518924416U, 15527311232U, 15535699072U,
-        15544089472U, 15552478336U, 15560866688U, 15569254528U, 15577642624U,
-        15586031488U, 15594419072U, 15602809472U, 15611199104U, 15619586432U,
-        15627975296U, 15636364928U, 15644753792U, 15653141888U, 15661529216U,
-        15669918848U, 15678305152U, 15686696576U, 15695083136U, 15703474048U,
-        15711861632U, 15720251264U, 15728636288U, 15737027456U, 15745417088U,
-        15753804928U, 15762194048U, 15770582656U, 15778971008U, 15787358336U,
-        15795747712U, 15804132224U, 15812523392U, 15820909696U, 15829300096U,
-        15837691264U, 15846071936U, 15854466944U, 15862855808U, 15871244672U,
-        15879634816U, 15888020608U, 15896409728U, 15904799104U, 15913185152U,
-        15921577088U, 15929966464U, 15938354816U, 15946743424U, 15955129472U,
-        15963519872U, 15971907968U, 15980296064U, 15988684928U, 15997073024U,
-        16005460864U, 16013851264U, 16022241152U, 16030629248U, 16039012736U,
-        16047406976U, 16055794816U, 16064181376U, 16072571264U, 16080957824U,
-        16089346688U, 16097737856U, 16106125184U, 16114514816U, 16122904192U,
-        16131292544U, 16139678848U, 16148066944U, 16156453504U, 16164839552U,
-        16173236096U, 16181623424U, 16190012032U, 16198401152U, 16206790528U,
-        16215177344U, 16223567744U, 16231956352U, 16240344704U, 16248731008U,
-        16257117824U, 16265504384U, 16273898624U, 16282281856U, 16290668672U,
-        16299064192U, 16307449216U, 16315842176U, 16324230016U, 16332613504U,
-        16341006464U, 16349394304U, 16357783168U, 16366172288U, 16374561664U,
-        16382951296U, 16391337856U, 16399726208U, 16408116352U, 16416505472U,
-        16424892032U, 16433282176U, 16441668224U, 16450058624U, 16458448768U,
-        16466836864U, 16475224448U, 16483613056U, 16492001408U, 16500391808U,
-        16508779648U, 16517166976U, 16525555328U, 16533944192U, 16542330752U,
-        16550719616U, 16559110528U, 16567497088U, 16575888512U, 16584274816U,
-        16592665472U, 16601051008U, 16609442944U, 16617832064U, 16626218624U,
-        16634607488U, 16642996096U, 16651385728U, 16659773824U, 16668163712U,
-        16676552576U, 16684938112U, 16693328768U, 16701718144U, 16710095488U,
-        16718492288U, 16726883968U, 16735272832U, 16743661184U, 16752049792U,
-        16760436608U, 16768827008U, 16777214336U, 16785599104U, 16793992832U,
-        16802381696U, 16810768768U, 16819151744U, 16827542656U, 16835934848U,
-        16844323712U, 16852711552U, 16861101952U, 16869489536U, 16877876864U,
-        16886265728U, 16894653056U, 16903044736U, 16911431296U, 16919821696U,
-        16928207488U, 16936592768U, 16944987776U, 16953375616U, 16961763968U,
-        16970152832U, 16978540928U, 16986929536U, 16995319168U, 17003704448U,
-        17012096896U, 17020481152U, 17028870784U, 17037262208U, 17045649536U,
-        17054039936U, 17062426496U, 17070814336U, 17079205504U, 17087592064U,
-        17095978112U, 17104369024U, 17112759424U, 17121147776U, 17129536384U,
-        17137926016U, 17146314368U, 17154700928U, 17163089792U, 17171480192U,
-        17179864192U, 17188256896U, 17196644992U, 17205033856U, 17213423488U,
-        17221811072U, 17230198912U, 17238588032U, 17246976896U, 17255360384U,
-        17263754624U, 17272143232U, 17280530048U, 17288918912U, 17297309312U,
-        17305696384U, 17314085504U, 17322475136U, 17330863744U, 17339252096U,
-        17347640192U, 17356026496U, 17364413824U, 17372796544U, 17381190016U,
-        17389583488U, 17397972608U, 17406360704U, 17414748544U, 17423135872U,
-        17431527296U, 17439915904U, 17448303232U, 17456691584U, 17465081728U,
-        17473468288U, 17481857408U, 17490247552U, 17498635904U, 17507022464U,
-        17515409024U, 17523801728U, 17532189824U, 17540577664U, 17548966016U,
-        17557353344U, 17565741184U, 17574131584U, 17582519168U, 17590907008U,
-        17599296128U, 17607687808U, 17616076672U, 17624455808U, 17632852352U,
-        17641238656U, 17649630848U, 17658018944U, 17666403968U, 17674794112U,
-        17683178368U, 17691573376U, 17699962496U, 17708350592U, 17716739968U,
-        17725126528U, 17733517184U, 17741898112U, 17750293888U, 17758673024U,
-        17767070336U, 17775458432U, 17783848832U, 17792236928U, 17800625536U,
-        17809012352U, 17817402752U, 17825785984U, 17834178944U, 17842563968U,
-        17850955648U, 17859344512U, 17867732864U, 17876119424U, 17884511872U,
-        17892900224U, 17901287296U, 17909677696U, 17918058112U, 17926451072U,
-        17934843776U, 17943230848U, 17951609216U, 17960008576U, 17968397696U,
-        17976784256U, 17985175424U, 17993564032U, 18001952128U, 18010339712U,
-        18018728576U, 18027116672U, 18035503232U, 18043894144U, 18052283264U,
-        18060672128U, 18069056384U, 18077449856U, 18085837184U, 18094225792U,
-        18102613376U, 18111004544U, 18119388544U, 18127781248U, 18136170368U,
-        18144558976U, 18152947328U, 18161336192U, 18169724288U, 18178108544U,
-        18186498944U, 18194886784U, 18203275648U, 18211666048U, 18220048768U,
-        18228444544U, 18236833408U, 18245220736U
+	1073739904U, 1082130304U, 1090514816U, 1098906752U, 1107293056U,
+	1115684224U, 1124070016U, 1132461952U, 1140849536U, 1149232768U,
+	1157627776U, 1166013824U, 1174404736U, 1182786944U, 1191180416U,
+	1199568512U, 1207958912U, 1216345216U, 1224732032U, 1233124736U,
+	1241513344U, 1249902464U, 1258290304U, 1266673792U, 1275067264U,
+	1283453312U, 1291844992U, 1300234112U, 1308619904U, 1317010048U,
+	1325397376U, 1333787776U, 1342176128U, 1350561664U, 1358954368U,
+	1367339392U, 1375731584U, 1384118144U, 1392507008U, 1400897408U,
+	1409284736U, 1417673344U, 1426062464U, 1434451072U, 1442839168U,
+	1451229056U, 1459615616U, 1468006016U, 1476394112U, 1484782976U,
+	1493171584U, 1501559168U, 1509948032U, 1518337664U, 1526726528U,
+	1535114624U, 1543503488U, 1551892096U, 1560278656U, 1568669056U,
+	1577056384U, 1585446272U, 1593831296U, 1602219392U, 1610610304U,
+	1619000192U, 1627386752U, 1635773824U, 1644164224U, 1652555648U,
+	1660943488U, 1669332608U, 1677721216U, 1686109312U, 1694497664U,
+	1702886272U, 1711274624U, 1719661184U, 1728047744U, 1736434816U,
+	1744829056U, 1753218944U, 1761606272U, 1769995904U, 1778382464U,
+	1786772864U, 1795157888U, 1803550592U, 1811937664U, 1820327552U,
+	1828711552U, 1837102976U, 1845488768U, 1853879936U, 1862269312U,
+	1870656896U, 1879048064U, 1887431552U, 1895825024U, 1904212096U,
+	1912601216U, 1920988544U, 1929379456U, 1937765504U, 1946156672U,
+	1954543232U, 1962932096U, 1971321728U, 1979707264U, 1988093056U,
+	1996487552U, 2004874624U, 2013262208U, 2021653888U, 2030039936U,
+	2038430848U, 2046819968U, 2055208576U, 2063596672U, 2071981952U,
+	2080373632U, 2088762752U, 2097149056U, 2105539712U, 2113928576U,
+	2122315136U, 2130700672U, 2139092608U, 2147483264U, 2155872128U,
+	2164257664U, 2172642176U, 2181035392U, 2189426048U, 2197814912U,
+	2206203008U, 2214587264U, 2222979712U, 2231367808U, 2239758208U,
+	2248145024U, 2256527744U, 2264922752U, 2273312128U, 2281701248U,
+	2290086272U, 2298476672U, 2306867072U, 2315251072U, 2323639168U,
+	2332032128U, 2340420224U, 2348808064U, 2357196416U, 2365580416U,
+	2373966976U, 2382363008U, 2390748544U, 2399139968U, 2407530368U,
+	2415918976U, 2424307328U, 2432695424U, 2441084288U, 2449472384U,
+	2457861248U, 2466247808U, 2474637184U, 2483026816U, 2491414144U,
+	2499803776U, 2508191872U, 2516582272U, 2524970368U, 2533359232U,
+	2541743488U, 2550134144U, 2558525056U, 2566913408U, 2575301504U,
+	2583686528U, 2592073856U, 2600467328U, 2608856192U, 2617240448U,
+	2625631616U, 2634022016U, 2642407552U, 2650796416U, 2659188352U,
+	2667574912U, 2675965312U, 2684352896U, 2692738688U, 2701130624U,
+	2709518464U, 2717907328U, 2726293376U, 2734685056U, 2743073152U,
+	2751462016U, 2759851648U, 2768232832U, 2776625536U, 2785017728U,
+	2793401984U, 2801794432U, 2810182016U, 2818571648U, 2826959488U,
+	2835349376U, 2843734144U, 2852121472U, 2860514432U, 2868900992U,
+	2877286784U, 2885676928U, 2894069632U, 2902451584U, 2910843008U,
+	2919234688U, 2927622784U, 2936011648U, 2944400768U, 2952789376U,
+	2961177728U, 2969565568U, 2977951616U, 2986338944U, 2994731392U,
+	3003120256U, 3011508352U, 3019895936U, 3028287104U, 3036675968U,
+	3045063808U, 3053452928U, 3061837696U, 3070228352U, 3078615424U,
+	3087003776U, 3095394944U, 3103782272U, 3112173184U, 3120562048U,
+	3128944768U, 3137339264U, 3145725056U, 3154109312U, 3162505088U,
+	3170893184U, 3179280256U, 3187669376U, 3196056704U, 3204445568U,
+	3212836736U, 3221224064U, 3229612928U, 3238002304U, 3246391168U,
+	3254778496U, 3263165824U, 3271556224U, 3279944576U, 3288332416U,
+	3296719232U, 3305110912U, 3313500032U, 3321887104U, 3330273152U,
+	3338658944U, 3347053184U, 3355440512U, 3363827072U, 3372220288U,
+	3380608384U, 3388997504U, 3397384576U, 3405774208U, 3414163072U,
+	3422551936U, 3430937984U, 3439328384U, 3447714176U, 3456104576U,
+	3464493952U, 3472883584U, 3481268864U, 3489655168U, 3498048896U,
+	3506434432U, 3514826368U, 3523213952U, 3531603584U, 3539987072U,
+	3548380288U, 3556763264U, 3565157248U, 3573545344U, 3581934464U,
+	3590324096U, 3598712704U, 3607098752U, 3615488384U, 3623877248U,
+	3632265856U, 3640646528U, 3649043584U, 3657430144U, 3665821568U,
+	3674207872U, 3682597504U, 3690984832U, 3699367808U, 3707764352U,
+	3716152448U, 3724541056U, 3732925568U, 3741318016U, 3749706368U,
+	3758091136U, 3766481536U, 3774872704U, 3783260032U, 3791650432U,
+	3800036224U, 3808427648U, 3816815488U, 3825204608U, 3833592704U,
+	3841981568U, 3850370432U, 3858755968U, 3867147904U, 3875536256U,
+	3883920512U, 3892313728U, 3900702592U, 3909087872U, 3917478784U,
+	3925868416U, 3934256512U, 3942645376U, 3951032192U, 3959422336U,
+	3967809152U, 3976200064U, 3984588416U, 3992974976U, 4001363584U,
+	4009751168U, 4018141312U, 4026530432U, 4034911616U, 4043308928U,
+	4051695488U, 4060084352U, 4068472448U, 4076862848U, 4085249408U,
+	4093640576U, 4102028416U, 4110413696U, 4118805632U, 4127194496U,
+	4135583104U, 4143971968U, 4152360832U, 4160746112U, 4169135744U,
+	4177525888U, 4185912704U, 4194303616U, 4202691968U, 4211076736U,
+	4219463552U, 4227855488U, 4236246656U, 4244633728U, 4253022848U,
+	4261412224U, 4269799808U, 4278184832U, 4286578048U, 4294962304U,
+	4303349632U, 4311743104U, 4320130432U, 4328521088U, 4336909184U,
+	4345295488U, 4353687424U, 4362073472U, 4370458496U, 4378852736U,
+	4387238528U, 4395630208U, 4404019072U, 4412407424U, 4420790656U,
+	4429182848U, 4437571456U, 4445962112U, 4454344064U, 4462738048U,
+	4471119232U, 4479516544U, 4487904128U, 4496289664U, 4504682368U,
+	4513068416U, 4521459584U, 4529846144U, 4538232704U, 4546619776U,
+	4555010176U, 4563402112U, 4571790208U, 4580174464U, 4588567936U,
+	4596957056U, 4605344896U, 4613734016U, 4622119808U, 4630511488U,
+	4638898816U, 4647287936U, 4655675264U, 4664065664U, 4672451968U,
+	4680842624U, 4689231488U, 4697620352U, 4706007424U, 4714397056U,
+	4722786176U, 4731173248U, 4739562368U, 4747951744U, 4756340608U,
+	4764727936U, 4773114496U, 4781504384U, 4789894784U, 4798283648U,
+	4806667648U, 4815059584U, 4823449472U, 4831835776U, 4840226176U,
+	4848612224U, 4857003392U, 4865391488U, 4873780096U, 4882169728U,
+	4890557312U, 4898946944U, 4907333248U, 4915722368U, 4924110976U,
+	4932499328U, 4940889728U, 4949276032U, 4957666432U, 4966054784U,
+	4974438016U, 4982831488U, 4991221376U, 4999607168U, 5007998848U,
+	5016386432U, 5024763776U, 5033164672U, 5041544576U, 5049941888U,
+	5058329728U, 5066717056U, 5075107456U, 5083494272U, 5091883904U,
+	5100273536U, 5108662144U, 5117048192U, 5125436032U, 5133827456U,
+	5142215296U, 5150605184U, 5158993024U, 5167382144U, 5175769472U,
+	5184157568U, 5192543872U, 5200936064U, 5209324928U, 5217711232U,
+	5226102656U, 5234490496U, 5242877312U, 5251263872U, 5259654016U,
+	5268040832U, 5276434304U, 5284819328U, 5293209728U, 5301598592U,
+	5309986688U, 5318374784U, 5326764416U, 5335151488U, 5343542144U,
+	5351929472U, 5360319872U, 5368706944U, 5377096576U, 5385484928U,
+	5393871232U, 5402263424U, 5410650496U, 5419040384U, 5427426944U,
+	5435816576U, 5444205952U, 5452594816U, 5460981376U, 5469367936U,
+	5477760896U, 5486148736U, 5494536832U, 5502925952U, 5511315328U,
+	5519703424U, 5528089984U, 5536481152U, 5544869504U, 5553256064U,
+	5561645696U, 5570032768U, 5578423936U, 5586811264U, 5595193216U,
+	5603585408U, 5611972736U, 5620366208U, 5628750464U, 5637143936U,
+	5645528192U, 5653921408U, 5662310272U, 5670694784U, 5679082624U,
+	5687474048U, 5695864448U, 5704251008U, 5712641408U, 5721030272U,
+	5729416832U, 5737806208U, 5746194304U, 5754583936U, 5762969984U,
+	5771358592U, 5779748224U, 5788137856U, 5796527488U, 5804911232U,
+	5813300608U, 5821692544U, 5830082176U, 5838468992U, 5846855552U,
+	5855247488U, 5863636096U, 5872024448U, 5880411008U, 5888799872U,
+	5897186432U, 5905576832U, 5913966976U, 5922352768U, 5930744704U,
+	5939132288U, 5947522432U, 5955911296U, 5964299392U, 5972688256U,
+	5981074304U, 5989465472U, 5997851008U, 6006241408U, 6014627968U,
+	6023015552U, 6031408256U, 6039796096U, 6048185216U, 6056574848U,
+	6064963456U, 6073351808U, 6081736064U, 6090128768U, 6098517632U,
+	6106906496U, 6115289216U, 6123680896U, 6132070016U, 6140459648U,
+	6148849024U, 6157237376U, 6165624704U, 6174009728U, 6182403712U,
+	6190792064U, 6199176064U, 6207569792U, 6215952256U, 6224345216U,
+	6232732544U, 6241124224U, 6249510272U, 6257899136U, 6266287744U,
+	6274676864U, 6283065728U, 6291454336U, 6299843456U, 6308232064U,
+	6316620928U, 6325006208U, 6333395584U, 6341784704U, 6350174848U,
+	6358562176U, 6366951296U, 6375337856U, 6383729536U, 6392119168U,
+	6400504192U, 6408895616U, 6417283456U, 6425673344U, 6434059136U,
+	6442444672U, 6450837376U, 6459223424U, 6467613056U, 6476004224U,
+	6484393088U, 6492781952U, 6501170048U, 6509555072U, 6517947008U,
+	6526336384U, 6534725504U, 6543112832U, 6551500672U, 6559888768U,
+	6568278656U, 6576662912U, 6585055616U, 6593443456U, 6601834112U,
+	6610219648U, 6618610304U, 6626999168U, 6635385472U, 6643777408U,
+	6652164224U, 6660552832U, 6668941952U, 6677330048U, 6685719424U,
+	6694107776U, 6702493568U, 6710882176U, 6719274112U, 6727662976U,
+	6736052096U, 6744437632U, 6752825984U, 6761213824U, 6769604224U,
+	6777993856U, 6786383488U, 6794770816U, 6803158144U, 6811549312U,
+	6819937664U, 6828326528U, 6836706176U, 6845101696U, 6853491328U,
+	6861880448U, 6870269312U, 6878655104U, 6887046272U, 6895433344U,
+	6903822208U, 6912212864U, 6920596864U, 6928988288U, 6937377152U,
+	6945764992U, 6954149248U, 6962544256U, 6970928768U, 6979317376U,
+	6987709312U, 6996093824U, 7004487296U, 7012875392U, 7021258624U,
+	7029652352U, 7038038912U, 7046427776U, 7054818944U, 7063207808U,
+	7071595136U, 7079980928U, 7088372608U, 7096759424U, 7105149824U,
+	7113536896U, 7121928064U, 7130315392U, 7138699648U, 7147092352U,
+	7155479168U, 7163865728U, 7172249984U, 7180648064U, 7189036672U,
+	7197424768U, 7205810816U, 7214196608U, 7222589824U, 7230975104U,
+	7239367552U, 7247755904U, 7256145536U, 7264533376U, 7272921472U,
+	7281308032U, 7289694848U, 7298088832U, 7306471808U, 7314864512U,
+	7323253888U, 7331643008U, 7340029568U, 7348419712U, 7356808832U,
+	7365196672U, 7373585792U, 7381973888U, 7390362752U, 7398750592U,
+	7407138944U, 7415528576U, 7423915648U, 7432302208U, 7440690304U,
+	7449080192U, 7457472128U, 7465860992U, 7474249088U, 7482635648U,
+	7491023744U, 7499412608U, 7507803008U, 7516192384U, 7524579968U,
+	7532967296U, 7541358464U, 7549745792U, 7558134656U, 7566524032U,
+	7574912896U, 7583300992U, 7591690112U, 7600075136U, 7608466816U,
+	7616854912U, 7625244544U, 7633629824U, 7642020992U, 7650410368U,
+	7658794112U, 7667187328U, 7675574912U, 7683961984U, 7692349568U,
+	7700739712U, 7709130368U, 7717519232U, 7725905536U, 7734295424U,
+	7742683264U, 7751069056U, 7759457408U, 7767849088U, 7776238208U,
+	7784626816U, 7793014912U, 7801405312U, 7809792128U, 7818179968U,
+	7826571136U, 7834957184U, 7843347328U, 7851732352U, 7860124544U,
+	7868512384U, 7876902016U, 7885287808U, 7893679744U, 7902067072U,
+	7910455936U, 7918844288U, 7927230848U, 7935622784U, 7944009344U,
+	7952400256U, 7960786048U, 7969176704U, 7977565312U, 7985953408U,
+	7994339968U, 8002730368U, 8011119488U, 8019508096U, 8027896192U,
+	8036285056U, 8044674688U, 8053062272U, 8061448832U, 8069838464U,
+	8078227328U, 8086616704U, 8095006592U, 8103393664U, 8111783552U,
+	8120171392U, 8128560256U, 8136949376U, 8145336704U, 8153726848U,
+	8162114944U, 8170503296U, 8178891904U, 8187280768U, 8195669632U,
+	8204058496U, 8212444544U, 8220834176U, 8229222272U, 8237612672U,
+	8246000768U, 8254389376U, 8262775168U, 8271167104U, 8279553664U,
+	8287944064U, 8296333184U, 8304715136U, 8313108352U, 8321497984U,
+	8329885568U, 8338274432U, 8346663296U, 8355052928U, 8363441536U,
+	8371828352U, 8380217984U, 8388606592U, 8396996224U, 8405384576U,
+	8413772672U, 8422161536U, 8430549376U, 8438939008U, 8447326592U,
+	8455715456U, 8464104832U, 8472492928U, 8480882048U, 8489270656U,
+	8497659776U, 8506045312U, 8514434944U, 8522823808U, 8531208832U,
+	8539602304U, 8547990656U, 8556378752U, 8564768384U, 8573154176U,
+	8581542784U, 8589933952U, 8598322816U, 8606705024U, 8615099264U,
+	8623487872U, 8631876992U, 8640264064U, 8648653952U, 8657040256U,
+	8665430656U, 8673820544U, 8682209152U, 8690592128U, 8698977152U,
+	8707374464U, 8715763328U, 8724151424U, 8732540032U, 8740928384U,
+	8749315712U, 8757704576U, 8766089344U, 8774480768U, 8782871936U,
+	8791260032U, 8799645824U, 8808034432U, 8816426368U, 8824812928U,
+	8833199488U, 8841591424U, 8849976448U, 8858366336U, 8866757248U,
+	8875147136U, 8883532928U, 8891923328U, 8900306816U, 8908700288U,
+	8917088384U, 8925478784U, 8933867392U, 8942250368U, 8950644608U,
+	8959032704U, 8967420544U, 8975809664U, 8984197504U, 8992584064U,
+	9000976256U, 9009362048U, 9017752448U, 9026141312U, 9034530688U,
+	9042917504U, 9051307904U, 9059694208U, 9068084864U, 9076471424U,
+	9084861824U, 9093250688U, 9101638528U, 9110027648U, 9118416512U,
+	9126803584U, 9135188096U, 9143581312U, 9151969664U, 9160356224U,
+	9168747136U, 9177134464U, 9185525632U, 9193910144U, 9202302848U,
+	9210690688U, 9219079552U, 9227465344U, 9235854464U, 9244244864U,
+	9252633472U, 9261021824U, 9269411456U, 9277799296U, 9286188928U,
+	9294574208U, 9302965888U, 9311351936U, 9319740032U, 9328131968U,
+	9336516736U, 9344907392U, 9353296768U, 9361685888U, 9370074752U,
+	9378463616U, 9386849408U, 9395239808U, 9403629184U, 9412016512U,
+	9420405376U, 9428795008U, 9437181568U, 9445570688U, 9453960832U,
+	9462346624U, 9470738048U, 9479121536U, 9487515008U, 9495903616U,
+	9504289664U, 9512678528U, 9521067904U, 9529456256U, 9537843584U,
+	9546233728U, 9554621312U, 9563011456U, 9571398784U, 9579788672U,
+	9588178304U, 9596567168U, 9604954496U, 9613343104U, 9621732992U,
+	9630121856U, 9638508416U, 9646898816U, 9655283584U, 9663675776U,
+	9672061312U, 9680449664U, 9688840064U, 9697230464U, 9705617536U,
+	9714003584U, 9722393984U, 9730772608U, 9739172224U, 9747561088U,
+	9755945344U, 9764338816U, 9772726144U, 9781116544U, 9789503872U,
+	9797892992U, 9806282624U, 9814670464U, 9823056512U, 9831439232U,
+	9839833984U, 9848224384U, 9856613504U, 9865000576U, 9873391232U,
+	9881772416U, 9890162816U, 9898556288U, 9906940544U, 9915333248U,
+	9923721088U, 9932108672U, 9940496512U, 9948888448U, 9957276544U,
+	9965666176U, 9974048384U, 9982441088U, 9990830464U, 9999219584U,
+	10007602816U, 10015996544U, 10024385152U, 10032774016U, 10041163648U,
+	10049548928U, 10057940096U, 10066329472U, 10074717824U, 10083105152U,
+	10091495296U, 10099878784U, 10108272256U, 10116660608U, 10125049216U,
+	10133437312U, 10141825664U, 10150213504U, 10158601088U, 10166991232U,
+	10175378816U, 10183766144U, 10192157312U, 10200545408U, 10208935552U,
+	10217322112U, 10225712768U, 10234099328U, 10242489472U, 10250876032U,
+	10259264896U, 10267656064U, 10276042624U, 10284429184U, 10292820352U,
+	10301209472U, 10309598848U, 10317987712U, 10326375296U, 10334763392U,
+	10343153536U, 10351541632U, 10359930752U, 10368318592U, 10376707456U,
+	10385096576U, 10393484672U, 10401867136U, 10410262144U, 10418647424U,
+	10427039104U, 10435425664U, 10443810176U, 10452203648U, 10460589952U,
+	10468982144U, 10477369472U, 10485759104U, 10494147712U, 10502533504U,
+	10510923392U, 10519313536U, 10527702656U, 10536091264U, 10544478592U,
+	10552867712U, 10561255808U, 10569642368U, 10578032768U, 10586423168U,
+	10594805632U, 10603200128U, 10611588992U, 10619976064U, 10628361344U,
+	10636754048U, 10645143424U, 10653531776U, 10661920384U, 10670307968U,
+	10678696832U, 10687086464U, 10695475072U, 10703863168U, 10712246144U,
+	10720639616U, 10729026688U, 10737414784U, 10745806208U, 10754190976U,
+	10762581376U, 10770971264U, 10779356288U, 10787747456U, 10796135552U,
+	10804525184U, 10812915584U, 10821301888U, 10829692288U, 10838078336U,
+	10846469248U, 10854858368U, 10863247232U, 10871631488U, 10880023424U,
+	10888412032U, 10896799616U, 10905188992U, 10913574016U, 10921964672U,
+	10930352768U, 10938742912U, 10947132544U, 10955518592U, 10963909504U,
+	10972298368U, 10980687488U, 10989074816U, 10997462912U, 11005851776U,
+	11014241152U, 11022627712U, 11031017344U, 11039403904U, 11047793024U,
+	11056184704U, 11064570752U, 11072960896U, 11081343872U, 11089737856U,
+	11098128256U, 11106514816U, 11114904448U, 11123293568U, 11131680128U,
+	11140065152U, 11148458368U, 11156845696U, 11165236864U, 11173624192U,
+	11182013824U, 11190402688U, 11198790784U, 11207179136U, 11215568768U,
+	11223957376U, 11232345728U, 11240734592U, 11249122688U, 11257511296U,
+	11265899648U, 11274285952U, 11282675584U, 11291065472U, 11299452544U,
+	11307842432U, 11316231296U, 11324616832U, 11333009024U, 11341395584U,
+	11349782656U, 11358172288U, 11366560384U, 11374950016U, 11383339648U,
+	11391721856U, 11400117376U, 11408504192U, 11416893568U, 11425283456U,
+	11433671552U, 11442061184U, 11450444672U, 11458837888U, 11467226752U,
+	11475611776U, 11484003968U, 11492392064U, 11500780672U, 11509169024U,
+	11517550976U, 11525944448U, 11534335616U, 11542724224U, 11551111808U,
+	11559500672U, 11567890304U, 11576277376U, 11584667008U, 11593056128U,
+	11601443456U, 11609830016U, 11618221952U, 11626607488U, 11634995072U,
+	11643387776U, 11651775104U, 11660161664U, 11668552576U, 11676940928U,
+	11685330304U, 11693718656U, 11702106496U, 11710496128U, 11718882688U,
+	11727273088U, 11735660416U, 11744050048U, 11752437376U, 11760824704U,
+	11769216128U, 11777604736U, 11785991296U, 11794381952U, 11802770048U,
+	11811157888U, 11819548544U, 11827932544U, 11836324736U, 11844713344U,
+	11853100928U, 11861486464U, 11869879936U, 11878268032U, 11886656896U,
+	11895044992U, 11903433088U, 11911822976U, 11920210816U, 11928600448U,
+	11936987264U, 11945375872U, 11953761152U, 11962151296U, 11970543488U,
+	11978928512U, 11987320448U, 11995708288U, 12004095104U, 12012486272U,
+	12020875136U, 12029255552U, 12037652096U, 12046039168U, 12054429568U,
+	12062813824U, 12071206528U, 12079594624U, 12087983744U, 12096371072U,
+	12104759936U, 12113147264U, 12121534592U, 12129924992U, 12138314624U,
+	12146703232U, 12155091584U, 12163481216U, 12171864704U, 12180255872U,
+	12188643968U, 12197034112U, 12205424512U, 12213811328U, 12222199424U,
+	12230590336U, 12238977664U, 12247365248U, 12255755392U, 12264143488U,
+	12272531584U, 12280920448U, 12289309568U, 12297694592U, 12306086528U,
+	12314475392U, 12322865024U, 12331253632U, 12339640448U, 12348029312U,
+	12356418944U, 12364805248U, 12373196672U, 12381580928U, 12389969024U,
+	12398357632U, 12406750592U, 12415138432U, 12423527552U, 12431916416U,
+	12440304512U, 12448692352U, 12457081216U, 12465467776U, 12473859968U,
+	12482245504U, 12490636672U, 12499025536U, 12507411584U, 12515801728U,
+	12524190592U, 12532577152U, 12540966272U, 12549354368U, 12557743232U,
+	12566129536U, 12574523264U, 12582911872U, 12591299456U, 12599688064U,
+	12608074624U, 12616463488U, 12624845696U, 12633239936U, 12641631616U,
+	12650019968U, 12658407296U, 12666795136U, 12675183232U, 12683574656U,
+	12691960192U, 12700350592U, 12708740224U, 12717128576U, 12725515904U,
+	12733906816U, 12742295168U, 12750680192U, 12759071872U, 12767460736U,
+	12775848832U, 12784236928U, 12792626816U, 12801014656U, 12809404288U,
+	12817789312U, 12826181504U, 12834568832U, 12842954624U, 12851345792U,
+	12859732352U, 12868122496U, 12876512128U, 12884901248U, 12893289088U,
+	12901672832U, 12910067584U, 12918455168U, 12926842496U, 12935232896U,
+	12943620736U, 12952009856U, 12960396928U, 12968786816U, 12977176192U,
+	12985563776U, 12993951104U, 13002341504U, 13010730368U, 13019115392U,
+	13027506304U, 13035895168U, 13044272512U, 13052673152U, 13061062528U,
+	13069446272U, 13077838976U, 13086227072U, 13094613632U, 13103000192U,
+	13111393664U, 13119782528U, 13128157568U, 13136559232U, 13144945024U,
+	13153329536U, 13161724288U, 13170111872U, 13178502784U, 13186884736U,
+	13195279744U, 13203667072U, 13212057472U, 13220445824U, 13228832128U,
+	13237221248U, 13245610624U, 13254000512U, 13262388352U, 13270777472U,
+	13279166336U, 13287553408U, 13295943296U, 13304331904U, 13312719488U,
+	13321108096U, 13329494656U, 13337885824U, 13346274944U, 13354663808U,
+	13363051136U, 13371439232U, 13379825024U, 13388210816U, 13396605056U,
+	13404995456U, 13413380224U, 13421771392U, 13430159744U, 13438546048U,
+	13446937216U, 13455326848U, 13463708288U, 13472103808U, 13480492672U,
+	13488875648U, 13497269888U, 13505657728U, 13514045312U, 13522435712U,
+	13530824576U, 13539210112U, 13547599232U, 13555989376U, 13564379008U,
+	13572766336U, 13581154432U, 13589544832U, 13597932928U, 13606320512U,
+	13614710656U, 13623097472U, 13631477632U, 13639874944U, 13648264064U,
+	13656652928U, 13665041792U, 13673430656U, 13681818496U, 13690207616U,
+	13698595712U, 13706982272U, 13715373184U, 13723762048U, 13732150144U,
+	13740536704U, 13748926592U, 13757316224U, 13765700992U, 13774090112U,
+	13782477952U, 13790869376U, 13799259008U, 13807647872U, 13816036736U,
+	13824425344U, 13832814208U, 13841202304U, 13849591424U, 13857978752U,
+	13866368896U, 13874754688U, 13883145344U, 13891533184U, 13899919232U,
+	13908311168U, 13916692096U, 13925085056U, 13933473152U, 13941866368U,
+	13950253696U, 13958643584U, 13967032192U, 13975417216U, 13983807616U,
+	13992197504U, 14000582272U, 14008973696U, 14017363072U, 14025752192U,
+	14034137984U, 14042528384U, 14050918016U, 14059301504U, 14067691648U,
+	14076083584U, 14084470144U, 14092852352U, 14101249664U, 14109635968U,
+	14118024832U, 14126407552U, 14134804352U, 14143188608U, 14151577984U,
+	14159968384U, 14168357248U, 14176741504U, 14185127296U, 14193521024U,
+	14201911424U, 14210301824U, 14218685056U, 14227067264U, 14235467392U,
+	14243855488U, 14252243072U, 14260630144U, 14269021568U, 14277409408U,
+	14285799296U, 14294187904U, 14302571392U, 14310961792U, 14319353728U,
+	14327738752U, 14336130944U, 14344518784U, 14352906368U, 14361296512U,
+	14369685376U, 14378071424U, 14386462592U, 14394848128U, 14403230848U,
+	14411627392U, 14420013952U, 14428402304U, 14436793472U, 14445181568U,
+	14453569664U, 14461959808U, 14470347904U, 14478737024U, 14487122816U,
+	14495511424U, 14503901824U, 14512291712U, 14520677504U, 14529064832U,
+	14537456768U, 14545845632U, 14554234496U, 14562618496U, 14571011456U,
+	14579398784U, 14587789184U, 14596172672U, 14604564608U, 14612953984U,
+	14621341312U, 14629724288U, 14638120832U, 14646503296U, 14654897536U,
+	14663284864U, 14671675264U, 14680061056U, 14688447616U, 14696835968U,
+	14705228416U, 14713616768U, 14722003328U, 14730392192U, 14738784128U,
+	14747172736U, 14755561088U, 14763947648U, 14772336512U, 14780725376U,
+	14789110144U, 14797499776U, 14805892736U, 14814276992U, 14822670208U,
+	14831056256U, 14839444352U, 14847836032U, 14856222848U, 14864612992U,
+	14872997504U, 14881388672U, 14889775744U, 14898165376U, 14906553472U,
+	14914944896U, 14923329664U, 14931721856U, 14940109696U, 14948497024U,
+	14956887424U, 14965276544U, 14973663616U, 14982053248U, 14990439808U,
+	14998830976U, 15007216768U, 15015605888U, 15023995264U, 15032385152U,
+	15040768384U, 15049154944U, 15057549184U, 15065939072U, 15074328448U,
+	15082715008U, 15091104128U, 15099493504U, 15107879296U, 15116269184U,
+	15124659584U, 15133042304U, 15141431936U, 15149824384U, 15158214272U,
+	15166602368U, 15174991232U, 15183378304U, 15191760512U, 15200154496U,
+	15208542592U, 15216931712U, 15225323392U, 15233708416U, 15242098048U,
+	15250489216U, 15258875264U, 15267265408U, 15275654528U, 15284043136U,
+	15292431488U, 15300819584U, 15309208192U, 15317596544U, 15325986176U,
+	15334374784U, 15342763648U, 15351151744U, 15359540608U, 15367929728U,
+	15376318336U, 15384706432U, 15393092992U, 15401481856U, 15409869952U,
+	15418258816U, 15426649984U, 15435037568U, 15443425664U, 15451815296U,
+	15460203392U, 15468589184U, 15476979328U, 15485369216U, 15493755776U,
+	15502146944U, 15510534272U, 15518924416U, 15527311232U, 15535699072U,
+	15544089472U, 15552478336U, 15560866688U, 15569254528U, 15577642624U,
+	15586031488U, 15594419072U, 15602809472U, 15611199104U, 15619586432U,
+	15627975296U, 15636364928U, 15644753792U, 15653141888U, 15661529216U,
+	15669918848U, 15678305152U, 15686696576U, 15695083136U, 15703474048U,
+	15711861632U, 15720251264U, 15728636288U, 15737027456U, 15745417088U,
+	15753804928U, 15762194048U, 15770582656U, 15778971008U, 15787358336U,
+	15795747712U, 15804132224U, 15812523392U, 15820909696U, 15829300096U,
+	15837691264U, 15846071936U, 15854466944U, 15862855808U, 15871244672U,
+	15879634816U, 15888020608U, 15896409728U, 15904799104U, 15913185152U,
+	15921577088U, 15929966464U, 15938354816U, 15946743424U, 15955129472U,
+	15963519872U, 15971907968U, 15980296064U, 15988684928U, 15997073024U,
+	16005460864U, 16013851264U, 16022241152U, 16030629248U, 16039012736U,
+	16047406976U, 16055794816U, 16064181376U, 16072571264U, 16080957824U,
+	16089346688U, 16097737856U, 16106125184U, 16114514816U, 16122904192U,
+	16131292544U, 16139678848U, 16148066944U, 16156453504U, 16164839552U,
+	16173236096U, 16181623424U, 16190012032U, 16198401152U, 16206790528U,
+	16215177344U, 16223567744U, 16231956352U, 16240344704U, 16248731008U,
+	16257117824U, 16265504384U, 16273898624U, 16282281856U, 16290668672U,
+	16299064192U, 16307449216U, 16315842176U, 16324230016U, 16332613504U,
+	16341006464U, 16349394304U, 16357783168U, 16366172288U, 16374561664U,
+	16382951296U, 16391337856U, 16399726208U, 16408116352U, 16416505472U,
+	16424892032U, 16433282176U, 16441668224U, 16450058624U, 16458448768U,
+	16466836864U, 16475224448U, 16483613056U, 16492001408U, 16500391808U,
+	16508779648U, 16517166976U, 16525555328U, 16533944192U, 16542330752U,
+	16550719616U, 16559110528U, 16567497088U, 16575888512U, 16584274816U,
+	16592665472U, 16601051008U, 16609442944U, 16617832064U, 16626218624U,
+	16634607488U, 16642996096U, 16651385728U, 16659773824U, 16668163712U,
+	16676552576U, 16684938112U, 16693328768U, 16701718144U, 16710095488U,
+	16718492288U, 16726883968U, 16735272832U, 16743661184U, 16752049792U,
+	16760436608U, 16768827008U, 16777214336U, 16785599104U, 16793992832U,
+	16802381696U, 16810768768U, 16819151744U, 16827542656U, 16835934848U,
+	16844323712U, 16852711552U, 16861101952U, 16869489536U, 16877876864U,
+	16886265728U, 16894653056U, 16903044736U, 16911431296U, 16919821696U,
+	16928207488U, 16936592768U, 16944987776U, 16953375616U, 16961763968U,
+	16970152832U, 16978540928U, 16986929536U, 16995319168U, 17003704448U,
+	17012096896U, 17020481152U, 17028870784U, 17037262208U, 17045649536U,
+	17054039936U, 17062426496U, 17070814336U, 17079205504U, 17087592064U,
+	17095978112U, 17104369024U, 17112759424U, 17121147776U, 17129536384U,
+	17137926016U, 17146314368U, 17154700928U, 17163089792U, 17171480192U,
+	17179864192U, 17188256896U, 17196644992U, 17205033856U, 17213423488U,
+	17221811072U, 17230198912U, 17238588032U, 17246976896U, 17255360384U,
+	17263754624U, 17272143232U, 17280530048U, 17288918912U, 17297309312U,
+	17305696384U, 17314085504U, 17322475136U, 17330863744U, 17339252096U,
+	17347640192U, 17356026496U, 17364413824U, 17372796544U, 17381190016U,
+	17389583488U, 17397972608U, 17406360704U, 17414748544U, 17423135872U,
+	17431527296U, 17439915904U, 17448303232U, 17456691584U, 17465081728U,
+	17473468288U, 17481857408U, 17490247552U, 17498635904U, 17507022464U,
+	17515409024U, 17523801728U, 17532189824U, 17540577664U, 17548966016U,
+	17557353344U, 17565741184U, 17574131584U, 17582519168U, 17590907008U,
+	17599296128U, 17607687808U, 17616076672U, 17624455808U, 17632852352U,
+	17641238656U, 17649630848U, 17658018944U, 17666403968U, 17674794112U,
+	17683178368U, 17691573376U, 17699962496U, 17708350592U, 17716739968U,
+	17725126528U, 17733517184U, 17741898112U, 17750293888U, 17758673024U,
+	17767070336U, 17775458432U, 17783848832U, 17792236928U, 17800625536U,
+	17809012352U, 17817402752U, 17825785984U, 17834178944U, 17842563968U,
+	17850955648U, 17859344512U, 17867732864U, 17876119424U, 17884511872U,
+	17892900224U, 17901287296U, 17909677696U, 17918058112U, 17926451072U,
+	17934843776U, 17943230848U, 17951609216U, 17960008576U, 17968397696U,
+	17976784256U, 17985175424U, 17993564032U, 18001952128U, 18010339712U,
+	18018728576U, 18027116672U, 18035503232U, 18043894144U, 18052283264U,
+	18060672128U, 18069056384U, 18077449856U, 18085837184U, 18094225792U,
+	18102613376U, 18111004544U, 18119388544U, 18127781248U, 18136170368U,
+	18144558976U, 18152947328U, 18161336192U, 18169724288U, 18178108544U,
+	18186498944U, 18194886784U, 18203275648U, 18211666048U, 18220048768U,
+	18228444544U, 18236833408U, 18245220736U
 };
 
 
@@ -478,335 +478,335 @@ static const uint64_t dag_sizes[2048] = {
 //         Sow[i*HashBytes]; j++]]]][[2]][[1]]
 
 const uint64_t cache_sizes[2048] = {
-        16776896U, 16907456U, 17039296U, 17170112U, 17301056U, 17432512U, 17563072U,
-        17693888U, 17824192U, 17955904U, 18087488U, 18218176U, 18349504U, 18481088U,
-        18611392U, 18742336U, 18874304U, 19004224U, 19135936U, 19267264U, 19398208U,
-        19529408U, 19660096U, 19791424U, 19922752U, 20053952U, 20184896U, 20315968U,
-        20446912U, 20576576U, 20709184U, 20840384U, 20971072U, 21102272U, 21233216U,
-        21364544U, 21494848U, 21626816U, 21757376U, 21887552U, 22019392U, 22151104U,
-        22281536U, 22412224U, 22543936U, 22675264U, 22806464U, 22935872U, 23068096U,
-        23198272U, 23330752U, 23459008U, 23592512U, 23723968U, 23854912U, 23986112U,
-        24116672U, 24247616U, 24378688U, 24509504U, 24640832U, 24772544U, 24903488U,
-        25034432U, 25165376U, 25296704U, 25427392U, 25558592U, 25690048U, 25820096U,
-        25951936U, 26081728U, 26214208U, 26345024U, 26476096U, 26606656U, 26737472U,
-        26869184U, 26998208U, 27131584U, 27262528U, 27393728U, 27523904U, 27655744U,
-        27786688U, 27917888U, 28049344U, 28179904U, 28311488U, 28441792U, 28573504U,
-        28700864U, 28835648U, 28966208U, 29096768U, 29228608U, 29359808U, 29490752U,
-        29621824U, 29752256U, 29882816U, 30014912U, 30144448U, 30273728U, 30406976U,
-        30538432U, 30670784U, 30799936U, 30932672U, 31063744U, 31195072U, 31325248U,
-        31456192U, 31588288U, 31719232U, 31850432U, 31981504U, 32110784U, 32243392U,
-        32372672U, 32505664U, 32636608U, 32767808U, 32897344U, 33029824U, 33160768U,
-        33289664U, 33423296U, 33554368U, 33683648U, 33816512U, 33947456U, 34076992U,
-        34208704U, 34340032U, 34471744U, 34600256U, 34734016U, 34864576U, 34993984U,
-        35127104U, 35258176U, 35386688U, 35518528U, 35650624U, 35782336U, 35910976U,
-        36044608U, 36175808U, 36305728U, 36436672U, 36568384U, 36699968U, 36830656U,
-        36961984U, 37093312U, 37223488U, 37355072U, 37486528U, 37617472U, 37747904U,
-        37879232U, 38009792U, 38141888U, 38272448U, 38403392U, 38535104U, 38660672U,
-        38795584U, 38925632U, 39059264U, 39190336U, 39320768U, 39452096U, 39581632U,
-        39713984U, 39844928U, 39974848U, 40107968U, 40238144U, 40367168U, 40500032U,
-        40631744U, 40762816U, 40894144U, 41023552U, 41155904U, 41286208U, 41418304U,
-        41547712U, 41680448U, 41811904U, 41942848U, 42073792U, 42204992U, 42334912U,
-        42467008U, 42597824U, 42729152U, 42860096U, 42991552U, 43122368U, 43253696U,
-        43382848U, 43515712U, 43646912U, 43777088U, 43907648U, 44039104U, 44170432U,
-        44302144U, 44433344U, 44564288U, 44694976U, 44825152U, 44956864U, 45088448U,
-        45219008U, 45350464U, 45481024U, 45612608U, 45744064U, 45874496U, 46006208U,
-        46136768U, 46267712U, 46399424U, 46529344U, 46660672U, 46791488U, 46923328U,
-        47053504U, 47185856U, 47316928U, 47447872U, 47579072U, 47710144U, 47839936U,
-        47971648U, 48103232U, 48234176U, 48365248U, 48496192U, 48627136U, 48757312U,
-        48889664U, 49020736U, 49149248U, 49283008U, 49413824U, 49545152U, 49675712U,
-        49807168U, 49938368U, 50069056U, 50200256U, 50331584U, 50462656U, 50593472U,
-        50724032U, 50853952U, 50986048U, 51117632U, 51248576U, 51379904U, 51510848U,
-        51641792U, 51773248U, 51903296U, 52035136U, 52164032U, 52297664U, 52427968U,
-        52557376U, 52690112U, 52821952U, 52952896U, 53081536U, 53213504U, 53344576U,
-        53475776U, 53608384U, 53738816U, 53870528U, 54000832U, 54131776U, 54263744U,
-        54394688U, 54525248U, 54655936U, 54787904U, 54918592U, 55049152U, 55181248U,
-        55312064U, 55442752U, 55574336U, 55705024U, 55836224U, 55967168U, 56097856U,
-        56228672U, 56358592U, 56490176U, 56621888U, 56753728U, 56884928U, 57015488U,
-        57146816U, 57278272U, 57409216U, 57540416U, 57671104U, 57802432U, 57933632U,
-        58064576U, 58195264U, 58326976U, 58457408U, 58588864U, 58720192U, 58849984U,
-        58981696U, 59113024U, 59243456U, 59375552U, 59506624U, 59637568U, 59768512U,
-        59897792U, 60030016U, 60161984U, 60293056U, 60423872U, 60554432U, 60683968U,
-        60817216U, 60948032U, 61079488U, 61209664U, 61341376U, 61471936U, 61602752U,
-        61733696U, 61865792U, 61996736U, 62127808U, 62259136U, 62389568U, 62520512U,
-        62651584U, 62781632U, 62910784U, 63045056U, 63176128U, 63307072U, 63438656U,
-        63569216U, 63700928U, 63831616U, 63960896U, 64093888U, 64225088U, 64355392U,
-        64486976U, 64617664U, 64748608U, 64879424U, 65009216U, 65142464U, 65273792U,
-        65402816U, 65535424U, 65666752U, 65797696U, 65927744U, 66060224U, 66191296U,
-        66321344U, 66453056U, 66584384U, 66715328U, 66846656U, 66977728U, 67108672U,
-        67239104U, 67370432U, 67501888U, 67631296U, 67763776U, 67895104U, 68026304U,
-        68157248U, 68287936U, 68419264U, 68548288U, 68681408U, 68811968U, 68942912U,
-        69074624U, 69205568U, 69337024U, 69467584U, 69599168U, 69729472U, 69861184U,
-        69989824U, 70122944U, 70253888U, 70385344U, 70515904U, 70647232U, 70778816U,
-        70907968U, 71040832U, 71171648U, 71303104U, 71432512U, 71564992U, 71695168U,
-        71826368U, 71958464U, 72089536U, 72219712U, 72350144U, 72482624U, 72613568U,
-        72744512U, 72875584U, 73006144U, 73138112U, 73268672U, 73400128U, 73530944U,
-        73662272U, 73793344U, 73924544U, 74055104U, 74185792U, 74316992U, 74448832U,
-        74579392U, 74710976U, 74841664U, 74972864U, 75102784U, 75233344U, 75364544U,
-        75497024U, 75627584U, 75759296U, 75890624U, 76021696U, 76152256U, 76283072U,
-        76414144U, 76545856U, 76676672U, 76806976U, 76937792U, 77070016U, 77200832U,
-        77331392U, 77462464U, 77593664U, 77725376U, 77856448U, 77987776U, 78118336U,
-        78249664U, 78380992U, 78511424U, 78642496U, 78773056U, 78905152U, 79033664U,
-        79166656U, 79297472U, 79429568U, 79560512U, 79690816U, 79822784U, 79953472U,
-        80084672U, 80214208U, 80346944U, 80477632U, 80608576U, 80740288U, 80870848U,
-        81002048U, 81133504U, 81264448U, 81395648U, 81525952U, 81657536U, 81786304U,
-        81919808U, 82050112U, 82181312U, 82311616U, 82443968U, 82573376U, 82705984U,
-        82835776U, 82967744U, 83096768U, 83230528U, 83359552U, 83491264U, 83622464U,
-        83753536U, 83886016U, 84015296U, 84147776U, 84277184U, 84409792U, 84540608U,
-        84672064U, 84803008U, 84934336U, 85065152U, 85193792U, 85326784U, 85458496U,
-        85589312U, 85721024U, 85851968U, 85982656U, 86112448U, 86244416U, 86370112U,
-        86506688U, 86637632U, 86769344U, 86900672U, 87031744U, 87162304U, 87293632U,
-        87424576U, 87555392U, 87687104U, 87816896U, 87947968U, 88079168U, 88211264U,
-        88341824U, 88473152U, 88603712U, 88735424U, 88862912U, 88996672U, 89128384U,
-        89259712U, 89390272U, 89521984U, 89652544U, 89783872U, 89914816U, 90045376U,
-        90177088U, 90307904U, 90438848U, 90569152U, 90700096U, 90832832U, 90963776U,
-        91093696U, 91223744U, 91356992U, 91486784U, 91618496U, 91749824U, 91880384U,
-        92012224U, 92143552U, 92273344U, 92405696U, 92536768U, 92666432U, 92798912U,
-        92926016U, 93060544U, 93192128U, 93322816U, 93453632U, 93583936U, 93715136U,
-        93845056U, 93977792U, 94109504U, 94240448U, 94371776U, 94501184U, 94632896U,
-        94764224U, 94895552U, 95023424U, 95158208U, 95287744U, 95420224U, 95550016U,
-        95681216U, 95811904U, 95943872U, 96075328U, 96203584U, 96337856U, 96468544U,
-        96599744U, 96731072U, 96860992U, 96992576U, 97124288U, 97254848U, 97385536U,
-        97517248U, 97647808U, 97779392U, 97910464U, 98041408U, 98172608U, 98303168U,
-        98434496U, 98565568U, 98696768U, 98827328U, 98958784U, 99089728U, 99220928U,
-        99352384U, 99482816U, 99614272U, 99745472U, 99876416U, 100007104U,
-        100138048U, 100267072U, 100401088U, 100529984U, 100662592U, 100791872U,
-        100925248U, 101056064U, 101187392U, 101317952U, 101449408U, 101580608U,
-        101711296U, 101841728U, 101973824U, 102104896U, 102235712U, 102366016U,
-        102498112U, 102628672U, 102760384U, 102890432U, 103021888U, 103153472U,
-        103284032U, 103415744U, 103545152U, 103677248U, 103808576U, 103939648U,
-        104070976U, 104201792U, 104332736U, 104462528U, 104594752U, 104725952U,
-        104854592U, 104988608U, 105118912U, 105247808U, 105381184U, 105511232U,
-        105643072U, 105774784U, 105903296U, 106037056U, 106167872U, 106298944U,
-        106429504U, 106561472U, 106691392U, 106822592U, 106954304U, 107085376U,
-        107216576U, 107346368U, 107478464U, 107609792U, 107739712U, 107872192U,
-        108003136U, 108131392U, 108265408U, 108396224U, 108527168U, 108657344U,
-        108789568U, 108920384U, 109049792U, 109182272U, 109312576U, 109444928U,
-        109572928U, 109706944U, 109837888U, 109969088U, 110099648U, 110230976U,
-        110362432U, 110492992U, 110624704U, 110755264U, 110886208U, 111017408U,
-        111148864U, 111279296U, 111410752U, 111541952U, 111673024U, 111803456U,
-        111933632U, 112066496U, 112196416U, 112328512U, 112457792U, 112590784U,
-        112715968U, 112852672U, 112983616U, 113114944U, 113244224U, 113376448U,
-        113505472U, 113639104U, 113770304U, 113901376U, 114031552U, 114163264U,
-        114294592U, 114425536U, 114556864U, 114687424U, 114818624U, 114948544U,
-        115080512U, 115212224U, 115343296U, 115473472U, 115605184U, 115736128U,
-        115867072U, 115997248U, 116128576U, 116260288U, 116391488U, 116522944U,
-        116652992U, 116784704U, 116915648U, 117046208U, 117178304U, 117308608U,
-        117440192U, 117569728U, 117701824U, 117833024U, 117964096U, 118094656U,
-        118225984U, 118357312U, 118489024U, 118617536U, 118749632U, 118882112U,
-        119012416U, 119144384U, 119275328U, 119406016U, 119537344U, 119668672U,
-        119798464U, 119928896U, 120061376U, 120192832U, 120321728U, 120454336U,
-        120584512U, 120716608U, 120848192U, 120979136U, 121109056U, 121241408U,
-        121372352U, 121502912U, 121634752U, 121764416U, 121895744U, 122027072U,
-        122157632U, 122289088U, 122421184U, 122550592U, 122682944U, 122813888U,
-        122945344U, 123075776U, 123207488U, 123338048U, 123468736U, 123600704U,
-        123731264U, 123861952U, 123993664U, 124124608U, 124256192U, 124386368U,
-        124518208U, 124649024U, 124778048U, 124911296U, 125041088U, 125173696U,
-        125303744U, 125432896U, 125566912U, 125696576U, 125829056U, 125958592U,
-        126090304U, 126221248U, 126352832U, 126483776U, 126615232U, 126746432U,
-        126876608U, 127008704U, 127139392U, 127270336U, 127401152U, 127532224U,
-        127663552U, 127794752U, 127925696U, 128055232U, 128188096U, 128319424U,
-        128449856U, 128581312U, 128712256U, 128843584U, 128973632U, 129103808U,
-        129236288U, 129365696U, 129498944U, 129629888U, 129760832U, 129892288U,
-        130023104U, 130154048U, 130283968U, 130416448U, 130547008U, 130678336U,
-        130807616U, 130939456U, 131071552U, 131202112U, 131331776U, 131464384U,
-        131594048U, 131727296U, 131858368U, 131987392U, 132120256U, 132250816U,
-        132382528U, 132513728U, 132644672U, 132774976U, 132905792U, 133038016U,
-        133168832U, 133299392U, 133429312U, 133562048U, 133692992U, 133823296U,
-        133954624U, 134086336U, 134217152U, 134348608U, 134479808U, 134607296U,
-        134741056U, 134872384U, 135002944U, 135134144U, 135265472U, 135396544U,
-        135527872U, 135659072U, 135787712U, 135921472U, 136052416U, 136182848U,
-        136313792U, 136444864U, 136576448U, 136707904U, 136837952U, 136970048U,
-        137099584U, 137232064U, 137363392U, 137494208U, 137625536U, 137755712U,
-        137887424U, 138018368U, 138149824U, 138280256U, 138411584U, 138539584U,
-        138672832U, 138804928U, 138936128U, 139066688U, 139196864U, 139328704U,
-        139460032U, 139590208U, 139721024U, 139852864U, 139984576U, 140115776U,
-        140245696U, 140376512U, 140508352U, 140640064U, 140769856U, 140902336U,
-        141032768U, 141162688U, 141294016U, 141426496U, 141556544U, 141687488U,
-        141819584U, 141949888U, 142080448U, 142212544U, 142342336U, 142474432U,
-        142606144U, 142736192U, 142868288U, 142997824U, 143129408U, 143258944U,
-        143392448U, 143523136U, 143653696U, 143785024U, 143916992U, 144045632U,
-        144177856U, 144309184U, 144440768U, 144570688U, 144701888U, 144832448U,
-        144965056U, 145096384U, 145227584U, 145358656U, 145489856U, 145620928U,
-        145751488U, 145883072U, 146011456U, 146144704U, 146275264U, 146407232U,
-        146538176U, 146668736U, 146800448U, 146931392U, 147062336U, 147193664U,
-        147324224U, 147455936U, 147586624U, 147717056U, 147848768U, 147979456U,
-        148110784U, 148242368U, 148373312U, 148503232U, 148635584U, 148766144U,
-        148897088U, 149028416U, 149159488U, 149290688U, 149420224U, 149551552U,
-        149683136U, 149814976U, 149943616U, 150076352U, 150208064U, 150338624U,
-        150470464U, 150600256U, 150732224U, 150862784U, 150993088U, 151125952U,
-        151254976U, 151388096U, 151519168U, 151649728U, 151778752U, 151911104U,
-        152042944U, 152174144U, 152304704U, 152435648U, 152567488U, 152698816U,
-        152828992U, 152960576U, 153091648U, 153222976U, 153353792U, 153484096U,
-        153616192U, 153747008U, 153878336U, 154008256U, 154139968U, 154270912U,
-        154402624U, 154533824U, 154663616U, 154795712U, 154926272U, 155057984U,
-        155188928U, 155319872U, 155450816U, 155580608U, 155712064U, 155843392U,
-        155971136U, 156106688U, 156237376U, 156367424U, 156499264U, 156630976U,
-        156761536U, 156892352U, 157024064U, 157155008U, 157284416U, 157415872U,
-        157545536U, 157677248U, 157810496U, 157938112U, 158071744U, 158203328U,
-        158334656U, 158464832U, 158596288U, 158727616U, 158858048U, 158988992U,
-        159121216U, 159252416U, 159381568U, 159513152U, 159645632U, 159776192U,
-        159906496U, 160038464U, 160169536U, 160300352U, 160430656U, 160563008U,
-        160693952U, 160822208U, 160956352U, 161086784U, 161217344U, 161349184U,
-        161480512U, 161611456U, 161742272U, 161873216U, 162002752U, 162135872U,
-        162266432U, 162397888U, 162529216U, 162660032U, 162790976U, 162922048U,
-        163052096U, 163184576U, 163314752U, 163446592U, 163577408U, 163707968U,
-        163839296U, 163969984U, 164100928U, 164233024U, 164364224U, 164494912U,
-        164625856U, 164756672U, 164887616U, 165019072U, 165150016U, 165280064U,
-        165412672U, 165543104U, 165674944U, 165805888U, 165936832U, 166067648U,
-        166198336U, 166330048U, 166461248U, 166591552U, 166722496U, 166854208U,
-        166985408U, 167116736U, 167246656U, 167378368U, 167508416U, 167641024U,
-        167771584U, 167903168U, 168034112U, 168164032U, 168295744U, 168427456U,
-        168557632U, 168688448U, 168819136U, 168951616U, 169082176U, 169213504U,
-        169344832U, 169475648U, 169605952U, 169738048U, 169866304U, 169999552U,
-        170131264U, 170262464U, 170393536U, 170524352U, 170655424U, 170782016U,
-        170917696U, 171048896U, 171179072U, 171310784U, 171439936U, 171573184U,
-        171702976U, 171835072U, 171966272U, 172097216U, 172228288U, 172359232U,
-        172489664U, 172621376U, 172747712U, 172883264U, 173014208U, 173144512U,
-        173275072U, 173407424U, 173539136U, 173669696U, 173800768U, 173931712U,
-        174063424U, 174193472U, 174325696U, 174455744U, 174586816U, 174718912U,
-        174849728U, 174977728U, 175109696U, 175242688U, 175374272U, 175504832U,
-        175636288U, 175765696U, 175898432U, 176028992U, 176159936U, 176291264U,
-        176422592U, 176552512U, 176684864U, 176815424U, 176946496U, 177076544U,
-        177209152U, 177340096U, 177470528U, 177600704U, 177731648U, 177864256U,
-        177994816U, 178126528U, 178257472U, 178387648U, 178518464U, 178650176U,
-        178781888U, 178912064U, 179044288U, 179174848U, 179305024U, 179436736U,
-        179568448U, 179698496U, 179830208U, 179960512U, 180092608U, 180223808U,
-        180354752U, 180485696U, 180617152U, 180748096U, 180877504U, 181009984U,
-        181139264U, 181272512U, 181402688U, 181532608U, 181663168U, 181795136U,
-        181926592U, 182057536U, 182190016U, 182320192U, 182451904U, 182582336U,
-        182713792U, 182843072U, 182976064U, 183107264U, 183237056U, 183368384U,
-        183494848U, 183631424U, 183762752U, 183893824U, 184024768U, 184154816U,
-        184286656U, 184417984U, 184548928U, 184680128U, 184810816U, 184941248U,
-        185072704U, 185203904U, 185335616U, 185465408U, 185596352U, 185727296U,
-        185859904U, 185989696U, 186121664U, 186252992U, 186383552U, 186514112U,
-        186645952U, 186777152U, 186907328U, 187037504U, 187170112U, 187301824U,
-        187429184U, 187562048U, 187693504U, 187825472U, 187957184U, 188087104U,
-        188218304U, 188349376U, 188481344U, 188609728U, 188743616U, 188874304U,
-        189005248U, 189136448U, 189265088U, 189396544U, 189528128U, 189660992U,
-        189791936U, 189923264U, 190054208U, 190182848U, 190315072U, 190447424U,
-        190577984U, 190709312U, 190840768U, 190971328U, 191102656U, 191233472U,
-        191364032U, 191495872U, 191626816U, 191758016U, 191888192U, 192020288U,
-        192148928U, 192282176U, 192413504U, 192542528U, 192674752U, 192805952U,
-        192937792U, 193068608U, 193198912U, 193330496U, 193462208U, 193592384U,
-        193723456U, 193854272U, 193985984U, 194116672U, 194247232U, 194379712U,
-        194508352U, 194641856U, 194772544U, 194900672U, 195035072U, 195166016U,
-        195296704U, 195428032U, 195558592U, 195690304U, 195818176U, 195952576U,
-        196083392U, 196214336U, 196345792U, 196476736U, 196607552U, 196739008U,
-        196869952U, 197000768U, 197130688U, 197262784U, 197394368U, 197523904U,
-        197656384U, 197787584U, 197916608U, 198049472U, 198180544U, 198310208U,
-        198442432U, 198573632U, 198705088U, 198834368U, 198967232U, 199097792U,
-        199228352U, 199360192U, 199491392U, 199621696U, 199751744U, 199883968U,
-        200014016U, 200146624U, 200276672U, 200408128U, 200540096U, 200671168U,
-        200801984U, 200933312U, 201062464U, 201194944U, 201326144U, 201457472U,
-        201588544U, 201719744U, 201850816U, 201981632U, 202111552U, 202244032U,
-        202374464U, 202505152U, 202636352U, 202767808U, 202898368U, 203030336U,
-        203159872U, 203292608U, 203423296U, 203553472U, 203685824U, 203816896U,
-        203947712U, 204078272U, 204208192U, 204341056U, 204472256U, 204603328U,
-        204733888U, 204864448U, 204996544U, 205125568U, 205258304U, 205388864U,
-        205517632U, 205650112U, 205782208U, 205913536U, 206044736U, 206176192U,
-        206307008U, 206434496U, 206569024U, 206700224U, 206831168U, 206961856U,
-        207093056U, 207223616U, 207355328U, 207486784U, 207616832U, 207749056U,
-        207879104U, 208010048U, 208141888U, 208273216U, 208404032U, 208534336U,
-        208666048U, 208796864U, 208927424U, 209059264U, 209189824U, 209321792U,
-        209451584U, 209582656U, 209715136U, 209845568U, 209976896U, 210106432U,
-        210239296U, 210370112U, 210501568U, 210630976U, 210763712U, 210894272U,
-        211024832U, 211156672U, 211287616U, 211418176U, 211549376U, 211679296U,
-        211812032U, 211942592U, 212074432U, 212204864U, 212334016U, 212467648U,
-        212597824U, 212727616U, 212860352U, 212991424U, 213120832U, 213253952U,
-        213385024U, 213515584U, 213645632U, 213777728U, 213909184U, 214040128U,
-        214170688U, 214302656U, 214433728U, 214564544U, 214695232U, 214826048U,
-        214956992U, 215089088U, 215219776U, 215350592U, 215482304U, 215613248U,
-        215743552U, 215874752U, 216005312U, 216137024U, 216267328U, 216399296U,
-        216530752U, 216661696U, 216790592U, 216923968U, 217054528U, 217183168U,
-        217316672U, 217448128U, 217579072U, 217709504U, 217838912U, 217972672U,
-        218102848U, 218233024U, 218364736U, 218496832U, 218627776U, 218759104U,
-        218888896U, 219021248U, 219151936U, 219281728U, 219413056U, 219545024U,
-        219675968U, 219807296U, 219938624U, 220069312U, 220200128U, 220331456U,
-        220461632U, 220592704U, 220725184U, 220855744U, 220987072U, 221117888U,
-        221249216U, 221378368U, 221510336U, 221642048U, 221772736U, 221904832U,
-        222031808U, 222166976U, 222297536U, 222428992U, 222559936U, 222690368U,
-        222820672U, 222953152U, 223083968U, 223213376U, 223345984U, 223476928U,
-        223608512U, 223738688U, 223869376U, 224001472U, 224132672U, 224262848U,
-        224394944U, 224524864U, 224657344U, 224788288U, 224919488U, 225050432U,
-        225181504U, 225312704U, 225443776U, 225574592U, 225704768U, 225834176U,
-        225966784U, 226097216U, 226229824U, 226360384U, 226491712U, 226623424U,
-        226754368U, 226885312U, 227015104U, 227147456U, 227278528U, 227409472U,
-        227539904U, 227669696U, 227802944U, 227932352U, 228065216U, 228196288U,
-        228326464U, 228457792U, 228588736U, 228720064U, 228850112U, 228981056U,
-        229113152U, 229243328U, 229375936U, 229505344U, 229636928U, 229769152U,
-        229894976U, 230030272U, 230162368U, 230292416U, 230424512U, 230553152U,
-        230684864U, 230816704U, 230948416U, 231079616U, 231210944U, 231342016U,
-        231472448U, 231603776U, 231733952U, 231866176U, 231996736U, 232127296U,
-        232259392U, 232388672U, 232521664U, 232652608U, 232782272U, 232914496U,
-        233043904U, 233175616U, 233306816U, 233438528U, 233569984U, 233699776U,
-        233830592U, 233962688U, 234092224U, 234221888U, 234353984U, 234485312U,
-        234618304U, 234749888U, 234880832U, 235011776U, 235142464U, 235274048U,
-        235403456U, 235535936U, 235667392U, 235797568U, 235928768U, 236057152U,
-        236190272U, 236322752U, 236453312U, 236583616U, 236715712U, 236846528U,
-        236976448U, 237108544U, 237239104U, 237371072U, 237501632U, 237630784U,
-        237764416U, 237895232U, 238026688U, 238157632U, 238286912U, 238419392U,
-        238548032U, 238681024U, 238812608U, 238941632U, 239075008U, 239206336U,
-        239335232U, 239466944U, 239599168U, 239730496U, 239861312U, 239992384U,
-        240122816U, 240254656U, 240385856U, 240516928U, 240647872U, 240779072U,
-        240909632U, 241040704U, 241171904U, 241302848U, 241433408U, 241565248U,
-        241696192U, 241825984U, 241958848U, 242088256U, 242220224U, 242352064U,
-        242481856U, 242611648U, 242744896U, 242876224U, 243005632U, 243138496U,
-        243268672U, 243400384U, 243531712U, 243662656U, 243793856U, 243924544U,
-        244054592U, 244187072U, 244316608U, 244448704U, 244580032U, 244710976U,
-        244841536U, 244972864U, 245104448U, 245233984U, 245365312U, 245497792U,
-        245628736U, 245759936U, 245889856U, 246021056U, 246152512U, 246284224U,
-        246415168U, 246545344U, 246675904U, 246808384U, 246939584U, 247070144U,
-        247199552U, 247331648U, 247463872U, 247593536U, 247726016U, 247857088U,
-        247987648U, 248116928U, 248249536U, 248380736U, 248512064U, 248643008U,
-        248773312U, 248901056U, 249036608U, 249167552U, 249298624U, 249429184U,
-        249560512U, 249692096U, 249822784U, 249954112U, 250085312U, 250215488U,
-        250345792U, 250478528U, 250608704U, 250739264U, 250870976U, 251002816U,
-        251133632U, 251263552U, 251395136U, 251523904U, 251657792U, 251789248U,
-        251919424U, 252051392U, 252182464U, 252313408U, 252444224U, 252575552U,
-        252706624U, 252836032U, 252968512U, 253099712U, 253227584U, 253361728U,
-        253493056U, 253623488U, 253754432U, 253885504U, 254017216U, 254148032U,
-        254279488U, 254410432U, 254541376U, 254672576U, 254803264U, 254933824U,
-        255065792U, 255196736U, 255326528U, 255458752U, 255589952U, 255721408U,
-        255851072U, 255983296U, 256114624U, 256244416U, 256374208U, 256507712U,
-        256636096U, 256768832U, 256900544U, 257031616U, 257162176U, 257294272U,
-        257424448U, 257555776U, 257686976U, 257818432U, 257949632U, 258079552U,
-        258211136U, 258342464U, 258473408U, 258603712U, 258734656U, 258867008U,
-        258996544U, 259127744U, 259260224U, 259391296U, 259522112U, 259651904U,
-        259784384U, 259915328U, 260045888U, 260175424U, 260308544U, 260438336U,
-        260570944U, 260700992U, 260832448U, 260963776U, 261092672U, 261226304U,
-        261356864U, 261487936U, 261619648U, 261750592U, 261879872U, 262011968U,
-        262143424U, 262274752U, 262404416U, 262537024U, 262667968U, 262799296U,
-        262928704U, 263061184U, 263191744U, 263322944U, 263454656U, 263585216U,
-        263716672U, 263847872U, 263978944U, 264108608U, 264241088U, 264371648U,
-        264501184U, 264632768U, 264764096U, 264895936U, 265024576U, 265158464U,
-        265287488U, 265418432U, 265550528U, 265681216U, 265813312U, 265943488U,
-        266075968U, 266206144U, 266337728U, 266468032U, 266600384U, 266731072U,
-        266862272U, 266993344U, 267124288U, 267255616U, 267386432U, 267516992U,
-        267648704U, 267777728U, 267910592U, 268040512U, 268172096U, 268302784U,
-        268435264U, 268566208U, 268696256U, 268828096U, 268959296U, 269090368U,
-        269221312U, 269352256U, 269482688U, 269614784U, 269745856U, 269876416U,
-        270007616U, 270139328U, 270270272U, 270401216U, 270531904U, 270663616U,
-        270791744U, 270924736U, 271056832U, 271186112U, 271317184U, 271449536U,
-        271580992U, 271711936U, 271843136U, 271973056U, 272105408U, 272236352U,
-        272367296U, 272498368U, 272629568U, 272759488U, 272891456U, 273022784U,
-        273153856U, 273284672U, 273415616U, 273547072U, 273677632U, 273808448U,
-        273937088U, 274071488U, 274200896U, 274332992U, 274463296U, 274595392U,
-        274726208U, 274857536U, 274988992U, 275118656U, 275250496U, 275382208U,
-        275513024U, 275643968U, 275775296U, 275906368U, 276037184U, 276167872U,
-        276297664U, 276429376U, 276560576U, 276692672U, 276822976U, 276955072U,
-        277085632U, 277216832U, 277347008U, 277478848U, 277609664U, 277740992U,
-        277868608U, 278002624U, 278134336U, 278265536U, 278395328U, 278526784U,
-        278657728U, 278789824U, 278921152U, 279052096U, 279182912U, 279313088U,
-        279443776U, 279576256U, 279706048U, 279838528U, 279969728U, 280099648U,
-        280230976U, 280361408U, 280493632U, 280622528U, 280755392U, 280887104U,
-        281018176U, 281147968U, 281278912U, 281411392U, 281542592U, 281673152U,
-        281803712U, 281935552U, 282066496U, 282197312U, 282329024U, 282458816U,
-        282590272U, 282720832U, 282853184U, 282983744U, 283115072U, 283246144U,
-        283377344U, 283508416U, 283639744U, 283770304U, 283901504U, 284032576U,
-        284163136U, 284294848U, 284426176U, 284556992U, 284687296U, 284819264U,
-        284950208U, 285081536U
+	16776896U, 16907456U, 17039296U, 17170112U, 17301056U, 17432512U, 17563072U,
+	17693888U, 17824192U, 17955904U, 18087488U, 18218176U, 18349504U, 18481088U,
+	18611392U, 18742336U, 18874304U, 19004224U, 19135936U, 19267264U, 19398208U,
+	19529408U, 19660096U, 19791424U, 19922752U, 20053952U, 20184896U, 20315968U,
+	20446912U, 20576576U, 20709184U, 20840384U, 20971072U, 21102272U, 21233216U,
+	21364544U, 21494848U, 21626816U, 21757376U, 21887552U, 22019392U, 22151104U,
+	22281536U, 22412224U, 22543936U, 22675264U, 22806464U, 22935872U, 23068096U,
+	23198272U, 23330752U, 23459008U, 23592512U, 23723968U, 23854912U, 23986112U,
+	24116672U, 24247616U, 24378688U, 24509504U, 24640832U, 24772544U, 24903488U,
+	25034432U, 25165376U, 25296704U, 25427392U, 25558592U, 25690048U, 25820096U,
+	25951936U, 26081728U, 26214208U, 26345024U, 26476096U, 26606656U, 26737472U,
+	26869184U, 26998208U, 27131584U, 27262528U, 27393728U, 27523904U, 27655744U,
+	27786688U, 27917888U, 28049344U, 28179904U, 28311488U, 28441792U, 28573504U,
+	28700864U, 28835648U, 28966208U, 29096768U, 29228608U, 29359808U, 29490752U,
+	29621824U, 29752256U, 29882816U, 30014912U, 30144448U, 30273728U, 30406976U,
+	30538432U, 30670784U, 30799936U, 30932672U, 31063744U, 31195072U, 31325248U,
+	31456192U, 31588288U, 31719232U, 31850432U, 31981504U, 32110784U, 32243392U,
+	32372672U, 32505664U, 32636608U, 32767808U, 32897344U, 33029824U, 33160768U,
+	33289664U, 33423296U, 33554368U, 33683648U, 33816512U, 33947456U, 34076992U,
+	34208704U, 34340032U, 34471744U, 34600256U, 34734016U, 34864576U, 34993984U,
+	35127104U, 35258176U, 35386688U, 35518528U, 35650624U, 35782336U, 35910976U,
+	36044608U, 36175808U, 36305728U, 36436672U, 36568384U, 36699968U, 36830656U,
+	36961984U, 37093312U, 37223488U, 37355072U, 37486528U, 37617472U, 37747904U,
+	37879232U, 38009792U, 38141888U, 38272448U, 38403392U, 38535104U, 38660672U,
+	38795584U, 38925632U, 39059264U, 39190336U, 39320768U, 39452096U, 39581632U,
+	39713984U, 39844928U, 39974848U, 40107968U, 40238144U, 40367168U, 40500032U,
+	40631744U, 40762816U, 40894144U, 41023552U, 41155904U, 41286208U, 41418304U,
+	41547712U, 41680448U, 41811904U, 41942848U, 42073792U, 42204992U, 42334912U,
+	42467008U, 42597824U, 42729152U, 42860096U, 42991552U, 43122368U, 43253696U,
+	43382848U, 43515712U, 43646912U, 43777088U, 43907648U, 44039104U, 44170432U,
+	44302144U, 44433344U, 44564288U, 44694976U, 44825152U, 44956864U, 45088448U,
+	45219008U, 45350464U, 45481024U, 45612608U, 45744064U, 45874496U, 46006208U,
+	46136768U, 46267712U, 46399424U, 46529344U, 46660672U, 46791488U, 46923328U,
+	47053504U, 47185856U, 47316928U, 47447872U, 47579072U, 47710144U, 47839936U,
+	47971648U, 48103232U, 48234176U, 48365248U, 48496192U, 48627136U, 48757312U,
+	48889664U, 49020736U, 49149248U, 49283008U, 49413824U, 49545152U, 49675712U,
+	49807168U, 49938368U, 50069056U, 50200256U, 50331584U, 50462656U, 50593472U,
+	50724032U, 50853952U, 50986048U, 51117632U, 51248576U, 51379904U, 51510848U,
+	51641792U, 51773248U, 51903296U, 52035136U, 52164032U, 52297664U, 52427968U,
+	52557376U, 52690112U, 52821952U, 52952896U, 53081536U, 53213504U, 53344576U,
+	53475776U, 53608384U, 53738816U, 53870528U, 54000832U, 54131776U, 54263744U,
+	54394688U, 54525248U, 54655936U, 54787904U, 54918592U, 55049152U, 55181248U,
+	55312064U, 55442752U, 55574336U, 55705024U, 55836224U, 55967168U, 56097856U,
+	56228672U, 56358592U, 56490176U, 56621888U, 56753728U, 56884928U, 57015488U,
+	57146816U, 57278272U, 57409216U, 57540416U, 57671104U, 57802432U, 57933632U,
+	58064576U, 58195264U, 58326976U, 58457408U, 58588864U, 58720192U, 58849984U,
+	58981696U, 59113024U, 59243456U, 59375552U, 59506624U, 59637568U, 59768512U,
+	59897792U, 60030016U, 60161984U, 60293056U, 60423872U, 60554432U, 60683968U,
+	60817216U, 60948032U, 61079488U, 61209664U, 61341376U, 61471936U, 61602752U,
+	61733696U, 61865792U, 61996736U, 62127808U, 62259136U, 62389568U, 62520512U,
+	62651584U, 62781632U, 62910784U, 63045056U, 63176128U, 63307072U, 63438656U,
+	63569216U, 63700928U, 63831616U, 63960896U, 64093888U, 64225088U, 64355392U,
+	64486976U, 64617664U, 64748608U, 64879424U, 65009216U, 65142464U, 65273792U,
+	65402816U, 65535424U, 65666752U, 65797696U, 65927744U, 66060224U, 66191296U,
+	66321344U, 66453056U, 66584384U, 66715328U, 66846656U, 66977728U, 67108672U,
+	67239104U, 67370432U, 67501888U, 67631296U, 67763776U, 67895104U, 68026304U,
+	68157248U, 68287936U, 68419264U, 68548288U, 68681408U, 68811968U, 68942912U,
+	69074624U, 69205568U, 69337024U, 69467584U, 69599168U, 69729472U, 69861184U,
+	69989824U, 70122944U, 70253888U, 70385344U, 70515904U, 70647232U, 70778816U,
+	70907968U, 71040832U, 71171648U, 71303104U, 71432512U, 71564992U, 71695168U,
+	71826368U, 71958464U, 72089536U, 72219712U, 72350144U, 72482624U, 72613568U,
+	72744512U, 72875584U, 73006144U, 73138112U, 73268672U, 73400128U, 73530944U,
+	73662272U, 73793344U, 73924544U, 74055104U, 74185792U, 74316992U, 74448832U,
+	74579392U, 74710976U, 74841664U, 74972864U, 75102784U, 75233344U, 75364544U,
+	75497024U, 75627584U, 75759296U, 75890624U, 76021696U, 76152256U, 76283072U,
+	76414144U, 76545856U, 76676672U, 76806976U, 76937792U, 77070016U, 77200832U,
+	77331392U, 77462464U, 77593664U, 77725376U, 77856448U, 77987776U, 78118336U,
+	78249664U, 78380992U, 78511424U, 78642496U, 78773056U, 78905152U, 79033664U,
+	79166656U, 79297472U, 79429568U, 79560512U, 79690816U, 79822784U, 79953472U,
+	80084672U, 80214208U, 80346944U, 80477632U, 80608576U, 80740288U, 80870848U,
+	81002048U, 81133504U, 81264448U, 81395648U, 81525952U, 81657536U, 81786304U,
+	81919808U, 82050112U, 82181312U, 82311616U, 82443968U, 82573376U, 82705984U,
+	82835776U, 82967744U, 83096768U, 83230528U, 83359552U, 83491264U, 83622464U,
+	83753536U, 83886016U, 84015296U, 84147776U, 84277184U, 84409792U, 84540608U,
+	84672064U, 84803008U, 84934336U, 85065152U, 85193792U, 85326784U, 85458496U,
+	85589312U, 85721024U, 85851968U, 85982656U, 86112448U, 86244416U, 86370112U,
+	86506688U, 86637632U, 86769344U, 86900672U, 87031744U, 87162304U, 87293632U,
+	87424576U, 87555392U, 87687104U, 87816896U, 87947968U, 88079168U, 88211264U,
+	88341824U, 88473152U, 88603712U, 88735424U, 88862912U, 88996672U, 89128384U,
+	89259712U, 89390272U, 89521984U, 89652544U, 89783872U, 89914816U, 90045376U,
+	90177088U, 90307904U, 90438848U, 90569152U, 90700096U, 90832832U, 90963776U,
+	91093696U, 91223744U, 91356992U, 91486784U, 91618496U, 91749824U, 91880384U,
+	92012224U, 92143552U, 92273344U, 92405696U, 92536768U, 92666432U, 92798912U,
+	92926016U, 93060544U, 93192128U, 93322816U, 93453632U, 93583936U, 93715136U,
+	93845056U, 93977792U, 94109504U, 94240448U, 94371776U, 94501184U, 94632896U,
+	94764224U, 94895552U, 95023424U, 95158208U, 95287744U, 95420224U, 95550016U,
+	95681216U, 95811904U, 95943872U, 96075328U, 96203584U, 96337856U, 96468544U,
+	96599744U, 96731072U, 96860992U, 96992576U, 97124288U, 97254848U, 97385536U,
+	97517248U, 97647808U, 97779392U, 97910464U, 98041408U, 98172608U, 98303168U,
+	98434496U, 98565568U, 98696768U, 98827328U, 98958784U, 99089728U, 99220928U,
+	99352384U, 99482816U, 99614272U, 99745472U, 99876416U, 100007104U,
+	100138048U, 100267072U, 100401088U, 100529984U, 100662592U, 100791872U,
+	100925248U, 101056064U, 101187392U, 101317952U, 101449408U, 101580608U,
+	101711296U, 101841728U, 101973824U, 102104896U, 102235712U, 102366016U,
+	102498112U, 102628672U, 102760384U, 102890432U, 103021888U, 103153472U,
+	103284032U, 103415744U, 103545152U, 103677248U, 103808576U, 103939648U,
+	104070976U, 104201792U, 104332736U, 104462528U, 104594752U, 104725952U,
+	104854592U, 104988608U, 105118912U, 105247808U, 105381184U, 105511232U,
+	105643072U, 105774784U, 105903296U, 106037056U, 106167872U, 106298944U,
+	106429504U, 106561472U, 106691392U, 106822592U, 106954304U, 107085376U,
+	107216576U, 107346368U, 107478464U, 107609792U, 107739712U, 107872192U,
+	108003136U, 108131392U, 108265408U, 108396224U, 108527168U, 108657344U,
+	108789568U, 108920384U, 109049792U, 109182272U, 109312576U, 109444928U,
+	109572928U, 109706944U, 109837888U, 109969088U, 110099648U, 110230976U,
+	110362432U, 110492992U, 110624704U, 110755264U, 110886208U, 111017408U,
+	111148864U, 111279296U, 111410752U, 111541952U, 111673024U, 111803456U,
+	111933632U, 112066496U, 112196416U, 112328512U, 112457792U, 112590784U,
+	112715968U, 112852672U, 112983616U, 113114944U, 113244224U, 113376448U,
+	113505472U, 113639104U, 113770304U, 113901376U, 114031552U, 114163264U,
+	114294592U, 114425536U, 114556864U, 114687424U, 114818624U, 114948544U,
+	115080512U, 115212224U, 115343296U, 115473472U, 115605184U, 115736128U,
+	115867072U, 115997248U, 116128576U, 116260288U, 116391488U, 116522944U,
+	116652992U, 116784704U, 116915648U, 117046208U, 117178304U, 117308608U,
+	117440192U, 117569728U, 117701824U, 117833024U, 117964096U, 118094656U,
+	118225984U, 118357312U, 118489024U, 118617536U, 118749632U, 118882112U,
+	119012416U, 119144384U, 119275328U, 119406016U, 119537344U, 119668672U,
+	119798464U, 119928896U, 120061376U, 120192832U, 120321728U, 120454336U,
+	120584512U, 120716608U, 120848192U, 120979136U, 121109056U, 121241408U,
+	121372352U, 121502912U, 121634752U, 121764416U, 121895744U, 122027072U,
+	122157632U, 122289088U, 122421184U, 122550592U, 122682944U, 122813888U,
+	122945344U, 123075776U, 123207488U, 123338048U, 123468736U, 123600704U,
+	123731264U, 123861952U, 123993664U, 124124608U, 124256192U, 124386368U,
+	124518208U, 124649024U, 124778048U, 124911296U, 125041088U, 125173696U,
+	125303744U, 125432896U, 125566912U, 125696576U, 125829056U, 125958592U,
+	126090304U, 126221248U, 126352832U, 126483776U, 126615232U, 126746432U,
+	126876608U, 127008704U, 127139392U, 127270336U, 127401152U, 127532224U,
+	127663552U, 127794752U, 127925696U, 128055232U, 128188096U, 128319424U,
+	128449856U, 128581312U, 128712256U, 128843584U, 128973632U, 129103808U,
+	129236288U, 129365696U, 129498944U, 129629888U, 129760832U, 129892288U,
+	130023104U, 130154048U, 130283968U, 130416448U, 130547008U, 130678336U,
+	130807616U, 130939456U, 131071552U, 131202112U, 131331776U, 131464384U,
+	131594048U, 131727296U, 131858368U, 131987392U, 132120256U, 132250816U,
+	132382528U, 132513728U, 132644672U, 132774976U, 132905792U, 133038016U,
+	133168832U, 133299392U, 133429312U, 133562048U, 133692992U, 133823296U,
+	133954624U, 134086336U, 134217152U, 134348608U, 134479808U, 134607296U,
+	134741056U, 134872384U, 135002944U, 135134144U, 135265472U, 135396544U,
+	135527872U, 135659072U, 135787712U, 135921472U, 136052416U, 136182848U,
+	136313792U, 136444864U, 136576448U, 136707904U, 136837952U, 136970048U,
+	137099584U, 137232064U, 137363392U, 137494208U, 137625536U, 137755712U,
+	137887424U, 138018368U, 138149824U, 138280256U, 138411584U, 138539584U,
+	138672832U, 138804928U, 138936128U, 139066688U, 139196864U, 139328704U,
+	139460032U, 139590208U, 139721024U, 139852864U, 139984576U, 140115776U,
+	140245696U, 140376512U, 140508352U, 140640064U, 140769856U, 140902336U,
+	141032768U, 141162688U, 141294016U, 141426496U, 141556544U, 141687488U,
+	141819584U, 141949888U, 142080448U, 142212544U, 142342336U, 142474432U,
+	142606144U, 142736192U, 142868288U, 142997824U, 143129408U, 143258944U,
+	143392448U, 143523136U, 143653696U, 143785024U, 143916992U, 144045632U,
+	144177856U, 144309184U, 144440768U, 144570688U, 144701888U, 144832448U,
+	144965056U, 145096384U, 145227584U, 145358656U, 145489856U, 145620928U,
+	145751488U, 145883072U, 146011456U, 146144704U, 146275264U, 146407232U,
+	146538176U, 146668736U, 146800448U, 146931392U, 147062336U, 147193664U,
+	147324224U, 147455936U, 147586624U, 147717056U, 147848768U, 147979456U,
+	148110784U, 148242368U, 148373312U, 148503232U, 148635584U, 148766144U,
+	148897088U, 149028416U, 149159488U, 149290688U, 149420224U, 149551552U,
+	149683136U, 149814976U, 149943616U, 150076352U, 150208064U, 150338624U,
+	150470464U, 150600256U, 150732224U, 150862784U, 150993088U, 151125952U,
+	151254976U, 151388096U, 151519168U, 151649728U, 151778752U, 151911104U,
+	152042944U, 152174144U, 152304704U, 152435648U, 152567488U, 152698816U,
+	152828992U, 152960576U, 153091648U, 153222976U, 153353792U, 153484096U,
+	153616192U, 153747008U, 153878336U, 154008256U, 154139968U, 154270912U,
+	154402624U, 154533824U, 154663616U, 154795712U, 154926272U, 155057984U,
+	155188928U, 155319872U, 155450816U, 155580608U, 155712064U, 155843392U,
+	155971136U, 156106688U, 156237376U, 156367424U, 156499264U, 156630976U,
+	156761536U, 156892352U, 157024064U, 157155008U, 157284416U, 157415872U,
+	157545536U, 157677248U, 157810496U, 157938112U, 158071744U, 158203328U,
+	158334656U, 158464832U, 158596288U, 158727616U, 158858048U, 158988992U,
+	159121216U, 159252416U, 159381568U, 159513152U, 159645632U, 159776192U,
+	159906496U, 160038464U, 160169536U, 160300352U, 160430656U, 160563008U,
+	160693952U, 160822208U, 160956352U, 161086784U, 161217344U, 161349184U,
+	161480512U, 161611456U, 161742272U, 161873216U, 162002752U, 162135872U,
+	162266432U, 162397888U, 162529216U, 162660032U, 162790976U, 162922048U,
+	163052096U, 163184576U, 163314752U, 163446592U, 163577408U, 163707968U,
+	163839296U, 163969984U, 164100928U, 164233024U, 164364224U, 164494912U,
+	164625856U, 164756672U, 164887616U, 165019072U, 165150016U, 165280064U,
+	165412672U, 165543104U, 165674944U, 165805888U, 165936832U, 166067648U,
+	166198336U, 166330048U, 166461248U, 166591552U, 166722496U, 166854208U,
+	166985408U, 167116736U, 167246656U, 167378368U, 167508416U, 167641024U,
+	167771584U, 167903168U, 168034112U, 168164032U, 168295744U, 168427456U,
+	168557632U, 168688448U, 168819136U, 168951616U, 169082176U, 169213504U,
+	169344832U, 169475648U, 169605952U, 169738048U, 169866304U, 169999552U,
+	170131264U, 170262464U, 170393536U, 170524352U, 170655424U, 170782016U,
+	170917696U, 171048896U, 171179072U, 171310784U, 171439936U, 171573184U,
+	171702976U, 171835072U, 171966272U, 172097216U, 172228288U, 172359232U,
+	172489664U, 172621376U, 172747712U, 172883264U, 173014208U, 173144512U,
+	173275072U, 173407424U, 173539136U, 173669696U, 173800768U, 173931712U,
+	174063424U, 174193472U, 174325696U, 174455744U, 174586816U, 174718912U,
+	174849728U, 174977728U, 175109696U, 175242688U, 175374272U, 175504832U,
+	175636288U, 175765696U, 175898432U, 176028992U, 176159936U, 176291264U,
+	176422592U, 176552512U, 176684864U, 176815424U, 176946496U, 177076544U,
+	177209152U, 177340096U, 177470528U, 177600704U, 177731648U, 177864256U,
+	177994816U, 178126528U, 178257472U, 178387648U, 178518464U, 178650176U,
+	178781888U, 178912064U, 179044288U, 179174848U, 179305024U, 179436736U,
+	179568448U, 179698496U, 179830208U, 179960512U, 180092608U, 180223808U,
+	180354752U, 180485696U, 180617152U, 180748096U, 180877504U, 181009984U,
+	181139264U, 181272512U, 181402688U, 181532608U, 181663168U, 181795136U,
+	181926592U, 182057536U, 182190016U, 182320192U, 182451904U, 182582336U,
+	182713792U, 182843072U, 182976064U, 183107264U, 183237056U, 183368384U,
+	183494848U, 183631424U, 183762752U, 183893824U, 184024768U, 184154816U,
+	184286656U, 184417984U, 184548928U, 184680128U, 184810816U, 184941248U,
+	185072704U, 185203904U, 185335616U, 185465408U, 185596352U, 185727296U,
+	185859904U, 185989696U, 186121664U, 186252992U, 186383552U, 186514112U,
+	186645952U, 186777152U, 186907328U, 187037504U, 187170112U, 187301824U,
+	187429184U, 187562048U, 187693504U, 187825472U, 187957184U, 188087104U,
+	188218304U, 188349376U, 188481344U, 188609728U, 188743616U, 188874304U,
+	189005248U, 189136448U, 189265088U, 189396544U, 189528128U, 189660992U,
+	189791936U, 189923264U, 190054208U, 190182848U, 190315072U, 190447424U,
+	190577984U, 190709312U, 190840768U, 190971328U, 191102656U, 191233472U,
+	191364032U, 191495872U, 191626816U, 191758016U, 191888192U, 192020288U,
+	192148928U, 192282176U, 192413504U, 192542528U, 192674752U, 192805952U,
+	192937792U, 193068608U, 193198912U, 193330496U, 193462208U, 193592384U,
+	193723456U, 193854272U, 193985984U, 194116672U, 194247232U, 194379712U,
+	194508352U, 194641856U, 194772544U, 194900672U, 195035072U, 195166016U,
+	195296704U, 195428032U, 195558592U, 195690304U, 195818176U, 195952576U,
+	196083392U, 196214336U, 196345792U, 196476736U, 196607552U, 196739008U,
+	196869952U, 197000768U, 197130688U, 197262784U, 197394368U, 197523904U,
+	197656384U, 197787584U, 197916608U, 198049472U, 198180544U, 198310208U,
+	198442432U, 198573632U, 198705088U, 198834368U, 198967232U, 199097792U,
+	199228352U, 199360192U, 199491392U, 199621696U, 199751744U, 199883968U,
+	200014016U, 200146624U, 200276672U, 200408128U, 200540096U, 200671168U,
+	200801984U, 200933312U, 201062464U, 201194944U, 201326144U, 201457472U,
+	201588544U, 201719744U, 201850816U, 201981632U, 202111552U, 202244032U,
+	202374464U, 202505152U, 202636352U, 202767808U, 202898368U, 203030336U,
+	203159872U, 203292608U, 203423296U, 203553472U, 203685824U, 203816896U,
+	203947712U, 204078272U, 204208192U, 204341056U, 204472256U, 204603328U,
+	204733888U, 204864448U, 204996544U, 205125568U, 205258304U, 205388864U,
+	205517632U, 205650112U, 205782208U, 205913536U, 206044736U, 206176192U,
+	206307008U, 206434496U, 206569024U, 206700224U, 206831168U, 206961856U,
+	207093056U, 207223616U, 207355328U, 207486784U, 207616832U, 207749056U,
+	207879104U, 208010048U, 208141888U, 208273216U, 208404032U, 208534336U,
+	208666048U, 208796864U, 208927424U, 209059264U, 209189824U, 209321792U,
+	209451584U, 209582656U, 209715136U, 209845568U, 209976896U, 210106432U,
+	210239296U, 210370112U, 210501568U, 210630976U, 210763712U, 210894272U,
+	211024832U, 211156672U, 211287616U, 211418176U, 211549376U, 211679296U,
+	211812032U, 211942592U, 212074432U, 212204864U, 212334016U, 212467648U,
+	212597824U, 212727616U, 212860352U, 212991424U, 213120832U, 213253952U,
+	213385024U, 213515584U, 213645632U, 213777728U, 213909184U, 214040128U,
+	214170688U, 214302656U, 214433728U, 214564544U, 214695232U, 214826048U,
+	214956992U, 215089088U, 215219776U, 215350592U, 215482304U, 215613248U,
+	215743552U, 215874752U, 216005312U, 216137024U, 216267328U, 216399296U,
+	216530752U, 216661696U, 216790592U, 216923968U, 217054528U, 217183168U,
+	217316672U, 217448128U, 217579072U, 217709504U, 217838912U, 217972672U,
+	218102848U, 218233024U, 218364736U, 218496832U, 218627776U, 218759104U,
+	218888896U, 219021248U, 219151936U, 219281728U, 219413056U, 219545024U,
+	219675968U, 219807296U, 219938624U, 220069312U, 220200128U, 220331456U,
+	220461632U, 220592704U, 220725184U, 220855744U, 220987072U, 221117888U,
+	221249216U, 221378368U, 221510336U, 221642048U, 221772736U, 221904832U,
+	222031808U, 222166976U, 222297536U, 222428992U, 222559936U, 222690368U,
+	222820672U, 222953152U, 223083968U, 223213376U, 223345984U, 223476928U,
+	223608512U, 223738688U, 223869376U, 224001472U, 224132672U, 224262848U,
+	224394944U, 224524864U, 224657344U, 224788288U, 224919488U, 225050432U,
+	225181504U, 225312704U, 225443776U, 225574592U, 225704768U, 225834176U,
+	225966784U, 226097216U, 226229824U, 226360384U, 226491712U, 226623424U,
+	226754368U, 226885312U, 227015104U, 227147456U, 227278528U, 227409472U,
+	227539904U, 227669696U, 227802944U, 227932352U, 228065216U, 228196288U,
+	228326464U, 228457792U, 228588736U, 228720064U, 228850112U, 228981056U,
+	229113152U, 229243328U, 229375936U, 229505344U, 229636928U, 229769152U,
+	229894976U, 230030272U, 230162368U, 230292416U, 230424512U, 230553152U,
+	230684864U, 230816704U, 230948416U, 231079616U, 231210944U, 231342016U,
+	231472448U, 231603776U, 231733952U, 231866176U, 231996736U, 232127296U,
+	232259392U, 232388672U, 232521664U, 232652608U, 232782272U, 232914496U,
+	233043904U, 233175616U, 233306816U, 233438528U, 233569984U, 233699776U,
+	233830592U, 233962688U, 234092224U, 234221888U, 234353984U, 234485312U,
+	234618304U, 234749888U, 234880832U, 235011776U, 235142464U, 235274048U,
+	235403456U, 235535936U, 235667392U, 235797568U, 235928768U, 236057152U,
+	236190272U, 236322752U, 236453312U, 236583616U, 236715712U, 236846528U,
+	236976448U, 237108544U, 237239104U, 237371072U, 237501632U, 237630784U,
+	237764416U, 237895232U, 238026688U, 238157632U, 238286912U, 238419392U,
+	238548032U, 238681024U, 238812608U, 238941632U, 239075008U, 239206336U,
+	239335232U, 239466944U, 239599168U, 239730496U, 239861312U, 239992384U,
+	240122816U, 240254656U, 240385856U, 240516928U, 240647872U, 240779072U,
+	240909632U, 241040704U, 241171904U, 241302848U, 241433408U, 241565248U,
+	241696192U, 241825984U, 241958848U, 242088256U, 242220224U, 242352064U,
+	242481856U, 242611648U, 242744896U, 242876224U, 243005632U, 243138496U,
+	243268672U, 243400384U, 243531712U, 243662656U, 243793856U, 243924544U,
+	244054592U, 244187072U, 244316608U, 244448704U, 244580032U, 244710976U,
+	244841536U, 244972864U, 245104448U, 245233984U, 245365312U, 245497792U,
+	245628736U, 245759936U, 245889856U, 246021056U, 246152512U, 246284224U,
+	246415168U, 246545344U, 246675904U, 246808384U, 246939584U, 247070144U,
+	247199552U, 247331648U, 247463872U, 247593536U, 247726016U, 247857088U,
+	247987648U, 248116928U, 248249536U, 248380736U, 248512064U, 248643008U,
+	248773312U, 248901056U, 249036608U, 249167552U, 249298624U, 249429184U,
+	249560512U, 249692096U, 249822784U, 249954112U, 250085312U, 250215488U,
+	250345792U, 250478528U, 250608704U, 250739264U, 250870976U, 251002816U,
+	251133632U, 251263552U, 251395136U, 251523904U, 251657792U, 251789248U,
+	251919424U, 252051392U, 252182464U, 252313408U, 252444224U, 252575552U,
+	252706624U, 252836032U, 252968512U, 253099712U, 253227584U, 253361728U,
+	253493056U, 253623488U, 253754432U, 253885504U, 254017216U, 254148032U,
+	254279488U, 254410432U, 254541376U, 254672576U, 254803264U, 254933824U,
+	255065792U, 255196736U, 255326528U, 255458752U, 255589952U, 255721408U,
+	255851072U, 255983296U, 256114624U, 256244416U, 256374208U, 256507712U,
+	256636096U, 256768832U, 256900544U, 257031616U, 257162176U, 257294272U,
+	257424448U, 257555776U, 257686976U, 257818432U, 257949632U, 258079552U,
+	258211136U, 258342464U, 258473408U, 258603712U, 258734656U, 258867008U,
+	258996544U, 259127744U, 259260224U, 259391296U, 259522112U, 259651904U,
+	259784384U, 259915328U, 260045888U, 260175424U, 260308544U, 260438336U,
+	260570944U, 260700992U, 260832448U, 260963776U, 261092672U, 261226304U,
+	261356864U, 261487936U, 261619648U, 261750592U, 261879872U, 262011968U,
+	262143424U, 262274752U, 262404416U, 262537024U, 262667968U, 262799296U,
+	262928704U, 263061184U, 263191744U, 263322944U, 263454656U, 263585216U,
+	263716672U, 263847872U, 263978944U, 264108608U, 264241088U, 264371648U,
+	264501184U, 264632768U, 264764096U, 264895936U, 265024576U, 265158464U,
+	265287488U, 265418432U, 265550528U, 265681216U, 265813312U, 265943488U,
+	266075968U, 266206144U, 266337728U, 266468032U, 266600384U, 266731072U,
+	266862272U, 266993344U, 267124288U, 267255616U, 267386432U, 267516992U,
+	267648704U, 267777728U, 267910592U, 268040512U, 268172096U, 268302784U,
+	268435264U, 268566208U, 268696256U, 268828096U, 268959296U, 269090368U,
+	269221312U, 269352256U, 269482688U, 269614784U, 269745856U, 269876416U,
+	270007616U, 270139328U, 270270272U, 270401216U, 270531904U, 270663616U,
+	270791744U, 270924736U, 271056832U, 271186112U, 271317184U, 271449536U,
+	271580992U, 271711936U, 271843136U, 271973056U, 272105408U, 272236352U,
+	272367296U, 272498368U, 272629568U, 272759488U, 272891456U, 273022784U,
+	273153856U, 273284672U, 273415616U, 273547072U, 273677632U, 273808448U,
+	273937088U, 274071488U, 274200896U, 274332992U, 274463296U, 274595392U,
+	274726208U, 274857536U, 274988992U, 275118656U, 275250496U, 275382208U,
+	275513024U, 275643968U, 275775296U, 275906368U, 276037184U, 276167872U,
+	276297664U, 276429376U, 276560576U, 276692672U, 276822976U, 276955072U,
+	277085632U, 277216832U, 277347008U, 277478848U, 277609664U, 277740992U,
+	277868608U, 278002624U, 278134336U, 278265536U, 278395328U, 278526784U,
+	278657728U, 278789824U, 278921152U, 279052096U, 279182912U, 279313088U,
+	279443776U, 279576256U, 279706048U, 279838528U, 279969728U, 280099648U,
+	280230976U, 280361408U, 280493632U, 280622528U, 280755392U, 280887104U,
+	281018176U, 281147968U, 281278912U, 281411392U, 281542592U, 281673152U,
+	281803712U, 281935552U, 282066496U, 282197312U, 282329024U, 282458816U,
+	282590272U, 282720832U, 282853184U, 282983744U, 283115072U, 283246144U,
+	283377344U, 283508416U, 283639744U, 283770304U, 283901504U, 284032576U,
+	284163136U, 284294848U, 284426176U, 284556992U, 284687296U, 284819264U,
+	284950208U, 285081536U
 };
 
 #ifdef __cplusplus
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h
index 9ca842e47..0ee402d9a 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/endian.h
@@ -3,38 +3,6 @@
 #include <stdint.h>
 #include "compiler.h"
 
-static const uint8_t BitReverseTable256[] =
-        {
-                0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
-                0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
-                0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
-                0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
-                0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
-                0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
-                0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
-                0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
-                0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
-                0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
-                0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
-                0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
-                0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
-                0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
-                0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
-                0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
-        };
-
-static inline uint32_t bitfn_swap32(uint32_t a) {
-    return (BitReverseTable256[a & 0xff] << 24) |
-            (BitReverseTable256[(a >> 8) & 0xff] << 16) |
-            (BitReverseTable256[(a >> 16) & 0xff] << 8) |
-            (BitReverseTable256[(a >> 24) & 0xff]);
-}
-
-static inline uint64_t bitfn_swap64(uint64_t a) {
-    return ((uint64_t) bitfn_swap32((uint32_t) (a >> 32))) |
-            (((uint64_t) bitfn_swap32((uint32_t) a)) << 32);
-}
-
 #if defined(__MINGW32__) || defined(_WIN32)
   # define LITTLE_ENDIAN 1234
   # define BYTE_ORDER    LITTLE_ENDIAN
@@ -53,22 +21,52 @@ static inline uint64_t bitfn_swap64(uint64_t a) {
   # define BIG_ENDIAN 1234
   # define BYTE_ORDER    BIG_ENDIAN
 #else
-
 # include <endian.h>
+#endif
 
+#if defined(_WIN32)
+#include <stdlib.h>
+#define ethash_swap_u32(input_) _byteswap_ulong(input_)
+#define ethash_swap_u64(input_) _byteswap_uint64(input_)
+#elif defined(__APPLE__)
+#include <libkern/OSByteOrder.h>
+#define ethash_swap_u32(input_) OSSwapInt32(input_)
+#define ethash_swap_u64(input_) OSSwapInt64(input_)
+#else // posix
+#include <byteswap.h>
+#define ethash_swap_u32(input_) __bswap_32(input_)
+#define ethash_swap_u64(input_) __bswap_64(input_)
 #endif
 
 
 #if LITTLE_ENDIAN == BYTE_ORDER
 
-#define fix_endian32(x) (x)
-#define fix_endian64(x) (x)
+#define fix_endian32(dst_ ,src_) dst_ = src_
+#define fix_endian32_same(val_)
+#define fix_endian64(dst_, src_) dst_ = src_
+#define fix_endian64_same(val_)
+#define fix_endian_arr32(arr_, size_)
+#define fix_endian_arr64(arr_, size_)
 
 #elif BIG_ENDIAN == BYTE_ORDER
 
-#define fix_endian32(x) bitfn_swap32(x)
-#define fix_endian64(x) bitfn_swap64(x)
+#define fix_endian32(dst_, src_) dst_ = ethash_swap_u32(src_)
+#define fix_endian32_same(val_) val_ = ethash_swap_u32(val_)
+#define fix_endian64(dst_, src_) dst_ = ethash_swap_u64(src_
+#define fix_endian64_same(val_) val_ = ethash_swap_u64(val_)
+#define fix_endian_arr32(arr_, size_)			\
+	do {										\
+	for (unsigned i_ = 0; i_ < (size_), ++i_) { \
+		arr_[i_] = ethash_swap_u32(arr_[i_]);	\
+	}											\
+	while (0)
+#define fix_endian_arr64(arr_, size_)			\
+	do {										\
+	for (unsigned i_ = 0; i_ < (size_), ++i_) { \
+		arr_[i_] = ethash_swap_u64(arr_[i_]);	\
+	}											\
+	while (0)									\
 
 #else
 # error "endian not supported"
-#endif // BYTE_ORDER
\ No newline at end of file
+#endif // BYTE_ORDER
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/ethash.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/ethash.h
index fad964449..0c6a1f9e9 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/ethash.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/ethash.h
@@ -26,124 +26,121 @@
 #include <stddef.h>
 #include "compiler.h"
 
-#define REVISION 23
-#define DATASET_BYTES_INIT 1073741824U // 2**30
-#define DATASET_BYTES_GROWTH 8388608U  // 2**23
-#define CACHE_BYTES_INIT 1073741824U // 2**24
-#define CACHE_BYTES_GROWTH 131072U  // 2**17
-#define EPOCH_LENGTH 30000U
-#define MIX_BYTES 128
-#define HASH_BYTES 64
-#define DATASET_PARENTS 256
-#define CACHE_ROUNDS 3
-#define ACCESSES 64
+#define ETHASH_REVISION 23
+#define ETHASH_DATASET_BYTES_INIT 1073741824U // 2**30
+#define ETHASH_DATASET_BYTES_GROWTH 8388608U  // 2**23
+#define ETHASH_CACHE_BYTES_INIT 1073741824U // 2**24
+#define ETHASH_CACHE_BYTES_GROWTH 131072U  // 2**17
+#define ETHASH_EPOCH_LENGTH 30000U
+#define ETHASH_MIX_BYTES 128
+#define ETHASH_HASH_BYTES 64
+#define ETHASH_DATASET_PARENTS 256
+#define ETHASH_CACHE_ROUNDS 3
+#define ETHASH_ACCESSES 64
+#define ETHASH_DAG_MAGIC_NUM_SIZE 8
+#define ETHASH_DAG_MAGIC_NUM 0xFEE1DEADBADDCAFE
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef struct ethash_params {
-	uint64_t full_size;               // Size of full data set (in bytes, multiple of mix size (128)).
-	uint64_t cache_size;              // Size of compute cache (in bytes, multiple of node size (64)).
-} ethash_params;
+/// Type of a seedhash/blockhash e.t.c.
+typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t;
 
-/// Type of a blockhash
-typedef struct ethash_blockhash { uint8_t b[32]; } ethash_blockhash_t;
-static inline uint8_t ethash_blockhash_get(ethash_blockhash_t const* hash, unsigned int i)
-{
-    return hash->b[i];
-}
+// convenience macro to statically initialize an h256_t
+// usage:
+// ethash_h256_t a = ethash_h256_static_init(1, 2, 3, ... )
+// have to provide all 32 values. If you don't provide all the rest
+// will simply be unitialized (not guranteed to be 0)
+#define ethash_h256_static_init(...)			\
+	{ {__VA_ARGS__} }
 
-static inline void ethash_blockhash_set(ethash_blockhash_t *hash, unsigned int i, uint8_t v)
-{
-    hash->b[i] = v;
-}
-
-static inline void ethash_blockhash_reset(ethash_blockhash_t *hash)
-{
-    memset(hash, 0, 32);
-}
+struct ethash_light;
+typedef struct ethash_light* ethash_light_t;
+struct ethash_full;
+typedef struct ethash_full* ethash_full_t;
+typedef int(*ethash_callback_t)(unsigned);
 
 typedef struct ethash_return_value {
-    ethash_blockhash_t result;
-    ethash_blockhash_t mix_hash;
-} ethash_return_value;
-
-uint64_t ethash_get_datasize(const uint32_t block_number);
-uint64_t ethash_get_cachesize(const uint32_t block_number);
-
-// initialize the parameters
-static inline void ethash_params_init(ethash_params *params, const uint32_t block_number) {
-	params->full_size = ethash_get_datasize(block_number);
-	params->cache_size = ethash_get_cachesize(block_number);
-}
-
-typedef struct ethash_cache {
-	void *mem;
-} ethash_cache;
-
-void ethash_mkcache(ethash_cache *cache, ethash_params const *params, ethash_blockhash_t const *seed);
-void ethash_compute_full_data(void *mem, ethash_params const *params, ethash_cache const *cache);
-void ethash_full(ethash_return_value *ret,
-                 void const *full_mem,
-                 ethash_params const *params,
-                 ethash_blockhash_t const *header_hash,
-                 const uint64_t nonce);
-void ethash_light(ethash_return_value *ret,
-                  ethash_cache const *cache,
-                  ethash_params const *params,
-                  ethash_blockhash_t const *header_hash,
-                  const uint64_t nonce);
-void ethash_get_seedhash(ethash_blockhash_t *seedhash, const uint32_t block_number);
-
-static inline void ethash_prep_light(void *cache, ethash_params const *params, ethash_blockhash_t const* seed)
-{
-    ethash_cache c;
-    c.mem = cache;
-    ethash_mkcache(&c, params, seed);
-}
-
-static inline void ethash_compute_light(ethash_return_value *ret, void const *cache, ethash_params const *params, ethash_blockhash_t const *header_hash, const uint64_t nonce)
-{
-    ethash_cache c;
-    c.mem = (void *) cache;
-    ethash_light(ret, &c, params, header_hash, nonce);
-}
-
-static inline void ethash_prep_full(void *full, ethash_params const *params, void const *cache)
-{
-    ethash_cache c;
-    c.mem = (void *) cache;
-    ethash_compute_full_data(full, params, &c);
-}
-
-static inline void ethash_compute_full(ethash_return_value *ret,
-                                       void const *full,
-                                       ethash_params const *params,
-                                       ethash_blockhash_t const *header_hash,
-                                       const uint64_t nonce)
-{
-    ethash_full(ret, full, params, header_hash, nonce);
-}
-
-// Returns if hash is less than or equal to difficulty
-static inline int ethash_check_difficulty(ethash_blockhash_t const *hash,
-                                          ethash_blockhash_t const *difficulty)
-{
-    // Difficulty is big endian
-    for (int i = 0; i < 32; i++) {
-        if (ethash_blockhash_get(hash, i) == ethash_blockhash_get(difficulty, i)) {
-            continue;
-        }
-        return ethash_blockhash_get(hash, i) < ethash_blockhash_get(difficulty, i);
-    }
-    return 1;
-}
-
-int ethash_quick_check_difficulty(ethash_blockhash_t const *header_hash,
-                                  const uint64_t nonce,
-                                  ethash_blockhash_t const *mix_hash,
-                                  ethash_blockhash_t const *difficulty);
+	ethash_h256_t result;
+	ethash_h256_t mix_hash;
+	bool success;
+} ethash_return_value_t;
+
+/**
+ * Allocate and initialize a new ethash_light handler
+ *
+ * @param block_number   The block number for which to create the handler
+ * @return               Newly allocated ethash_light handler or NULL in case of
+ *                       ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
+ */
+ethash_light_t ethash_light_new(uint64_t block_number);
+/**
+ * Frees a previously allocated ethash_light handler
+ * @param light        The light handler to free
+ */
+void ethash_light_delete(ethash_light_t light);
+/**
+ * Calculate the light client data
+ *
+ * @param light          The light client handler
+ * @param header_hash    The header hash to pack into the mix
+ * @param nonce          The nonce to pack into the mix
+ * @return               an object of ethash_return_value_t holding the return values
+ */
+ethash_return_value_t ethash_light_compute(
+	ethash_light_t light,
+	ethash_h256_t const header_hash,
+	uint64_t nonce
+);
+
+/**
+ * Allocate and initialize a new ethash_full handler
+ *
+ * @param light         The light handler containing the cache.
+ * @param callback      A callback function with signature of @ref ethash_callback_t
+ *                      It accepts an unsigned with which a progress of DAG calculation
+ *                      can be displayed. If all goes well the callback should return 0.
+ *                      If a non-zero value is returned then DAG generation will stop.
+ *                      Be advised. A progress value of 100 means that DAG creation is
+ *                      almost complete and that this function will soon return succesfully.
+ *                      It does not mean that the function has already had a succesfull return.
+ * @return              Newly allocated ethash_full handler or NULL in case of
+ *                      ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
+ */
+ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback);
+
+/**
+ * Frees a previously allocated ethash_full handler
+ * @param full    The light handler to free
+ */
+void ethash_full_delete(ethash_full_t full);
+/**
+ * Calculate the full client data
+ *
+ * @param full           The full client handler
+ * @param header_hash    The header hash to pack into the mix
+ * @param nonce          The nonce to pack into the mix
+ * @return               An object of ethash_return_value to hold the return value
+ */
+ethash_return_value_t ethash_full_compute(
+	ethash_full_t full,
+	ethash_h256_t const header_hash,
+	uint64_t nonce
+);
+/**
+ * Get a pointer to the full DAG data
+ */
+void const* ethash_full_dag(ethash_full_t full);
+/**
+ * Get the size of the DAG data
+ */
+uint64_t ethash_full_dag_size(ethash_full_t full);
+
+/**
+ * Calculate the seedhash for a given block number
+ */
+ethash_h256_t ethash_get_seedhash(uint64_t block_number);
 
 #ifdef __cplusplus
 }
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/fnv.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/fnv.h
index edabeaae2..d23c4e247 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/fnv.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/fnv.h
@@ -29,10 +29,11 @@ extern "C" {
 
 #define FNV_PRIME 0x01000193
 
-static inline uint32_t fnv_hash(const uint32_t x, const uint32_t y) {
-	return x*FNV_PRIME ^ y;
+static inline uint32_t fnv_hash(uint32_t const x, uint32_t const y)
+{
+	return x * FNV_PRIME ^ y;
 }
 
 #ifdef __cplusplus
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c
index 5009d52f5..607e44138 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c
@@ -8,11 +8,11 @@
 
   ethash is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
-  along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+  along with cpp-ethereum.	If not, see <http://www.gnu.org/licenses/>.
 */
 /** @file internal.c
 * @author Tim Hughes <tim@twistedfury.com>
@@ -23,11 +23,15 @@
 #include <assert.h>
 #include <inttypes.h>
 #include <stddef.h>
+#include <errno.h>
+#include <math.h>
+#include "mmap.h"
 #include "ethash.h"
 #include "fnv.h"
 #include "endian.h"
 #include "internal.h"
 #include "data_sizes.h"
+#include "io.h"
 
 #ifdef WITH_CRYPTOPP
 
@@ -37,274 +41,456 @@
 #include "sha3.h"
 #endif // WITH_CRYPTOPP
 
-uint64_t ethash_get_datasize(const uint32_t block_number) {
-    assert(block_number / EPOCH_LENGTH < 2048);
-    return dag_sizes[block_number / EPOCH_LENGTH];
+uint64_t ethash_get_datasize(uint64_t const block_number)
+{
+	assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
+	return dag_sizes[block_number / ETHASH_EPOCH_LENGTH];
 }
 
-uint64_t ethash_get_cachesize(const uint32_t block_number) {
-    assert(block_number / EPOCH_LENGTH < 2048);
-    return cache_sizes[block_number / EPOCH_LENGTH];
+uint64_t ethash_get_cachesize(uint64_t const block_number)
+{
+	assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
+	return cache_sizes[block_number / ETHASH_EPOCH_LENGTH];
 }
 
 // Follows Sergio's "STRICT MEMORY HARD HASHING FUNCTIONS" (2014)
 // https://bitslog.files.wordpress.com/2013/12/memohash-v0-3.pdf
 // SeqMemoHash(s, R, N)
-void static ethash_compute_cache_nodes(node *const nodes,
-                                       ethash_params const *params,
-                                       ethash_blockhash_t const* seed)
-{
-    assert((params->cache_size % sizeof(node)) == 0);
-    uint32_t const num_nodes = (uint32_t) (params->cache_size / sizeof(node));
-
-    SHA3_512(nodes[0].bytes, (uint8_t*)seed, 32);
-
-    for (unsigned i = 1; i != num_nodes; ++i) {
-        SHA3_512(nodes[i].bytes, nodes[i - 1].bytes, 64);
-    }
-
-    for (unsigned j = 0; j != CACHE_ROUNDS; j++) {
-        for (unsigned i = 0; i != num_nodes; i++) {
-            uint32_t const idx = nodes[i].words[0] % num_nodes;
-            node data;
-            data = nodes[(num_nodes - 1 + i) % num_nodes];
-            for (unsigned w = 0; w != NODE_WORDS; ++w) {
-                data.words[w] ^= nodes[idx].words[w];
-            }
-            SHA3_512(nodes[i].bytes, data.bytes, sizeof(data));
-        }
-    }
-
-    // now perform endian conversion
-#if BYTE_ORDER != LITTLE_ENDIAN
-    for (unsigned w = 0; w != (num_nodes*NODE_WORDS); ++w)
-    {
-        nodes->words[w] = fix_endian32(nodes->words[w]);
-    }
-#endif
-}
-
-void ethash_mkcache(ethash_cache *cache,
-                    ethash_params const *params,
-                    ethash_blockhash_t const* seed)
+bool static ethash_compute_cache_nodes(
+	node* const nodes,
+	uint64_t cache_size,
+	ethash_h256_t const* seed
+)
 {
-    node *nodes = (node *) cache->mem;
-    ethash_compute_cache_nodes(nodes, params, seed);
+	if (cache_size % sizeof(node) != 0) {
+		return false;
+	}
+	uint32_t const num_nodes = (uint32_t) (cache_size / sizeof(node));
+
+	SHA3_512(nodes[0].bytes, (uint8_t*)seed, 32);
+
+	for (uint32_t i = 1; i != num_nodes; ++i) {
+		SHA3_512(nodes[i].bytes, nodes[i - 1].bytes, 64);
+	}
+
+	for (uint32_t j = 0; j != ETHASH_CACHE_ROUNDS; j++) {
+		for (uint32_t i = 0; i != num_nodes; i++) {
+			uint32_t const idx = nodes[i].words[0] % num_nodes;
+			node data;
+			data = nodes[(num_nodes - 1 + i) % num_nodes];
+			for (uint32_t w = 0; w != NODE_WORDS; ++w) {
+				data.words[w] ^= nodes[idx].words[w];
+			}
+			SHA3_512(nodes[i].bytes, data.bytes, sizeof(data));
+		}
+	}
+
+	// now perform endian conversion
+	fix_endian_arr32(nodes->words, num_nodes * NODE_WORDS);
+	return true;
 }
 
-void ethash_calculate_dag_item(node *const ret,
-                               const unsigned node_index,
-                               const struct ethash_params *params,
-                               const struct ethash_cache *cache)
+void ethash_calculate_dag_item(
+	node* const ret,
+	uint32_t node_index,
+	ethash_light_t const light
+)
 {
-    uint32_t num_parent_nodes = (uint32_t) (params->cache_size / sizeof(node));
-    node const *cache_nodes = (node const *) cache->mem;
-    node const *init = &cache_nodes[node_index % num_parent_nodes];
-
-    memcpy(ret, init, sizeof(node));
-    ret->words[0] ^= node_index;
-    SHA3_512(ret->bytes, ret->bytes, sizeof(node));
-
+	uint32_t num_parent_nodes = (uint32_t) (light->cache_size / sizeof(node));
+	node const* cache_nodes = (node const *) light->cache;
+	node const* init = &cache_nodes[node_index % num_parent_nodes];
+	memcpy(ret, init, sizeof(node));
+	ret->words[0] ^= node_index;
+	SHA3_512(ret->bytes, ret->bytes, sizeof(node));
 #if defined(_M_X64) && ENABLE_SSE
-    __m128i const fnv_prime = _mm_set1_epi32(FNV_PRIME);
-    __m128i xmm0 = ret->xmm[0];
-    __m128i xmm1 = ret->xmm[1];
-    __m128i xmm2 = ret->xmm[2];
-    __m128i xmm3 = ret->xmm[3];
+	__m128i const fnv_prime = _mm_set1_epi32(FNV_PRIME);
+	__m128i xmm0 = ret->xmm[0];
+	__m128i xmm1 = ret->xmm[1];
+	__m128i xmm2 = ret->xmm[2];
+	__m128i xmm3 = ret->xmm[3];
 #endif
 
-    for (unsigned i = 0; i != DATASET_PARENTS; ++i) {
-        uint32_t parent_index = ((node_index ^ i) * FNV_PRIME ^ ret->words[i % NODE_WORDS]) % num_parent_nodes;
-        node const *parent = &cache_nodes[parent_index];
+	for (uint32_t i = 0; i != ETHASH_DATASET_PARENTS; ++i) {
+		uint32_t parent_index = fnv_hash(node_index ^ i, ret->words[i % NODE_WORDS]) % num_parent_nodes;
+		node const *parent = &cache_nodes[parent_index];
 
 #if defined(_M_X64) && ENABLE_SSE
-        {
-            xmm0 = _mm_mullo_epi32(xmm0, fnv_prime);
-            xmm1 = _mm_mullo_epi32(xmm1, fnv_prime);
-            xmm2 = _mm_mullo_epi32(xmm2, fnv_prime);
-            xmm3 = _mm_mullo_epi32(xmm3, fnv_prime);
-            xmm0 = _mm_xor_si128(xmm0, parent->xmm[0]);
-            xmm1 = _mm_xor_si128(xmm1, parent->xmm[1]);
-            xmm2 = _mm_xor_si128(xmm2, parent->xmm[2]);
-            xmm3 = _mm_xor_si128(xmm3, parent->xmm[3]);
-
-            // have to write to ret as values are used to compute index
-            ret->xmm[0] = xmm0;
-            ret->xmm[1] = xmm1;
-            ret->xmm[2] = xmm2;
-            ret->xmm[3] = xmm3;
-        }
-        #else
-        {
-            for (unsigned w = 0; w != NODE_WORDS; ++w) {
-                ret->words[w] = fnv_hash(ret->words[w], parent->words[w]);
-            }
-        }
+		{
+			xmm0 = _mm_mullo_epi32(xmm0, fnv_prime);
+			xmm1 = _mm_mullo_epi32(xmm1, fnv_prime);
+			xmm2 = _mm_mullo_epi32(xmm2, fnv_prime);
+			xmm3 = _mm_mullo_epi32(xmm3, fnv_prime);
+			xmm0 = _mm_xor_si128(xmm0, parent->xmm[0]);
+			xmm1 = _mm_xor_si128(xmm1, parent->xmm[1]);
+			xmm2 = _mm_xor_si128(xmm2, parent->xmm[2]);
+			xmm3 = _mm_xor_si128(xmm3, parent->xmm[3]);
+
+			// have to write to ret as values are used to compute index
+			ret->xmm[0] = xmm0;
+			ret->xmm[1] = xmm1;
+			ret->xmm[2] = xmm2;
+			ret->xmm[3] = xmm3;
+		}
+		#else
+		{
+			for (unsigned w = 0; w != NODE_WORDS; ++w) {
+				ret->words[w] = fnv_hash(ret->words[w], parent->words[w]);
+			}
+		}
 #endif
-    }
-
-    SHA3_512(ret->bytes, ret->bytes, sizeof(node));
+	}
+	SHA3_512(ret->bytes, ret->bytes, sizeof(node));
 }
 
-void ethash_compute_full_data(
-        void *mem,
-        ethash_params const *params,
-        ethash_cache const *cache) {
-    assert((params->full_size % (sizeof(uint32_t) * MIX_WORDS)) == 0);
-    assert((params->full_size % sizeof(node)) == 0);
-    node *full_nodes = mem;
-
-    // now compute full nodes
-    for (unsigned n = 0; n != (params->full_size / sizeof(node)); ++n) {
-        ethash_calculate_dag_item(&(full_nodes[n]), n, params, cache);
-    }
+bool ethash_compute_full_data(
+	void* mem,
+	uint64_t full_size,
+	ethash_light_t const light,
+	ethash_callback_t callback
+)
+{
+	if (full_size % (sizeof(uint32_t) * MIX_WORDS) != 0 ||
+		(full_size % sizeof(node)) != 0) {
+		return false;
+	}
+	uint32_t const max_n = (uint32_t)(full_size / sizeof(node));
+	node* full_nodes = mem;
+	double const progress_change = 1.0f / max_n;
+	double progress = 0.0f;
+	// now compute full nodes
+	for (uint32_t n = 0; n != max_n; ++n) {
+		if (callback &&
+			n % (max_n / 100) == 0 &&
+			callback((unsigned int)(ceil(progress * 100.0f))) != 0) {
+
+			return false;
+		}
+		progress += progress_change;
+		ethash_calculate_dag_item(&(full_nodes[n]), n, light);
+	}
+	return true;
 }
 
-static void ethash_hash(ethash_return_value *ret,
-                        node const *full_nodes,
-                        ethash_cache const *cache,
-                        ethash_params const *params,
-                        ethash_blockhash_t const *header_hash,
-                        const uint64_t nonce)
+static bool ethash_hash(
+	ethash_return_value_t* ret,
+	node const* full_nodes,
+	ethash_light_t const light,
+	uint64_t full_size,
+	ethash_h256_t const header_hash,
+	uint64_t const nonce
+)
 {
+	if (full_size % MIX_WORDS != 0) {
+		return false;
+	}
+
+	// pack hash and nonce together into first 40 bytes of s_mix
+	assert(sizeof(node) * 8 == 512);
+	node s_mix[MIX_NODES + 1];
+	memcpy(s_mix[0].bytes, &header_hash, 32);
+	fix_endian64(s_mix[0].double_words[4], nonce);
+
+	// compute sha3-512 hash and replicate across mix
+	SHA3_512(s_mix->bytes, s_mix->bytes, 40);
+	fix_endian_arr32(s_mix[0].words, 16);
+
+	node* const mix = s_mix + 1;
+	for (uint32_t w = 0; w != MIX_WORDS; ++w) {
+		mix->words[w] = s_mix[0].words[w % NODE_WORDS];
+	}
+
+	unsigned const page_size = sizeof(uint32_t) * MIX_WORDS;
+	unsigned const num_full_pages = (unsigned) (full_size / page_size);
+
+	for (unsigned i = 0; i != ETHASH_ACCESSES; ++i) {
+		uint32_t const index = fnv_hash(s_mix->words[0] ^ i, mix->words[i % MIX_WORDS]) % num_full_pages;
+
+		for (unsigned n = 0; n != MIX_NODES; ++n) {
+			node const* dag_node;
+			if (full_nodes) {
+				dag_node = &full_nodes[MIX_NODES * index + n];
+			} else {
+				node tmp_node;
+				ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, light);
+				dag_node = &tmp_node;
+			}
 
-    assert((params->full_size % MIX_WORDS) == 0);
-
-    // pack hash and nonce together into first 40 bytes of s_mix
-    assert(sizeof(node) * 8 == 512);
-    node s_mix[MIX_NODES + 1];
-    memcpy(s_mix[0].bytes, header_hash, 32);
-
-#if BYTE_ORDER != LITTLE_ENDIAN
-    s_mix[0].double_words[4] = fix_endian64(nonce);
-#else
-    s_mix[0].double_words[4] = nonce;
+#if defined(_M_X64) && ENABLE_SSE
+			{
+				__m128i fnv_prime = _mm_set1_epi32(FNV_PRIME);
+				__m128i xmm0 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[0]);
+				__m128i xmm1 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[1]);
+				__m128i xmm2 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[2]);
+				__m128i xmm3 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[3]);
+				mix[n].xmm[0] = _mm_xor_si128(xmm0, dag_node->xmm[0]);
+				mix[n].xmm[1] = _mm_xor_si128(xmm1, dag_node->xmm[1]);
+				mix[n].xmm[2] = _mm_xor_si128(xmm2, dag_node->xmm[2]);
+				mix[n].xmm[3] = _mm_xor_si128(xmm3, dag_node->xmm[3]);
+			}
+			#else
+			{
+				for (unsigned w = 0; w != NODE_WORDS; ++w) {
+					mix[n].words[w] = fnv_hash(mix[n].words[w], dag_node->words[w]);
+				}
+			}
 #endif
+		}
+
+	}
+
+	// compress mix
+	for (uint32_t w = 0; w != MIX_WORDS; w += 4) {
+		uint32_t reduction = mix->words[w + 0];
+		reduction = reduction * FNV_PRIME ^ mix->words[w + 1];
+		reduction = reduction * FNV_PRIME ^ mix->words[w + 2];
+		reduction = reduction * FNV_PRIME ^ mix->words[w + 3];
+		mix->words[w / 4] = reduction;
+	}
+
+	fix_endian_arr32(mix->words, MIX_WORDS / 4);
+	memcpy(&ret->mix_hash, mix->bytes, 32);
+	// final Keccak hash
+	SHA3_256(&ret->result, s_mix->bytes, 64 + 32); // Keccak-256(s + compressed_mix)
+	return true;
+}
 
-    // compute sha3-512 hash and replicate across mix
-    SHA3_512(s_mix->bytes, s_mix->bytes, 40);
-
-#if BYTE_ORDER != LITTLE_ENDIAN
-    for (unsigned w = 0; w != 16; ++w) {
-        s_mix[0].words[w] = fix_endian32(s_mix[0].words[w]);
-    }
-#endif
+void ethash_quick_hash(
+	ethash_h256_t* return_hash,
+	ethash_h256_t const* header_hash,
+	uint64_t const nonce,
+	ethash_h256_t const* mix_hash
+)
+{
+	uint8_t buf[64 + 32];
+	memcpy(buf, header_hash, 32);
+	fix_endian64_same(nonce);
+	memcpy(&(buf[32]), &nonce, 8);
+	SHA3_512(buf, buf, 40);
+	memcpy(&(buf[64]), mix_hash, 32);
+	SHA3_256(return_hash, buf, 64 + 32);
+}
 
-    node *const mix = s_mix + 1;
-    for (unsigned w = 0; w != MIX_WORDS; ++w) {
-        mix->words[w] = s_mix[0].words[w % NODE_WORDS];
-    }
+ethash_h256_t ethash_get_seedhash(uint64_t block_number)
+{
+	ethash_h256_t ret;
+	ethash_h256_reset(&ret);
+	uint64_t const epochs = block_number / ETHASH_EPOCH_LENGTH;
+	for (uint32_t i = 0; i < epochs; ++i)
+		SHA3_256(&ret, (uint8_t*)&ret, 32);
+	return ret;
+}
 
-    unsigned const
-            page_size = sizeof(uint32_t) * MIX_WORDS,
-            num_full_pages = (unsigned) (params->full_size / page_size);
+int ethash_quick_check_difficulty(
+	ethash_h256_t const* header_hash,
+	uint64_t const nonce,
+	ethash_h256_t const* mix_hash,
+	ethash_h256_t const* difficulty
+)
+{
 
+	ethash_h256_t return_hash;
+	ethash_quick_hash(&return_hash, header_hash, nonce, mix_hash);
+	return ethash_check_difficulty(&return_hash, difficulty);
+}
 
-    for (unsigned i = 0; i != ACCESSES; ++i) {
-        uint32_t const index = ((s_mix->words[0] ^ i) * FNV_PRIME ^ mix->words[i % MIX_WORDS]) % num_full_pages;
+ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed)
+{
+	struct ethash_light *ret;
+	ret = calloc(sizeof(*ret), 1);
+	if (!ret) {
+		return NULL;
+	}
+	ret->cache = malloc((size_t)cache_size);
+	if (!ret->cache) {
+		goto fail_free_light;
+	}
+	node* nodes = (node*)ret->cache;
+	if (!ethash_compute_cache_nodes(nodes, cache_size, seed)) {
+		goto fail_free_cache_mem;
+	}
+	ret->cache_size = cache_size;
+	return ret;
+
+fail_free_cache_mem:
+	free(ret->cache);
+fail_free_light:
+	free(ret);
+	return NULL;
+}
 
-        for (unsigned n = 0; n != MIX_NODES; ++n) {
-            const node *dag_node = &full_nodes[MIX_NODES * index + n];
+ethash_light_t ethash_light_new(uint64_t block_number)
+{
+	ethash_h256_t seedhash = ethash_get_seedhash(block_number);
+	ethash_light_t ret;
+	ret = ethash_light_new_internal(ethash_get_cachesize(block_number), &seedhash);
+	ret->block_number = block_number;
+	return ret;
+}
 
-            if (!full_nodes) {
-                node tmp_node;
-                ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, params, cache);
-                dag_node = &tmp_node;
-            }
+void ethash_light_delete(ethash_light_t light)
+{
+	if (light->cache) {
+		free(light->cache);
+	}
+	free(light);
+}
 
-#if defined(_M_X64) && ENABLE_SSE
-            {
-                __m128i fnv_prime = _mm_set1_epi32(FNV_PRIME);
-                __m128i xmm0 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[0]);
-                __m128i xmm1 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[1]);
-                __m128i xmm2 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[2]);
-                __m128i xmm3 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[3]);
-                mix[n].xmm[0] = _mm_xor_si128(xmm0, dag_node->xmm[0]);
-                mix[n].xmm[1] = _mm_xor_si128(xmm1, dag_node->xmm[1]);
-                mix[n].xmm[2] = _mm_xor_si128(xmm2, dag_node->xmm[2]);
-                mix[n].xmm[3] = _mm_xor_si128(xmm3, dag_node->xmm[3]);
-            }
-            #else
-            {
-                for (unsigned w = 0; w != NODE_WORDS; ++w) {
-                    mix[n].words[w] = fnv_hash(mix[n].words[w], dag_node->words[w]);
-                }
-            }
-#endif
-        }
-
-    }
-
-    // compress mix
-    for (unsigned w = 0; w != MIX_WORDS; w += 4) {
-        uint32_t reduction = mix->words[w + 0];
-        reduction = reduction * FNV_PRIME ^ mix->words[w + 1];
-        reduction = reduction * FNV_PRIME ^ mix->words[w + 2];
-        reduction = reduction * FNV_PRIME ^ mix->words[w + 3];
-        mix->words[w / 4] = reduction;
-    }
-
-#if BYTE_ORDER != LITTLE_ENDIAN
-    for (unsigned w = 0; w != MIX_WORDS/4; ++w) {
-        mix->words[w] = fix_endian32(mix->words[w]);
-    }
-#endif
+ethash_return_value_t ethash_light_compute_internal(
+	ethash_light_t light,
+	uint64_t full_size,
+	ethash_h256_t const header_hash,
+	uint64_t nonce
+)
+{
+  	ethash_return_value_t ret;
+	ret.success = true;
+	if (!ethash_hash(&ret, NULL, light, full_size, header_hash, nonce)) {
+		ret.success = false;
+	}
+	return ret;
+}
 
-    memcpy(&ret->mix_hash, mix->bytes, 32);
-    // final Keccak hash
-    SHA3_256(&ret->result, s_mix->bytes, 64 + 32); // Keccak-256(s + compressed_mix)
+ethash_return_value_t ethash_light_compute(
+	ethash_light_t light,
+	ethash_h256_t const header_hash,
+	uint64_t nonce
+)
+{
+	uint64_t full_size = ethash_get_datasize(light->block_number);
+	return ethash_light_compute_internal(light, full_size, header_hash, nonce);
 }
 
-void ethash_quick_hash(ethash_blockhash_t *return_hash,
-                       ethash_blockhash_t const *header_hash,
-                       const uint64_t nonce,
-                       ethash_blockhash_t const *mix_hash)
+static bool ethash_mmap(struct ethash_full* ret, FILE* f)
 {
+	int fd;
+	char* mmapped_data;
+	ret->file = f;
+	if ((fd = ethash_fileno(ret->file)) == -1) {
+		return false;
+	}
+	mmapped_data= mmap(
+		NULL,
+		(size_t)ret->file_size + ETHASH_DAG_MAGIC_NUM_SIZE,
+		PROT_READ | PROT_WRITE,
+		MAP_SHARED,
+		fd,
+		0
+	);
+	if (mmapped_data == MAP_FAILED) {
+		return false;
+	}
+	ret->data = (node*)(mmapped_data + ETHASH_DAG_MAGIC_NUM_SIZE);
+	return true;
+}
 
-    uint8_t buf[64 + 32];
-    memcpy(buf, header_hash, 32);
-#if BYTE_ORDER != LITTLE_ENDIAN
-    nonce = fix_endian64(nonce);
-#endif
-    memcpy(&(buf[32]), &nonce, 8);
-    SHA3_512(buf, buf, 40);
-    memcpy(&(buf[64]), mix_hash, 32);
-    SHA3_256(return_hash, buf, 64 + 32);
+ethash_full_t ethash_full_new_internal(
+	char const* dirname,
+	ethash_h256_t const seed_hash,
+	uint64_t full_size,
+	ethash_light_t const light,
+	ethash_callback_t callback
+)
+{
+	struct ethash_full* ret;
+	FILE *f = NULL;
+	ret = calloc(sizeof(*ret), 1);
+	if (!ret) {
+		return NULL;
+	}
+	ret->file_size = (size_t)full_size;
+	switch (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, false)) {
+	case ETHASH_IO_FAIL:
+		goto fail_free_full;
+	case ETHASH_IO_MEMO_MATCH:
+		if (!ethash_mmap(ret, f)) {
+			goto fail_close_file;
+		}
+		return ret;
+	case ETHASH_IO_MEMO_SIZE_MISMATCH:
+		// if a DAG of same filename but unexpected size is found, silently force new file creation
+		if (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, true) != ETHASH_IO_MEMO_MISMATCH) {
+			goto fail_free_full;
+		}
+		// fallthrough to the mismatch case here, DO NOT go through match
+	case ETHASH_IO_MEMO_MISMATCH:
+		if (!ethash_mmap(ret, f)) {
+			goto fail_close_file;
+		}
+		break;
+	}
+
+	if (!ethash_compute_full_data(ret->data, full_size, light, callback)) {
+		goto fail_free_full_data;
+	}
+
+	// after the DAG has been filled then we finalize it by writting the magic number at the beginning
+	if (fseek(f, 0, SEEK_SET) != 0) {
+		goto fail_free_full_data;
+	}
+	uint64_t const magic_num = ETHASH_DAG_MAGIC_NUM;
+	if (fwrite(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
+		goto fail_free_full_data;
+	}
+	fflush(f); // make sure the magic number IS there
+	return ret;
+
+fail_free_full_data:
+	// could check that munmap(..) == 0 but even if it did not can't really do anything here
+	munmap(ret->data, (size_t)full_size);
+fail_close_file:
+	fclose(ret->file);
+fail_free_full:
+	free(ret);
+	return NULL;
 }
 
-void ethash_get_seedhash(ethash_blockhash_t *seedhash, const uint32_t block_number)
+ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback)
 {
-    ethash_blockhash_reset(seedhash);
-    const uint32_t epochs = block_number / EPOCH_LENGTH;
-    for (uint32_t i = 0; i < epochs; ++i)
-        SHA3_256(seedhash, (uint8_t*)seedhash, 32);
+	char strbuf[256];
+	if (!ethash_get_default_dirname(strbuf, 256)) {
+		return NULL;
+	}
+	uint64_t full_size = ethash_get_datasize(light->block_number);
+	ethash_h256_t seedhash = ethash_get_seedhash(light->block_number);
+	return ethash_full_new_internal(strbuf, seedhash, full_size, light, callback);
 }
 
-int ethash_quick_check_difficulty(ethash_blockhash_t const *header_hash,
-                                  const uint64_t nonce,
-                                  ethash_blockhash_t const *mix_hash,
-                                  ethash_blockhash_t const *difficulty)
+void ethash_full_delete(ethash_full_t full)
 {
+	// could check that munmap(..) == 0 but even if it did not can't really do anything here
+	munmap(full->data, (size_t)full->file_size);
+	if (full->file) {
+		fclose(full->file);
+	}
+	free(full);
+}
 
-    ethash_blockhash_t return_hash;
-    ethash_quick_hash(&return_hash, header_hash, nonce, mix_hash);
-    return ethash_check_difficulty(&return_hash, difficulty);
+ethash_return_value_t ethash_full_compute(
+	ethash_full_t full,
+	ethash_h256_t const header_hash,
+	uint64_t nonce
+)
+{
+	ethash_return_value_t ret;
+	ret.success = true;
+	if (!ethash_hash(
+		&ret,
+		(node const*)full->data,
+		NULL,
+		full->file_size,
+		header_hash,
+		nonce)) {
+		ret.success = false;
+	}
+	return ret;
 }
 
-void ethash_full(ethash_return_value *ret,
-                 void const *full_mem,
-                 ethash_params const *params,
-                 ethash_blockhash_t const *header_hash,
-                 const uint64_t nonce)
+void const* ethash_full_dag(ethash_full_t full)
 {
-    ethash_hash(ret, (node const *) full_mem, NULL, params, header_hash, nonce);
+	return full->data;
 }
 
-void ethash_light(ethash_return_value *ret,
-                  ethash_cache const *cache,
-                  ethash_params const *params,
-                  ethash_blockhash_t const *header_hash,
-                  const uint64_t nonce)
+uint64_t ethash_full_dag_size(ethash_full_t full)
 {
-    ethash_hash(ret, NULL, cache, params, header_hash, nonce);
+	return full->file_size;
 }
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.h
index 1e19cd1fd..221ff290a 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.h
@@ -2,6 +2,7 @@
 #include "compiler.h"
 #include "endian.h"
 #include "ethash.h"
+#include <stdio.h>
 
 #define ENABLE_SSE 0
 
@@ -15,14 +16,14 @@ extern "C" {
 
 // compile time settings
 #define NODE_WORDS (64/4)
-#define MIX_WORDS (MIX_BYTES/4)
+#define MIX_WORDS (ETHASH_MIX_BYTES/4)
 #define MIX_NODES (MIX_WORDS / NODE_WORDS)
 #include <stdint.h>
 
 typedef union node {
-    uint8_t bytes[NODE_WORDS * 4];
-    uint32_t words[NODE_WORDS];
-    uint64_t double_words[NODE_WORDS / 2];
+	uint8_t bytes[NODE_WORDS * 4];
+	uint32_t words[NODE_WORDS];
+	uint64_t double_words[NODE_WORDS / 2];
 
 #if defined(_M_X64) && ENABLE_SSE
 	__m128i xmm[NODE_WORDS/4];
@@ -30,15 +31,139 @@ typedef union node {
 
 } node;
 
-void ethash_calculate_dag_item(node *const ret,
-                               const unsigned node_index,
-                               ethash_params const *params,
-                               ethash_cache const *cache);
+static inline uint8_t ethash_h256_get(ethash_h256_t const* hash, unsigned int i)
+{
+	return hash->b[i];
+}
+
+static inline void ethash_h256_set(ethash_h256_t* hash, unsigned int i, uint8_t v)
+{
+	hash->b[i] = v;
+}
+
+static inline void ethash_h256_reset(ethash_h256_t* hash)
+{
+	memset(hash, 0, 32);
+}
+
+// Returns if hash is less than or equal to difficulty
+static inline int ethash_check_difficulty(
+	ethash_h256_t const* hash,
+	ethash_h256_t const* difficulty
+)
+{
+	// Difficulty is big endian
+	for (int i = 0; i < 32; i++) {
+		if (ethash_h256_get(hash, i) == ethash_h256_get(difficulty, i)) {
+			continue;
+		}
+		return ethash_h256_get(hash, i) < ethash_h256_get(difficulty, i);
+	}
+	return 1;
+}
+
+int ethash_quick_check_difficulty(
+	ethash_h256_t const* header_hash,
+	uint64_t const nonce,
+	ethash_h256_t const* mix_hash,
+	ethash_h256_t const* difficulty
+);
+
+struct ethash_light {
+	void* cache;
+	uint64_t cache_size;
+	uint64_t block_number;
+};
+
+/**
+ * Allocate and initialize a new ethash_light handler. Internal version
+ *
+ * @param cache_size    The size of the cache in bytes
+ * @param seed          Block seedhash to be used during the computation of the
+ *                      cache nodes
+ * @return              Newly allocated ethash_light handler or NULL in case of
+ *                      ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
+ */
+ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed);
+
+/**
+ * Calculate the light client data. Internal version.
+ *
+ * @param light          The light client handler
+ * @param full_size      The size of the full data in bytes.
+ * @param header_hash    The header hash to pack into the mix
+ * @param nonce          The nonce to pack into the mix
+ * @return               The resulting hash.
+ */
+ethash_return_value_t ethash_light_compute_internal(
+	ethash_light_t light,
+	uint64_t full_size,
+	ethash_h256_t const header_hash,
+	uint64_t nonce
+);
+
+struct ethash_full {
+	FILE* file;
+	uint64_t file_size;
+	node* data;
+};
+
+/**
+ * Allocate and initialize a new ethash_full handler. Internal version.
+ *
+ * @param dirname        The directory in which to put the DAG file.
+ * @param seedhash       The seed hash of the block. Used in the DAG file naming.
+ * @param full_size      The size of the full data in bytes.
+ * @param cache          A cache object to use that was allocated with @ref ethash_cache_new().
+ *                       Iff this function succeeds the ethash_full_t will take memory
+ *                       memory ownership of the cache and free it at deletion. If
+ *                       not then the user still has to handle freeing of the cache himself.
+ * @param callback       A callback function with signature of @ref ethash_callback_t
+ *                       It accepts an unsigned with which a progress of DAG calculation
+ *                       can be displayed. If all goes well the callback should return 0.
+ *                       If a non-zero value is returned then DAG generation will stop.
+ * @return               Newly allocated ethash_full handler or NULL in case of
+ *                       ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
+ */
+ethash_full_t ethash_full_new_internal(
+	char const* dirname,
+	ethash_h256_t const seed_hash,
+	uint64_t full_size,
+	ethash_light_t const light,
+	ethash_callback_t callback
+);
+
+void ethash_calculate_dag_item(
+	node* const ret,
+	uint32_t node_index,
+	ethash_light_t const cache
+);
+
+void ethash_quick_hash(
+	ethash_h256_t* return_hash,
+	ethash_h256_t const* header_hash,
+	const uint64_t nonce,
+	ethash_h256_t const* mix_hash
+);
+
+uint64_t ethash_get_datasize(uint64_t const block_number);
+uint64_t ethash_get_cachesize(uint64_t const block_number);
 
-void ethash_quick_hash(ethash_blockhash_t *return_hash,
-                       ethash_blockhash_t const *header_hash,
-                       const uint64_t nonce,
-                       ethash_blockhash_t const *mix_hash);
+/**
+ * Compute the memory data for a full node's memory
+ *
+ * @param mem         A pointer to an ethash full's memory
+ * @param full_size   The size of the full data in bytes
+ * @param cache       A cache object to use in the calculation
+ * @param callback    The callback function. Check @ref ethash_full_new() for details.
+ * @return            true if all went fine and false for invalid parameters
+ */
+bool ethash_compute_full_data(
+	void* mem,
+	uint64_t full_size,
+	ethash_light_t const light,
+	ethash_callback_t callback
+);
 
 #ifdef __cplusplus
 }
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.c
index 5a8eebae5..5b4e7da2b 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.c
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.c
@@ -22,68 +22,81 @@
 #include <string.h>
 #include <stdio.h>
 
-// silly macro to save some typing
-#define PASS_ARR(c_) (c_), sizeof(c_)
-
-static bool ethash_io_write_file(char const *dirname,
-                                 char const* filename,
-                                 size_t filename_length,
-                                 void const* data,
-                                 size_t data_size)
-{
-    bool ret = false;
-    char *fullname = ethash_io_create_filename(dirname, filename, filename_length);
-    if (!fullname) {
-        return false;
-    }
-    FILE *f = fopen(fullname, "wb");
-    if (!f) {
-        goto free_name;
-    }
-    if (data_size != fwrite(data, 1, data_size, f)) {
-        goto close;
-    }
-
-    ret = true;
-close:
-    fclose(f);
-free_name:
-    free(fullname);
-    return ret;
-}
-
-bool ethash_io_write(char const *dirname,
-                     ethash_params const* params,
-                     ethash_blockhash_t seedhash,
-                     void const* cache,
-                     uint8_t **data,
-                     uint64_t *data_size)
+enum ethash_io_rc ethash_io_prepare(
+	char const* dirname,
+	ethash_h256_t const seedhash,
+	FILE** output_file,
+	uint64_t file_size,
+	bool force_create
+)
 {
-    char info_buffer[DAG_MEMO_BYTESIZE];
-    // allocate the bytes
-    uint8_t *temp_data_ptr = malloc((size_t)params->full_size);
-    if (!temp_data_ptr) {
-        goto end;
-    }
-    ethash_compute_full_data(temp_data_ptr, params, cache);
+	char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
+	enum ethash_io_rc ret = ETHASH_IO_FAIL;
 
-    if (!ethash_io_write_file(dirname, PASS_ARR(DAG_FILE_NAME), temp_data_ptr, (size_t)params->full_size)) {
-        goto fail_free;
-    }
+	// assert directory exists
+	if (!ethash_mkdir(dirname)) {
+		goto end;
+	}
 
-    ethash_io_serialize_info(REVISION, seedhash, info_buffer);
-    if (!ethash_io_write_file(dirname, PASS_ARR(DAG_MEMO_NAME), info_buffer, DAG_MEMO_BYTESIZE)) {
-        goto fail_free;
-    }
+	ethash_io_mutable_name(ETHASH_REVISION, &seedhash, mutable_name);
+	char* tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name));
+	if (!tmpfile) {
+		goto end;
+	}
 
-    *data = temp_data_ptr;
-    *data_size = params->full_size;
-    return true;
+	FILE *f;
+	if (!force_create) {
+		// try to open the file
+		f = ethash_fopen(tmpfile, "rb+");
+		if (f) {
+			size_t found_size;
+			if (!ethash_file_size(f, &found_size)) {
+				fclose(f);
+				goto free_memo;
+			}
+			if (file_size != found_size - ETHASH_DAG_MAGIC_NUM_SIZE) {
+				fclose(f);
+				ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
+				goto free_memo;
+			}
+			// compare the magic number, no need to care about endianess since it's local
+			uint64_t magic_num;
+			if (fread(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
+				// I/O error
+				fclose(f);
+				ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
+				goto free_memo;
+			}
+			if (magic_num != ETHASH_DAG_MAGIC_NUM) {
+				fclose(f);
+				ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
+				goto free_memo;
+			}
+			ret = ETHASH_IO_MEMO_MATCH;
+			goto set_file;
+		}
+	}
+	
+	// file does not exist, will need to be created
+	f = ethash_fopen(tmpfile, "wb+");
+	if (!f) {
+		goto free_memo;
+	}
+	// make sure it's of the proper size
+	if (fseek(f, (long int)(file_size + ETHASH_DAG_MAGIC_NUM_SIZE - 1), SEEK_SET) != 0) {
+		fclose(f);
+		goto free_memo;
+	}
+	fputc('\n', f);
+	fflush(f);
+	ret = ETHASH_IO_MEMO_MISMATCH;
+	goto set_file;
 
-fail_free:
-    free(temp_data_ptr);
+	ret = ETHASH_IO_MEMO_MATCH;
+set_file:
+	*output_file = f;
+free_memo:
+	free(tmpfile);
 end:
-    return false;
+	return ret;
 }
-
-#undef PASS_ARR
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.h
index 8cf8b69bf..26c82f111 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io.h
@@ -22,93 +22,162 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <stdbool.h>
+#include <stdio.h>
+#ifdef __cplusplus
+#define __STDC_FORMAT_MACROS 1
+#endif
+#include <inttypes.h>
+#include "endian.h"
 #include "ethash.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
-
-static const char DAG_FILE_NAME[] = "full";
-static const char DAG_MEMO_NAME[] = "full.info";
-// MSVC thinks that "static const unsigned int" is not a compile time variable. Sorry for the #define :(
-#define DAG_MEMO_BYTESIZE 36
-
+// Maximum size for mutable part of DAG file name
+// 10 is for maximum number of digits of a uint32_t (for REVISION)
+// 1 is for _ and 16 is for the first 16 hex digits for first 8 bytes of
+// the seedhash and last 1 is for the null terminating character
+// Reference: https://github.com/ethereum/wiki/wiki/Ethash-DAG
+#define DAG_MUTABLE_NAME_MAX_SIZE (10 + 1 + 16 + 1)
 /// Possible return values of @see ethash_io_prepare
 enum ethash_io_rc {
-    ETHASH_IO_FAIL = 0,      ///< There has been an IO failure
-    ETHASH_IO_MEMO_MISMATCH, ///< Memo file either did not exist or there was content mismatch
-    ETHASH_IO_MEMO_MATCH,    ///< Memo file existed and contents matched. No need to do anything
+	ETHASH_IO_FAIL = 0,           ///< There has been an IO failure
+	ETHASH_IO_MEMO_SIZE_MISMATCH, ///< DAG with revision/hash match, but file size was wrong.
+	ETHASH_IO_MEMO_MISMATCH,      ///< The DAG file did not exist or there was revision/hash mismatch
+	ETHASH_IO_MEMO_MATCH,         ///< DAG file existed and revision/hash matched. No need to do anything
 };
 
+// small hack for windows. I don't feel I should use va_args and forward just
+// to have this one function properly cross-platform abstracted
+#if defined(_WIN32)
+#define snprintf(...) sprintf_s(__VA_ARGS__)
+#endif
+
 /**
  * Prepares io for ethash
  *
- * Create the DAG directory if it does not exist, and check if the memo file matches.
- * If it does not match then it's deleted to pave the way for @ref ethash_io_write()
+ * Create the DAG directory and the DAG file if they don't exist.
  *
- * @param dirname        A null terminated c-string of the path of the ethash
- *                       data directory. If it does not exist it's created.
- * @param seedhash       The seedhash of the current block number
- * @return               For possible return values @see enum ethash_io_rc
+ * @param[in] dirname        A null terminated c-string of the path of the ethash
+ *                           data directory. If it does not exist it's created.
+ * @param[in] seedhash       The seedhash of the current block number, used in the
+ *                           naming of the file as can be seen from the spec at:
+ *                           https://github.com/ethereum/wiki/wiki/Ethash-DAG
+ * @param[out] output_file   If there was no failure then this will point to an open
+ *                           file descriptor. User is responsible for closing it.
+ *                           In the case of memo match then the file is open on read
+ *                           mode, while on the case of mismatch a new file is created
+ *                           on write mode
+ * @param[in] file_size      The size that the DAG file should have on disk
+ * @param[out] force_create  If true then there is no check to see if the file
+ *                           already exists
+ * @return                   For possible return values @see enum ethash_io_rc
  */
-enum ethash_io_rc ethash_io_prepare(char const *dirname, ethash_blockhash_t seedhash);
+enum ethash_io_rc ethash_io_prepare(
+	char const* dirname,
+	ethash_h256_t const seedhash,
+	FILE** output_file,
+	uint64_t file_size,
+	bool force_create
+);
 
 /**
- * Fully computes data and writes it to the file on disk.
+ * An fopen wrapper for no-warnings crossplatform fopen.
  *
- * This function should be called after @see ethash_io_prepare() and only if
- * its return value is @c ETHASH_IO_MEMO_MISMATCH. Will write both the full data
- * and the memo file.
+ * Msvc compiler considers fopen to be insecure and suggests to use their
+ * alternative. This is a wrapper for this alternative. Another way is to
+ * #define _CRT_SECURE_NO_WARNINGS, but disabling all security warnings does
+ * not sound like a good idea.
  *
- * @param[in] dirname        A null terminated c-string of the path of the ethash
- *                           data directory. Has to exist.
- * @param[in] params         An ethash_params object containing the full size
- *                           and the cache size
- * @param[in] seedhash       The seedhash of the current block number
- * @param[in] cache          The cache data. Would have usually been calulated by
- *                           @see ethash_prep_light().
- * @param[out] data          Pass a pointer to uint8_t by reference here. If the
- *                           function is succesfull then this point to the allocated
- *                           data calculated by @see ethash_prep_full(). Memory
- *                           ownership is transfered to the callee. Remember that
- *                           you eventually need to free this with a call to free().
- * @param[out] data_size     Pass a uint64_t by value. If the function is succesfull
- *                           then this will contain the number of bytes allocated
- *                           for @a data.
- * @return                   True for success and false in case of failure.
+ * @param file_name        The path to the file to open
+ * @param mode             Opening mode. Check fopen()
+ * @return                 The FILE* or NULL in failure
  */
-bool ethash_io_write(char const *dirname,
-                     ethash_params const* params,
-                     ethash_blockhash_t seedhash,
-                     void const* cache,
-                     uint8_t **data,
-                     uint64_t *data_size);
+FILE* ethash_fopen(char const* file_name, char const* mode);
 
-static inline void ethash_io_serialize_info(uint32_t revision,
-                                            ethash_blockhash_t seed_hash,
-                                            char *output)
-{
-    // if .info is only consumed locally we don't really care about endianess
-    memcpy(output, &revision, 4);
-    memcpy(output + 4, &seed_hash, 32);
-}
+/**
+ * An strncat wrapper for no-warnings crossplatform strncat.
+ *
+ * Msvc compiler considers strncat to be insecure and suggests to use their
+ * alternative. This is a wrapper for this alternative. Another way is to
+ * #define _CRT_SECURE_NO_WARNINGS, but disabling all security warnings does
+ * not sound like a good idea.
+ *
+ * @param des              Destination buffer
+ * @param dest_size        Maximum size of the destination buffer. This is the
+ *                         extra argument for the MSVC secure strncat
+ * @param src              Souce buffer
+ * @param count            Number of bytes to copy from source
+ * @return                 If all is well returns the dest buffer. If there is an
+ *                         error returns NULL
+ */
+char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count);
 
-static inline char *ethash_io_create_filename(char const *dirname,
-                                              char const* filename,
-                                              size_t filename_length)
-{
-    // in C the cast is not needed, but a C++ compiler will complain for invalid conversion
-    char *name = (char*)malloc(strlen(dirname) + filename_length);
-    if (!name) {
-        return NULL;
-    }
+/**
+ * A cross-platform mkdir wrapper to create a directory or assert it's there
+ *
+ * @param dirname        The full path of the directory to create
+ * @return               true if the directory was created or if it already
+ *                       existed
+ */
+bool ethash_mkdir(char const* dirname);
 
-    name[0] = '\0';
-    strcat(name, dirname);
-    strcat(name, filename);
-    return name;
-}
+/**
+ * Get a file's size
+ *
+ * @param[in] f        The open file stream whose size to get
+ * @param[out] size    Pass a size_t by reference to contain the file size
+ * @return             true in success and false if there was a failure
+ */
+bool ethash_file_size(FILE* f, size_t* ret_size);
+
+/**
+ * Get a file descriptor number from a FILE stream
+ *
+ * @param f            The file stream whose fd to get
+ * @return             Platform specific fd handler
+ */
+int ethash_fileno(FILE* f);
 
+/**
+ * Create the filename for the DAG.
+ *
+ * @param dirname            The directory name in which the DAG file should reside
+ *                           If it does not end with a directory separator it is appended.
+ * @param filename           The actual name of the file
+ * @param filename_length    The length of the filename in bytes
+ * @return                   A char* containing the full name. User must deallocate.
+ */
+char* ethash_io_create_filename(
+	char const* dirname,
+	char const* filename,
+	size_t filename_length
+);
+
+/**
+ * Gets the default directory name for the DAG depending on the system
+ *
+ * The spec defining this directory is here: https://github.com/ethereum/wiki/wiki/Ethash-DAG
+ *
+ * @param[out] strbuf          A string buffer of sufficient size to keep the
+ *                             null termninated string of the directory name
+ * @param[in]  buffsize        Size of @a strbuf in bytes
+ * @return                     true for success and false otherwise
+ */
+bool ethash_get_default_dirname(char* strbuf, size_t buffsize);
+
+static inline bool ethash_io_mutable_name(
+	uint32_t revision,
+	ethash_h256_t const* seed_hash,
+	char* output
+)
+{
+    uint64_t hash = *((uint64_t*)seed_hash);
+#if LITTLE_ENDIAN == BYTE_ORDER
+    hash = ethash_swap_u64(hash);
+#endif
+    return snprintf(output, DAG_MUTABLE_NAME_MAX_SIZE, "%u_%016" PRIx64, revision, hash) >= 0;
+}
 
 #ifdef __cplusplus
 }
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_posix.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_posix.c
index 693bdf750..7f03d5482 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_posix.c
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_posix.c
@@ -27,50 +27,76 @@
 #include <stdio.h>
 #include <unistd.h>
 
-enum ethash_io_rc ethash_io_prepare(char const *dirname, ethash_blockhash_t seedhash)
+FILE* ethash_fopen(char const* file_name, char const* mode)
 {
-    char read_buffer[DAG_MEMO_BYTESIZE];
-    char expect_buffer[DAG_MEMO_BYTESIZE];
-    enum ethash_io_rc ret = ETHASH_IO_FAIL;
+	return fopen(file_name, mode);
+}
 
-    // assert directory exists, full owner permissions and read/search for others
-    int rc = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
-    if (rc == -1 && errno != EEXIST) {
-        goto end;
-    }
+char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count)
+{
+	return strlen(dest) + count + 1 <= dest_size ? strncat(dest, src, count) : NULL;
+}
 
-    char *memofile = ethash_io_create_filename(dirname, DAG_MEMO_NAME, sizeof(DAG_MEMO_NAME));
-    if (!memofile) {
-        goto end;
-    }
+bool ethash_mkdir(char const* dirname)
+{
+	int rc = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+	return rc != -1 || errno == EEXIST;
+}
 
-    // try to open memo file
-    FILE *f = fopen(memofile, "rb");
-    if (!f) {
-        // file does not exist, so no checking happens. All is fine.
-        ret = ETHASH_IO_MEMO_MISMATCH;
-        goto free_memo;
-    }
+int ethash_fileno(FILE *f)
+{
+	return fileno(f);
+}
 
-    if (fread(read_buffer, 1, DAG_MEMO_BYTESIZE, f) != DAG_MEMO_BYTESIZE) {
-        goto close;
-    }
+char* ethash_io_create_filename(
+	char const* dirname,
+	char const* filename,
+	size_t filename_length
+)
+{
+	size_t dirlen = strlen(dirname);
+	size_t dest_size = dirlen + filename_length + 1;
+	if (dirname[dirlen] != '/') {
+		dest_size += 1;
+	}
+	char* name = malloc(dest_size);
+	if (!name) {
+		return NULL;
+	}
 
-    ethash_io_serialize_info(REVISION, seedhash, expect_buffer);
-    if (memcmp(read_buffer, expect_buffer, DAG_MEMO_BYTESIZE) != 0) {
-        // we have different memo contents so delete the memo file
-        if (unlink(memofile) != 0) {
-            goto close;
-        }
-        ret = ETHASH_IO_MEMO_MISMATCH;
-    }
+	name[0] = '\0';
+	ethash_strncat(name, dest_size, dirname, dirlen);
+	if (dirname[dirlen] != '/') {
+		ethash_strncat(name, dest_size, "/", 1);
+	}
+	ethash_strncat(name, dest_size, filename, filename_length);
+	return name;
+}
 
-    ret = ETHASH_IO_MEMO_MATCH;
+bool ethash_file_size(FILE* f, size_t* ret_size)
+{
+	struct stat st;
+	int fd;
+	if ((fd = fileno(f)) == -1 || fstat(fd, &st) != 0) {
+		return false;
+	}
+	*ret_size = st.st_size;
+	return true;
+}
 
-close:
-    fclose(f);
-free_memo:
-    free(memofile);
-end:
-    return ret;
+bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
+{
+	static const char dir_suffix[] = ".ethash/";
+	strbuf[0] = '\0';
+	char* home_dir = getenv("HOME");
+	size_t len = strlen(home_dir);
+	if (!ethash_strncat(strbuf, buffsize, home_dir, len)) {
+		return false;
+	}
+	if (home_dir[len] != '/') {
+		if (!ethash_strncat(strbuf, buffsize, "/", 1)) {
+			return false;
+		}
+	}
+	return ethash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix));
 }
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_win32.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_win32.c
index 2cabc939a..d9c54d141 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_win32.c
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/io_win32.c
@@ -23,51 +23,78 @@
 #include <direct.h>
 #include <errno.h>
 #include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <Shlobj.h>
 
-enum ethash_io_rc ethash_io_prepare(char const *dirname, ethash_blockhash_t seedhash)
+FILE* ethash_fopen(char const* file_name, char const* mode)
 {
-    char read_buffer[DAG_MEMO_BYTESIZE];
-    char expect_buffer[DAG_MEMO_BYTESIZE];
-    enum ethash_io_rc ret = ETHASH_IO_FAIL;
+	FILE* f;
+	return fopen_s(&f, file_name, mode) == 0 ? f : NULL;
+}
 
-    // assert directory exists
-    int rc = _mkdir(dirname);
-    if (rc == -1 && errno != EEXIST) {
-        goto end;
-    }
+char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count)
+{
+	return strncat_s(dest, dest_size, src, count) == 0 ? dest : NULL;
+}
 
-    char *memofile = ethash_io_create_filename(dirname, DAG_MEMO_NAME, sizeof(DAG_MEMO_NAME));
-    if (!memofile) {
-        goto end;
-    }
+bool ethash_mkdir(char const* dirname)
+{
+	int rc = _mkdir(dirname);
+	return rc != -1 || errno == EEXIST;
+}
 
-    // try to open memo file
-    FILE *f = fopen(memofile, "rb");
-    if (!f) {
-        // file does not exist, so no checking happens. All is fine.
-        ret = ETHASH_IO_MEMO_MISMATCH;
-        goto free_memo;
-    }
+int ethash_fileno(FILE* f)
+{
+	return _fileno(f);
+}
 
-    if (fread(read_buffer, 1, DAG_MEMO_BYTESIZE, f) != DAG_MEMO_BYTESIZE) {
-        goto close;
-    }
+char* ethash_io_create_filename(
+	char const* dirname,
+	char const* filename,
+	size_t filename_length
+)
+{
+	size_t dirlen = strlen(dirname);
+	size_t dest_size = dirlen + filename_length + 1;
+	if (dirname[dirlen] != '\\' || dirname[dirlen] != '/') {
+		dest_size += 1;
+	}
+	char* name = malloc(dest_size);
+	if (!name) {
+		return NULL;
+	}
+
+	name[0] = '\0';
+	ethash_strncat(name, dest_size, dirname, dirlen);
+	if (dirname[dirlen] != '\\' || dirname[dirlen] != '/') {
+		ethash_strncat(name, dest_size, "\\", 1);
+	}
+	ethash_strncat(name, dest_size, filename, filename_length);
+	return name;
+}
 
-    ethash_io_serialize_info(REVISION, seedhash, expect_buffer);
-    if (memcmp(read_buffer, expect_buffer, DAG_MEMO_BYTESIZE) != 0) {
-        // we have different memo contents so delete the memo file
-        if (_unlink(memofile) != 0) {
-            goto close;
-        }
-        ret = ETHASH_IO_MEMO_MISMATCH;
-    }
+bool ethash_file_size(FILE* f, size_t* ret_size)
+{
+	struct _stat st;
+	int fd;
+	if ((fd = _fileno(f)) == -1 || _fstat(fd, &st) != 0) {
+		return false;
+	}
+	*ret_size = st.st_size;
+	return true;
+}
 
-    ret = ETHASH_IO_MEMO_MATCH;
+bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
+{
+	static const char dir_suffix[] = "Appdata\\Ethash\\";
+	strbuf[0] = '\0';
+	if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, (WCHAR*)strbuf))) {
+		return false;
+	}
+	if (!ethash_strncat(strbuf, buffsize, "\\", 1)) {
+		return false;
+	}
 
-close:
-    fclose(f);
-free_memo:
-    free(memofile);
-end:
-    return ret;
+	return ethash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix));
 }
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/mmap.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/mmap.h
new file mode 100644
index 000000000..1e226e83f
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/mmap.h
@@ -0,0 +1,47 @@
+/*
+  This file is part of ethash.
+
+  ethash is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  ethash is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with ethash.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file mmap.h
+ * @author Lefteris Karapetsas <lefteris@ethdev.com>
+ * @date 2015
+ */
+#pragma once
+#if defined(__MINGW32__) || defined(_WIN32)
+#include <sys/types.h>
+
+#define PROT_READ     0x1
+#define PROT_WRITE    0x2
+/* This flag is only available in WinXP+ */
+#ifdef FILE_MAP_EXECUTE
+#define PROT_EXEC     0x4
+#else
+#define PROT_EXEC        0x0
+#define FILE_MAP_EXECUTE 0
+#endif
+
+#define MAP_SHARED    0x01
+#define MAP_PRIVATE   0x02
+#define MAP_ANONYMOUS 0x20
+#define MAP_ANON      MAP_ANONYMOUS
+#define MAP_FAILED    ((void *) -1)
+
+void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset);
+void munmap(void* addr, size_t length);
+#else // posix, yay! ^_^
+#include <sys/mman.h>
+#endif
+
+
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/mmap_win32.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/mmap_win32.c
new file mode 100644
index 000000000..42968b98a
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/mmap_win32.c
@@ -0,0 +1,84 @@
+/* mmap() replacement for Windows
+ *
+ * Author: Mike Frysinger <vapier@gentoo.org>
+ * Placed into the public domain
+ */
+
+/* References:
+ * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
+ * CloseHandle:       http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
+ * MapViewOfFile:     http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
+ * UnmapViewOfFile:   http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
+ */
+
+#include <io.h>
+#include <windows.h>
+#include "mmap.h"
+
+#ifdef __USE_FILE_OFFSET64
+# define DWORD_HI(x) (x >> 32)
+# define DWORD_LO(x) ((x) & 0xffffffff)
+#else
+# define DWORD_HI(x) (0)
+# define DWORD_LO(x) (x)
+#endif
+
+void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset)
+{
+	if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
+		return MAP_FAILED;
+	if (fd == -1) {
+		if (!(flags & MAP_ANON) || offset)
+			return MAP_FAILED;
+	} else if (flags & MAP_ANON)
+		return MAP_FAILED;
+
+	DWORD flProtect;
+	if (prot & PROT_WRITE) {
+		if (prot & PROT_EXEC)
+			flProtect = PAGE_EXECUTE_READWRITE;
+		else
+			flProtect = PAGE_READWRITE;
+	} else if (prot & PROT_EXEC) {
+		if (prot & PROT_READ)
+			flProtect = PAGE_EXECUTE_READ;
+		else if (prot & PROT_EXEC)
+			flProtect = PAGE_EXECUTE;
+	} else
+		flProtect = PAGE_READONLY;
+
+	off_t end = length + offset;
+	HANDLE mmap_fd, h;
+	if (fd == -1)
+		mmap_fd = INVALID_HANDLE_VALUE;
+	else
+		mmap_fd = (HANDLE)_get_osfhandle(fd);
+	h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
+	if (h == NULL)
+		return MAP_FAILED;
+
+	DWORD dwDesiredAccess;
+	if (prot & PROT_WRITE)
+		dwDesiredAccess = FILE_MAP_WRITE;
+	else
+		dwDesiredAccess = FILE_MAP_READ;
+	if (prot & PROT_EXEC)
+		dwDesiredAccess |= FILE_MAP_EXECUTE;
+	if (flags & MAP_PRIVATE)
+		dwDesiredAccess |= FILE_MAP_COPY;
+	void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
+	if (ret == NULL) {
+		ret = MAP_FAILED;
+	}
+	// since we are handling the file ourselves with fd, close the Windows Handle here
+	CloseHandle(h);
+	return ret;
+}
+
+void munmap(void* addr, size_t length)
+{
+	UnmapViewOfFile(addr);
+}
+
+#undef DWORD_HI
+#undef DWORD_LO
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3.c
index 0c28230b8..e72fe1018 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3.c
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3.c
@@ -17,65 +17,65 @@
 
 /*** Constants. ***/
 static const uint8_t rho[24] = \
-  { 1,  3,   6, 10, 15, 21,
-        28, 36, 45, 55,  2, 14,
-        27, 41, 56,  8, 25, 43,
-        62, 18, 39, 61, 20, 44};
+	{ 1,  3,   6, 10, 15, 21,
+	  28, 36, 45, 55,  2, 14,
+	  27, 41, 56,  8, 25, 43,
+	  62, 18, 39, 61, 20, 44};
 static const uint8_t pi[24] = \
-  {10,  7, 11, 17, 18, 3,
-        5, 16,  8, 21, 24, 4,
-        15, 23, 19, 13, 12, 2,
-        20, 14, 22,  9, 6,  1};
+	{10,  7, 11, 17, 18, 3,
+	 5, 16,  8, 21, 24, 4,
+	 15, 23, 19, 13, 12, 2,
+	 20, 14, 22,  9, 6,  1};
 static const uint64_t RC[24] = \
-  {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
-        0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
-        0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
-        0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
-        0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
-        0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
+	{1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
+	 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
+	 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
+	 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
+	 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
+	 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
 
 /*** Helper macros to unroll the permutation. ***/
 #define rol(x, s) (((x) << s) | ((x) >> (64 - s)))
 #define REPEAT6(e) e e e e e e
 #define REPEAT24(e) REPEAT6(e e e e)
 #define REPEAT5(e) e e e e e
-#define FOR5(v, s, e) \
-  v = 0;            \
-  REPEAT5(e; v += s;)
+#define FOR5(v, s, e)							\
+	v = 0;										\
+	REPEAT5(e; v += s;)
 
 /*** Keccak-f[1600] ***/
 static inline void keccakf(void* state) {
-    uint64_t* a = (uint64_t*)state;
-    uint64_t b[5] = {0};
-    uint64_t t = 0;
-    uint8_t x, y;
+	uint64_t* a = (uint64_t*)state;
+	uint64_t b[5] = {0};
+	uint64_t t = 0;
+	uint8_t x, y;
 
-    for (int i = 0; i < 24; i++) {
-        // Theta
-        FOR5(x, 1,
-                b[x] = 0;
-                FOR5(y, 5,
-                        b[x] ^= a[x + y]; ))
-        FOR5(x, 1,
-                FOR5(y, 5,
-                        a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))
-        // Rho and pi
-        t = a[1];
-        x = 0;
-        REPEAT24(b[0] = a[pi[x]];
-                a[pi[x]] = rol(t, rho[x]);
-                t = b[0];
-                x++; )
-        // Chi
-        FOR5(y,
-                5,
-                FOR5(x, 1,
-                        b[x] = a[y + x];)
-                FOR5(x, 1,
-                a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))
-        // Iota
-        a[0] ^= RC[i];
-    }
+	for (int i = 0; i < 24; i++) {
+		// Theta
+		FOR5(x, 1,
+				b[x] = 0;
+				FOR5(y, 5,
+						b[x] ^= a[x + y]; ))
+		FOR5(x, 1,
+				FOR5(y, 5,
+						a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))
+		// Rho and pi
+		t = a[1];
+		x = 0;
+		REPEAT24(b[0] = a[pi[x]];
+				a[pi[x]] = rol(t, rho[x]);
+				t = b[0];
+				x++; )
+		// Chi
+		FOR5(y,
+				5,
+				FOR5(x, 1,
+						b[x] = a[y + x];)
+				FOR5(x, 1,
+				a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))
+		// Iota
+		a[0] ^= RC[i];
+	}
 }
 
 /******** The FIPS202-defined functions. ********/
@@ -83,20 +83,20 @@ static inline void keccakf(void* state) {
 /*** Some helper macros. ***/
 
 #define _(S) do { S } while (0)
-#define FOR(i, ST, L, S) \
-  _(for (size_t i = 0; i < L; i += ST) { S; })
-#define mkapply_ds(NAME, S)                                          \
-  static inline void NAME(uint8_t* dst,                              \
-                          const uint8_t* src,                        \
-                          size_t len) {                              \
-    FOR(i, 1, len, S);                                               \
-  }
-#define mkapply_sd(NAME, S)                                          \
-  static inline void NAME(const uint8_t* src,                        \
-                          uint8_t* dst,                              \
-                          size_t len) {                              \
-    FOR(i, 1, len, S);                                               \
-  }
+#define FOR(i, ST, L, S)							\
+	_(for (size_t i = 0; i < L; i += ST) { S; })
+#define mkapply_ds(NAME, S)						\
+	static inline void NAME(uint8_t* dst,			\
+		const uint8_t* src,						\
+		size_t len) {								\
+		FOR(i, 1, len, S);							\
+	}
+#define mkapply_sd(NAME, S)						\
+	static inline void NAME(const uint8_t* src,	\
+		uint8_t* dst,								\
+		size_t len) {								\
+		FOR(i, 1, len, S);							\
+	}
 
 mkapply_ds(xorin, dst[i] ^= src[i])  // xorin
 mkapply_sd(setout, dst[i] = src[i])  // setout
@@ -105,47 +105,47 @@ mkapply_sd(setout, dst[i] = src[i])  // setout
 #define Plen 200
 
 // Fold P*F over the full blocks of an input.
-#define foldP(I, L, F) \
-  while (L >= rate) {  \
-    F(a, I, rate);     \
-    P(a);              \
-    I += rate;         \
-    L -= rate;         \
-  }
+#define foldP(I, L, F)								\
+	while (L >= rate) {							\
+		F(a, I, rate);								\
+		P(a);										\
+		I += rate;									\
+		L -= rate;									\
+	}
 
 /** The sponge-based hash construction. **/
 static inline int hash(uint8_t* out, size_t outlen,
-        const uint8_t* in, size_t inlen,
-        size_t rate, uint8_t delim) {
-    if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
-        return -1;
-    }
-    uint8_t a[Plen] = {0};
-    // Absorb input.
-    foldP(in, inlen, xorin);
-    // Xor in the DS and pad frame.
-    a[inlen] ^= delim;
-    a[rate - 1] ^= 0x80;
-    // Xor in the last block.
-    xorin(a, in, inlen);
-    // Apply P
-    P(a);
-    // Squeeze output.
-    foldP(out, outlen, setout);
-    setout(a, out, outlen);
-    memset(a, 0, 200);
-    return 0;
+		const uint8_t* in, size_t inlen,
+		size_t rate, uint8_t delim) {
+	if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
+		return -1;
+	}
+	uint8_t a[Plen] = {0};
+	// Absorb input.
+	foldP(in, inlen, xorin);
+	// Xor in the DS and pad frame.
+	a[inlen] ^= delim;
+	a[rate - 1] ^= 0x80;
+	// Xor in the last block.
+	xorin(a, in, inlen);
+	// Apply P
+	P(a);
+	// Squeeze output.
+	foldP(out, outlen, setout);
+	setout(a, out, outlen);
+	memset(a, 0, 200);
+	return 0;
 }
 
-#define defsha3(bits)                                             \
-  int sha3_##bits(uint8_t* out, size_t outlen,                    \
-                  const uint8_t* in, size_t inlen) {              \
-    if (outlen > (bits/8)) {                                      \
-      return -1;                                                  \
-    }                                                             \
-    return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01);  \
-  }
+#define defsha3(bits)													\
+	int sha3_##bits(uint8_t* out, size_t outlen,						\
+		const uint8_t* in, size_t inlen) {								\
+		if (outlen > (bits/8)) {										\
+			return -1;                                                  \
+		}																\
+		return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01);	\
+	}
 
 /*** FIPS202 SHA3 FOFs ***/
 defsha3(256)
-defsha3(512)
\ No newline at end of file
+defsha3(512)
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3.h
index 84dca241b..a38006292 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3.h
@@ -8,22 +8,22 @@ extern "C" {
 #include <stdint.h>
 #include <stdlib.h>
 
-struct ethash_blockhash;
+struct ethash_h256;
 
 #define decsha3(bits) \
-  int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t);
+	int sha3_##bits(uint8_t*, size_t, uint8_t const*, size_t);
 
 decsha3(256)
 decsha3(512)
 
-static inline void SHA3_256(struct ethash_blockhash const* ret, uint8_t const *data, const size_t size)
+static inline void SHA3_256(struct ethash_h256 const* ret, uint8_t const* data, size_t const size)
 {
-    sha3_256((uint8_t*)ret, 32, data, size);
+	sha3_256((uint8_t*)ret, 32, data, size);
 }
 
-static inline void SHA3_512(uint8_t *ret, uint8_t const *data, const size_t size)
+static inline void SHA3_512(uint8_t* ret, uint8_t const* data, size_t const size)
 {
-    sha3_512(ret, 64, data, size);
+	sha3_512(ret, 64, data, size);
 }
 
 #ifdef __cplusplus
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp
index e4d8b1855..2a7c02664 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp
@@ -23,13 +23,15 @@
 #include <cryptopp/sha3.h>
 
 extern "C" {
-struct ethash_blockhash;
-typedef struct ethash_blockhash ethash_blockhash_t;
-void SHA3_256(ethash_blockhash_t const* ret, const uint8_t *data, size_t size) {
-    CryptoPP::SHA3_256().CalculateDigest((uint8_t*)ret, data, size);
+struct ethash_h256;
+typedef struct ethash_h256 ethash_h256_t;
+void SHA3_256(ethash_h256_t const* ret, uint8_t const* data, size_t size)
+{
+	CryptoPP::SHA3_256().CalculateDigest((uint8_t*)ret, data, size);
 }
 
-void SHA3_512(uint8_t *const ret, const uint8_t *data, size_t size) {
-  CryptoPP::SHA3_512().CalculateDigest(ret, data, size);
+void SHA3_512(uint8_t* const ret, uint8_t const* data, size_t size)
+{
+	CryptoPP::SHA3_512().CalculateDigest(ret, data, size);
 }
 }
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.h
index 6b257b87c..9edc407d5 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.h
@@ -8,11 +8,10 @@
 extern "C" {
 #endif
 
-struct ethash_blockhash;
-typedef struct ethash_blockhash ethash_blockhash_t;
+struct ethash_h256;
 
-void SHA3_256(ethash_blockhash_t *const ret, const uint8_t *data, size_t size);
-void SHA3_512(uint8_t *const ret, const uint8_t *data, size_t size);
+void SHA3_256(struct ethash_h256 const* ret, uint8_t const* data, size_t size);
+void SHA3_512(uint8_t* const ret, uint8_t const* data, size_t size);
 
 #ifdef __cplusplus
 }
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util.h b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util.h
index ba8957815..c5fc6e55b 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util.h
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util.h
@@ -27,7 +27,7 @@ extern "C" {
 #endif
 
 #ifdef _MSC_VER
-void debugf(const char *str, ...);
+void debugf(char const* str, ...);
 #else
 #define debugf printf
 #endif
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util_win32.c
similarity index 85%
rename from Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util.c
rename to Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util_win32.c
index fbf268b7d..268e6db05 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util.c
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util_win32.c
@@ -22,20 +22,17 @@
 #include <stdio.h>
 #include "util.h"
 
-#ifdef _MSC_VER
 
 // foward declare without all of Windows.h
-__declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString);
+__declspec(dllimport) void __stdcall OutputDebugStringA(char const* lpOutputString);
 
-void debugf(const char *str, ...)
+void debugf(char const* str, ...)
 {
 	va_list args;
-    va_start(args, str);
+	va_start(args, str);
 
 	char buf[1<<16];
 	_vsnprintf_s(buf, sizeof(buf), sizeof(buf), str, args);
 	buf[sizeof(buf)-1] = '\0';
 	OutputDebugStringA(buf);
 }
-
-#endif
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/src/python/core.c b/Godeps/_workspace/src/github.com/ethereum/ethash/src/python/core.c
index 9024bd584..d77b9761b 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/src/python/core.c
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/src/python/core.c
@@ -13,16 +13,16 @@
 #define PY_CONST_STRING_FORMAT "s"
 #endif
 
-#define MIX_WORDS (MIX_BYTES/4)
+#define MIX_WORDS (ETHASH_MIX_BYTES/4)
 
 static PyObject *
 get_cache_size(PyObject *self, PyObject *args) {
     unsigned long block_number;
     if (!PyArg_ParseTuple(args, "k", &block_number))
         return 0;
-    if (block_number >= EPOCH_LENGTH * 2048) {
+    if (block_number >= ETHASH_EPOCH_LENGTH * 2048) {
         char error_message[1024];
-        sprintf(error_message, "Block number must be less than %i (was %lu)", EPOCH_LENGTH * 2048, block_number);
+        sprintf(error_message, "Block number must be less than %i (was %lu)", ETHASH_EPOCH_LENGTH * 2048, block_number);
 
         PyErr_SetString(PyExc_ValueError, error_message);
         return 0;
@@ -36,9 +36,9 @@ get_full_size(PyObject *self, PyObject *args) {
     unsigned long block_number;
     if (!PyArg_ParseTuple(args, "k", &block_number))
         return 0;
-    if (block_number >= EPOCH_LENGTH * 2048) {
+    if (block_number >= ETHASH_EPOCH_LENGTH * 2048) {
         char error_message[1024];
-        sprintf(error_message, "Block number must be less than %i (was %lu)", EPOCH_LENGTH * 2048, block_number);
+        sprintf(error_message, "Block number must be less than %i (was %lu)", ETHASH_EPOCH_LENGTH * 2048, block_number);
 
         PyErr_SetString(PyExc_ValueError, error_message);
         return 0;
@@ -69,7 +69,7 @@ mkcache_bytes(PyObject *self, PyObject *args) {
     params.cache_size = (size_t) cache_size;
     ethash_cache cache;
     cache.mem = malloc(cache_size);
-    ethash_mkcache(&cache, &params, (ethash_blockhash_t *) seed);
+    ethash_mkcache(&cache, &params, (ethash_h256_t *) seed);
     PyObject * val = Py_BuildValue(PY_STRING_FORMAT, cache.mem, cache_size);
     free(cache.mem);
     return val;
@@ -92,9 +92,9 @@ calc_dataset_bytes(PyObject *self, PyObject *args) {
         return 0;
     }
 
-    if (cache_size % HASH_BYTES != 0) {
+    if (cache_size % ETHASH_HASH_BYTES != 0) {
         char error_message[1024];
-        sprintf(error_message, "The size of the cache must be a multiple of %i bytes (was %i)", HASH_BYTES, cache_size);
+        sprintf(error_message, "The size of the cache must be a multiple of %i bytes (was %i)", ETHASH_HASH_BYTES, cache_size);
         PyErr_SetString(PyExc_ValueError, error_message);
         return 0;
     }
@@ -127,9 +127,9 @@ hashimoto_light(PyObject *self, PyObject *args) {
         PyErr_SetString(PyExc_ValueError, error_message);
         return 0;
     }
-    if (cache_size % HASH_BYTES != 0) {
+    if (cache_size % ETHASH_HASH_BYTES != 0) {
         char error_message[1024];
-        sprintf(error_message, "The size of the cache must be a multiple of %i bytes (was %i)", HASH_BYTES, cache_size);
+        sprintf(error_message, "The size of the cache must be a multiple of %i bytes (was %i)", ETHASH_HASH_BYTES, cache_size);
         PyErr_SetString(PyExc_ValueError, error_message);
         return 0;
     }
@@ -146,7 +146,7 @@ hashimoto_light(PyObject *self, PyObject *args) {
     params.full_size = (size_t) full_size;
     ethash_cache cache;
     cache.mem = (void *) cache_bytes;
-    ethash_light(&out, &cache, &params, (ethash_blockhash_t *) header, nonce);
+    ethash_light(&out, &cache, &params, (ethash_h256_t *) header, nonce);
     return Py_BuildValue("{" PY_CONST_STRING_FORMAT ":" PY_STRING_FORMAT "," PY_CONST_STRING_FORMAT ":" PY_STRING_FORMAT "}",
                          "mix digest", &out.mix_hash, 32,
                          "result", &out.result, 32);
@@ -181,7 +181,7 @@ hashimoto_full(PyObject *self, PyObject *args) {
     ethash_return_value out;
     ethash_params params;
     params.full_size = (size_t) full_size;
-    ethash_full(&out, (void *) full_bytes, &params, (ethash_blockhash_t *) header, nonce);
+    ethash_full(&out, (void *) full_bytes, &params, (ethash_h256_t *) header, nonce);
     return Py_BuildValue("{" PY_CONST_STRING_FORMAT ":" PY_STRING_FORMAT ", " PY_CONST_STRING_FORMAT ":" PY_STRING_FORMAT "}",
                          "mix digest", &out.mix_hash, 32,
                          "result", &out.result, 32);
@@ -227,9 +227,9 @@ mine(PyObject *self, PyObject *args) {
 
     // TODO: Multi threading?
     do {
-        ethash_full(&out, (void *) full_bytes, &params, (const ethash_blockhash_t *) header, nonce++);
+        ethash_full(&out, (void *) full_bytes, &params, (const ethash_h256_t *) header, nonce++);
         // TODO: disagrees with the spec https://github.com/ethereum/wiki/wiki/Ethash#mining
-    } while (!ethash_check_difficulty(&out.result, (const ethash_blockhash_t *) difficulty));
+    } while (!ethash_check_difficulty(&out.result, (const ethash_h256_t *) difficulty));
 
     return Py_BuildValue("{" PY_CONST_STRING_FORMAT ":" PY_STRING_FORMAT ", " PY_CONST_STRING_FORMAT ":" PY_STRING_FORMAT ", " PY_CONST_STRING_FORMAT ":K}",
             "mix digest", &out.mix_hash, 32,
@@ -243,15 +243,14 @@ get_seedhash(PyObject *self, PyObject *args) {
     unsigned long block_number;
     if (!PyArg_ParseTuple(args, "k", &block_number))
         return 0;
-    if (block_number >= EPOCH_LENGTH * 2048) {
+    if (block_number >= ETHASH_EPOCH_LENGTH * 2048) {
         char error_message[1024];
-        sprintf(error_message, "Block number must be less than %i (was %lu)", EPOCH_LENGTH * 2048, block_number);
+        sprintf(error_message, "Block number must be less than %i (was %lu)", ETHASH_EPOCH_LENGTH * 2048, block_number);
 
         PyErr_SetString(PyExc_ValueError, error_message);
         return 0;
     }
-    ethash_blockhash_t seedhash;
-    ethash_get_seedhash(&seedhash, block_number);
+    ethash_h256_t seedhash = ethash_get_seedhash(block_number);
     return Py_BuildValue(PY_STRING_FORMAT, (char *) &seedhash, 32);
 }
 
@@ -306,17 +305,17 @@ static struct PyModuleDef PyethashModule = {
 PyMODINIT_FUNC PyInit_pyethash(void) {
     PyObject *module =  PyModule_Create(&PyethashModule);
     // Following Spec: https://github.com/ethereum/wiki/wiki/Ethash#definitions
-    PyModule_AddIntConstant(module, "REVISION", (long) REVISION);
-    PyModule_AddIntConstant(module, "DATASET_BYTES_INIT", (long) DATASET_BYTES_INIT);
-    PyModule_AddIntConstant(module, "DATASET_BYTES_GROWTH", (long) DATASET_BYTES_GROWTH);
-    PyModule_AddIntConstant(module, "CACHE_BYTES_INIT", (long) CACHE_BYTES_INIT);
-    PyModule_AddIntConstant(module, "CACHE_BYTES_GROWTH", (long) CACHE_BYTES_GROWTH);
-    PyModule_AddIntConstant(module, "EPOCH_LENGTH", (long) EPOCH_LENGTH);
-    PyModule_AddIntConstant(module, "MIX_BYTES", (long) MIX_BYTES);
-    PyModule_AddIntConstant(module, "HASH_BYTES", (long) HASH_BYTES);
-    PyModule_AddIntConstant(module, "DATASET_PARENTS", (long) DATASET_PARENTS);
-    PyModule_AddIntConstant(module, "CACHE_ROUNDS", (long) CACHE_ROUNDS);
-    PyModule_AddIntConstant(module, "ACCESSES", (long) ACCESSES);
+    PyModule_AddIntConstant(module, "REVISION", (long) ETHASH_REVISION);
+    PyModule_AddIntConstant(module, "DATASET_BYTES_INIT", (long) ETHASH_DATASET_BYTES_INIT);
+    PyModule_AddIntConstant(module, "DATASET_BYTES_GROWTH", (long) ETHASH_DATASET_BYTES_GROWTH);
+    PyModule_AddIntConstant(module, "CACHE_BYTES_INIT", (long) ETHASH_CACHE_BYTES_INIT);
+    PyModule_AddIntConstant(module, "CACHE_BYTES_GROWTH", (long) ETHASH_CACHE_BYTES_GROWTH);
+    PyModule_AddIntConstant(module, "EPOCH_LENGTH", (long) ETHASH_EPOCH_LENGTH);
+    PyModule_AddIntConstant(module, "MIX_BYTES", (long) ETHASH_MIX_BYTES);
+    PyModule_AddIntConstant(module, "HASH_BYTES", (long) ETHASH_HASH_BYTES);
+    PyModule_AddIntConstant(module, "DATASET_PARENTS", (long) ETHASH_DATASET_PARENTS);
+    PyModule_AddIntConstant(module, "CACHE_ROUNDS", (long) ETHASH_CACHE_ROUNDS);
+    PyModule_AddIntConstant(module, "ACCESSES", (long) ETHASH_ACCESSES);
     return module;
 }
 #else
@@ -324,16 +323,16 @@ PyMODINIT_FUNC
 initpyethash(void) {
     PyObject *module = Py_InitModule("pyethash", PyethashMethods);
     // Following Spec: https://github.com/ethereum/wiki/wiki/Ethash#definitions
-    PyModule_AddIntConstant(module, "REVISION", (long) REVISION);
-    PyModule_AddIntConstant(module, "DATASET_BYTES_INIT", (long) DATASET_BYTES_INIT);
-    PyModule_AddIntConstant(module, "DATASET_BYTES_GROWTH", (long) DATASET_BYTES_GROWTH);
-    PyModule_AddIntConstant(module, "CACHE_BYTES_INIT", (long) CACHE_BYTES_INIT);
-    PyModule_AddIntConstant(module, "CACHE_BYTES_GROWTH", (long) CACHE_BYTES_GROWTH);
-    PyModule_AddIntConstant(module, "EPOCH_LENGTH", (long) EPOCH_LENGTH);
-    PyModule_AddIntConstant(module, "MIX_BYTES", (long) MIX_BYTES);
-    PyModule_AddIntConstant(module, "HASH_BYTES", (long) HASH_BYTES);
-    PyModule_AddIntConstant(module, "DATASET_PARENTS", (long) DATASET_PARENTS);
-    PyModule_AddIntConstant(module, "CACHE_ROUNDS", (long) CACHE_ROUNDS);
-    PyModule_AddIntConstant(module, "ACCESSES", (long) ACCESSES);
+    PyModule_AddIntConstant(module, "REVISION", (long) ETHASH_REVISION);
+    PyModule_AddIntConstant(module, "DATASET_BYTES_INIT", (long) ETHASH_DATASET_BYTES_INIT);
+    PyModule_AddIntConstant(module, "DATASET_BYTES_GROWTH", (long) ETHASH_DATASET_BYTES_GROWTH);
+    PyModule_AddIntConstant(module, "CACHE_BYTES_INIT", (long) ETHASH_CACHE_BYTES_INIT);
+    PyModule_AddIntConstant(module, "CACHE_BYTES_GROWTH", (long) ETHASH_CACHE_BYTES_GROWTH);
+    PyModule_AddIntConstant(module, "EPOCH_LENGTH", (long) ETHASH_EPOCH_LENGTH);
+    PyModule_AddIntConstant(module, "MIX_BYTES", (long) ETHASH_MIX_BYTES);
+    PyModule_AddIntConstant(module, "HASH_BYTES", (long) ETHASH_HASH_BYTES);
+    PyModule_AddIntConstant(module, "DATASET_PARENTS", (long) ETHASH_DATASET_PARENTS);
+    PyModule_AddIntConstant(module, "CACHE_ROUNDS", (long) ETHASH_CACHE_ROUNDS);
+    PyModule_AddIntConstant(module, "ACCESSES", (long) ETHASH_ACCESSES);
 }
 #endif
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/CMakeLists.txt b/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/CMakeLists.txt
index dd91d8a92..f94531c3d 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/CMakeLists.txt
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/CMakeLists.txt
@@ -27,13 +27,16 @@ IF( NOT Boost_FOUND )
     find_package(Boost 1.48.0 COMPONENTS unit_test_framework system filesystem)
 ENDIF()
 
-IF( Boost_FOUND )
+IF (Boost_FOUND)
+    message(STATUS "boost header: ${Boost_INCLUDE_DIRS}")
+    message(STATUS "boost libs  : ${Boost_LIBRARIES}")
+
     include_directories( ${Boost_INCLUDE_DIR} )
     include_directories(../../src)
 
-    link_directories ( ${Boost_LIBRARY_DIRS} )
+    link_directories(${Boost_LIBRARY_DIRS})
     file(GLOB HEADERS "*.h")
-    if (NOT MSVC)
+    if ((NOT MSVC) AND (NOT APPLE))
         ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK)
     endif()
     if (NOT CRYPTOPP_FOUND)
@@ -48,11 +51,11 @@ IF( Boost_FOUND )
         set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -std=c++11 ")
    endif()
 
-    add_executable (Test test.cpp ${HEADERS})
+    add_executable (Test "./test.cpp" ${HEADERS})
     target_link_libraries(Test ${ETHHASH_LIBS})
     target_link_libraries(Test ${Boost_FILESYSTEM_LIBRARIES})
     target_link_libraries(Test ${Boost_SYSTEM_LIBRARIES})
-    target_link_libraries (Test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+    target_link_libraries(Test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
 
     if (CRYPTOPP_FOUND)
         TARGET_LINK_LIBRARIES(Test ${CRYPTOPP_LIBRARIES})
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp b/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp
index ffe8d53f3..55fe02316 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp
@@ -12,6 +12,11 @@
 #include <libethash/sha3.h>
 #endif // WITH_CRYPTOPP
 
+#ifdef _WIN32
+#include <windows.h>
+#include <Shlobj.h>
+#endif
+
 #define BOOST_TEST_MODULE Daggerhashimoto
 #define BOOST_TEST_MAIN
 
@@ -22,367 +27,609 @@
 #include <boost/test/unit_test.hpp>
 
 using namespace std;
+using byte = uint8_t;
+using bytes = std::vector<byte>;
 namespace fs = boost::filesystem;
 
 // Just an alloca "wrapper" to silence uint64_t to size_t conversion warnings in windows
 // consider replacing alloca calls with something better though!
 #define our_alloca(param__) alloca((size_t)(param__))
 
-std::string bytesToHexString(const uint8_t *str, const uint64_t s) {
-    std::ostringstream ret;
 
-    for (size_t i = 0; i < s; ++i)
-        ret << std::hex << std::setfill('0') << std::setw(2) << std::nouppercase << (int) str[i];
+// some functions taken from eth::dev for convenience.
+std::string bytesToHexString(const uint8_t *str, const uint64_t s)
+{
+	std::ostringstream ret;
+
+	for (size_t i = 0; i < s; ++i)
+		ret << std::hex << std::setfill('0') << std::setw(2) << std::nouppercase << (int) str[i];
+
+	return ret.str();
+}
+
+std::string blockhashToHexString(ethash_h256_t* _hash)
+{
+	return bytesToHexString((uint8_t*)_hash, 32);
+}
 
-    return ret.str();
+int fromHex(char _i)
+{
+	if (_i >= '0' && _i <= '9')
+		return _i - '0';
+	if (_i >= 'a' && _i <= 'f')
+		return _i - 'a' + 10;
+	if (_i >= 'A' && _i <= 'F')
+		return _i - 'A' + 10;
+
+	BOOST_REQUIRE_MESSAGE(false, "should never get here");
+	return -1;
 }
 
-std::string blockhashToHexString(ethash_blockhash_t *hash) {
-    return bytesToHexString((uint8_t*)hash, 32);
+bytes hexStringToBytes(std::string const& _s)
+{
+	unsigned s = (_s[0] == '0' && _s[1] == 'x') ? 2 : 0;
+	std::vector<uint8_t> ret;
+	ret.reserve((_s.size() - s + 1) / 2);
+
+	if (_s.size() % 2)
+		try
+		{
+			ret.push_back(fromHex(_s[s++]));
+		}
+		catch (...)
+		{
+			ret.push_back(0);
+		}
+	for (unsigned i = s; i < _s.size(); i += 2)
+		try
+		{
+			ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1])));
+		}
+		catch (...){
+			ret.push_back(0);
+		}
+	return ret;
 }
 
+ethash_h256_t stringToBlockhash(std::string const& _s)
+{
+	ethash_h256_t ret;
+	bytes b = hexStringToBytes(_s);
+	memcpy(&ret, b.data(), b.size());
+	return ret;
+}
+
+
+
 BOOST_AUTO_TEST_CASE(fnv_hash_check) {
-    uint32_t x = 1235U;
-    const uint32_t
-            y = 9999999U,
-            expected = (FNV_PRIME * x) ^y;
+	uint32_t x = 1235U;
+	const uint32_t
+			y = 9999999U,
+			expected = (FNV_PRIME * x) ^y;
 
-    x = fnv_hash(x, y);
+	x = fnv_hash(x, y);
 
-    BOOST_REQUIRE_MESSAGE(x == expected,
-            "\nexpected: " << expected << "\n"
-                    << "actual: " << x << "\n");
+	BOOST_REQUIRE_MESSAGE(x == expected,
+			"\nexpected: " << expected << "\n"
+					<< "actual: " << x << "\n");
 
 }
 
 BOOST_AUTO_TEST_CASE(SHA256_check) {
-    ethash_blockhash_t input;
-    ethash_blockhash_t out;
-    memcpy(&input, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
-    SHA3_256(&out, (uint8_t*)&input, 32);
-    const std::string
-            expected = "2b5ddf6f4d21c23de216f44d5e4bdc68e044b71897837ea74c83908be7037cd7",
-        actual = bytesToHexString((uint8_t*)&out, 32);
-    BOOST_REQUIRE_MESSAGE(expected == actual,
-            "\nexpected: " << expected.c_str() << "\n"
-                    << "actual: " << actual.c_str() << "\n");
+	ethash_h256_t input;
+	ethash_h256_t out;
+	memcpy(&input, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+	SHA3_256(&out, (uint8_t*)&input, 32);
+	const std::string
+			expected = "2b5ddf6f4d21c23de216f44d5e4bdc68e044b71897837ea74c83908be7037cd7",
+		actual = bytesToHexString((uint8_t*)&out, 32);
+	BOOST_REQUIRE_MESSAGE(expected == actual,
+			"\nexpected: " << expected.c_str() << "\n"
+					<< "actual: " << actual.c_str() << "\n");
 }
 
 BOOST_AUTO_TEST_CASE(SHA512_check) {
-    uint8_t input[64], out[64];
-    memcpy(input, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 64);
-    SHA3_512(out, input, 64);
-    const std::string
-            expected = "0be8a1d334b4655fe58c6b38789f984bb13225684e86b20517a55ab2386c7b61c306f25e0627c60064cecd6d80cd67a82b3890bd1289b7ceb473aad56a359405",
-            actual = bytesToHexString(out, 64);
-    BOOST_REQUIRE_MESSAGE(expected == actual,
-            "\nexpected: " << expected.c_str() << "\n"
-                    << "actual: " << actual.c_str() << "\n");
+	uint8_t input[64], out[64];
+	memcpy(input, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 64);
+	SHA3_512(out, input, 64);
+	const std::string
+			expected = "0be8a1d334b4655fe58c6b38789f984bb13225684e86b20517a55ab2386c7b61c306f25e0627c60064cecd6d80cd67a82b3890bd1289b7ceb473aad56a359405",
+			actual = bytesToHexString(out, 64);
+	BOOST_REQUIRE_MESSAGE(expected == actual,
+			"\nexpected: " << expected.c_str() << "\n"
+					<< "actual: " << actual.c_str() << "\n");
+}
+
+BOOST_AUTO_TEST_CASE(test_swap_endian32) {
+	uint32_t v32 = (uint32_t)0xBAADF00D;
+	v32 = ethash_swap_u32(v32);
+	BOOST_REQUIRE_EQUAL(v32, (uint32_t)0x0DF0ADBA);
+}
+
+BOOST_AUTO_TEST_CASE(test_swap_endian64) {
+	uint64_t v64 = (uint64_t)0xFEE1DEADDEADBEEF;
+	v64 = ethash_swap_u64(v64);
+	BOOST_REQUIRE_EQUAL(v64, (uint64_t)0xEFBEADDEADDEE1FE);
 }
 
 BOOST_AUTO_TEST_CASE(ethash_params_init_genesis_check) {
-    ethash_params params;
-    ethash_params_init(&params, 0);
-    BOOST_REQUIRE_MESSAGE(params.full_size < DATASET_BYTES_INIT,
-            "\nfull size: " << params.full_size << "\n"
-                    << "should be less than or equal to: " << DATASET_BYTES_INIT << "\n");
-    BOOST_REQUIRE_MESSAGE(params.full_size + 20 * MIX_BYTES >= DATASET_BYTES_INIT,
-            "\nfull size + 20*MIX_BYTES: " << params.full_size + 20 * MIX_BYTES << "\n"
-                    << "should be greater than or equal to: " << DATASET_BYTES_INIT << "\n");
-    BOOST_REQUIRE_MESSAGE(params.cache_size < DATASET_BYTES_INIT / 32,
-            "\ncache size: " << params.cache_size << "\n"
-                    << "should be less than or equal to: " << DATASET_BYTES_INIT / 32 << "\n");
+	uint64_t full_size = ethash_get_datasize(0);
+	uint64_t cache_size = ethash_get_cachesize(0);
+	BOOST_REQUIRE_MESSAGE(full_size < ETHASH_DATASET_BYTES_INIT,
+			"\nfull size: " << full_size << "\n"
+					<< "should be less than or equal to: " << ETHASH_DATASET_BYTES_INIT << "\n");
+	BOOST_REQUIRE_MESSAGE(full_size + 20 * ETHASH_MIX_BYTES >= ETHASH_DATASET_BYTES_INIT,
+			"\nfull size + 20*MIX_BYTES: " << full_size + 20 * ETHASH_MIX_BYTES << "\n"
+					<< "should be greater than or equal to: " << ETHASH_DATASET_BYTES_INIT << "\n");
+	BOOST_REQUIRE_MESSAGE(cache_size < ETHASH_DATASET_BYTES_INIT / 32,
+			"\ncache size: " << cache_size << "\n"
+					<< "should be less than or equal to: " << ETHASH_DATASET_BYTES_INIT / 32 << "\n");
 }
 
 BOOST_AUTO_TEST_CASE(ethash_params_init_genesis_calcifide_check) {
-    ethash_params params;
-    ethash_params_init(&params, 0);
-    const uint32_t expected_full_size = 1073739904;
-    const uint32_t expected_cache_size = 16776896;
-    BOOST_REQUIRE_MESSAGE(params.full_size == expected_full_size,
-            "\nexpected: " << expected_cache_size << "\n"
-                    << "actual: " << params.full_size << "\n");
-    BOOST_REQUIRE_MESSAGE(params.cache_size == expected_cache_size,
-            "\nexpected: " << expected_cache_size << "\n"
-                    << "actual: " << params.cache_size << "\n");
+	uint64_t full_size = ethash_get_datasize(0);
+	uint64_t cache_size = ethash_get_cachesize(0);
+	const uint32_t expected_full_size = 1073739904;
+	const uint32_t expected_cache_size = 16776896;
+	BOOST_REQUIRE_MESSAGE(full_size == expected_full_size,
+			"\nexpected: " << expected_cache_size << "\n"
+					<< "actual: " << full_size << "\n");
+	BOOST_REQUIRE_MESSAGE(cache_size == expected_cache_size,
+			"\nexpected: " << expected_cache_size << "\n"
+					<< "actual: " << cache_size << "\n");
 }
 
-BOOST_AUTO_TEST_CASE(light_and_full_client_checks) {
-    ethash_params params;
-    ethash_blockhash_t seed;
-    ethash_blockhash_t hash;
-    ethash_blockhash_t difficulty;
-    ethash_return_value light_out;
-    ethash_return_value full_out;
-    memcpy(&seed, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
-    memcpy(&hash, "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
-
-    // Set the difficulty
-    ethash_blockhash_set(&difficulty, 0, 197);
-    ethash_blockhash_set(&difficulty, 1, 90);
-    for (int i = 2; i < 32; i++)
-        ethash_blockhash_set(&difficulty, i, 255);
-
-    ethash_params_init(&params, 0);
-    params.cache_size = 1024;
-    params.full_size = 1024 * 32;
-    ethash_cache cache;
-    cache.mem = our_alloca(params.cache_size);
-    ethash_mkcache(&cache, &params, &seed);
-    node *full_mem = (node *) our_alloca(params.full_size);
-    ethash_compute_full_data(full_mem, &params, &cache);
-
-    {
-        const std::string
-                expected = "2da2b506f21070e1143d908e867962486d6b0a02e31d468fd5e3a7143aafa76a14201f63374314e2a6aaf84ad2eb57105dea3378378965a1b3873453bb2b78f9a8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995c259440b89fa3481c2c33171477c305c8e1e421f8d8f6d59585449d0034f3e421808d8da6bbd0b6378f567647cc6c4ba6c434592b198ad444e7284905b7c6adaf70bf43ec2daa7bd5e8951aa609ab472c124cf9eba3d38cff5091dc3f58409edcc386c743c3bd66f92408796ee1e82dd149eaefbf52b00ce33014a6eb3e50625413b072a58bc01da28262f42cbe4f87d4abc2bf287d15618405a1fe4e386fcdafbb171064bd99901d8f81dd6789396ce5e364ac944bbbd75a7827291c70b42d26385910cd53ca535ab29433dd5c5714d26e0dce95514c5ef866329c12e958097e84462197c2b32087849dab33e88b11da61d52f9dbc0b92cc61f742c07dbbf751c49d7678624ee60dfbe62e5e8c47a03d8247643f3d16ad8c8e663953bcda1f59d7e2d4a9bf0768e789432212621967a8f41121ad1df6ae1fa78782530695414c6213942865b2730375019105cae91a4c17a558d4b63059661d9f108362143107babe0b848de412e4da59168cce82bfbff3c99e022dd6ac1e559db991f2e3f7bb910cefd173e65ed00a8d5d416534e2c8416ff23977dbf3eb7180b75c71580d08ce95efeb9b0afe904ea12285a392aff0c8561ff79fca67f694a62b9e52377485c57cc3598d84cac0a9d27960de0cc31ff9bbfe455acaa62c8aa5d2cce96f345da9afe843d258a99c4eaf3650fc62efd81c7b81cd0d534d2d71eeda7a6e315d540b4473c80f8730037dc2ae3e47b986240cfc65ccc565f0d8cde0bc68a57e39a271dda57440b3598bee19f799611d25731a96b5dbbbefdff6f4f656161462633030d62560ea4e9c161cf78fc96a2ca5aaa32453a6c5dea206f766244e8c9d9a8dc61185ce37f1fc804459c5f07434f8ecb34141b8dcae7eae704c950b55556c5f40140c3714b45eddb02637513268778cbf937a33e4e33183685f9deb31ef54e90161e76d969587dd782eaa94e289420e7c2ee908517f5893a26fdb5873d68f92d118d4bcf98d7a4916794d6ab290045e30f9ea00ca547c584b8482b0331ba1539a0f2714fddc3a0b06b0cfbb6a607b8339c39bcfd6640b1f653e9d70ef6c985b",
-                actual = bytesToHexString((uint8_t const *) cache.mem, params.cache_size);
-
-        BOOST_REQUIRE_MESSAGE(expected == actual,
-                "\nexpected: " << expected.c_str() << "\n"
-                        << "actual: " << actual.c_str() << "\n");
-    }
-
-
-    {
-        node node;
-        ethash_calculate_dag_item(&node, 0, &params, &cache);
-        const std::string
-                actual = bytesToHexString((uint8_t const *) &node, sizeof(node)),
-                expected = "b1698f829f90b35455804e5185d78f549fcb1bdce2bee006d4d7e68eb154b596be1427769eb1c3c3e93180c760af75f81d1023da6a0ffbe321c153a7c0103597";
-        BOOST_REQUIRE_MESSAGE(actual == expected,
-                "\n" << "expected: " << expected.c_str() << "\n"
-                        << "actual: " << actual.c_str() << "\n");
-    }
-
-    {
-        for (int i = 0; i < params.full_size / sizeof(node); ++i) {
-            for (uint32_t j = 0; j < 32; ++j) {
-                node expected_node;
-                ethash_calculate_dag_item(&expected_node, j, &params, &cache);
-                const std::string
-                        actual = bytesToHexString((uint8_t const *) &(full_mem[j]), sizeof(node)),
-                        expected = bytesToHexString((uint8_t const *) &expected_node, sizeof(node));
-                BOOST_REQUIRE_MESSAGE(actual == expected,
-                        "\ni: " << j << "\n"
-                                << "expected: " << expected.c_str() << "\n"
-                                << "actual: " << actual.c_str() << "\n");
-            }
-        }
-    }
-
-    {
-        uint64_t nonce = 0x7c7c597c;
-        ethash_full(&full_out, full_mem, &params, &hash, nonce);
-        ethash_light(&light_out, &cache, &params, &hash, nonce);
-        const std::string
-                light_result_string = blockhashToHexString(&light_out.result),
-                full_result_string = blockhashToHexString(&full_out.result);
-        BOOST_REQUIRE_MESSAGE(light_result_string == full_result_string,
-                "\nlight result: " << light_result_string.c_str() << "\n"
-                        << "full result: " << full_result_string.c_str() << "\n");
-        const std::string
-                light_mix_hash_string = blockhashToHexString(&light_out.mix_hash),
-                full_mix_hash_string = blockhashToHexString(&full_out.mix_hash);
-        BOOST_REQUIRE_MESSAGE(full_mix_hash_string == light_mix_hash_string,
-                "\nlight mix hash: " << light_mix_hash_string.c_str() << "\n"
-                        << "full mix hash: " << full_mix_hash_string.c_str() << "\n");
-        ethash_blockhash_t check_hash;
-        ethash_quick_hash(&check_hash, &hash, nonce, &full_out.mix_hash);
-        const std::string check_hash_string = blockhashToHexString(&check_hash);
-        BOOST_REQUIRE_MESSAGE(check_hash_string == full_result_string,
-                "\ncheck hash string: " << check_hash_string.c_str() << "\n"
-                        << "full result: " << full_result_string.c_str() << "\n");
-    }
-    {
-        ethash_full(&full_out, full_mem, &params, &hash, 5);
-        std::string
-                light_result_string = blockhashToHexString(&light_out.result),
-                full_result_string = blockhashToHexString(&full_out.result);
-
-        BOOST_REQUIRE_MESSAGE(light_result_string != full_result_string,
-                "\nlight result and full result should differ: " << light_result_string.c_str() << "\n");
-
-        ethash_light(&light_out, &cache, &params, &hash, 5);
-        light_result_string = blockhashToHexString(&light_out.result);
-        BOOST_REQUIRE_MESSAGE(light_result_string == full_result_string,
-                "\nlight result and full result should be the same\n"
-                        << "light result: " << light_result_string.c_str() << "\n"
-                        << "full result: " << full_result_string.c_str() << "\n");
-        std::string
-                light_mix_hash_string = blockhashToHexString(&light_out.mix_hash),
-                full_mix_hash_string = blockhashToHexString(&full_out.mix_hash);
-        BOOST_REQUIRE_MESSAGE(full_mix_hash_string == light_mix_hash_string,
-                "\nlight mix hash: " << light_mix_hash_string.c_str() << "\n"
-                        << "full mix hash: " << full_mix_hash_string.c_str() << "\n");
-        BOOST_REQUIRE_MESSAGE(ethash_check_difficulty(&full_out.result, &difficulty),
-                "ethash_check_difficulty failed"
-        );
-        BOOST_REQUIRE_MESSAGE(ethash_quick_check_difficulty(&hash, 5U, &full_out.mix_hash, &difficulty),
-                "ethash_quick_check_difficulty failed"
-        );
-    }
+BOOST_AUTO_TEST_CASE(ethash_check_difficulty_check) {
+	ethash_h256_t hash;
+	ethash_h256_t target;
+	memcpy(&hash, "11111111111111111111111111111111", 32);
+	memcpy(&target, "22222222222222222222222222222222", 32);
+	BOOST_REQUIRE_MESSAGE(
+			ethash_check_difficulty(&hash, &target),
+			"\nexpected \"" << std::string((char *) &hash, 32).c_str() << "\" to have the same or less difficulty than \"" << std::string((char *) &target, 32).c_str() << "\"\n");
+	BOOST_REQUIRE_MESSAGE(
+		ethash_check_difficulty(&hash, &hash), "");
+			// "\nexpected \"" << hash << "\" to have the same or less difficulty than \"" << hash << "\"\n");
+	memcpy(&target, "11111111111111111111111111111112", 32);
+	BOOST_REQUIRE_MESSAGE(
+		ethash_check_difficulty(&hash, &target), "");
+			// "\nexpected \"" << hash << "\" to have the same or less difficulty than \"" << target << "\"\n");
+	memcpy(&target, "11111111111111111111111111111110", 32);
+	BOOST_REQUIRE_MESSAGE(
+			!ethash_check_difficulty(&hash, &target), "");
+			// "\nexpected \"" << hash << "\" to have more difficulty than \"" << target << "\"\n");
 }
 
-BOOST_AUTO_TEST_CASE(ethash_check_difficulty_check) {
-    ethash_blockhash_t hash;
-    ethash_blockhash_t target;
-    memcpy(&hash, "11111111111111111111111111111111", 32);
-    memcpy(&target, "22222222222222222222222222222222", 32);
-    BOOST_REQUIRE_MESSAGE(
-            ethash_check_difficulty(&hash, &target),
-            "\nexpected \"" << std::string((char *) &hash, 32).c_str() << "\" to have the same or less difficulty than \"" << std::string((char *) &target, 32).c_str() << "\"\n");
-    BOOST_REQUIRE_MESSAGE(
-        ethash_check_difficulty(&hash, &hash), "");
-            // "\nexpected \"" << hash << "\" to have the same or less difficulty than \"" << hash << "\"\n");
-    memcpy(&target, "11111111111111111111111111111112", 32);
-    BOOST_REQUIRE_MESSAGE(
-        ethash_check_difficulty(&hash, &target), "");
-            // "\nexpected \"" << hash << "\" to have the same or less difficulty than \"" << target << "\"\n");
-    memcpy(&target, "11111111111111111111111111111110", 32);
-    BOOST_REQUIRE_MESSAGE(
-            !ethash_check_difficulty(&hash, &target), "");
-            // "\nexpected \"" << hash << "\" to have more difficulty than \"" << target << "\"\n");
+BOOST_AUTO_TEST_CASE(test_ethash_io_mutable_name) {
+	char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
+	// should have at least 8 bytes provided since this is what we test :)
+	ethash_h256_t seed1 = ethash_h256_static_init(0, 10, 65, 255, 34, 55, 22, 8);
+	ethash_io_mutable_name(1, &seed1, mutable_name);
+	BOOST_REQUIRE_EQUAL(0, strcmp(mutable_name, "1_000a41ff22371608"));
+	ethash_h256_t seed2 = ethash_h256_static_init(0, 0, 0, 0, 0, 0, 0, 0);
+	ethash_io_mutable_name(44, &seed2, mutable_name);
+	BOOST_REQUIRE_EQUAL(0, strcmp(mutable_name, "44_0000000000000000"));
 }
 
 BOOST_AUTO_TEST_CASE(test_ethash_dir_creation) {
-    ethash_blockhash_t seedhash;
-    memset(&seedhash, 0, 32);
-    BOOST_REQUIRE_EQUAL(
-        ETHASH_IO_MEMO_MISMATCH,
-        ethash_io_prepare("./test_ethash_directory/", seedhash)
-    );
-
-    // let's make sure that the directory was created
-    BOOST_REQUIRE(fs::is_directory(fs::path("./test_ethash_directory/")));
-
-    // cleanup
-    fs::remove_all("./test_ethash_directory/");
+	ethash_h256_t seedhash;
+	FILE *f = NULL;
+	memset(&seedhash, 0, 32);
+	BOOST_REQUIRE_EQUAL(
+		ETHASH_IO_MEMO_MISMATCH,
+		ethash_io_prepare("./test_ethash_directory/", seedhash, &f, 64, false)
+	);
+	BOOST_REQUIRE(f);
+
+	// let's make sure that the directory was created
+	BOOST_REQUIRE(fs::is_directory(fs::path("./test_ethash_directory/")));
+
+	// cleanup
+	fclose(f);
+	fs::remove_all("./test_ethash_directory/");
+}
+
+BOOST_AUTO_TEST_CASE(test_ethash_io_memo_file_match) {
+	uint64_t full_size;
+	uint64_t cache_size;
+	ethash_h256_t seed;
+	ethash_h256_t hash;
+	FILE* f;
+	memcpy(&seed, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+	memcpy(&hash, "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+
+	cache_size = 1024;
+	full_size = 1024 * 32;
+
+	ethash_light_t light = ethash_light_new_internal(cache_size, &seed);
+	ethash_full_t full = ethash_full_new_internal(
+		"./test_ethash_directory/",
+		seed,
+		full_size,
+		light,
+		NULL
+	);
+	BOOST_ASSERT(full);
+	// let's make sure that the directory was created
+	BOOST_REQUIRE(fs::is_directory(fs::path("./test_ethash_directory/")));
+	// delete the full here so that memory is properly unmapped and FILE handler freed
+	ethash_full_delete(full);
+	// and check that we have a match when checking again
+	BOOST_REQUIRE_EQUAL(
+		ETHASH_IO_MEMO_MATCH,
+		ethash_io_prepare("./test_ethash_directory/", seed, &f, full_size, false)
+	);
+	BOOST_REQUIRE(f);
+
+	// cleanup
+	fclose(f);
+	ethash_light_delete(light);
+	fs::remove_all("./test_ethash_directory/");
 }
 
-BOOST_AUTO_TEST_CASE(test_ethash_io_write_files_are_created) {
-    ethash_blockhash_t seedhash;
-    static const int blockn = 0;
-    ethash_get_seedhash(&seedhash, blockn);
-    BOOST_REQUIRE_EQUAL(
-        ETHASH_IO_MEMO_MISMATCH,
-        ethash_io_prepare("./test_ethash_directory/", seedhash)
-    );
-
- // let's make sure that the directory was created
-    BOOST_REQUIRE(fs::is_directory(fs::path("./test_ethash_directory/")));
-
-    ethash_cache cache;
-    ethash_params params;
-    uint8_t *data;
-    uint64_t size;
-    ethash_params_init(&params, blockn);
-    params.cache_size = 1024;
-    params.full_size = 1024 * 32;
-    cache.mem = our_alloca(params.cache_size);
-    ethash_mkcache(&cache, &params, &seedhash);
-
-    BOOST_REQUIRE(
-        ethash_io_write("./test_ethash_directory/", &params, seedhash, &cache, &data, &size)
-    );
-
-    BOOST_REQUIRE(fs::exists(fs::path("./test_ethash_directory/full")));
-    BOOST_REQUIRE(fs::exists(fs::path("./test_ethash_directory/full.info")));
-
-    // cleanup
-    fs::remove_all("./test_ethash_directory/");
-    free(data);
+BOOST_AUTO_TEST_CASE(test_ethash_io_memo_file_size_mismatch) {
+	static const int blockn = 0;
+	ethash_h256_t seedhash = ethash_get_seedhash(blockn);
+	FILE *f = NULL;
+	BOOST_REQUIRE_EQUAL(
+		ETHASH_IO_MEMO_MISMATCH,
+		ethash_io_prepare("./test_ethash_directory/", seedhash, &f, 64, false)
+	);
+	BOOST_REQUIRE(f);
+	fclose(f);
+
+	// let's make sure that the directory was created
+	BOOST_REQUIRE(fs::is_directory(fs::path("./test_ethash_directory/")));
+	// and check that we get the size mismatch detected if we request diffferent size
+	BOOST_REQUIRE_EQUAL(
+		ETHASH_IO_MEMO_SIZE_MISMATCH,
+		ethash_io_prepare("./test_ethash_directory/", seedhash, &f, 65, false)
+	);
+
+	// cleanup
+	fs::remove_all("./test_ethash_directory/");
 }
 
-BOOST_AUTO_TEST_CASE(test_ethash_io_memo_file_match) {
-    ethash_blockhash_t seedhash;
-    static const int blockn = 0;
-    ethash_get_seedhash(&seedhash, blockn);
-    BOOST_REQUIRE_EQUAL(
-        ETHASH_IO_MEMO_MISMATCH,
-        ethash_io_prepare("./test_ethash_directory/", seedhash)
-    );
-
-    // let's make sure that the directory was created
-    BOOST_REQUIRE(fs::is_directory(fs::path("./test_ethash_directory/")));
-
-    ethash_cache cache;
-    ethash_params params;
-    uint8_t *data;
-    uint64_t size;
-    ethash_params_init(&params, blockn);
-    params.cache_size = 1024;
-    params.full_size = 1024 * 32;
-    cache.mem = our_alloca(params.cache_size);
-    ethash_mkcache(&cache, &params, &seedhash);
-
-    BOOST_REQUIRE(
-        ethash_io_write("./test_ethash_directory/", &params, seedhash, &cache, &data, &size)
-    );
-
-    BOOST_REQUIRE(fs::exists(fs::path("./test_ethash_directory/full")));
-    BOOST_REQUIRE(fs::exists(fs::path("./test_ethash_directory/full.info")));
-
-    BOOST_REQUIRE_EQUAL(
-        ETHASH_IO_MEMO_MATCH,
-        ethash_io_prepare("./test_ethash_directory/", seedhash)
-    );
-
-    // cleanup
-    fs::remove_all("./test_ethash_directory/");
-    free(data);
+BOOST_AUTO_TEST_CASE(test_ethash_get_default_dirname) {
+	char result[256];
+	// this is really not an easy thing to test for in a unit test, so yeah it does look ugly
+#ifdef _WIN32
+	char homedir[256];
+	BOOST_REQUIRE(SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, (WCHAR*)homedir)));
+	BOOST_REQUIRE(ethash_get_default_dirname(result, 256));
+	std::string res = std::string(homedir) + std::string("\\Appdata\\Ethash\\");
+#else
+	char* homedir = getenv("HOME");
+	BOOST_REQUIRE(ethash_get_default_dirname(result, 256));
+	std::string res = std::string(homedir) + std::string("/.ethash/");
+#endif
+	BOOST_CHECK_MESSAGE(strcmp(res.c_str(), result) == 0,
+		"Expected \"" + res + "\" but got \"" + std::string(result) +  "\""
+   );
+}
+
+BOOST_AUTO_TEST_CASE(light_and_full_client_checks) {
+	uint64_t full_size;
+	uint64_t cache_size;
+	ethash_h256_t seed;
+	ethash_h256_t hash;
+	ethash_h256_t difficulty;
+	ethash_return_value_t light_out;
+	ethash_return_value_t full_out;
+	memcpy(&seed, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+	memcpy(&hash, "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+
+	// Set the difficulty
+	ethash_h256_set(&difficulty, 0, 197);
+	ethash_h256_set(&difficulty, 1, 90);
+	for (int i = 2; i < 32; i++)
+		ethash_h256_set(&difficulty, i, 255);
+
+	cache_size = 1024;
+	full_size = 1024 * 32;
+
+	ethash_light_t light = ethash_light_new_internal(cache_size, &seed);
+	ethash_full_t full = ethash_full_new_internal(
+		"./test_ethash_directory/",
+		seed,
+		full_size,
+		light,
+		NULL
+	);
+	BOOST_ASSERT(full);
+	{
+		const std::string
+				expected = "2da2b506f21070e1143d908e867962486d6b0a02e31d468fd5e3a7143aafa76a14201f63374314e2a6aaf84ad2eb57105dea3378378965a1b3873453bb2b78f9a8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995c259440b89fa3481c2c33171477c305c8e1e421f8d8f6d59585449d0034f3e421808d8da6bbd0b6378f567647cc6c4ba6c434592b198ad444e7284905b7c6adaf70bf43ec2daa7bd5e8951aa609ab472c124cf9eba3d38cff5091dc3f58409edcc386c743c3bd66f92408796ee1e82dd149eaefbf52b00ce33014a6eb3e50625413b072a58bc01da28262f42cbe4f87d4abc2bf287d15618405a1fe4e386fcdafbb171064bd99901d8f81dd6789396ce5e364ac944bbbd75a7827291c70b42d26385910cd53ca535ab29433dd5c5714d26e0dce95514c5ef866329c12e958097e84462197c2b32087849dab33e88b11da61d52f9dbc0b92cc61f742c07dbbf751c49d7678624ee60dfbe62e5e8c47a03d8247643f3d16ad8c8e663953bcda1f59d7e2d4a9bf0768e789432212621967a8f41121ad1df6ae1fa78782530695414c6213942865b2730375019105cae91a4c17a558d4b63059661d9f108362143107babe0b848de412e4da59168cce82bfbff3c99e022dd6ac1e559db991f2e3f7bb910cefd173e65ed00a8d5d416534e2c8416ff23977dbf3eb7180b75c71580d08ce95efeb9b0afe904ea12285a392aff0c8561ff79fca67f694a62b9e52377485c57cc3598d84cac0a9d27960de0cc31ff9bbfe455acaa62c8aa5d2cce96f345da9afe843d258a99c4eaf3650fc62efd81c7b81cd0d534d2d71eeda7a6e315d540b4473c80f8730037dc2ae3e47b986240cfc65ccc565f0d8cde0bc68a57e39a271dda57440b3598bee19f799611d25731a96b5dbbbefdff6f4f656161462633030d62560ea4e9c161cf78fc96a2ca5aaa32453a6c5dea206f766244e8c9d9a8dc61185ce37f1fc804459c5f07434f8ecb34141b8dcae7eae704c950b55556c5f40140c3714b45eddb02637513268778cbf937a33e4e33183685f9deb31ef54e90161e76d969587dd782eaa94e289420e7c2ee908517f5893a26fdb5873d68f92d118d4bcf98d7a4916794d6ab290045e30f9ea00ca547c584b8482b0331ba1539a0f2714fddc3a0b06b0cfbb6a607b8339c39bcfd6640b1f653e9d70ef6c985b",
+				actual = bytesToHexString((uint8_t const *) light->cache, cache_size);
+
+		BOOST_REQUIRE_MESSAGE(expected == actual,
+				"\nexpected: " << expected.c_str() << "\n"
+						<< "actual: " << actual.c_str() << "\n");
+	}
+	{
+		node node;
+		ethash_calculate_dag_item(&node, 0, light);
+		const std::string
+				actual = bytesToHexString((uint8_t const *) &node, sizeof(node)),
+				expected = "b1698f829f90b35455804e5185d78f549fcb1bdce2bee006d4d7e68eb154b596be1427769eb1c3c3e93180c760af75f81d1023da6a0ffbe321c153a7c0103597";
+		BOOST_REQUIRE_MESSAGE(actual == expected,
+				"\n" << "expected: " << expected.c_str() << "\n"
+						<< "actual: " << actual.c_str() << "\n");
+	}
+	{
+		for (int i = 0; i < full_size / sizeof(node); ++i) {
+			for (uint32_t j = 0; j < 32; ++j) {
+				node expected_node;
+				ethash_calculate_dag_item(&expected_node, j, light);
+				const std::string
+						actual = bytesToHexString((uint8_t const *) &(full->data[j]), sizeof(node)),
+						expected = bytesToHexString((uint8_t const *) &expected_node, sizeof(node));
+				BOOST_REQUIRE_MESSAGE(actual == expected,
+						"\ni: " << j << "\n"
+								<< "expected: " << expected.c_str() << "\n"
+								<< "actual: " << actual.c_str() << "\n");
+			}
+		}
+	}
+	{
+		uint64_t nonce = 0x7c7c597c;
+		full_out = ethash_full_compute(full, hash, nonce);
+		BOOST_REQUIRE(full_out.success);
+		light_out = ethash_light_compute_internal(light, full_size, hash, nonce);
+		BOOST_REQUIRE(light_out.success);
+		const std::string
+				light_result_string = blockhashToHexString(&light_out.result),
+				full_result_string = blockhashToHexString(&full_out.result);
+		BOOST_REQUIRE_MESSAGE(light_result_string == full_result_string,
+				"\nlight result: " << light_result_string.c_str() << "\n"
+						<< "full result: " << full_result_string.c_str() << "\n");
+		const std::string
+				light_mix_hash_string = blockhashToHexString(&light_out.mix_hash),
+				full_mix_hash_string = blockhashToHexString(&full_out.mix_hash);
+		BOOST_REQUIRE_MESSAGE(full_mix_hash_string == light_mix_hash_string,
+				"\nlight mix hash: " << light_mix_hash_string.c_str() << "\n"
+						<< "full mix hash: " << full_mix_hash_string.c_str() << "\n");
+		ethash_h256_t check_hash;
+		ethash_quick_hash(&check_hash, &hash, nonce, &full_out.mix_hash);
+		const std::string check_hash_string = blockhashToHexString(&check_hash);
+		BOOST_REQUIRE_MESSAGE(check_hash_string == full_result_string,
+				"\ncheck hash string: " << check_hash_string.c_str() << "\n"
+						<< "full result: " << full_result_string.c_str() << "\n");
+	}
+	{
+		full_out = ethash_full_compute(full, hash, 5);
+		BOOST_REQUIRE(full_out.success);
+		std::string
+				light_result_string = blockhashToHexString(&light_out.result),
+				full_result_string = blockhashToHexString(&full_out.result);
+		BOOST_REQUIRE_MESSAGE(light_result_string != full_result_string,
+				"\nlight result and full result should differ: " << light_result_string.c_str() << "\n");
+
+		light_out = ethash_light_compute_internal(light, full_size, hash, 5);
+		BOOST_REQUIRE(light_out.success);
+		light_result_string = blockhashToHexString(&light_out.result);
+		BOOST_REQUIRE_MESSAGE(light_result_string == full_result_string,
+				"\nlight result and full result should be the same\n"
+						<< "light result: " << light_result_string.c_str() << "\n"
+						<< "full result: " << full_result_string.c_str() << "\n");
+		std::string
+				light_mix_hash_string = blockhashToHexString(&light_out.mix_hash),
+				full_mix_hash_string = blockhashToHexString(&full_out.mix_hash);
+		BOOST_REQUIRE_MESSAGE(full_mix_hash_string == light_mix_hash_string,
+				"\nlight mix hash: " << light_mix_hash_string.c_str() << "\n"
+						<< "full mix hash: " << full_mix_hash_string.c_str() << "\n");
+		BOOST_REQUIRE_MESSAGE(ethash_check_difficulty(&full_out.result, &difficulty),
+				"ethash_check_difficulty failed"
+		);
+		BOOST_REQUIRE_MESSAGE(ethash_quick_check_difficulty(&hash, 5U, &full_out.mix_hash, &difficulty),
+				"ethash_quick_check_difficulty failed"
+		);
+	}
+	ethash_light_delete(light);
+	ethash_full_delete(full);
+	fs::remove_all("./test_ethash_directory/");
+}
+
+BOOST_AUTO_TEST_CASE(ethash_full_new_when_dag_exists_with_wrong_size) {
+	uint64_t full_size;
+	uint64_t cache_size;
+	ethash_h256_t seed;
+	ethash_h256_t hash;
+	ethash_return_value_t full_out;
+	ethash_return_value_t light_out;
+	memcpy(&seed, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+	memcpy(&hash, "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+
+	cache_size = 1024;
+	full_size = 1024 * 32;
+
+	// first make a DAG file of "wrong size"
+	FILE *f;
+	BOOST_REQUIRE_EQUAL(
+		ETHASH_IO_MEMO_MISMATCH,
+		ethash_io_prepare("./test_ethash_directory/", seed, &f, 64, false)
+	);
+	fclose(f);
+
+	// then create new DAG, which should detect the wrong size and force create a new file
+	ethash_light_t light = ethash_light_new_internal(cache_size, &seed);
+	BOOST_ASSERT(light);
+	ethash_full_t full = ethash_full_new_internal(
+		"./test_ethash_directory/",
+		seed,
+		full_size,
+		light,
+		NULL
+	);
+	BOOST_ASSERT(full);
+	{
+		uint64_t nonce = 0x7c7c597c;
+		full_out = ethash_full_compute(full, hash, nonce);
+		BOOST_REQUIRE(full_out.success);
+		light_out = ethash_light_compute_internal(light, full_size, hash, nonce);
+		BOOST_REQUIRE(light_out.success);
+		const std::string
+				light_result_string = blockhashToHexString(&light_out.result),
+				full_result_string = blockhashToHexString(&full_out.result);
+		BOOST_REQUIRE_MESSAGE(light_result_string == full_result_string,
+				"\nlight result: " << light_result_string.c_str() << "\n"
+						<< "full result: " << full_result_string.c_str() << "\n");
+		const std::string
+				light_mix_hash_string = blockhashToHexString(&light_out.mix_hash),
+				full_mix_hash_string = blockhashToHexString(&full_out.mix_hash);
+		BOOST_REQUIRE_MESSAGE(full_mix_hash_string == light_mix_hash_string,
+				"\nlight mix hash: " << light_mix_hash_string.c_str() << "\n"
+						<< "full mix hash: " << full_mix_hash_string.c_str() << "\n");
+		ethash_h256_t check_hash;
+		ethash_quick_hash(&check_hash, &hash, nonce, &full_out.mix_hash);
+		const std::string check_hash_string = blockhashToHexString(&check_hash);
+		BOOST_REQUIRE_MESSAGE(check_hash_string == full_result_string,
+				"\ncheck hash string: " << check_hash_string.c_str() << "\n"
+						<< "full result: " << full_result_string.c_str() << "\n");
+	}
+
+	ethash_light_delete(light);
+	ethash_full_delete(full);
+	fs::remove_all("./test_ethash_directory/");
 }
 
-// could have used dev::contentsNew but don't wanna try to import
-// libdevcore just for one function
-static std::vector<char> readFileIntoVector(char const* filename)
+static bool g_executed = false;
+static unsigned g_prev_progress = 0;
+static int test_full_callback(unsigned _progress)
 {
-    ifstream ifs(filename, ios::binary|ios::ate);
-    ifstream::pos_type pos = ifs.tellg();
+	g_executed = true;
+	BOOST_CHECK(_progress >= g_prev_progress);
+	g_prev_progress = _progress;
+	return 0;
+}
 
-    std::vector<char> result((unsigned int)pos);
+static int test_full_callback_that_fails(unsigned _progress)
+{
+	return 1;
+}
 
-    ifs.seekg(0, ios::beg);
-    ifs.read(&result[0], pos);
+static int test_full_callback_create_incomplete_dag(unsigned _progress)
+{
+	if (_progress >= 30) {
+		return 1;
+	}
+	return 0;
+}
+
+BOOST_AUTO_TEST_CASE(full_client_callback) {
+	uint64_t full_size;
+	uint64_t cache_size;
+	ethash_h256_t seed;
+	ethash_h256_t hash;
+	memcpy(&seed, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+	memcpy(&hash, "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+
+	cache_size = 1024;
+	full_size = 1024 * 32;
+
+	ethash_light_t light = ethash_light_new_internal(cache_size, &seed);
+	ethash_full_t full = ethash_full_new_internal(
+		"./test_ethash_directory/",
+		seed,
+		full_size,
+		light,
+		test_full_callback
+	);
+	BOOST_ASSERT(full);
+	BOOST_CHECK(g_executed);
+	BOOST_REQUIRE_EQUAL(g_prev_progress, 100);
+
+	ethash_full_delete(full);
+	ethash_light_delete(light);
+	fs::remove_all("./test_ethash_directory/");
+}
+
+BOOST_AUTO_TEST_CASE(failing_full_client_callback) {
+	uint64_t full_size;
+	uint64_t cache_size;
+	ethash_h256_t seed;
+	ethash_h256_t hash;
+	memcpy(&seed, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+	memcpy(&hash, "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+
+	cache_size = 1024;
+	full_size = 1024 * 32;
+
+	ethash_light_t light = ethash_light_new_internal(cache_size, &seed);
+	ethash_full_t full = ethash_full_new_internal(
+		"./test_ethash_directory/",
+		seed,
+		full_size,
+		light,
+		test_full_callback_that_fails
+	);
+	BOOST_ASSERT(!full);
+	ethash_light_delete(light);
+	fs::remove_all("./test_ethash_directory/");
+}
 
-    return result;
+BOOST_AUTO_TEST_CASE(test_incomplete_dag_file) {
+	uint64_t full_size;
+	uint64_t cache_size;
+	ethash_h256_t seed;
+	ethash_h256_t hash;
+	memcpy(&seed, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+	memcpy(&hash, "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
+
+	cache_size = 1024;
+	full_size = 1024 * 32;
+
+	ethash_light_t light = ethash_light_new_internal(cache_size, &seed);
+	// create a full but stop at 30%, so no magic number is written
+	ethash_full_t full = ethash_full_new_internal(
+		"./test_ethash_directory/",
+		seed,
+		full_size,
+		light,
+		test_full_callback_create_incomplete_dag
+	);
+	BOOST_ASSERT(!full);
+	FILE *f = NULL;
+	// confirm that we get a size_mismatch because the magic number is missing
+	BOOST_REQUIRE_EQUAL(
+		ETHASH_IO_MEMO_SIZE_MISMATCH,
+		ethash_io_prepare("./test_ethash_directory/", seed, &f, full_size, false)
+	);
+	ethash_light_delete(light);
+	fs::remove_all("./test_ethash_directory/");
+}
+
+BOOST_AUTO_TEST_CASE(test_block_verification) {
+	ethash_light_t light = ethash_light_new(22);
+	ethash_h256_t seedhash = stringToBlockhash("372eca2454ead349c3df0ab5d00b0b706b23e49d469387db91811cee0358fc6d");
+	BOOST_ASSERT(light);
+	ethash_return_value_t ret = ethash_light_compute(
+		light,
+		seedhash,
+		0x495732e0ed7a801c
+	);
+	BOOST_REQUIRE_EQUAL(blockhashToHexString(&ret.result), "00000b184f1fdd88bfd94c86c39e65db0c36144d5e43f745f722196e730cb614");
+	ethash_light_delete(light);
+}
+
+// Test of Full DAG creation with the minimal ethash.h API.
+// Commented out since travis tests would take too much time.
+// Uncomment and run on your own machine if you want to confirm
+// it works fine.
+#if 0
+static int lef_cb(unsigned _progress)
+{
+	printf("CREATING DAG. PROGRESS: %u\n", _progress);
+	fflush(stdout);
+	return 0;
 }
 
-BOOST_AUTO_TEST_CASE(test_ethash_io_memo_file_contents) {
-    ethash_blockhash_t seedhash;
-    static const int blockn = 0;
-    ethash_get_seedhash(&seedhash, blockn);
-    BOOST_REQUIRE_EQUAL(
-        ETHASH_IO_MEMO_MISMATCH,
-        ethash_io_prepare("./test_ethash_directory/", seedhash)
-    );
-
-    // let's make sure that the directory was created
-    BOOST_REQUIRE(fs::is_directory(fs::path("./test_ethash_directory/")));
-
-    ethash_cache cache;
-    ethash_params params;
-    uint8_t *data;
-    uint64_t size;
-    ethash_params_init(&params, blockn);
-    params.cache_size = 1024;
-    params.full_size = 1024 * 32;
-    cache.mem = our_alloca(params.cache_size);
-    ethash_mkcache(&cache, &params, &seedhash);
-    
-    BOOST_REQUIRE(
-        ethash_io_write("./test_ethash_directory/", &params, seedhash, &cache, &data, &size)
-    );
-
-    BOOST_REQUIRE(fs::exists(fs::path("./test_ethash_directory/full")));
-    BOOST_REQUIRE(fs::exists(fs::path("./test_ethash_directory/full.info")));
-
-    char expect_buffer[DAG_MEMO_BYTESIZE];
-    ethash_io_serialize_info(REVISION, seedhash, expect_buffer);
-    auto vec = readFileIntoVector("./test_ethash_directory/full.info");
-    BOOST_REQUIRE_EQUAL(vec.size(), DAG_MEMO_BYTESIZE);
-    BOOST_REQUIRE(memcmp(expect_buffer, &vec[0], DAG_MEMO_BYTESIZE) == 0);
-
-    // cleanup
-    fs::remove_all("./test_ethash_directory/");
-    free(data);
+BOOST_AUTO_TEST_CASE(full_dag_test) {
+	ethash_light_t light = ethash_light_new(55);
+	BOOST_ASSERT(light);
+	ethash_full_t full = ethash_full_new(light, lef_cb);
+	BOOST_ASSERT(full);
+	ethash_light_delete(light);
+	ethash_full_delete(full);
 }
+#endif
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.sh b/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.sh
index 6d02d30f8..92b6b8b66 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.sh
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.sh
@@ -3,6 +3,13 @@
 # Strict mode
 set -e
 
+VALGRIND_ARGS="--tool=memcheck"
+VALGRIND_ARGS+=" --leak-check=yes"
+VALGRIND_ARGS+=" --track-origins=yes"
+VALGRIND_ARGS+=" --show-reachable=yes"
+VALGRIND_ARGS+=" --num-callers=20"
+VALGRIND_ARGS+=" --track-fds=yes"
+
 SOURCE="${BASH_SOURCE[0]}"
 while [ -h "$SOURCE" ]; do
   DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
@@ -17,3 +24,9 @@ cd $TEST_DIR/build ;
 cmake ../../.. > /dev/null 
 make Test 
 ./test/c/Test
+
+# If we have valgrind also run memory check tests
+if hash valgrind 2>/dev/null; then
+	echo "======== Running tests under valgrind ========";
+	cd $TEST_DIR/build/ && valgrind $VALGRIND_ARGS ./test/c/Test
+fi
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/test/go/ethash_test.go b/Godeps/_workspace/src/github.com/ethereum/ethash/test/go/ethash_test.go
deleted file mode 100644
index 67ca51702..000000000
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/test/go/ethash_test.go
+++ /dev/null
@@ -1,82 +0,0 @@
-package ethashTest
-
-import (
-	"bytes"
-	"crypto/rand"
-	"encoding/hex"
-	"log"
-	"math/big"
-	"testing"
-
-	"github.com/ethereum/ethash"
-	"github.com/ethereum/go-ethereum/core"
-	"github.com/ethereum/go-ethereum/ethdb"
-)
-
-func TestEthash(t *testing.T) {
-	seedHash := make([]byte, 32)
-	_, err := rand.Read(seedHash)
-	if err != nil {
-		panic(err)
-	}
-
-	db, err := ethdb.NewMemDatabase()
-	if err != nil {
-		panic(err)
-	}
-
-	blockProcessor, err := core.NewCanonical(5, db)
-	if err != nil {
-		panic(err)
-	}
-
-	log.Println("Block Number: ", blockProcessor.ChainManager().CurrentBlock().Number())
-
-	e := ethash.New(blockProcessor.ChainManager())
-
-	miningHash := make([]byte, 32)
-	if _, err := rand.Read(miningHash); err != nil {
-		panic(err)
-	}
-	diff := big.NewInt(10000)
-	log.Println("difficulty", diff)
-
-	nonce := uint64(0)
-
-	ghash_full := e.FullHash(nonce, miningHash)
-	log.Printf("ethash full (on nonce): %x %x\n", ghash_full, nonce)
-
-	ghash_light := e.LightHash(nonce, miningHash)
-	log.Printf("ethash light (on nonce): %x %x\n", ghash_light, nonce)
-
-	if bytes.Compare(ghash_full, ghash_light) != 0 {
-		t.Errorf("full: %x, light: %x", ghash_full, ghash_light)
-	}
-}
-
-func TestGetSeedHash(t *testing.T) {
-	seed0, err := ethash.GetSeedHash(0)
-	if err != nil {
-		t.Errorf("Failed to get seedHash for block 0: %v", err)
-	}
-	if bytes.Compare(seed0, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) != 0 {
-		log.Printf("seedHash for block 0 should be 0s, was: %v\n", seed0)
-	}
-	seed1, err := ethash.GetSeedHash(30000)
-	if err != nil {
-		t.Error(err)
-	}
-
-	// From python:
-	// > from pyethash import get_seedhash
-	// > get_seedhash(30000)
-	expectedSeed1, err := hex.DecodeString("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")
-	if err != nil {
-		t.Error(err)
-	}
-
-	if bytes.Compare(seed1, expectedSeed1) != 0 {
-		log.Printf("seedHash for block 1 should be: %v,\nactual value: %v\n", expectedSeed1, seed1)
-	}
-
-}
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/test/test.sh b/Godeps/_workspace/src/github.com/ethereum/ethash/test/test.sh
index fd3508609..aaeaa878c 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/test/test.sh
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/test/test.sh
@@ -24,8 +24,9 @@ fi
 echo -e "\n################# Testing C ##################"
 $TEST_DIR/c/test.sh
 
-echo -e "\n################# Testing Python ##################"
-$TEST_DIR/python/test.sh
+# Temporarily commenting out python tests until they conform to the API
+#echo -e "\n################# Testing Python ##################"
+#$TEST_DIR/python/test.sh
 
-#echo "################# Testing Go ##################"
-#$TEST_DIR/go/test.sh
+echo "################# Testing Go ##################"
+cd $TEST_DIR/.. && go test -timeout 9999s
-- 
GitLab