crypto_pow.c 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2012, 2013, 2019 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file util/crypto_pow.c
  18. * @brief proof-of-work hashing
  19. * @author Christian Grothoff
  20. * @author Bart Polot
  21. */
  22. #include "platform.h"
  23. #include "gnunet_crypto_lib.h"
  24. #include <gcrypt.h>
  25. /* FIXME: change to 1 for #3795 / 0.12! */
  26. #define NEW_CRYPTO 0
  27. /**
  28. * Calculate the 'proof-of-work' hash (an expensive hash).
  29. * We're using a non-standard formula to avoid issues with
  30. * ASICs appearing (see #3795).
  31. *
  32. * @param salt salt for the hash
  33. * @param buf data to hash
  34. * @param buf_len number of bytes in @a buf
  35. * @param result where to write the resulting hash
  36. */
  37. void
  38. GNUNET_CRYPTO_pow_hash (const char *salt,
  39. const void *buf,
  40. size_t buf_len,
  41. struct GNUNET_HashCode *result)
  42. {
  43. #if NEW_CRYPTO
  44. struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
  45. struct GNUNET_CRYPTO_SymmetricSessionKey skey;
  46. char rbuf[buf_len];
  47. GNUNET_break (0 == gcry_kdf_derive (buf,
  48. buf_len,
  49. GCRY_KDF_SCRYPT,
  50. 1 /* subalgo */,
  51. salt,
  52. strlen (salt),
  53. 2 /* iterations; keep cost of individual op small */,
  54. sizeof(skey),
  55. &skey));
  56. GNUNET_CRYPTO_symmetric_derive_iv (&iv,
  57. &skey,
  58. "gnunet-proof-of-work-iv",
  59. strlen ("gnunet-proof-of-work-iv"),
  60. salt,
  61. strlen (salt),
  62. NULL, 0);
  63. GNUNET_CRYPTO_symmetric_encrypt (buf,
  64. buf_len,
  65. &skey,
  66. &iv,
  67. &rbuf);
  68. GNUNET_break (0 == gcry_kdf_derive (rbuf,
  69. buf_len,
  70. GCRY_KDF_SCRYPT,
  71. 1 /* subalgo */,
  72. salt,
  73. strlen (salt),
  74. 2 /* iterations; keep cost of individual op small */,
  75. sizeof(struct GNUNET_HashCode),
  76. result));
  77. #else
  78. GNUNET_break (0 == gcry_kdf_derive (buf,
  79. buf_len,
  80. GCRY_KDF_SCRYPT,
  81. 1 /* subalgo */,
  82. salt,
  83. strlen (salt),
  84. 2 /* iterations; keep cost of individual op small */,
  85. sizeof(struct GNUNET_HashCode),
  86. result));
  87. #endif
  88. }
  89. /* end of crypto_pow.c */