Continued:
[core.git] / contrib / chash / lib / functions.php
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']);
12
13         // Return it directly
14         return $hash;
15 }
16
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);
27
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         }
33
34         // Return it
35         return $hash;
36 }
37
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         //* NOISY-DEBUG: */ printf('[%s:%d]: hash(%d)=%s - CALLED!'. PHP_EOL, __FUNCTION__, __LINE__, strlen($hash), $hash);
47         $sum = 0;
48
49         // Part of the hash is not decodeable
50         $decodeA = explode('$', $hash);
51         $decode = $decodeA[4];
52
53         // Loop through hash
54         //* NOISY-DEBUG: */ printf('[%s:%d]: decode=%s' . PHP_EOL, __FUNCTION__, __LINE__, $decode);
55         for ($idx = 0; $idx < (strlen($decode) / 2); $idx++) {
56                 // And add it
57                 $sum = $sum + hexdec(substr($decode, $idx, 2));
58         }
59
60         // And return it
61         //* NOISY-DEBUG: */ printf('[%s:%d]: sum=%d - EXIT!' . PHP_EOL, __FUNCTION__, __LINE__, $sum);
62         return $sum;
63 }
64
65 /**
66  * Calculates new nonce
67  *
68  * @return      void
69  */
70 function calculateNonce () {
71         // Linear incrementation
72         $GLOBALS['nonce'] += $GLOBALS['none_increment'];
73 }
74
75 /**
76  * Writes/flushes check-point file
77  *
78  * @param       $hash   Found hash or gensis hash
79  * @return      void
80  */
81 function flushCheckPointFile ($hash) {
82         // Display message
83         print ('FLUSHING: Writing ' . count($GLOBALS['found_hashes']) . ' blocks ...' . PHP_EOL);
84
85         // Start timer
86         $timer = microtime(true);
87
88         // Flush data
89         file_put_contents(
90                 CHECKPOINT_FILE,
91                 //        0  1  2  3  4  5  6  7  8  9 10 11
92                 sprintf('%d|%s|%d|%d|%d|%d|%s|%d|%s|%s|%s|%s',
93                         // 0
94                         $GLOBALS['total_blocks'],
95                         // 1
96                         $GLOBALS['total_reward'],
97                         // 2
98                         $GLOBALS['total_hashes'],
99                         // 3
100                         $GLOBALS['total_found'],
101                         // 4
102                         $GLOBALS['total_restarts'],
103                         // 5
104                         $GLOBALS['hash_cycles'],
105                         // 6
106                         $GLOBALS['salt'],
107                         // 7
108                         $GLOBALS['difficulty'],
109                         // 8
110                         base64_encode((float) $GLOBALS['nonce']),
111                         // 9
112                         $hash,
113                         // 10
114                         $GLOBALS['root_hash'],
115                         // 11
116                         base64_encode(gzcompress(json_encode($GLOBALS['found_hashes'])))
117                 )
118         );
119
120         // Set time
121         $GLOBALS['time_flush'] = microtime(true);
122         print ('FLUSHING: Took ' . ($GLOBALS['time_flush'] - $timer) . ' seconds.' . PHP_EOL);
123 }
124
125 /**
126  * Adds a found hash and flushes the checkpoint file
127  *
128  * @param       $hash   Hash to save
129  */
130 function addFoundHash ($hash) {
131         // Increment counter
132         $GLOBALS['total_found']++;
133
134         // Add hash to array
135         array_push($GLOBALS['found_hashes'][$GLOBALS['total_blocks']], [
136                 'current_hash' => $GLOBALS['current_hash'],
137                 'root_hash'    => $GLOBALS['root_hash'],
138                 'nonce'        => (float) $GLOBALS['nonce'],
139                 'iter'         => $GLOBALS['iteration'],
140                 'hashes_block' => $GLOBALS['hashes_block'],
141                 'hash_cycles'  => $GLOBALS['hash_cycles'],
142                 'difficulty'   => $GLOBALS['difficulty'],
143                 'nonce_hash'   => $hash,
144         ]);
145
146         // Found hash:
147         //* NOISY-DEBUG: */ print ('FOUND: hash=' . $hash . ',nonce=' . $GLOBALS['nonce'] . ',total_found=' . $GLOBALS['total_found'] . PHP_EOL);
148
149         // Set time as a new hash was found
150         $GLOBALS['found_time'] = microtime(true);
151 }
152
153 /**
154  * Initializes nonce
155  *
156  * @return      void
157  */
158 function initNonce () {
159         $GLOBALS['nonce'] = 1 / (mt_rand() ^ (1 / pi()));
160         print (__FUNCTION__ . ': nonce=' . $GLOBALS['nonce'] . PHP_EOL);
161 }
162
163 /**
164  * Sums all hex parts of the hash to one final sum
165  *
166  * @param       $hash   Hex-hash to sum
167  * @return      Sum of hash
168  */
169 function sumHash ($hash) {
170         // Init it
171         $sum = 0;
172
173         for ($i = 0; $i < (strlen($hash) / 2); $i++) {
174                 $sum += hexdec(substr($hash, $i, 2));
175         }
176
177         return $sum;
178 }
179
180 /**
181  * Loads check-point file, if found
182  *
183  * @return      void
184  */
185 function loadCheckpointFile () {
186         // Is the check point there?
187         if (is_readable(CHECKPOINT_FILE)) {
188                 // Then load it
189                 $checkPoint = file_get_contents(CHECKPOINT_FILE);
190
191                 // Explode it
192                 $data = explode('|', $checkPoint);
193
194                 // Assert on count
195                 assert(count($data) == 10);
196
197                 // 1st element is nonce, 2nd hash, 3rd found hashes
198                 $GLOBALS['total_blocks']   = $data[0];
199                 $GLOBALS['total_reward']   = $data[1];
200                 $GLOBALS['total_hashes']   = $data[2];
201                 $GLOBALS['total_found']    = $data[3];
202                 $GLOBALS['total_restarts'] = $data[4];
203                 $GLOBALS['hash_cycles']    = intval($data[5]);
204                 $GLOBALS['salt']           = $data[6];
205                 $GLOBALS['difficulty']     = $data[7];
206                 $GLOBALS['nonce']          = (float) base64_decode($data[8]);
207                 $GLOBALS['current_hash']   = $data[9];
208                 $GLOBALS['root_hash']      = $data[10];
209                 $GLOBALS['found_hashes']   = json_decode(gzuncompress(base64_decode($data[11])), TRUE);
210         }
211 }