GNUnet  0.11.x
gnunet-scrypt.c
Go to the documentation of this file.
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  */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 #include <gcrypt.h>
28 
29 
33 static struct GNUNET_CRYPTO_PowSalt salt = { "gnunet-nse-proof" };
34 
35 
39 static unsigned long long nse_work_required;
40 
45 
47 
48 static uint64_t proof;
49 
51 
52 static const struct GNUNET_CONFIGURATION_Handle *cfg;
53 
54 static char *pkfn;
55 
56 static char *pwfn;
57 
58 
64 static void
65 shutdown_task (void *cls)
66 {
67  (void) cls;
68  if (GNUNET_OK !=
70  &proof,
71  sizeof(proof),
75  "write",
76  pwfn);
77 }
78 
79 
86 static unsigned int
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 
104 static void
105 find_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;
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);
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);
149  "Current: %llu [%s/proof]\n",
150  (unsigned long long) counter,
152  if (proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE))
153  {
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 =
168  &find_proof,
169  NULL);
170 }
171 
172 
181 static void
182 run (void *cls,
183  char *const *args,
184  const char *cfgfile,
185  const struct GNUNET_CONFIGURATION_Handle *config)
186 {
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  {
198  "NSE",
199  "PROOFFILE",
200  &pwfn))
201  {
204  return;
205  }
206  }
207  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Proof of Work file: %s\n", 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  {
216  "PEER",
217  "PRIVATE_KEY",
218  &pkfn))
219  {
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 ==
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);
238  &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  {
247  "NSE",
248  "WORKBITS",
250  {
253  return;
254  }
255  if (nse_work_required >= sizeof(struct GNUNET_HashCode) * 8)
256  {
258  "NSE",
259  "WORKBITS",
260  _ ("Value is too large.\n"));
262  return;
263  }
264  else if (0 == nse_work_required)
265  {
267  return;
268  }
269  }
271 
273  "Delay between tries: %s\n",
275  proof_task =
277  &find_proof,
278  NULL);
280 }
281 
282 
290 int
291 main (int argc, char *const *argv)
292 {
293  struct GNUNET_GETOPT_CommandLineOption options[] = {
295  'b',
296  "bits",
297  "BITS",
298  gettext_noop ("number of bits to require for the proof of work"),
301  'k',
302  "keyfile",
303  "FILE",
304  gettext_noop ("file with private key, otherwise default is used"),
305  &pkfn),
307  'o',
308  "outfile",
309  "FILE",
310  gettext_noop ("file with proof of work, otherwise default is used"),
311  &pwfn),
313  "timeout",
314  "TIME",
315  gettext_noop (
316  "time to wait between calculations"),
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 */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_relative_time(char shortName, const char *name, const char *argumentHelp, const char *description, struct GNUNET_TIME_Relative *val)
Allow user to specify a struct GNUNET_TIME_Relative (using human-readable "fancy" time)...
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:363
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1199
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1331
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1459
static void find_proof(void *cls)
Find our proof of work.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
Definition of a command line option.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
static char * pkfn
Definition: gnunet-scrypt.c:54
static char * pwfn
Definition: gnunet-scrypt.c:56
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_filename(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a filename (automatically path expanded).
static struct GNUNET_SCHEDULER_Task * proof_task
Definition: gnunet-scrypt.c:50
static unsigned int count_leading_zeroes(const struct GNUNET_HashCode *hash)
Count the leading zeroes in hash.
Definition: gnunet-scrypt.c:87
static const struct GNUNET_CONFIGURATION_Handle * cfg
Definition: gnunet-scrypt.c:52
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition: scheduler.c:1223
static unsigned long long nse_work_required
Amount of work required (W-bit collisions) for NSE proofs, in collision-bits.
Definition: gnunet-scrypt.c:39
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
static uint64_t proof
Definition: gnunet-scrypt.c:48
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config)
Main function that will be run by the scheduler.
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:251
static struct GNUNET_TIME_Relative proof_find_delay
Interval between proof find runs.
Definition: gnunet-scrypt.c:44
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:702
static char buf[2048]
static const struct GNUNET_CONFIGURATION_Handle * config
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:86
Run when otherwise idle.
void GNUNET_CRYPTO_pow_hash(const struct GNUNET_CRYPTO_PowSalt *salt, const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
Calculate the &#39;proof-of-work&#39; hash (an expensive hash).
Definition: crypto_pow.c:41
#define GNUNET_free_nz(ptr)
Wrapper around free.
Value for a salt for GNUNET_CRYPTO_pow_hash().
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_ulong(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned long long *val)
Allow user to specify an unsigned long long.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:197
enum GNUNET_GenericReturnValue GNUNET_DISK_fn_write(const char *fn, const void *buf, size_t buf_size, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file atomically.
Definition: disk.c:705
Private ECC key encoded for transmission.
int main(int argc, char *const *argv)
Program to manipulate ECC key files.
static void shutdown_task(void *cls)
Write our current proof to disk.
Definition: gnunet-scrypt.c:65
configuration data
Definition: configuration.c:84
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:263
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:46
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
int GNUNET_CRYPTO_eddsa_key_from_file(const char *filename, int do_create, struct GNUNET_CRYPTO_EddsaPrivateKey *pkey)
Create a new private key by reading it from a file.
int GNUNET_CRYPTO_hash_get_bit_ltr(const struct GNUNET_HashCode *code, unsigned int bit)
Obtain a bit from a hashcode.
Definition: crypto_hash.c:171
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition: time.c:376
Time for absolute times used by GNUnet, in microseconds.
#define ROUND_SIZE
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
Definition: gnunet-scrypt.c:33
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:437
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:644
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...