aboutsummaryrefslogtreecommitdiff
path: root/src/util/gnunet-scrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/gnunet-scrypt.c')
-rw-r--r--src/util/gnunet-scrypt.c342
1 files changed, 0 insertions, 342 deletions
diff --git a/src/util/gnunet-scrypt.c b/src/util/gnunet-scrypt.c
deleted file mode 100644
index fe8b6769f..000000000
--- a/src/util/gnunet-scrypt.c
+++ /dev/null
@@ -1,342 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2014 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file util/gnunet-scrypt.c
22 * @brief tool to manipulate SCRYPT proofs of work.
23 * @author Bart Polot
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include <gcrypt.h>
28
29
30/**
31 * Salt for PoW calcualations.
32 */
33static struct GNUNET_CRYPTO_PowSalt salt = { "gnunet-nse-proof" };
34
35
36/**
37 * Amount of work required (W-bit collisions) for NSE proofs, in collision-bits.
38 */
39static unsigned long long nse_work_required;
40
41/**
42 * Interval between proof find runs.
43 */
44static struct GNUNET_TIME_Relative proof_find_delay;
45
46static struct GNUNET_CRYPTO_EddsaPublicKey pub;
47
48static uint64_t proof;
49
50static struct GNUNET_SCHEDULER_Task *proof_task;
51
52static const struct GNUNET_CONFIGURATION_Handle *cfg;
53
54static char *pkfn;
55
56static char *pwfn;
57
58
59/**
60 * Write our current proof to disk.
61 *
62 * @param cls closure
63 */
64static void
65shutdown_task (void *cls)
66{
67 (void) cls;
68 if (GNUNET_OK !=
69 GNUNET_DISK_fn_write (pwfn,
70 &proof,
71 sizeof(proof),
72 GNUNET_DISK_PERM_USER_READ
73 | GNUNET_DISK_PERM_USER_WRITE))
74 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
75 "write",
76 pwfn);
77}
78
79
80/**
81 * Count the leading zeroes in hash.
82 *
83 * @param hash to count leading zeros in
84 * @return the number of leading zero bits.
85 */
86static unsigned int
87count_leading_zeroes (const struct GNUNET_HashCode *hash)
88{
89 unsigned int hash_count;
90
91 hash_count = 0;
92 while (0 == GNUNET_CRYPTO_hash_get_bit_ltr (hash, hash_count))
93 hash_count++;
94 return hash_count;
95}
96
97
98/**
99 * Find our proof of work.
100 *
101 * @param cls closure (unused)
102 * @param tc task context
103 */
104static void
105find_proof (void *cls)
106{
107#define ROUND_SIZE 10
108 uint64_t counter;
109 char buf[sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
110 + sizeof(uint64_t)] GNUNET_ALIGN;
111 struct GNUNET_HashCode result;
112 unsigned int i;
113 struct GNUNET_TIME_Absolute timestamp;
114 struct GNUNET_TIME_Relative elapsed;
115
116 (void) cls;
117 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
118 "Got Proof of Work %llu\n",
119 (unsigned long long) proof);
120 proof_task = NULL;
121 GNUNET_memcpy (&buf[sizeof(uint64_t)],
122 &pub,
123 sizeof(struct GNUNET_CRYPTO_EddsaPublicKey));
124 i = 0;
125 counter = proof;
126 timestamp = GNUNET_TIME_absolute_get ();
127 while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
128 {
129 GNUNET_memcpy (buf, &counter, sizeof(uint64_t));
130 GNUNET_CRYPTO_pow_hash (&salt,
131 buf,
132 sizeof(buf),
133 &result);
134 if (nse_work_required <= count_leading_zeroes (&result))
135 {
136 proof = counter;
137 fprintf (stdout,
138 "Proof of work found: %llu!\n",
139 (unsigned long long) proof);
140 GNUNET_SCHEDULER_shutdown ();
141 return;
142 }
143 counter++;
144 i++;
145 }
146 elapsed = GNUNET_TIME_absolute_get_duration (timestamp);
147 elapsed = GNUNET_TIME_relative_divide (elapsed, ROUND_SIZE);
148 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
149 "Current: %llu [%s/proof]\n",
150 (unsigned long long) counter,
151 GNUNET_STRINGS_relative_time_to_string (elapsed, 0));
152 if (proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE))
153 {
154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
155 "Testing proofs currently at %llu\n",
156 (unsigned long long) counter);
157 /* remember progress every 100 rounds */
158 proof = counter;
159 shutdown_task (NULL);
160 }
161 else
162 {
163 proof = counter;
164 }
165 proof_task =
166 GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay,
167 GNUNET_SCHEDULER_PRIORITY_IDLE,
168 &find_proof,
169 NULL);
170}
171
172
173/**
174 * Main function that will be run by the scheduler.
175 *
176 * @param cls closure
177 * @param args remaining command-line arguments
178 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
179 * @param cfg configuration
180 */
181static void
182run (void *cls,
183 char *const *args,
184 const char *cfgfile,
185 const struct GNUNET_CONFIGURATION_Handle *config)
186{
187 struct GNUNET_CRYPTO_EddsaPrivateKey pk;
188 char *pids;
189
190 (void) cls;
191 (void) args;
192 (void) cfgfile;
193 cfg = config;
194 /* load proof of work */
195 if (NULL == pwfn)
196 {
197 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
198 "NSE",
199 "PROOFFILE",
200 &pwfn))
201 {
202 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE");
203 GNUNET_SCHEDULER_shutdown ();
204 return;
205 }
206 }
207 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Proof of Work file: %s\n", pwfn);
208 if ((GNUNET_YES != GNUNET_DISK_file_test (pwfn)) ||
209 (sizeof(proof) != GNUNET_DISK_fn_read (pwfn, &proof, sizeof(proof))))
210 proof = 0;
211
212 /* load private key */
213 if (NULL == pkfn)
214 {
215 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
216 "PEER",
217 "PRIVATE_KEY",
218 &pkfn))
219 {
220 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
221 "PEER",
222 "PRIVATE_KEY");
223 return;
224 }
225 }
226 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Private Key file: %s\n", pkfn);
227 if (GNUNET_SYSERR ==
228 GNUNET_CRYPTO_eddsa_key_from_file (pkfn,
229 GNUNET_YES,
230 &pk))
231 {
232 fprintf (stderr, _ ("Loading hostkey from `%s' failed.\n"), pkfn);
233 GNUNET_free (pkfn);
234 return;
235 }
236 GNUNET_free (pkfn);
237 GNUNET_CRYPTO_eddsa_key_get_public (&pk,
238 &pub);
239 pids = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub);
240 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Peer ID: %s\n", pids);
241 GNUNET_free (pids);
242
243 /* get target bit amount */
244 if (0 == nse_work_required)
245 {
246 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
247 "NSE",
248 "WORKBITS",
249 &nse_work_required))
250 {
251 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS");
252 GNUNET_SCHEDULER_shutdown ();
253 return;
254 }
255 if (nse_work_required >= sizeof(struct GNUNET_HashCode) * 8)
256 {
257 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
258 "NSE",
259 "WORKBITS",
260 _ ("Value is too large.\n"));
261 GNUNET_SCHEDULER_shutdown ();
262 return;
263 }
264 else if (0 == nse_work_required)
265 {
266 GNUNET_SCHEDULER_shutdown ();
267 return;
268 }
269 }
270 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Bits: %llu\n", nse_work_required);
271
272 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
273 "Delay between tries: %s\n",
274 GNUNET_STRINGS_relative_time_to_string (proof_find_delay, 1));
275 proof_task =
276 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
277 &find_proof,
278 NULL);
279 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
280}
281
282
283/**
284 * Program to manipulate ECC key files.
285 *
286 * @param argc number of arguments from the command line
287 * @param argv command line arguments
288 * @return 0 ok, 1 on error
289 */
290int
291main (int argc, char *const *argv)
292{
293 struct GNUNET_GETOPT_CommandLineOption options[] = {
294 GNUNET_GETOPT_option_ulong (
295 'b',
296 "bits",
297 "BITS",
298 gettext_noop ("number of bits to require for the proof of work"),
299 &nse_work_required),
300 GNUNET_GETOPT_option_filename (
301 'k',
302 "keyfile",
303 "FILE",
304 gettext_noop ("file with private key, otherwise default is used"),
305 &pkfn),
306 GNUNET_GETOPT_option_filename (
307 'o',
308 "outfile",
309 "FILE",
310 gettext_noop ("file with proof of work, otherwise default is used"),
311 &pwfn),
312 GNUNET_GETOPT_option_relative_time ('t',
313 "timeout",
314 "TIME",
315 gettext_noop (
316 "time to wait between calculations"),
317 &proof_find_delay),
318 GNUNET_GETOPT_OPTION_END
319 };
320 int ret;
321
322 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
323 return 2;
324
325 ret =
326 (GNUNET_OK ==
327 GNUNET_PROGRAM_run (argc,
328 argv,
329 "gnunet-scrypt [OPTIONS] prooffile",
330 gettext_noop ("Manipulate GNUnet proof of work files"),
331 options,
332 &run,
333 NULL))
334 ? 0
335 : 1;
336 GNUNET_free_nz ((void *) argv);
337 GNUNET_free (pwfn);
338 return ret;
339}
340
341
342/* end of gnunet-scrypt.c */