219 lines
5.9 KiB
JavaScript
219 lines
5.9 KiB
JavaScript
var bignum = require('bignum');
|
|
var multiHashing = require('multi-hashing');
|
|
var util = require('./util.js');
|
|
|
|
|
|
var algos = module.exports = global.algos = {
|
|
sha256: {
|
|
//Uncomment diff if you want to use hardcoded truncated diff
|
|
//diff: new Buffer('00000000ffff0000000000000000000000000000000000000000000000000000', 'hex'),
|
|
shift: 32,
|
|
multiplier: Math.pow(2, 32),
|
|
hash: function(){
|
|
return function(){
|
|
return util.sha256d.apply(this, arguments);
|
|
}
|
|
}
|
|
},
|
|
scrypt: {
|
|
//Uncomment diff if you want to use hardcoded truncated diff
|
|
//diff: new Buffer('0000ffff00000000000000000000000000000000000000000000000000000000', 'hex'),
|
|
shift: 20,
|
|
multiplier: Math.pow(2, 16),
|
|
hash: function(){
|
|
return function(){
|
|
return multiHashing.scrypt.apply(this, arguments);
|
|
}
|
|
}
|
|
},
|
|
'scrypt-jane': {
|
|
shift: 20,
|
|
multiplier: Math.pow(2, 16),
|
|
hash: function(coinConfig){
|
|
var nTimestamp = coinConfig.chainStartTime || 1367991200;
|
|
var nMin = coinConfig.nMin || 4;
|
|
var nMax = coinConfig.nMax || 30;
|
|
return function(data, nTime){
|
|
return multiHashing.scryptjane(data, nTime, nTimestamp, nMin, nMax);
|
|
}
|
|
}
|
|
},
|
|
'scrypt-n': {
|
|
shift: 20,
|
|
multiplier: Math.pow(2, 16),
|
|
hash: function(coinConfig){
|
|
|
|
var timeTable = coinConfig.timeTable || {
|
|
"2048": 1389306217, "4096": 1456415081, "8192": 1506746729, "16384": 1557078377, "32768": 1657741673,
|
|
"65536": 1859068265, "131072": 2060394857, "262144": 1722307603, "524288": 1769642992
|
|
};
|
|
|
|
var nFactor = (function(){
|
|
var n = Object.keys(timeTable).sort().reverse().filter(function(nKey){
|
|
return Date.now() / 1000 > timeTable[nKey];
|
|
})[0];
|
|
|
|
var nInt = parseInt(n);
|
|
return Math.log(nInt) / Math.log(2);
|
|
})();
|
|
|
|
return function(data) {
|
|
return multiHashing.scryptn(data, nFactor);
|
|
}
|
|
}
|
|
},
|
|
x11: {
|
|
shift: 20,
|
|
multiplier: Math.pow(2, 32.3),
|
|
hash: function(){
|
|
return function(){
|
|
return multiHashing.x11.apply(this, arguments);
|
|
}
|
|
}
|
|
},
|
|
quark: {
|
|
shift: 20,
|
|
multipler: Math.pow(2, 16),
|
|
hash: function(){
|
|
return function(){
|
|
return multiHashing.quark.apply(this, arguments);
|
|
}
|
|
}
|
|
},
|
|
skein: {
|
|
shift: 20,
|
|
hash: function(){
|
|
return function(){
|
|
return multiHashing.skein.apply(this, arguments);
|
|
}
|
|
}
|
|
},
|
|
bcrypt: {
|
|
shift: 11,
|
|
hash: function(){
|
|
return function(){
|
|
return multiHashing.bcrypt.apply(this, arguments);
|
|
}
|
|
}
|
|
},
|
|
keccak: {
|
|
shift: 24,
|
|
multiplier: Math.pow(2, 24),
|
|
hash: function(){
|
|
return function(data){
|
|
return multiHashing.keccak(data);
|
|
}
|
|
}
|
|
},
|
|
blake: {
|
|
shift: 24,
|
|
hash: function(){
|
|
return function(){
|
|
|
|
}
|
|
}
|
|
},
|
|
fugue: {
|
|
shift: 24,
|
|
hash: function(){
|
|
return function(){
|
|
|
|
}
|
|
}
|
|
},
|
|
shavite: {
|
|
shift: 20,
|
|
hash: function(){
|
|
return function(){
|
|
|
|
}
|
|
}
|
|
},
|
|
hefty1: {
|
|
shift: 16,
|
|
hash: function(){
|
|
return function(){
|
|
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
//Creates a non-truncated max difficulty (diff1) by bitwise right-shifting the max value of a uint256
|
|
function ShiftMax256Right(shiftRight){
|
|
|
|
//Max value uint256 (an array of ones representing 256 enabled bits)
|
|
var arr256 = Array.apply(null, new Array(256)).map(Number.prototype.valueOf, 1);
|
|
|
|
//An array of zero bits for how far the max uint256 is shifted right
|
|
var arrLeft = Array.apply(null, new Array(shiftRight)).map(Number.prototype.valueOf, 0);
|
|
|
|
//Add zero bits to uint256 and remove the bits shifted out
|
|
arr256 = arrLeft.concat(arr256).slice(0, 256);
|
|
|
|
//An array of bytes to convert the bits to, 8 bits in a byte so length will be 32
|
|
var octets = [];
|
|
|
|
for (var i = 0; i < 32; i++){
|
|
|
|
octets[i] = 0;
|
|
|
|
//The 8 bits for this byte
|
|
var bits = arr256.slice(i * 8, i * 8 + 8);
|
|
|
|
//Bit math to add the bits into a byte
|
|
for (var f = 0; f < bits.length; f++){
|
|
var multiplier = Math.pow(2, f);
|
|
octets[i] += bits[f] * multiplier;
|
|
}
|
|
|
|
}
|
|
|
|
return new Buffer(octets);;
|
|
}
|
|
|
|
|
|
function BufferToCompact(startingBuff){
|
|
var bigNum = bignum.fromBuffer(startingBuff);
|
|
var buff = bigNum.toBuffer();
|
|
|
|
buff = buff.readUInt8(0) > 0x7f ? Buffer.concat([new Buffer([0x00]), buff]) : buff;
|
|
|
|
buff = Buffer.concat([new Buffer([buff.length]), buff]);
|
|
var compact = buff.slice(0, 4);
|
|
return compact;
|
|
}
|
|
|
|
|
|
function ConvertBitsToBuff(bitsBuff){
|
|
var numBytes = bitsBuff.readUInt8(0);
|
|
var bigBits = bignum.fromBuffer(bitsBuff.slice(1));
|
|
var target = bigBits.mul(
|
|
bignum(2).pow(
|
|
bignum(8).mul(
|
|
numBytes - 3
|
|
)
|
|
)
|
|
);
|
|
|
|
var resultBuff = target.toBuffer();
|
|
var buff256 = new Buffer(32);
|
|
buff256.fill(0);
|
|
resultBuff.copy(buff256, buff256.length - resultBuff.length);
|
|
|
|
return buff256;
|
|
}
|
|
|
|
for (var algo in algos){
|
|
if (!algos[algo].diff) {
|
|
var nonTruncatedDiff = ShiftMax256Right(algos[algo].shift);
|
|
var compactBits = BufferToCompact(nonTruncatedDiff);
|
|
var truncatedDiff = ConvertBitsToBuff(compactBits);
|
|
|
|
algos[algo].bits = compactBits;
|
|
algos[algo].diff = truncatedDiff;
|
|
algos[algo].nonTruncatedDiff = nonTruncatedDiff;
|
|
algos[algo].diff = nonTruncatedDiff;
|
|
}
|
|
}
|