aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/ethereum/ethash/js/ethash.js
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/ethereum/ethash/js/ethash.js')
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/ethash/js/ethash.js328
1 files changed, 168 insertions, 160 deletions
diff --git a/Godeps/_workspace/src/github.com/ethereum/ethash/js/ethash.js b/Godeps/_workspace/src/github.com/ethereum/ethash/js/ethash.js
index bec1284f6..edff47e63 100644
--- a/Godeps/_workspace/src/github.com/ethereum/ethash/js/ethash.js
+++ b/Godeps/_workspace/src/github.com/ethereum/ethash/js/ethash.js
@@ -7,184 +7,192 @@
var Keccak = require('./keccak');
var util = require('./util');
+var ethUtil = require('ethereumjs-util');
// 32-bit unsigned modulo
-function mod32(x, n)
-{
- return (x>>>0) % (n>>>0);
+function mod32(x, n) {
+ return (x >>> 0) % (n >>> 0);
}
-function fnv(x, y)
-{
- // js integer multiply by 0x01000193 will lose precision
- return ((x*0x01000000 | 0) + (x*0x193 | 0)) ^ y;
+function fnv(x, y) {
+ // js integer multiply by 0x01000193 will lose precision
+ return ((x * 0x01000000 | 0) + (x * 0x193 | 0)) ^ y;
}
-function computeCache(params, seedWords)
-{
- var cache = new Uint32Array(params.cacheSize >> 2);
- var cacheNodeCount = params.cacheSize >> 6;
-
- // Initialize cache
- var keccak = new Keccak();
- keccak.digestWords(cache, 0, 16, seedWords, 0, seedWords.length);
- for (var n = 1; n < cacheNodeCount; ++n)
- {
- keccak.digestWords(cache, n<<4, 16, cache, (n-1)<<4, 16);
- }
-
- var tmp = new Uint32Array(16);
-
- // Do randmemohash passes
- for (var r = 0; r < params.cacheRounds; ++r)
- {
- for (var n = 0; n < cacheNodeCount; ++n)
- {
- var p0 = mod32(n + cacheNodeCount - 1, cacheNodeCount) << 4;
- var p1 = mod32(cache[n<<4|0], cacheNodeCount) << 4;
-
- for (var w = 0; w < 16; w=(w+1)|0)
- {
- tmp[w] = cache[p0 | w] ^ cache[p1 | w];
- }
-
- keccak.digestWords(cache, n<<4, 16, tmp, 0, tmp.length);
- }
- }
- return cache;
+function computeCache(params, seedWords) {
+ var cache = new Uint32Array(params.cacheSize >> 2);
+ var cacheNodeCount = params.cacheSize >> 6;
+
+ // Initialize cache
+ var keccak = new Keccak();
+ keccak.digestWords(cache, 0, 16, seedWords, 0, seedWords.length);
+ for (var n = 1; n < cacheNodeCount; ++n) {
+ keccak.digestWords(cache, n << 4, 16, cache, (n - 1) << 4, 16);
+ }
+
+ var tmp = new Uint32Array(16);
+
+ // Do randmemohash passes
+ for (var r = 0; r < params.cacheRounds; ++r) {
+ for (var n = 0; n < cacheNodeCount; ++n) {
+ var p0 = mod32(n + cacheNodeCount - 1, cacheNodeCount) << 4;
+ var p1 = mod32(cache[n << 4 | 0], cacheNodeCount) << 4;
+
+ for (var w = 0; w < 16; w = (w + 1) | 0) {
+ tmp[w] = cache[p0 | w] ^ cache[p1 | w];
+ }
+
+ keccak.digestWords(cache, n << 4, 16, tmp, 0, tmp.length);
+ }
+ }
+ return cache;
}
-function computeDagNode(o_node, params, cache, keccak, nodeIndex)
-{
- var cacheNodeCount = params.cacheSize >> 6;
- var dagParents = params.dagParents;
-
- var c = (nodeIndex % cacheNodeCount) << 4;
- var mix = o_node;
- for (var w = 0; w < 16; ++w)
- {
- mix[w] = cache[c|w];
- }
- mix[0] ^= nodeIndex;
- keccak.digestWords(mix, 0, 16, mix, 0, 16);
-
- for (var p = 0; p < dagParents; ++p)
- {
- // compute cache node (word) index
- c = mod32(fnv(nodeIndex ^ p, mix[p&15]), cacheNodeCount) << 4;
-
- for (var w = 0; w < 16; ++w)
- {
- mix[w] = fnv(mix[w], cache[c|w]);
- }
- }
-
- keccak.digestWords(mix, 0, 16, mix, 0, 16);
+function computeDagNode(o_node, params, cache, keccak, nodeIndex) {
+ var cacheNodeCount = params.cacheSize >> 6;
+ var dagParents = params.dagParents;
+
+ var c = (nodeIndex % cacheNodeCount) << 4;
+ var mix = o_node;
+ for (var w = 0; w < 16; ++w) {
+ mix[w] = cache[c | w];
+ }
+ mix[0] ^= nodeIndex;
+ keccak.digestWords(mix, 0, 16, mix, 0, 16);
+
+ for (var p = 0; p < dagParents; ++p) {
+ // compute cache node (word) index
+ c = mod32(fnv(nodeIndex ^ p, mix[p & 15]), cacheNodeCount) << 4;
+
+ for (var w = 0; w < 16; ++w) {
+ mix[w] = fnv(mix[w], cache[c | w]);
+ }
+ }
+
+ keccak.digestWords(mix, 0, 16, mix, 0, 16);
}
-function computeHashInner(mix, params, cache, keccak, tempNode)
-{
- var mixParents = params.mixParents|0;
- var mixWordCount = params.mixSize >> 2;
- var mixNodeCount = mixWordCount >> 4;
- var dagPageCount = (params.dagSize / params.mixSize) >> 0;
-
- // grab initial first word
- var s0 = mix[0];
-
- // initialise mix from initial 64 bytes
- for (var w = 16; w < mixWordCount; ++w)
- {
- mix[w] = mix[w & 15];
- }
-
- for (var a = 0; a < mixParents; ++a)
- {
- var p = mod32(fnv(s0 ^ a, mix[a & (mixWordCount-1)]), dagPageCount);
- var d = (p * mixNodeCount)|0;
-
- for (var n = 0, w = 0; n < mixNodeCount; ++n, w += 16)
- {
- computeDagNode(tempNode, params, cache, keccak, (d + n)|0);
-
- for (var v = 0; v < 16; ++v)
- {
- mix[w|v] = fnv(mix[w|v], tempNode[v]);
- }
- }
- }
+function computeHashInner(mix, params, cache, keccak, tempNode) {
+ var mixParents = params.mixParents | 0;
+ var mixWordCount = params.mixSize >> 2;
+ var mixNodeCount = mixWordCount >> 4;
+ var dagPageCount = (params.dagSize / params.mixSize) >> 0;
+
+ // grab initial first word
+ var s0 = mix[0];
+
+ // initialise mix from initial 64 bytes
+ for (var w = 16; w < mixWordCount; ++w) {
+ mix[w] = mix[w & 15];
+ }
+
+ for (var a = 0; a < mixParents; ++a) {
+ var p = mod32(fnv(s0 ^ a, mix[a & (mixWordCount - 1)]), dagPageCount);
+ var d = (p * mixNodeCount) | 0;
+
+ for (var n = 0, w = 0; n < mixNodeCount; ++n, w += 16) {
+ computeDagNode(tempNode, params, cache, keccak, (d + n) | 0);
+
+ for (var v = 0; v < 16; ++v) {
+ mix[w | v] = fnv(mix[w | v], tempNode[v]);
+ }
+ }
+ }
}
-function convertSeed(seed)
-{
- // todo, reconcile with spec, byte ordering?
- // todo, big-endian conversion
- var newSeed = util.toWords(seed);
- if (newSeed === null)
- throw Error("Invalid seed '" + seed + "'");
- return newSeed;
+function convertSeed(seed) {
+ // todo, reconcile with spec, byte ordering?
+ // todo, big-endian conversion
+ var newSeed = util.toWords(seed);
+ if (newSeed === null)
+ throw Error("Invalid seed '" + seed + "'");
+ return newSeed;
}
-exports.defaultParams = function()
-{
- return {
- cacheSize: 1048384,
- cacheRounds: 3,
- dagSize: 1073739904,
- dagParents: 256,
- mixSize: 128,
- mixParents: 64,
- };
+var params = exports.params = {
+ REVISION: 23,
+ DATASET_BYTES_INIT: 1073741824,
+ DATASET_BYTES_GROWTH: 8388608,
+ CACHE_BYTES_INIT: 1073741824,
+ CACHE_BYTES_GROWTH: 131072,
+ EPOCH_LENGTH: 30000,
+ MIX_BYTES: 128,
+ HASH_BYTES: 64,
+ DATASET_PARENTS: 256,
+ CACHE_ROUNDS: 3,
+ ACCESSES: 64
+};
+
+var cache_sizes = require('./cache_sizes');
+var dag_sizes = require('./dag_sizes');
+
+exports.calcSeed = function(blockNum) {
+ var epoch;
+
+ var seed = new Uint8Array(32);
+
+ if (blockNum > cache_sizes.length * params.EPOCH_LENGTH) {
+ return new Error('Time to upgrade to POS!!!');
+ } else {
+ epoch = Math.floor(blockNum / params.EPOCH_LENGTH);
+
+ for (var i = 0; i < epoch; i++) {
+ seed = ethUtil.sha3(new Buffer(seed));
+ }
+ return seed;
+ }
};
-exports.Ethash = function(params, seed)
-{
- // precompute cache and related values
- seed = convertSeed(seed);
- var cache = computeCache(params, seed);
-
- // preallocate buffers/etc
- var initBuf = new ArrayBuffer(96);
- var initBytes = new Uint8Array(initBuf);
- var initWords = new Uint32Array(initBuf);
- var mixWords = new Uint32Array(params.mixSize / 4);
- var tempNode = new Uint32Array(16);
- var keccak = new Keccak();
-
- var retWords = new Uint32Array(8);
- var retBytes = new Uint8Array(retWords.buffer); // supposedly read-only
-
- this.hash = function(header, nonce)
- {
- // compute initial hash
- initBytes.set(header, 0);
- initBytes.set(nonce, 32);
- keccak.digestWords(initWords, 0, 16, initWords, 0, 8 + nonce.length/4);
-
- // compute mix
- for (var i = 0; i != 16; ++i)
- {
- mixWords[i] = initWords[i];
- }
- computeHashInner(mixWords, params, cache, keccak, tempNode);
-
- // compress mix and append to initWords
- for (var i = 0; i != mixWords.length; i += 4)
- {
- initWords[16 + i/4] = fnv(fnv(fnv(mixWords[i], mixWords[i+1]), mixWords[i+2]), mixWords[i+3]);
- }
-
- // final Keccak hashes
- keccak.digestWords(retWords, 0, 8, initWords, 0, 24); // Keccak-256(s + cmix)
- return retBytes;
- };
-
- this.cacheDigest = function()
- {
- return keccak.digest(32, new Uint8Array(cache.buffer));
- };
+exports.defaultParams = function() {
+ return {
+ cacheSize: 1048384,
+ cacheRounds: 3,
+ dagSize: 1073739904,
+ dagParents: 256,
+ mixSize: 128,
+ mixParents: 64
+ };
};
+exports.Ethash = function(params, seed) {
+ // precompute cache and related values
+ // seed = convertSeed(seed);
+ var cache = computeCache(params, seed);
+
+ // preallocate buffers/etc
+ var initBuf = new ArrayBuffer(96);
+ var initBytes = new Uint8Array(initBuf);
+ var initWords = new Uint32Array(initBuf);
+ var mixWords = new Uint32Array(params.mixSize / 4);
+ var tempNode = new Uint32Array(16);
+ var keccak = new Keccak();
+
+ var retWords = new Uint32Array(8);
+ var retBytes = new Uint8Array(retWords.buffer); // supposedly read-only
+ this.hash = function(header, nonce) {
+ // compute initial hash
+ initBytes.set(header, 0);
+ initBytes.set(nonce, 32);
+ keccak.digestWords(initWords, 0, 16, initWords, 0, 8 + nonce.length / 4);
+ // compute mix
+ for (var i = 0; i !== 16; ++i) {
+ mixWords[i] = initWords[i];
+ }
+ computeHashInner(mixWords, params, cache, keccak, tempNode);
+ // compress mix and append to initWords
+ for (var i = 0; i !== mixWords.length; i += 4) {
+ initWords[16 + i / 4] = fnv(fnv(fnv(mixWords[i], mixWords[i + 1]), mixWords[i + 2]), mixWords[i + 3]);
+ }
+
+ // final Keccak hashes
+ keccak.digestWords(retWords, 0, 8, initWords, 0, 24); // Keccak-256(s + cmix)
+ return retBytes;
+ };
+
+ this.cacheDigest = function() {
+ return keccak.digest(32, new Uint8Array(cache.buffer));
+ };
+};