Calculate POW target
This commit is contained in:
parent
8c2f180037
commit
a7eb439706
|
@ -5,6 +5,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var hash = require("hash.js");
|
var hash = require("hash.js");
|
||||||
|
var BN = require("bn.js");
|
||||||
|
var assert = require("./util").assert;
|
||||||
|
|
||||||
exports.sha512 = function(buf) {
|
exports.sha512 = function(buf) {
|
||||||
return new Buffer(hash.sha512().update(buf).digest());
|
return new Buffer(hash.sha512().update(buf).digest());
|
||||||
|
@ -23,3 +25,19 @@ exports.randomBytes = function(size) {
|
||||||
window.crypto.getRandomValues(arr);
|
window.crypto.getRandomValues(arr);
|
||||||
return new Buffer(arr);
|
return new Buffer(arr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var B64 = new BN("18446744073709551616");
|
||||||
|
|
||||||
|
exports.getTarget = function(opts) {
|
||||||
|
var length = new BN(opts.payloadLength);
|
||||||
|
length.iaddn(8);
|
||||||
|
length.iaddn(opts.payloadLengthExtraBytes);
|
||||||
|
var denominator = new BN(opts.ttl);
|
||||||
|
denominator.imul(length);
|
||||||
|
denominator.idivn(65536);
|
||||||
|
denominator.iadd(length);
|
||||||
|
denominator.imul(new BN(opts.nonceTrialsPerByte));
|
||||||
|
var target = parseInt(B64.div(denominator).toString(16), 16);
|
||||||
|
assert(target <= 9007199254740991, "Unsafe target");
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var crypto = require("crypto");
|
var crypto = require("crypto");
|
||||||
|
var bignum = require("bignum");
|
||||||
|
var assert = require("./util").assert;
|
||||||
|
|
||||||
var createHash = crypto.createHash;
|
var createHash = crypto.createHash;
|
||||||
|
|
||||||
exports.sha512 = function(buf) {
|
exports.sha512 = function(buf) {
|
||||||
|
@ -20,3 +23,25 @@ exports.ripemd160 = function(buf) {
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.randomBytes = crypto.randomBytes;
|
exports.randomBytes = crypto.randomBytes;
|
||||||
|
|
||||||
|
// 2^64.
|
||||||
|
var B64 = bignum("18446744073709551616");
|
||||||
|
|
||||||
|
// NOTE(Kagami): We can't calculate entire target in JavaScript but the
|
||||||
|
// result can be represented in native number type without losing
|
||||||
|
// precision (targets mainly much less than 2^53).
|
||||||
|
exports.getTarget = function(opts) {
|
||||||
|
// Calculate it bottom-up, right-to-left.
|
||||||
|
var length = bignum(opts.payloadLength)
|
||||||
|
// To account for the nonce which we will append later.
|
||||||
|
.add(8)
|
||||||
|
.add(opts.payloadLengthExtraBytes);
|
||||||
|
var denominator = bignum(opts.ttl)
|
||||||
|
.mul(length)
|
||||||
|
.div(65536)
|
||||||
|
.add(length)
|
||||||
|
.mul(opts.nonceTrialsPerByte);
|
||||||
|
var target = B64.div(denominator).toNumber();
|
||||||
|
assert(target <= 9007199254740991, "Unsafe target");
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
|
31
lib/pow.js
31
lib/pow.js
|
@ -3,3 +3,34 @@
|
||||||
* @see {@link https://bitmessage.org/wiki/Proof_of_work}
|
* @see {@link https://bitmessage.org/wiki/Proof_of_work}
|
||||||
* @module bitmessage/pow
|
* @module bitmessage/pow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var platform = require("./platform");
|
||||||
|
|
||||||
|
var DEFAULT_TRIALS_PER_BYTE = 1000;
|
||||||
|
var DEFAULT_EXTRA_BYTES = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate target
|
||||||
|
* @param {{ttl: number, payloadLength: number}} opts - Target options
|
||||||
|
* @return {number} Target.
|
||||||
|
*/
|
||||||
|
// Just a wrapper around platform-specific implementation.
|
||||||
|
exports.getTarget = function(opts) {
|
||||||
|
var nonceTrialsPerByte = opts.nonceTrialsPerByte;
|
||||||
|
// Automatically raise lower values per spec.
|
||||||
|
if (!nonceTrialsPerByte || nonceTrialsPerByte < DEFAULT_TRIALS_PER_BYTE) {
|
||||||
|
nonceTrialsPerByte = DEFAULT_TRIALS_PER_BYTE;
|
||||||
|
}
|
||||||
|
var payloadLengthExtraBytes = opts.payloadLengthExtraBytes;
|
||||||
|
if (!payloadLengthExtraBytes || payloadLengthExtraBytes < DEFAULT_EXTRA_BYTES) {
|
||||||
|
payloadLengthExtraBytes = DEFAULT_EXTRA_BYTES;
|
||||||
|
}
|
||||||
|
return platform.getTarget({
|
||||||
|
ttl: opts.ttl,
|
||||||
|
payloadLength: opts.payloadLength,
|
||||||
|
nonceTrialsPerByte: nonceTrialsPerByte,
|
||||||
|
payloadLengthExtraBytes: payloadLengthExtraBytes,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"./lib/platform.js": "./lib/platform.browser.js"
|
"./lib/platform.js": "./lib/platform.browser.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "ALL_TESTS=1 mocha && xvfb-run -a karma start && jshint .",
|
"test": "ALL_TESTS=1 mocha && ALL_TESTS=1 xvfb-run -a karma start && jshint .",
|
||||||
"m": "mocha",
|
"m": "mocha",
|
||||||
"k": "xvfb-run -a karma start",
|
"k": "xvfb-run -a karma start",
|
||||||
"kc": "xvfb-run -a karma start --browsers Chromium",
|
"kc": "xvfb-run -a karma start --browsers Chromium",
|
||||||
|
@ -46,10 +46,13 @@
|
||||||
"mocha": "*"
|
"mocha": "*"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bignum": "^0.9.0",
|
||||||
|
"bn.js": "^1.0.0",
|
||||||
"bs58": "^2.0.0",
|
"bs58": "^2.0.0",
|
||||||
"buffer-equal": "~0.0.1",
|
"buffer-equal": "~0.0.1",
|
||||||
"eccrypto": "^0.1.2",
|
"eccrypto": "^0.1.2",
|
||||||
"hash.js": "^1.0.2",
|
"hash.js": "^1.0.2",
|
||||||
"object-assign": "^2.0.0"
|
"object-assign": "^2.0.0",
|
||||||
|
"sha.js": "^2.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
test.js
12
test.js
|
@ -15,6 +15,7 @@ var messageEncodings = structs.messageEncodings;
|
||||||
var serviceFeatures = structs.serviceFeatures;
|
var serviceFeatures = structs.serviceFeatures;
|
||||||
var pubkeyFeatures = structs.pubkeyFeatures;
|
var pubkeyFeatures = structs.pubkeyFeatures;
|
||||||
var WIF = bitmessage.WIF;
|
var WIF = bitmessage.WIF;
|
||||||
|
var POW = bitmessage.POW;
|
||||||
var Address = bitmessage.Address;
|
var Address = bitmessage.Address;
|
||||||
|
|
||||||
describe("Crypto", function() {
|
describe("Crypto", function() {
|
||||||
|
@ -263,6 +264,13 @@ describe("WIF", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("POW", function() {
|
||||||
|
it("should calculate target", function() {
|
||||||
|
expect(POW.getTarget({ttl: 2418984, payloadLength: 628, nonceTrialsPerByte: 1000, payloadLengthExtraBytes: 1000})).to.equal(297422593171);
|
||||||
|
expect(POW.getTarget({ttl: 86400, payloadLength: 628})).to.equal(4864647698763);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("High-level classes", function() {
|
describe("High-level classes", function() {
|
||||||
// FIXME(Kagami): Add more fail tests.
|
// FIXME(Kagami): Add more fail tests.
|
||||||
describe("Address", function() {
|
describe("Address", function() {
|
||||||
|
@ -296,7 +304,9 @@ describe("High-level classes", function() {
|
||||||
expect(addr2.ripe[0]).to.equal(0);
|
expect(addr2.ripe[0]).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (allTests) {
|
// FIXME(Kagami): Don't run it in browser currently because it's
|
||||||
|
// very slow. This need to be fixed.
|
||||||
|
if (allTests && typeof window === "undefined") {
|
||||||
it("should allow to generate shorter address", function() {
|
it("should allow to generate shorter address", function() {
|
||||||
this.timeout(60000);
|
this.timeout(60000);
|
||||||
var addr = Address.fromRandom({ripelen: 18});
|
var addr = Address.fromRandom({ripelen: 18});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user