2019-02-10 19:53:54 +00:00
|
|
|
/*
|
|
|
|
* @project: TERA
|
|
|
|
* @version: Development (beta)
|
|
|
|
* @license: MIT (not for evil)
|
2019-03-16 16:08:05 +00:00
|
|
|
* @copyright: Yuriy Ivanov (Vtools) 2017-2019 [progr76@gmail.com]
|
2019-02-10 19:53:54 +00:00
|
|
|
* Web: https://terafoundation.org
|
|
|
|
* Twitter: https://twitter.com/terafoundation
|
|
|
|
* Telegram: https://web.telegram.org/#/im?p=@terafoundation
|
|
|
|
*/
|
|
|
|
|
|
|
|
require("./library.js");
|
|
|
|
const crypto = require('crypto');
|
|
|
|
global.MAX_SUPER_VALUE_POW = (1 << 30) * 2;
|
|
|
|
var BuferForStr = Buffer.alloc(32);
|
|
|
|
global.GetHexFromAddres = function (arr)
|
|
|
|
{
|
|
|
|
if(!arr)
|
|
|
|
return "";
|
|
|
|
if(arr.data !== undefined)
|
|
|
|
arr = arr.data;
|
|
|
|
for(var i = 0; i < 32; i++)
|
|
|
|
BuferForStr[i] = arr[i];
|
|
|
|
return BuferForStr.toString('hex').toUpperCase();
|
|
|
|
};
|
|
|
|
global.GetArr32FromHex = function (Str)
|
|
|
|
{
|
|
|
|
var array = new Uint8Array(32);
|
|
|
|
for(var i = 0; i < array.length; i++)
|
|
|
|
{
|
|
|
|
array[i] = parseInt(Str.substr(i * 2, 2), 16);
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
};
|
|
|
|
global.GetAddresFromHex = GetArr32FromHex;
|
|
|
|
global.GetHexAddresFromPublicKey = function (arr)
|
|
|
|
{
|
|
|
|
return Buffer.from(arr.slice(1)).toString('hex').toUpperCase();
|
|
|
|
};
|
|
|
|
global.GetHexFromArr = function (arr)
|
|
|
|
{
|
|
|
|
if(!arr)
|
|
|
|
return "";
|
|
|
|
else
|
|
|
|
return Buffer.from(arr).toString('hex').toUpperCase();
|
|
|
|
};
|
|
|
|
|
|
|
|
function GetArrFromHex(Str)
|
|
|
|
{
|
|
|
|
var array = [];
|
|
|
|
for(var i = 0; i < Str.length / 2; i++)
|
|
|
|
{
|
|
|
|
array[i] = parseInt(Str.substr(i * 2, 2), 16);
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
};
|
|
|
|
global.GetArrFromHex = GetArrFromHex;
|
|
|
|
global.GetHexFromArrBlock = function (Arr,LenBlock)
|
|
|
|
{
|
|
|
|
var Str = "";
|
|
|
|
var Arr2 = [];
|
|
|
|
for(var i = 0; i < Arr.length; i++)
|
|
|
|
{
|
|
|
|
Arr2[i % LenBlock] = Arr[i];
|
|
|
|
if(Arr2.length >= LenBlock)
|
|
|
|
{
|
|
|
|
Str += GetHexFromArr(Arr2) + "\n";
|
|
|
|
Arr2 = [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(Arr2.length)
|
|
|
|
{
|
|
|
|
Str += GetHexFromArr(Arr2);
|
|
|
|
}
|
|
|
|
return Str;
|
|
|
|
};
|
|
|
|
global.GetPublicKeyFromAddres = function (Arr)
|
|
|
|
{
|
|
|
|
var RetArr = new Uint8Array(33);
|
|
|
|
RetArr[0] = 2;
|
|
|
|
for(var i = 1; i < 33; i++)
|
|
|
|
RetArr[i] = Arr[i - 1];
|
|
|
|
return RetArr;
|
|
|
|
};
|
|
|
|
global.GetSign = function (Context,Msg)
|
|
|
|
{
|
|
|
|
var hash = shabuf(Msg);
|
|
|
|
var sigObj = secp256k1.sign(hash, Context.KeyPair.getPrivateKey());
|
|
|
|
return sigObj.signature;
|
|
|
|
};
|
|
|
|
global.GetVerifySign = function (ContextAddr,Msg,Sign)
|
|
|
|
{
|
|
|
|
var hash = shabuf(Msg);
|
|
|
|
if(ContextAddr.publickey === undefined)
|
|
|
|
ContextAddr.publickey = GetPublicKeyFromAddres(ContextAddr.addrArr);
|
|
|
|
var Result = secp256k1.verify(hash, Sign, ContextAddr.publickey);
|
|
|
|
return Result;
|
|
|
|
};
|
|
|
|
global.CheckDevelopSign = function (SignArr,Sign)
|
|
|
|
{
|
|
|
|
var hash = shabuf(SignArr);
|
|
|
|
for(var i = 0; i < DEVELOP_PUB_KEY_ARR.length; i++)
|
|
|
|
{
|
|
|
|
var Result = secp256k1.verify(hash, Buffer.from(Sign), DEVELOP_PUB_KEY_ARR[i]);
|
|
|
|
if(Result)
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
global.CheckContextSecret = function (Context,ContextAddrTo)
|
|
|
|
{
|
|
|
|
if(ContextAddrTo.Secret === undefined)
|
|
|
|
{
|
|
|
|
if(ContextAddrTo.publickey === undefined)
|
|
|
|
{
|
|
|
|
ContextAddrTo.publickey = GetPublicKeyFromAddres(ContextAddrTo.addrArr);
|
|
|
|
}
|
|
|
|
ContextAddrTo.Secret = Context.KeyPair.computeSecret(ContextAddrTo.publickey, null);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
global.GetSignHash = function (Context,ContextAddrTo,Msg)
|
|
|
|
{
|
|
|
|
CheckContextSecret(Context, ContextAddrTo);
|
|
|
|
if(typeof Msg === "string")
|
|
|
|
Msg = Buffer.from(Msg);
|
|
|
|
var Buf = Buffer.concat([Msg, ContextAddrTo.Secret], Msg.length + ContextAddrTo.Secret.length);
|
|
|
|
var Arr = shaarr(Buf);
|
|
|
|
return Arr;
|
|
|
|
};
|
|
|
|
global.GetVerifyHash = function (Context,ContextAddr,Msg,Sign1)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var Sign2 = GetSignHash(Context, ContextAddr, Msg);
|
|
|
|
for(var i = 0; i < Sign1.length; i++)
|
|
|
|
if(Sign1[i] !== Sign2[i])
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch(e)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
global.GetKeyPair = function (password,secret,startnonce1,startnonce2)
|
|
|
|
{
|
|
|
|
secret = secret || "low";
|
|
|
|
startnonce1 = startnonce1 || 0;
|
|
|
|
startnonce2 = startnonce2 || 0;
|
|
|
|
var KeyPair = crypto.createECDH('secp256k1');
|
|
|
|
var private1 = shaarr(password);
|
|
|
|
var private2 = private1;
|
|
|
|
var nonce1 = 0;
|
|
|
|
if(secret === "high")
|
|
|
|
for(nonce1 = startnonce1; nonce1 < 2000000000; nonce1++)
|
|
|
|
{
|
|
|
|
private1[31] = nonce1 & 0xFF;
|
|
|
|
private1[30] = (nonce1 >>> 8) & 0xFF;
|
|
|
|
private1[29] = (nonce1 >>> 16) & 0xFF;
|
|
|
|
private1[28] = (nonce1 >>> 24) & 0xFF;
|
|
|
|
private2 = shaarr(private1);
|
|
|
|
if(private2[0] === 0 && private2[1] === 0 && private2[2] === 0)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nonce1++;
|
|
|
|
}
|
|
|
|
var nonce2;
|
|
|
|
for(nonce2 = startnonce2; nonce2 < 2000000000; nonce2++)
|
|
|
|
{
|
|
|
|
private2[31] = nonce2 & 0xFF;
|
|
|
|
private2[30] = (nonce2 >>> 8) & 0xFF;
|
|
|
|
private2[29] = (nonce2 >>> 16) & 0xFF;
|
|
|
|
private2[28] = (nonce2 >>> 24) & 0xFF;
|
|
|
|
KeyPair.setPrivateKey(Buffer.from(private2));
|
|
|
|
var Data = KeyPair.getPublicKey('', 'compressed');
|
|
|
|
if(Data[0] === 2 && Data[31] === 0 && Data[32] === 0)
|
|
|
|
{
|
|
|
|
KeyPair.nonce1 = nonce1;
|
|
|
|
KeyPair.nonce2 = nonce2;
|
|
|
|
KeyPair.PubKeyArr = KeyPair.getPublicKey('', 'compressed');
|
|
|
|
KeyPair.addrArr = KeyPair.PubKeyArr.slice(1);
|
|
|
|
KeyPair.addrStr = GetHexFromArr(KeyPair.addrArr);
|
|
|
|
KeyPair.addr = KeyPair.addrArr;
|
|
|
|
return KeyPair;
|
|
|
|
}
|
|
|
|
nonce2++;
|
|
|
|
}
|
|
|
|
throw "ERROR. Key pair not found. Try another password!";
|
|
|
|
};
|
|
|
|
global.GetKeyPairTest = function (password,Power)
|
|
|
|
{
|
|
|
|
var KeyPair = crypto.createECDH('secp256k1');
|
|
|
|
var private2 = shaarr(password);
|
|
|
|
for(var nonce2 = 0; nonce2 < 1000000000; nonce2++)
|
|
|
|
{
|
|
|
|
private2[31] = nonce2 & 0xFF;
|
|
|
|
private2[30] = (nonce2 >> 8) & 0xFF;
|
|
|
|
private2[29] = (nonce2 >> 16) & 0xFF;
|
|
|
|
private2[28] = (nonce2 >> 24) & 0xFF;
|
|
|
|
KeyPair.setPrivateKey(Buffer.from(private2));
|
|
|
|
var Data = KeyPair.getPublicKey('', 'compressed');
|
|
|
|
if(Data[0] === 2)
|
|
|
|
{
|
|
|
|
if(Power)
|
|
|
|
{
|
|
|
|
var nBits = GetPowPower(Data.slice(1));
|
|
|
|
if(nBits < Power)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
KeyPair.PubKeyArr = Data;
|
|
|
|
KeyPair.addrArr = KeyPair.PubKeyArr.slice(1);
|
|
|
|
KeyPair.addrStr = GetHexFromArr(KeyPair.addrArr);
|
|
|
|
KeyPair.addr = KeyPair.addrArr;
|
|
|
|
return KeyPair;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw "ERROR. Key pair not found. Try another password!";
|
|
|
|
};
|
|
|
|
|
|
|
|
function GetArrFromValue(Num)
|
|
|
|
{
|
|
|
|
var arr = [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];
|
|
|
|
arr[0] = Num & 0xFF;
|
|
|
|
arr[1] = (Num >>> 8) & 0xFF;
|
|
|
|
arr[2] = (Num >>> 16) & 0xFF;
|
|
|
|
arr[3] = (Num >>> 24) & 0xFF;
|
|
|
|
var NumH = Math.floor(Num / 4294967296);
|
|
|
|
arr[4] = NumH & 0xFF;
|
|
|
|
arr[5] = (NumH >>> 8) & 0xFF;
|
|
|
|
return arr;
|
|
|
|
};
|
|
|
|
|
|
|
|
function GetHashWithNonce(hash0,nonce)
|
|
|
|
{
|
|
|
|
return shaarr2(hash0, GetArrFromValue(nonce));
|
|
|
|
};
|
|
|
|
global.GetHashWithValues = GetHashWithValues;
|
|
|
|
|
|
|
|
function GetHashWithValues(hash0,value1,value2,bNotCopy)
|
|
|
|
{
|
|
|
|
var hash;
|
|
|
|
if(bNotCopy)
|
|
|
|
hash = hash0;
|
|
|
|
else
|
|
|
|
hash = hash0.slice();
|
|
|
|
hash[0] = value1 & 0xFF;
|
|
|
|
hash[1] = (value1 >>> 8) & 0xFF;
|
|
|
|
hash[2] = (value1 >>> 16) & 0xFF;
|
|
|
|
hash[3] = (value1 >>> 24) & 0xFF;
|
|
|
|
hash[4] = value2 & 0xFF;
|
|
|
|
hash[5] = (value2 >>> 8) & 0xFF;
|
|
|
|
hash[6] = (value2 >>> 16) & 0xFF;
|
|
|
|
hash[7] = (value2 >>> 24) & 0xFF;
|
|
|
|
var arrhash = shaarr(hash);
|
|
|
|
return arrhash;
|
|
|
|
};
|
|
|
|
|
|
|
|
function GetPowPower(arrhash)
|
|
|
|
{
|
|
|
|
var SumBit = 0;
|
|
|
|
if(arrhash)
|
|
|
|
for(var i = 0; i < arrhash.length; i++)
|
|
|
|
{
|
|
|
|
var CurSum = Math.clz32(arrhash[i]) - 24;
|
|
|
|
SumBit += CurSum;
|
|
|
|
if(CurSum !== 8)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return SumBit;
|
|
|
|
};
|
|
|
|
|
|
|
|
function GetPowValue(arrhash)
|
|
|
|
{
|
|
|
|
var value = (arrhash[0] << 23) * 2 + (arrhash[1] << 16) + (arrhash[2] << 8) + arrhash[3];
|
|
|
|
value = value * 256 + arrhash[4];
|
|
|
|
value = value * 256 + arrhash[5];
|
|
|
|
return value;
|
|
|
|
};
|
|
|
|
global.CreateNoncePOWExtern = CreateNoncePOWExtern;
|
|
|
|
|
|
|
|
function CreateNoncePOWExtern(arr0,BlockNum,count,startnone)
|
|
|
|
{
|
|
|
|
var arr = [];
|
|
|
|
for(var i = 0; i < arr0.length; i++)
|
|
|
|
arr[i] = arr0[i];
|
|
|
|
if(!startnone)
|
|
|
|
startnone = 0;
|
|
|
|
var maxnonce = 0;
|
|
|
|
var supervalue = MAX_SUPER_VALUE_POW;
|
|
|
|
for(var nonce = startnone; nonce <= startnone + count; nonce++)
|
|
|
|
{
|
|
|
|
var arrhash = GetHashWithValues(arr, nonce, BlockNum, true);
|
|
|
|
var value = GetPowValue(arrhash);
|
|
|
|
if(value < supervalue)
|
|
|
|
{
|
|
|
|
maxnonce = nonce;
|
|
|
|
supervalue = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return maxnonce;
|
|
|
|
};
|
|
|
|
global.CreateNoncePOWExternMinPower = CreateNoncePOWExternMinPower;
|
|
|
|
|
|
|
|
function CreateNoncePOWExternMinPower(arr0,BlockNum,MinPow)
|
|
|
|
{
|
|
|
|
var arr = [];
|
|
|
|
for(var i = 0; i < arr0.length; i++)
|
|
|
|
arr[i] = arr0[i];
|
|
|
|
var nonce = 0;
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
var arrhash = GetHashWithValues(arr, nonce, BlockNum, true);
|
|
|
|
var power = GetPowPower(arrhash);
|
|
|
|
if(power >= MinPow)
|
|
|
|
{
|
|
|
|
return nonce;
|
|
|
|
}
|
|
|
|
nonce++;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
global.CreateNoncePOWInner = function (arr0,count)
|
|
|
|
{
|
|
|
|
var Hash;
|
|
|
|
var arr = arr0.slice();
|
|
|
|
var maxnonce = 0;
|
|
|
|
var supervalue = MAX_SUPER_VALUE_POW;
|
|
|
|
for(var nonce = 0; nonce < count; nonce++)
|
|
|
|
{
|
|
|
|
var hashTest = GetHashWithNonce(arr, nonce);
|
|
|
|
var value = GetPowValue(hashTest);
|
|
|
|
if(value < supervalue)
|
|
|
|
{
|
|
|
|
maxnonce = nonce;
|
|
|
|
supervalue = value;
|
|
|
|
Hash = hashTest;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {nonce:maxnonce, Hash:Hash};
|
|
|
|
};
|
|
|
|
global.CreateAddrPOW = function (SeqHash,AddrArr,MaxHash,Start,CountNonce,BlockNum)
|
|
|
|
{
|
|
|
|
var MaxNonce = 0;
|
|
|
|
var bFind = 0;
|
|
|
|
for(var nonce = Start; nonce < Start + CountNonce; nonce++)
|
|
|
|
{
|
|
|
|
AddrArr[6] = nonce & 0xFF;
|
|
|
|
AddrArr[7] = (nonce >>> 8) & 0xFF;
|
|
|
|
AddrArr[8] = (nonce >>> 16) & 0xFF;
|
|
|
|
AddrArr[9] = (nonce >>> 24) & 0xFF;
|
|
|
|
var HashTest = shaarrblock2(SeqHash, AddrArr, BlockNum);
|
|
|
|
if(CompareArr(MaxHash, HashTest) >= 0)
|
|
|
|
{
|
|
|
|
MaxHash = HashTest;
|
|
|
|
MaxNonce = nonce;
|
|
|
|
bFind = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(bFind)
|
|
|
|
{
|
|
|
|
AddrArr[6] = MaxNonce & 0xFF;
|
|
|
|
AddrArr[7] = (MaxNonce >>> 8) & 0xFF;
|
|
|
|
AddrArr[8] = (MaxNonce >>> 16) & 0xFF;
|
|
|
|
AddrArr[9] = (MaxNonce >>> 24) & 0xFF;
|
|
|
|
}
|
|
|
|
return {MaxHash:MaxHash, LastNonce:nonce, MaxNonce:MaxNonce, bFind:bFind};
|
|
|
|
};
|
|
|
|
|
|
|
|
function IsZeroArr(arr)
|
|
|
|
{
|
|
|
|
if(arr)
|
|
|
|
for(var i = 0; i < arr.length; i++)
|
|
|
|
{
|
|
|
|
if(arr[i])
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
function CalcHashFromArray(ArrHashes,bOriginalSeq)
|
|
|
|
{
|
|
|
|
if(bOriginalSeq === undefined)
|
|
|
|
ArrHashes.sort(CompareArr);
|
|
|
|
var Buf = [];
|
|
|
|
for(var i = 0; i < ArrHashes.length; i++)
|
|
|
|
{
|
|
|
|
var Value = ArrHashes[i];
|
|
|
|
for(var n = 0; n < Value.length; n++)
|
|
|
|
Buf.push(Value[n]);
|
|
|
|
}
|
|
|
|
if(Buf.length === 0)
|
|
|
|
return [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];
|
|
|
|
else
|
|
|
|
if(Buf.length === 32)
|
|
|
|
return Buf;
|
|
|
|
var Hash = shaarr(Buf);
|
|
|
|
return Hash;
|
|
|
|
};
|
|
|
|
|
|
|
|
function CalcHash3FromArray(ArrHashes,bOriginalSeq)
|
|
|
|
{
|
|
|
|
if(bOriginalSeq === undefined)
|
|
|
|
ArrHashes.sort(CompareArr);
|
|
|
|
var Buf = [];
|
|
|
|
for(var i = 0; i < ArrHashes.length; i++)
|
|
|
|
{
|
|
|
|
var Value = ArrHashes[i];
|
|
|
|
for(var n = 0; n < Value.length; n++)
|
|
|
|
Buf.push(Value[n]);
|
|
|
|
}
|
|
|
|
if(Buf.length === 0)
|
|
|
|
return [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];
|
|
|
|
else
|
|
|
|
if(Buf.length === 32)
|
|
|
|
return Buf;
|
|
|
|
var Hash = sha3(Buf);
|
|
|
|
return Hash;
|
|
|
|
};
|
|
|
|
|
|
|
|
function CalcMerkl3FromArray(Arr,Tree0)
|
|
|
|
{
|
|
|
|
var Tree, bSort;
|
|
|
|
if(Tree0)
|
|
|
|
{
|
|
|
|
bSort = 0;
|
|
|
|
Tree = Tree0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bSort = 1;
|
|
|
|
Tree = {Levels:[], Full:true};
|
|
|
|
}
|
|
|
|
Tree.Levels.push(Arr);
|
|
|
|
if(Arr.length < 2)
|
|
|
|
{
|
|
|
|
if(Arr.length === 0)
|
|
|
|
Tree.Root = [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];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(Arr[0].length === 32)
|
|
|
|
Tree.Root = Arr[0];
|
|
|
|
else
|
|
|
|
Tree.Root = sha3(Arr[0]);
|
|
|
|
}
|
|
|
|
return Tree;
|
|
|
|
}
|
|
|
|
if(bSort)
|
|
|
|
{
|
|
|
|
Arr.sort(CompareArr);
|
|
|
|
}
|
|
|
|
var Arr2 = [];
|
|
|
|
var len = Math.floor(Arr.length / 2);
|
|
|
|
for(var i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
var Hash = sha3arr2(Arr[i * 2], Arr[i * 2 + 1]);
|
|
|
|
Arr2.push(Hash);
|
|
|
|
}
|
|
|
|
if(len * 2 !== Arr.length)
|
|
|
|
{
|
|
|
|
Arr2.push(Arr[Arr.length - 1]);
|
|
|
|
}
|
|
|
|
return CalcMerkl3FromArray(Arr2, Tree);
|
|
|
|
};
|
|
|
|
|
|
|
|
function CalcMerkl0FromArray(Arr,Tree0)
|
|
|
|
{
|
|
|
|
var Tree, bSort;
|
|
|
|
if(Tree0)
|
|
|
|
{
|
|
|
|
bSort = 0;
|
|
|
|
Tree = Tree0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bSort = 1;
|
|
|
|
Tree = {Levels:[], Full:true};
|
|
|
|
}
|
|
|
|
Tree.Levels.push(Arr);
|
|
|
|
if(Arr.length < 2)
|
|
|
|
{
|
|
|
|
if(Arr.length === 0)
|
|
|
|
Tree.Root = [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];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(Arr[0].length === 32)
|
|
|
|
Tree.Root = Arr[0];
|
|
|
|
else
|
|
|
|
Tree.Root = shaarr(Arr[0]);
|
|
|
|
}
|
|
|
|
return Tree;
|
|
|
|
}
|
|
|
|
if(bSort)
|
|
|
|
{
|
|
|
|
Arr.sort(CompareArr);
|
|
|
|
}
|
|
|
|
var Arr2 = [];
|
|
|
|
var len = Math.floor(Arr.length / 2);
|
|
|
|
for(var i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
var Hash = shaarr2(Arr[i * 2], Arr[i * 2 + 1]);
|
|
|
|
Arr2.push(Hash);
|
|
|
|
}
|
|
|
|
if(len * 2 !== Arr.length)
|
|
|
|
{
|
|
|
|
Arr2.push(Arr[Arr.length - 1]);
|
|
|
|
}
|
|
|
|
return CalcMerkl0FromArray(Arr2, Tree);
|
|
|
|
};
|
|
|
|
|
|
|
|
function CalcMerklFromArray(BlockNum,Arr)
|
|
|
|
{
|
|
|
|
if(BlockNum >= global.BLOCKNUM_TICKET_ALGO)
|
|
|
|
{
|
|
|
|
return CalcMerkl3FromArray(Arr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return CalcMerkl0FromArray(Arr);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function CalcTreeHashFromArrBody(BlockNum,arrContent)
|
|
|
|
{
|
|
|
|
if(arrContent)
|
|
|
|
{
|
|
|
|
var arrHASH = [];
|
|
|
|
for(var i = 0; i < arrContent.length; i++)
|
|
|
|
{
|
|
|
|
var HASH;
|
|
|
|
if(BlockNum >= global.BLOCKNUM_TICKET_ALGO)
|
|
|
|
HASH = sha3(arrContent[i]);
|
|
|
|
else
|
|
|
|
HASH = shaarr(arrContent[i]);
|
|
|
|
arrHASH.push(HASH);
|
|
|
|
}
|
|
|
|
var Tree = CalcMerklFromArray(BlockNum, arrHASH);
|
|
|
|
return Tree.Root;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return [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];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function TestMerklTree()
|
|
|
|
{
|
|
|
|
var h1 = [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];
|
|
|
|
var h2 = shaarr("2");
|
|
|
|
var h3 = shaarr("3");
|
|
|
|
var h4 = shaarr("4");
|
|
|
|
var h5 = shaarr("5");
|
|
|
|
var Tree = {RecalcCount:0};
|
|
|
|
var CalcMap = {};
|
|
|
|
Tree.LevelsHash = [[h1, h2]];
|
|
|
|
Tree.RecalcCount = 0;
|
|
|
|
CalcMap[0] = 1;
|
|
|
|
CalcMap[1] = 1;
|
|
|
|
UpdateMerklTree(Tree, CalcMap, 0);
|
|
|
|
CalcMap = {};
|
|
|
|
Tree.LevelsHash[0] = [h1, h2, h3, h4];
|
|
|
|
Tree.RecalcCount = 0;
|
|
|
|
CalcMap[2] = 1;
|
|
|
|
CalcMap[3] = 1;
|
|
|
|
UpdateMerklTree(Tree, CalcMap, 0);
|
|
|
|
CalcMap = {};
|
|
|
|
Tree.LevelsHash[0] = [h1, h2, h3];
|
|
|
|
Tree.RecalcCount = 0;
|
|
|
|
CalcMap[Tree.LevelsHash[0].length - 1] = 1;
|
|
|
|
UpdateMerklTree(Tree, CalcMap, 0);
|
|
|
|
ToLog("Root=" + GetHexFromArr(Tree.Root));
|
|
|
|
ToLog("RecalcCount=" + Tree.RecalcCount);
|
|
|
|
var TreeTest = {LevelsArr:Tree.LevelsHash, LevelsCalc:[[]], RecalcCount:0};
|
|
|
|
UpdateMerklTree0(TreeTest, 0);
|
|
|
|
ToLog("HashTest=" + GetHexFromArr(TreeTest.Root));
|
|
|
|
if(CompareArr(TreeTest.Root, Tree.Root) !== 0)
|
|
|
|
ToLog("=========ERROR HASHTEST==============");
|
|
|
|
};
|
|
|
|
|
|
|
|
function UpdateMerklTree(Tree,CalcMap,NumLevel)
|
|
|
|
{
|
|
|
|
var HashArr = Tree.LevelsHash[NumLevel];
|
|
|
|
if(!HashArr || !HashArr.length)
|
|
|
|
{
|
|
|
|
Tree.LevelsHash.length = NumLevel + 1;
|
|
|
|
Tree.MaxLevel = NumLevel;
|
|
|
|
Tree.Root = [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];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if(HashArr.length === 1)
|
|
|
|
{
|
|
|
|
Tree.LevelsHash.length = NumLevel + 1;
|
|
|
|
Tree.MaxLevel = NumLevel;
|
|
|
|
Tree.Root = HashArr[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
var CalcMap2 = {};
|
|
|
|
var HashArr2 = Tree.LevelsHash[NumLevel + 1];
|
|
|
|
if(!HashArr2)
|
|
|
|
{
|
|
|
|
HashArr2 = [];
|
|
|
|
Tree.LevelsHash[NumLevel + 1] = HashArr2;
|
|
|
|
}
|
|
|
|
var len2 = Math.floor(HashArr.length / 2);
|
|
|
|
HashArr2.length = Math.floor(0.5 + HashArr.length / 2);
|
|
|
|
var Count = 0;
|
|
|
|
var LastIndex = HashArr.length - 1;
|
|
|
|
for(var key in CalcMap)
|
|
|
|
{
|
|
|
|
var i2 = Math.floor(key / 2);
|
|
|
|
if(i2 < len2)
|
|
|
|
{
|
|
|
|
Count++;
|
|
|
|
CalcMap2[i2] = 1;
|
|
|
|
HashArr2[i2] = sha3(arr2(HashArr[i2 * 2], HashArr[i2 * 2 + 1]));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(key > LastIndex)
|
|
|
|
{
|
|
|
|
CalcMap2[i2] = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if(i2 === len2)
|
|
|
|
{
|
|
|
|
Count++;
|
|
|
|
CalcMap2[i2] = 1;
|
|
|
|
HashArr2[i2] = HashArr[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(Count)
|
|
|
|
{
|
|
|
|
Tree.RecalcCount += Count;
|
|
|
|
UpdateMerklTree(Tree, CalcMap2, NumLevel + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function UpdateMerklTreeErrr(Tree,CalcMap,NumLevel)
|
|
|
|
{
|
|
|
|
var HashArr = Tree.LevelsHash[NumLevel];
|
|
|
|
if(!HashArr || !HashArr.length)
|
|
|
|
{
|
|
|
|
Tree.LevelsHash.length = NumLevel + 1;
|
|
|
|
Tree.MaxLevel = NumLevel;
|
|
|
|
Tree.Root = [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];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if(HashArr.length === 1)
|
|
|
|
{
|
|
|
|
Tree.LevelsHash.length = NumLevel + 1;
|
|
|
|
Tree.MaxLevel = NumLevel;
|
|
|
|
Tree.Root = HashArr[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
var CalcMap2 = {};
|
|
|
|
var HashArr2 = Tree.LevelsHash[NumLevel + 1];
|
|
|
|
if(!HashArr2)
|
|
|
|
{
|
|
|
|
HashArr2 = [];
|
|
|
|
Tree.LevelsHash[NumLevel + 1] = HashArr2;
|
|
|
|
}
|
|
|
|
var len2 = Math.floor(HashArr.length / 2);
|
|
|
|
var Count = 0;
|
|
|
|
var LastIndex = HashArr.length - 1;
|
|
|
|
for(var key in CalcMap)
|
|
|
|
{
|
|
|
|
var i = Math.floor(key / 2);
|
|
|
|
if(i < len2)
|
|
|
|
{
|
|
|
|
Count++;
|
|
|
|
CalcMap2[i] = 1;
|
|
|
|
HashArr2[i] = sha3(arr2(HashArr[i * 2], HashArr[i * 2 + 1]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(len2 * 2 !== HashArr.length && CalcMap[LastIndex] !== undefined)
|
|
|
|
{
|
|
|
|
i = len2;
|
|
|
|
len2++;
|
|
|
|
Count++;
|
|
|
|
CalcMap2[i] = 1;
|
|
|
|
HashArr2[i] = HashArr[LastIndex];
|
|
|
|
if(HashArr2.length !== len2)
|
|
|
|
{
|
|
|
|
Count++;
|
|
|
|
HashArr2.length = len2;
|
|
|
|
delete CalcMap2[len2 - 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(Count)
|
|
|
|
{
|
|
|
|
Tree.RecalcCount += Count;
|
|
|
|
UpdateMerklTree(Tree, CalcMap2, NumLevel + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function UpdateMerklTree0(Tree,NumLevel)
|
|
|
|
{
|
|
|
|
var HashArr = Tree.LevelsArr[NumLevel];
|
|
|
|
if(!HashArr || !HashArr.length)
|
|
|
|
{
|
|
|
|
Tree.LevelsArr.length = NumLevel + 1;
|
|
|
|
Tree.MaxLevel = NumLevel;
|
|
|
|
Tree.Root = [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];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if(HashArr.length === 1)
|
|
|
|
{
|
|
|
|
Tree.LevelsArr.length = NumLevel + 1;
|
|
|
|
Tree.MaxLevel = NumLevel;
|
|
|
|
Tree.Root = HashArr[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
var CalcArr = Tree.LevelsCalc[NumLevel];
|
|
|
|
var HashArr2 = Tree.LevelsArr[NumLevel + 1];
|
|
|
|
if(!HashArr2)
|
|
|
|
{
|
|
|
|
HashArr2 = [];
|
|
|
|
Tree.LevelsArr[NumLevel + 1] = HashArr2;
|
|
|
|
}
|
|
|
|
var CalcArr2 = Tree.LevelsCalc[NumLevel + 1];
|
|
|
|
if(!CalcArr2)
|
|
|
|
{
|
|
|
|
CalcArr2 = [];
|
|
|
|
Tree.LevelsCalc[NumLevel + 1] = CalcArr2;
|
|
|
|
}
|
|
|
|
var len2 = Math.floor(HashArr.length / 2);
|
|
|
|
var Count = 0;
|
|
|
|
for(var i = 0; i < len2; i++)
|
|
|
|
{
|
|
|
|
if(!CalcArr[i * 2] || !CalcArr[i * 2 + 1])
|
|
|
|
{
|
|
|
|
CalcArr[i * 2] = 1;
|
|
|
|
CalcArr[i * 2 + 1] = 1;
|
|
|
|
Count++;
|
|
|
|
CalcArr2[i] = 0;
|
|
|
|
HashArr2[i] = sha3(arr2(HashArr[i * 2], HashArr[i * 2 + 1]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var LastIndex = HashArr.length - 1;
|
|
|
|
if(len2 * 2 !== HashArr.length || !CalcArr[LastIndex])
|
|
|
|
{
|
|
|
|
i = len2;
|
|
|
|
len2++;
|
|
|
|
Count++;
|
|
|
|
CalcArr[LastIndex] = 1;
|
|
|
|
CalcArr2[i] = 0;
|
|
|
|
HashArr2[i] = HashArr[LastIndex];
|
|
|
|
}
|
|
|
|
if(HashArr2.length !== len2)
|
|
|
|
{
|
|
|
|
Count++;
|
|
|
|
HashArr2.length = len2;
|
|
|
|
CalcArr2.length = len2;
|
|
|
|
CalcArr2[len2 - 1] = 0;
|
|
|
|
}
|
|
|
|
if(Count)
|
|
|
|
{
|
|
|
|
Tree.RecalcCount += Count;
|
|
|
|
UpdateMerklTree0(Tree, NumLevel + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, 0, 2147516545, 2147483648, 32777,
|
|
|
|
2147483648, 138, 0, 136, 0, 2147516425, 0, 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, 2147483648,
|
|
|
|
32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, 2147516545, 2147483648, 32896, 2147483648, 2147483649,
|
|
|
|
0, 2147516424, 2147483648];
|
|
|
|
|
|
|
|
function Mesh(s,Count)
|
|
|
|
{
|
|
|
|
var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15,
|
|
|
|
b16, b17, b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, b34, b35, b36, b37, b38, b39, b40,
|
|
|
|
b41, b42, b43, b44, b45, b46, b47, b48, b49;
|
|
|
|
for(n = 0; n < Count; n += 2)
|
|
|
|
{
|
|
|
|
c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40];
|
|
|
|
c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41];
|
|
|
|
c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42];
|
|
|
|
c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43];
|
|
|
|
c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44];
|
|
|
|
c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45];
|
|
|
|
c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46];
|
|
|
|
c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47];
|
|
|
|
c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48];
|
|
|
|
c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49];
|
|
|
|
h = c8 ^ ((c2 << 1) | (c3 >>> 31));
|
|
|
|
l = c9 ^ ((c3 << 1) | (c2 >>> 31));
|
|
|
|
s[0] ^= h;
|
|
|
|
s[1] ^= l;
|
|
|
|
s[10] ^= h;
|
|
|
|
s[11] ^= l;
|
|
|
|
s[20] ^= h;
|
|
|
|
s[21] ^= l;
|
|
|
|
s[30] ^= h;
|
|
|
|
s[31] ^= l;
|
|
|
|
s[40] ^= h;
|
|
|
|
s[41] ^= l;
|
|
|
|
h = c0 ^ ((c4 << 1) | (c5 >>> 31));
|
|
|
|
l = c1 ^ ((c5 << 1) | (c4 >>> 31));
|
|
|
|
s[2] ^= h;
|
|
|
|
s[3] ^= l;
|
|
|
|
s[12] ^= h;
|
|
|
|
s[13] ^= l;
|
|
|
|
s[22] ^= h;
|
|
|
|
s[23] ^= l;
|
|
|
|
s[32] ^= h;
|
|
|
|
s[33] ^= l;
|
|
|
|
s[42] ^= h;
|
|
|
|
s[43] ^= l;
|
|
|
|
h = c2 ^ ((c6 << 1) | (c7 >>> 31));
|
|
|
|
l = c3 ^ ((c7 << 1) | (c6 >>> 31));
|
|
|
|
s[4] ^= h;
|
|
|
|
s[5] ^= l;
|
|
|
|
s[14] ^= h;
|
|
|
|
s[15] ^= l;
|
|
|
|
s[24] ^= h;
|
|
|
|
s[25] ^= l;
|
|
|
|
s[34] ^= h;
|
|
|
|
s[35] ^= l;
|
|
|
|
s[44] ^= h;
|
|
|
|
s[45] ^= l;
|
|
|
|
h = c4 ^ ((c8 << 1) | (c9 >>> 31));
|
|
|
|
l = c5 ^ ((c9 << 1) | (c8 >>> 31));
|
|
|
|
s[6] ^= h;
|
|
|
|
s[7] ^= l;
|
|
|
|
s[16] ^= h;
|
|
|
|
s[17] ^= l;
|
|
|
|
s[26] ^= h;
|
|
|
|
s[27] ^= l;
|
|
|
|
s[36] ^= h;
|
|
|
|
s[37] ^= l;
|
|
|
|
s[46] ^= h;
|
|
|
|
s[47] ^= l;
|
|
|
|
h = c6 ^ ((c0 << 1) | (c1 >>> 31));
|
|
|
|
l = c7 ^ ((c1 << 1) | (c0 >>> 31));
|
|
|
|
s[8] ^= h;
|
|
|
|
s[9] ^= l;
|
|
|
|
s[18] ^= h;
|
|
|
|
s[19] ^= l;
|
|
|
|
s[28] ^= h;
|
|
|
|
s[29] ^= l;
|
|
|
|
s[38] ^= h;
|
|
|
|
s[39] ^= l;
|
|
|
|
s[48] ^= h;
|
|
|
|
s[49] ^= l;
|
|
|
|
b0 = s[0];
|
|
|
|
b1 = s[1];
|
|
|
|
b32 = (s[11] << 4) | (s[10] >>> 28);
|
|
|
|
b33 = (s[10] << 4) | (s[11] >>> 28);
|
|
|
|
b14 = (s[20] << 3) | (s[21] >>> 29);
|
|
|
|
b15 = (s[21] << 3) | (s[20] >>> 29);
|
|
|
|
b46 = (s[31] << 9) | (s[30] >>> 23);
|
|
|
|
b47 = (s[30] << 9) | (s[31] >>> 23);
|
|
|
|
b28 = (s[40] << 18) | (s[41] >>> 14);
|
|
|
|
b29 = (s[41] << 18) | (s[40] >>> 14);
|
|
|
|
b20 = (s[2] << 1) | (s[3] >>> 31);
|
|
|
|
b21 = (s[3] << 1) | (s[2] >>> 31);
|
|
|
|
b2 = (s[13] << 12) | (s[12] >>> 20);
|
|
|
|
b3 = (s[12] << 12) | (s[13] >>> 20);
|
|
|
|
b34 = (s[22] << 10) | (s[23] >>> 22);
|
|
|
|
b35 = (s[23] << 10) | (s[22] >>> 22);
|
|
|
|
b16 = (s[33] << 13) | (s[32] >>> 19);
|
|
|
|
b17 = (s[32] << 13) | (s[33] >>> 19);
|
|
|
|
b48 = (s[42] << 2) | (s[43] >>> 30);
|
|
|
|
b49 = (s[43] << 2) | (s[42] >>> 30);
|
|
|
|
b40 = (s[5] << 30) | (s[4] >>> 2);
|
|
|
|
b41 = (s[4] << 30) | (s[5] >>> 2);
|
|
|
|
b22 = (s[14] << 6) | (s[15] >>> 26);
|
|
|
|
b23 = (s[15] << 6) | (s[14] >>> 26);
|
|
|
|
b4 = (s[25] << 11) | (s[24] >>> 21);
|
|
|
|
b5 = (s[24] << 11) | (s[25] >>> 21);
|
|
|
|
b36 = (s[34] << 15) | (s[35] >>> 17);
|
|
|
|
b37 = (s[35] << 15) | (s[34] >>> 17);
|
|
|
|
b18 = (s[45] << 29) | (s[44] >>> 3);
|
|
|
|
b19 = (s[44] << 29) | (s[45] >>> 3);
|
|
|
|
b10 = (s[6] << 28) | (s[7] >>> 4);
|
|
|
|
b11 = (s[7] << 28) | (s[6] >>> 4);
|
|
|
|
b42 = (s[17] << 23) | (s[16] >>> 9);
|
|
|
|
b43 = (s[16] << 23) | (s[17] >>> 9);
|
|
|
|
b24 = (s[26] << 25) | (s[27] >>> 7);
|
|
|
|
b25 = (s[27] << 25) | (s[26] >>> 7);
|
|
|
|
b6 = (s[36] << 21) | (s[37] >>> 11);
|
|
|
|
b7 = (s[37] << 21) | (s[36] >>> 11);
|
|
|
|
b38 = (s[47] << 24) | (s[46] >>> 8);
|
|
|
|
b39 = (s[46] << 24) | (s[47] >>> 8);
|
|
|
|
b30 = (s[8] << 27) | (s[9] >>> 5);
|
|
|
|
b31 = (s[9] << 27) | (s[8] >>> 5);
|
|
|
|
b12 = (s[18] << 20) | (s[19] >>> 12);
|
|
|
|
b13 = (s[19] << 20) | (s[18] >>> 12);
|
|
|
|
b44 = (s[29] << 7) | (s[28] >>> 25);
|
|
|
|
b45 = (s[28] << 7) | (s[29] >>> 25);
|
|
|
|
b26 = (s[38] << 8) | (s[39] >>> 24);
|
|
|
|
b27 = (s[39] << 8) | (s[38] >>> 24);
|
|
|
|
b8 = (s[48] << 14) | (s[49] >>> 18);
|
|
|
|
b9 = (s[49] << 14) | (s[48] >>> 18);
|
|
|
|
s[0] = b0 ^ (~b2 & b4);
|
|
|
|
s[1] = b1 ^ (~b3 & b5);
|
|
|
|
s[10] = b10 ^ (~b12 & b14);
|
|
|
|
s[11] = b11 ^ (~b13 & b15);
|
|
|
|
s[20] = b20 ^ (~b22 & b24);
|
|
|
|
s[21] = b21 ^ (~b23 & b25);
|
|
|
|
s[30] = b30 ^ (~b32 & b34);
|
|
|
|
s[31] = b31 ^ (~b33 & b35);
|
|
|
|
s[40] = b40 ^ (~b42 & b44);
|
|
|
|
s[41] = b41 ^ (~b43 & b45);
|
|
|
|
s[2] = b2 ^ (~b4 & b6);
|
|
|
|
s[3] = b3 ^ (~b5 & b7);
|
|
|
|
s[12] = b12 ^ (~b14 & b16);
|
|
|
|
s[13] = b13 ^ (~b15 & b17);
|
|
|
|
s[22] = b22 ^ (~b24 & b26);
|
|
|
|
s[23] = b23 ^ (~b25 & b27);
|
|
|
|
s[32] = b32 ^ (~b34 & b36);
|
|
|
|
s[33] = b33 ^ (~b35 & b37);
|
|
|
|
s[42] = b42 ^ (~b44 & b46);
|
|
|
|
s[43] = b43 ^ (~b45 & b47);
|
|
|
|
s[4] = b4 ^ (~b6 & b8);
|
|
|
|
s[5] = b5 ^ (~b7 & b9);
|
|
|
|
s[14] = b14 ^ (~b16 & b18);
|
|
|
|
s[15] = b15 ^ (~b17 & b19);
|
|
|
|
s[24] = b24 ^ (~b26 & b28);
|
|
|
|
s[25] = b25 ^ (~b27 & b29);
|
|
|
|
s[34] = b34 ^ (~b36 & b38);
|
|
|
|
s[35] = b35 ^ (~b37 & b39);
|
|
|
|
s[44] = b44 ^ (~b46 & b48);
|
|
|
|
s[45] = b45 ^ (~b47 & b49);
|
|
|
|
s[6] = b6 ^ (~b8 & b0);
|
|
|
|
s[7] = b7 ^ (~b9 & b1);
|
|
|
|
s[16] = b16 ^ (~b18 & b10);
|
|
|
|
s[17] = b17 ^ (~b19 & b11);
|
|
|
|
s[26] = b26 ^ (~b28 & b20);
|
|
|
|
s[27] = b27 ^ (~b29 & b21);
|
|
|
|
s[36] = b36 ^ (~b38 & b30);
|
|
|
|
s[37] = b37 ^ (~b39 & b31);
|
|
|
|
s[46] = b46 ^ (~b48 & b40);
|
|
|
|
s[47] = b47 ^ (~b49 & b41);
|
|
|
|
s[8] = b8 ^ (~b0 & b2);
|
|
|
|
s[9] = b9 ^ (~b1 & b3);
|
|
|
|
s[18] = b18 ^ (~b10 & b12);
|
|
|
|
s[19] = b19 ^ (~b11 & b13);
|
|
|
|
s[28] = b28 ^ (~b20 & b22);
|
|
|
|
s[29] = b29 ^ (~b21 & b23);
|
|
|
|
s[38] = b38 ^ (~b30 & b32);
|
|
|
|
s[39] = b39 ^ (~b31 & b33);
|
|
|
|
s[48] = b48 ^ (~b40 & b42);
|
|
|
|
s[49] = b49 ^ (~b41 & b43);
|
|
|
|
s[0] ^= RC[n];
|
|
|
|
s[1] ^= RC[n + 1];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function WriteNumToArr0(body,Num)
|
|
|
|
{
|
|
|
|
body[0] ^= Num & 0xFF;
|
|
|
|
body[1] ^= (Num >>> 8) & 0xFF;
|
|
|
|
body[2] ^= (Num >>> 16) & 0xFF;
|
|
|
|
body[3] ^= (Num >>> 24) & 0xFF;
|
|
|
|
};
|
|
|
|
|
|
|
|
function ClientHex(Str,nonce)
|
|
|
|
{
|
|
|
|
var arr = [0, 0, 0, 0];
|
|
|
|
for(var i = 0; i < Str.length; i++)
|
|
|
|
arr[4 + i] = Str.charCodeAt(i);
|
|
|
|
WriteNumToArr0(arr, nonce);
|
|
|
|
Mesh(arr, 60);
|
|
|
|
return GetHexFromArr(arr) + "-" + nonce;
|
|
|
|
};
|
|
|
|
global.ClientHex = ClientHex;
|
|
|
|
var GlobalCryptID = 0;
|
|
|
|
var DeltaTimeCryptID = new Date(2018, 1, 1) - 0;
|
|
|
|
|
|
|
|
function Encrypt(Arr,Arr2,ArrSecret)
|
|
|
|
{
|
|
|
|
const StartLen = 9;
|
|
|
|
var arrRnd = Buffer.alloc(StartLen);
|
|
|
|
GlobalCryptID++;
|
|
|
|
arrRnd.writeUInt32LE(GlobalCryptID, 1, 4);
|
|
|
|
var Time = Math.floor((Date.now() - DeltaTimeCryptID) / 1000);
|
|
|
|
arrRnd.writeUInt32LE(Time, 5, 4);
|
|
|
|
Arr2[0] = Arr[0];
|
|
|
|
for(var i = 1; i < StartLen; i++)
|
|
|
|
Arr2[i] = arrRnd[i];
|
|
|
|
var SecretBuf = Buffer.concat([Arr2.slice(0, StartLen), ArrSecret]);
|
|
|
|
DoSecret(Arr, Arr2, SecretBuf, 9);
|
|
|
|
};
|
|
|
|
|
|
|
|
function Decrypt(Arr,Arr2,ArrSecret)
|
|
|
|
{
|
|
|
|
const StartLen = 9;
|
|
|
|
var SecretBuf = Buffer.concat([Arr.slice(0, StartLen), ArrSecret]);
|
|
|
|
DoSecret(Arr, Arr2, SecretBuf, StartLen);
|
|
|
|
};
|
|
|
|
|
|
|
|
function DoSecret(Arr,Arr2,SecretBuf,StartLen)
|
|
|
|
{
|
|
|
|
var CryptID = SecretBuf.readUInt32LE(1, 4);
|
|
|
|
var Pos = StartLen;
|
|
|
|
while(Pos < Arr.length)
|
|
|
|
{
|
|
|
|
var CurBuf = shaarr(SecretBuf);
|
|
|
|
for(var i = 0; i < 32 && Pos < Arr.length; i++, Pos++)
|
|
|
|
{
|
|
|
|
Arr2[Pos] = Arr[Pos] ^ CurBuf[i];
|
|
|
|
}
|
|
|
|
CryptID++;
|
|
|
|
SecretBuf.writeUInt32LE(CryptID, 5, 4);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function TestEncryptDecrypt()
|
|
|
|
{
|
|
|
|
var ArrSecret = Buffer.from([1, 1, 1, 1, 1, 1]);
|
|
|
|
var Arr = GetArrFromStr(" Secret message", 64);
|
|
|
|
var Arr2 = Buffer.from(new Uint8Array(Arr.length));
|
|
|
|
var Arr3 = Buffer.from(new Uint8Array(Arr.length));
|
|
|
|
console.log("Message:");
|
|
|
|
console.log(Arr);
|
|
|
|
console.log("-------------------");
|
|
|
|
Encrypt(Arr, Arr2, ArrSecret);
|
|
|
|
console.log("Encrypt:");
|
|
|
|
console.log(Arr2);
|
|
|
|
console.log("-------------------");
|
|
|
|
Decrypt(Arr2, Arr3, ArrSecret);
|
|
|
|
console.log("Decrypt:");
|
|
|
|
console.log(Utf8ArrayToStr(Arr3.slice(9)));
|
|
|
|
};
|
|
|
|
|
|
|
|
function toUTF8Array(str)
|
|
|
|
{
|
|
|
|
var utf8 = [];
|
|
|
|
for(var i = 0; str && i < str.length; i++)
|
|
|
|
{
|
|
|
|
var charcode = str.charCodeAt(i);
|
|
|
|
if(charcode < 0x80)
|
|
|
|
utf8.push(charcode);
|
|
|
|
else
|
|
|
|
if(charcode < 0x800)
|
|
|
|
{
|
|
|
|
utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if(charcode < 0xd800 || charcode >= 0xe000)
|
|
|
|
{
|
|
|
|
utf8.push(0xe0 | (charcode >> 12), 0x80 | ((charcode >> 6) & 0x3f), 0x80 | (charcode & 0x3f));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));
|
|
|
|
utf8.push(0xf0 | (charcode >> 18), 0x80 | ((charcode >> 12) & 0x3f), 0x80 | ((charcode >> 6) & 0x3f), 0x80 | (charcode & 0x3f));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return utf8;
|
|
|
|
};
|
|
|
|
|
|
|
|
function Utf8ArrayToStr(array)
|
|
|
|
{
|
|
|
|
var out, i, len, c;
|
|
|
|
var char2, char3;
|
|
|
|
out = "";
|
|
|
|
len = array.length;
|
|
|
|
i = 0;
|
|
|
|
while(i < len)
|
|
|
|
{
|
|
|
|
c = array[i++];
|
|
|
|
switch(c >> 4)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
case 4:
|
|
|
|
case 5:
|
|
|
|
case 6:
|
|
|
|
case 7:
|
|
|
|
out += String.fromCharCode(c);
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
case 13:
|
|
|
|
char2 = array[i++];
|
|
|
|
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
|
|
|
|
break;
|
|
|
|
case 14:
|
|
|
|
char2 = array[i++];
|
|
|
|
char3 = array[i++];
|
|
|
|
out += String.fromCharCode(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(var i = 0; i < out.length; i++)
|
|
|
|
{
|
|
|
|
if(out.charCodeAt(i) === 0)
|
|
|
|
{
|
|
|
|
out = out.substr(0, i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
};
|
|
|
|
|
|
|
|
function GetArr32FromStr(Str)
|
|
|
|
{
|
|
|
|
return GetArrFromStr(Str, 32);
|
|
|
|
};
|
|
|
|
|
|
|
|
function GetArrFromStr(Str,Len)
|
|
|
|
{
|
|
|
|
var arr = toUTF8Array(Str);
|
|
|
|
for(var i = arr.length; i < Len; i++)
|
|
|
|
{
|
|
|
|
arr[i] = 0;
|
|
|
|
}
|
|
|
|
return arr.slice(0, Len);
|
|
|
|
};
|
|
|
|
global.CalcHash3FromArray = CalcHash3FromArray;
|
|
|
|
global.CalcHashFromArray = CalcHashFromArray;
|
|
|
|
global.CalcMerklFromArray = CalcMerklFromArray;
|
|
|
|
global.CalcTreeHashFromArrBody = CalcTreeHashFromArrBody;
|
|
|
|
global.UpdateMerklTree = UpdateMerklTree;
|
|
|
|
global.IsZeroArr = IsZeroArr;
|
|
|
|
global.GetHashWithNonce = GetHashWithNonce;
|
|
|
|
global.GetPowPower = GetPowPower;
|
|
|
|
global.GetArrFromValue = GetArrFromValue;
|
|
|
|
global.GetPowValue = GetPowValue;
|
|
|
|
global.Mesh = Mesh;
|
|
|
|
global.Encrypt = Encrypt;
|
|
|
|
global.Decrypt = Decrypt;
|
|
|
|
global.toUTF8Array = toUTF8Array;
|
|
|
|
global.Utf8ArrayToStr = Utf8ArrayToStr;
|
|
|
|
global.GetArrFromStr = GetArrFromStr;
|
|
|
|
global.IsDeveloperAccount = function (Key)
|
|
|
|
{
|
|
|
|
for(var i = 0; i < global.DEVELOP_PUB_KEY_ARR.length; i++)
|
|
|
|
if(CompareArr(Key, global.DEVELOP_PUB_KEY_ARR[i]) === 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
global.DEVELOP_PUB_KEY_ARR = ["0222263942b11f7a78e11c43903094f870a2bf728bc8be085023b4eaf4e6228cd9", "02250c8c8f7f7e1468cdc5e9b9203841ba14250e2f480f77ebcd502f3e691506d8",
|
|
|
|
"027c0caec4e6f8f08d220f6dab24bb6f53d3f1d7b95231216805d9fac85d34a95f", "025defd5b884cc02f6948cd0d62b03d7b7445bf942206ab935158b6be8f0f7a2ce",
|
|
|
|
"024a97d69cd81c965f162b4b8b7b506263bc8aec8dbcea9eec59f73b5b470a0be1", ];
|
|
|
|
for(var i = 0; i < DEVELOP_PUB_KEY_ARR.length; i++)
|
|
|
|
DEVELOP_PUB_KEY_ARR[i] = Buffer.from(GetArrFromHex(DEVELOP_PUB_KEY_ARR[i]));
|
|
|
|
global.DEVELOP_PUB_KEY = DEVELOP_PUB_KEY_ARR[0];
|
|
|
|
global.DEVELOP_PUB_KEY0 = Buffer.from(GetArrFromHex("022e80aa78bc07c72781fac12488096f0bfa7b4f48fbab0f2a92e208d1ee3654df"));
|
|
|
|
if(LOCAL_RUN)
|
|
|
|
{
|
|
|
|
global.DEVELOP_PUB_KEY0 = Buffer.from(GetArrFromHex("026A04AB98D9E4774AD806E302DDDEB63BEA16B5CB5F223EE77478E861BB583EB3"));
|
|
|
|
global.DEVELOP_PUB_KEY = global.DEVELOP_PUB_KEY0;
|
|
|
|
}
|
|
|
|
global.ARR_PUB_KEY = ["027ae0dce92d8be1f893525b226695ddf0fe6ad756349a76777ff51f3b59067d70", "02769165a6f9950d023a415ee668b80bb96b5c9ae2035d97bdfb44f356175a44ff",
|
|
|
|
"021566c6feb5495594fc4bbea27795e1db5a663b3fe81ea9846268d5c394e24c23", "0215accbc993e67216c9b7f3912b29b91671864e861e61ab73589913c946839efa",
|
|
|
|
"0270e0c5acb8eefe7faddac45503da4885e02fb554975d12907f6c33ac6c6bdba5", "0202f2aad628f46d433faf70ba6bf12ab9ed96a46923b592a72508dc43af36cb80",
|
|
|
|
"0254f373fc44ac4a3e80ec8cb8cc3693a856caa82e0493067bdead78ce8ec354b8", "027617f9511b0b0cdbda8f3e17907732731296321846f3fd6fd19460f7227d9482",
|
|
|
|
];
|
|
|
|
if(global.TEST_NETWORK || LOCAL_RUN)
|
|
|
|
{
|
|
|
|
for(var i = 0; i < 100; i++)
|
|
|
|
global.ARR_PUB_KEY[i] = GetHexFromArr(DEVELOP_PUB_KEY0);
|
|
|
|
global.DEVELOP_PUB_KEY_ARR = [DEVELOP_PUB_KEY0];
|
|
|
|
global.DEVELOP_PUB_KEY = DEVELOP_PUB_KEY_ARR[0];
|
|
|
|
}
|