1 <?php
2 /**
3  * Calculates a simple but stronger hash from given string. No salts are being
4  * added here.
5  *
6  * @param       \$str    The string to be hashed
7  * @return      \$hash   The hash from string \$str
8  */
9 function hashString (\$str) {
10         // Calculate strong hash from given string
11         \$hash = Scrypt::hash(\$str, \$GLOBALS['salt'], \$GLOBALS['difficulty']);
13         // Return it directly
14         return \$hash;
15 }
17 /**
18  * Multiple-hashes given string. This is done by hashing the given string and
19  * then hashing the generated hash again.
20  *
21  * @param       \$str    The string to be hashed 4 times
22  * @return      \$hash   The generated hash
23  */
24 function multipleHashString (\$str) {
25         // Generate hash from given hash
26         \$hash = hashString(\$str);
28         // Now over-hash it
29         for (\$idx = 0; \$idx < (\$GLOBALS['hash_cycles'] - 1); \$idx++) {
30                 // Over-hash the given hash
31                 \$hash = hashString(\$hash);
32         } // END - for
34         // Return it
35         return \$hash;
36 }
38 /**
39  * Calculates sum from given hash
40  *
41  * @param       \$hash   Hash to calculate sum from
42  * @return      \$sum    Sum from given hash
43  */
44 function calculateSumFromHash (\$hash) {
45         // Everything starts with zero ...
46         \$sum = 0;
48         // Loop through hash
49         for (\$idx = 0; \$idx < (strlen(\$hash) / 2); \$idx++) {
50                 // And add it
51                 \$sum = \$sum + hexdec(substr(\$hash, \$idx, 2));
52         } // END - for
54         // And return it
55         return \$sum;
56 }
58 /**
59  * Calculates new nonce
60  *
61  * @return      void
62  */
63 function calculateNonce () {
64         // Linear incrementation
65         \$GLOBALS['nonce'] += \$GLOBALS['none_increment'];
66 }
68 /**
69  * Writes/flushes check-point file
70  *
71  * @param       \$hash   Found hash or gensis hash
72  * @return      void
73  */
74 function flushCheckPointFile (\$hash) {
75         // Display message
76         print ('FLUSHING: Writing ' . count(\$GLOBALS['found_hashes']) . ' blocks ...' . PHP_EOL);
78         // Start timer
79         \$timer = microtime(true);
81         // Flush data
82         file_put_contents(
83                 CHECK_POINT,
84                 \$GLOBALS['total_blocks'] . '|' .
85                 \$GLOBALS['total_reward'] . '|' .
86                 \$GLOBALS['total_hashes'] . '|' .
87                 \$GLOBALS['total_found'] . '|' .
88                 \$GLOBALS['total_restarts'] . '|' .
89                 \$GLOBALS['hash_cycles'] . '|' .
90                 \$GLOBALS['salt'] . '|' .
91                 \$GLOBALS['difficulty'] . '|' .
92                 base64_encode((float) \$GLOBALS['nonce']) . '|' .
93                 \$hash . '|' .
94                 \$GLOBALS['root_hash'] . '|' .
95                 base64_encode(gzcompress(json_encode(\$GLOBALS['found_hashes'])))
96         );
98         // Set time
99         \$GLOBALS['time_flush'] = microtime(true);
100         print ('FLUSHING: Took ' . (\$GLOBALS['time_flush'] - \$timer) . ' seconds.' . PHP_EOL);
101 }
103 /**
104  * Adds a found hash and flushes the checkpoint file
105  *
106  * @param       \$hash   Hash to save
107  */
108 function addFoundHash (\$hash) {
109         // Increment counter
110         \$GLOBALS['total_found']++;
112         // Add hash to array
113         array_push(\$GLOBALS['found_hashes'][\$GLOBALS['total_blocks']], array(
114                 'current_hash' => \$GLOBALS['current_hash'],
115                 'root_hash'    => \$GLOBALS['root_hash'],
116                 'nonce'        => (float) \$GLOBALS['nonce'],
117                 'iter'         => \$GLOBALS['iteration'],
118                 'hashes_block' => \$GLOBALS['hashes_block'],
119                 'hash_cycles'  => \$GLOBALS['hash_cycles'],
120                 'difficulty'   => \$GLOBALS['difficulty'],
121                 'nonce_hash'   => \$hash,
122         ));
124         // Found hash:
125         print ('FOUND: hash=' . \$hash . ',nonce=' . \$GLOBALS['nonce'] . ',total_found=' . \$GLOBALS['total_found'] . PHP_EOL);
127         // Set time as a new hash was found
128         \$GLOBALS['found_time'] = microtime(true);
130         // Flush check-point file after new hash is found
131         flushCheckPointFile(\$hash);
132 }
134 /**
135  * Initializes nonce
136  *
137  * @return      void
138  */
139 function initNonce () {
140         \$GLOBALS['nonce'] = 1 / (mt_rand() ^ pi());
141         print (__FUNCTION__ . ': nonce=' . \$GLOBALS['nonce'] . PHP_EOL);
142 }
144 /**
145  * Sums all hex parts of the hash to one final sum
146  *
147  * @param       \$hash   Hex-hash to sum
148  * @return      Sum of hash
149  */
150 function sumHash (\$hash) {
151         // Init it
152         \$sum = 0;
154         for (\$i = 0; \$i < (strlen(\$hash) / 2); \$i++) {
155                 \$sum += hexdec(substr(\$hash, \$i, 2));
156         }
158         return \$sum;
159 }
161 /**
162  * Loads check-point file, if found
163  *
164  * @return      void
165  */
166 function loadCheckpointFile () {
167         // Is the check point there?
168         if (is_readable(CHECK_POINT)) {
169                 // Then load it
170                 \$checkPoint = file_get_contents(CHECK_POINT);
172                 // Explode it
173                 \$data = explode('|', \$checkPoint);
175                 // Assert on count
176                 assert(count(\$data) == 10);
178                 // 1st element is nonce, 2nd hash, 3rd found hashes
179                 \$GLOBALS['total_blocks']   = \$data;
180                 \$GLOBALS['total_reward']   = \$data;
181                 \$GLOBALS['total_hashes']   = \$data;
182                 \$GLOBALS['total_found']    = \$data;
183                 \$GLOBALS['total_restarts'] = \$data;
184                 \$GLOBALS['hash_cycles']    = intval(\$data);
185                 \$GLOBALS['salt']           = \$data;
186                 \$GLOBALS['difficulty']     = \$data;
187                 \$GLOBALS['nonce']          = (float) base64_decode(\$data);
188                 \$GLOBALS['current_hash']   = \$data;
189                 \$GLOBALS['root_hash']      = \$data;
190                 \$GLOBALS['found_hashes']   = json_decode(gzuncompress(base64_decode(\$data)));
191         } // END - if
192 }