Advertisement
Guest User

Untitled

a guest
Dec 23rd, 2023
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 4.22 KB | Cybersecurity | 0 0
  1. 'use strict';
  2.  
  3. var isObject = require('./utils').isObject,
  4.  
  5.     Parallel = require('paralleljs'),
  6.  
  7.     defaultOptions = {
  8.         resolved: function() {},
  9.  
  10.         evalPath: null,
  11.         sha3Path: null,
  12.  
  13.         workersCount: navigator.hardwareConcurrency || 4,
  14.         workersLifetime: 15,  // seconds
  15.         workersOffset: 1
  16.     };
  17.  
  18. function POW(options) {
  19.     if (!isObject(options)) {
  20.         options = {};
  21.     }
  22.  
  23.     this.options = Object.assign({}, defaultOptions, options);
  24. }
  25.  
  26. POW.isSupported = Parallel.isSupported;
  27.  
  28. POW.prototype = {
  29.     solve: function(challenge) {
  30.         challenge = Object.entries(challenge);
  31.  
  32.         this.startedOps = 0;
  33.         this.doneOps = 0;
  34.         this.results = {};
  35.  
  36.         challenge.forEach(function(ch) {
  37.             var key = ch[0],
  38.                 value = ch[1],
  39.                 stamp, prefix;
  40.  
  41.             if (!value.algorithm) {
  42.                 return;
  43.             }
  44.             stamp = this.makeStamp(value);
  45.             prefix = this.makePrefix(value);
  46.  
  47.             this.startedOps++;
  48.             this.results[key] = null;
  49.  
  50.             this.spawn(key, stamp, prefix);
  51.         }.bind(this));
  52.     },
  53.     spawn: function(key, stamp, prefix) {
  54.         var data = [],
  55.             expiresAt = Date.now() / 1000 + this.options.workersLifetime,
  56.             parallel;
  57.  
  58.         for (var i = 0; i < this.options.workersCount; i++) {
  59.             data.push({
  60.                 key: key,
  61.                 stamp: stamp,
  62.                 prefix: prefix,
  63.                 offset: this.options.workersOffset + i,
  64.                 step: this.options.workersCount,
  65.                 expiresAt: expiresAt
  66.             });
  67.         }
  68.  
  69.         parallel = new Parallel(data, {
  70.             evalPath: this.options.evalPath,
  71.             maxWorkers: this.options.workersCount
  72.         });
  73.         parallel.require(this.options.sha3Path).race(workersSolve).then(this.resolved.bind(this));
  74.     },
  75.     resolved: function(results) {
  76.         var result = null,
  77.             resultsPairs = Object.entries(results);
  78.  
  79.         for (var i = 0; i < resultsPairs.length; i++) {
  80.             if (resultsPairs[i][1] !== null) {
  81.                 result = resultsPairs[i][1];
  82.                 break;
  83.             }
  84.         }
  85.  
  86.         this.results[result.key] = result.counter;
  87.  
  88.         if (++this.doneOps !== this.startedOps) {
  89.             return;
  90.         }
  91.  
  92.         if (!this.checkResults()) {
  93.             this.options.resolved({
  94.                 type: 'pow'
  95.             });
  96.             return;
  97.         }
  98.  
  99.         this.options.resolved({
  100.             type: 'pow',
  101.             results: this.results,
  102.             key: this.options.challengeKey
  103.         });
  104.     },
  105.     checkResults: function() {
  106.         var results = Object.values(this.results);
  107.  
  108.         return results.every(Boolean);
  109.     },
  110.  
  111.     makeStamp: function(challenge) {
  112.         return [
  113.             challenge.algorithm.version,
  114.             challenge.complexity,
  115.             challenge.timestamp,
  116.             challenge.algorithm.resourse,
  117.             challenge.algorithm.extension,
  118.             challenge.random_string // jshint ignore:line
  119.         ].join(':');
  120.     },
  121.     makePrefix: function(challenge) {
  122.         return new Array(challenge.complexity + 1).join('0');
  123.     }
  124. };
  125.  
  126. var workersSolve = function(options) {
  127.     var key = options.key,
  128.         stamp = options.stamp,
  129.         prefix = options.prefix,
  130.         counter = options.offset,
  131.         step = options.step,
  132.         expiresAt = options.expiresAt;
  133.  
  134.     var checkIsExpired = function() {
  135.         var now = Date.now() / 1000;
  136.         return expiresAt < now;
  137.     };
  138.  
  139.     var checkPrefix = function(counter) {
  140.         var hash = CryptoJS.SHA3([stamp, counter].join(':'));
  141.         return String(hash, {
  142.             outputLength: 512
  143.         }).indexOf(prefix) === 0;
  144.     };
  145.  
  146.     while (true) {
  147.         if (counter % 1000 === 0 && checkIsExpired()) {
  148.             return {
  149.                 key: key,
  150.                 counter: null
  151.             };
  152.         }
  153.  
  154.         if (checkPrefix(counter)) {
  155.             return {
  156.                 key: key,
  157.                 counter: counter
  158.             };
  159.         }
  160.  
  161.         counter += step;
  162.     }
  163. };
  164.  
  165. module.exports = POW;
  166.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement