#pragma once #ifndef MESSMER_CPPUTILS_CRYPTO_KDF_SCRYPT_H #define MESSMER_CPPUTILS_CRYPTO_KDF_SCRYPT_H #include "../../macros.h" #include "../../random/Random.h" extern "C" { #include } #include #include "DerivedKey.h" namespace cpputils { struct SCryptParanoidSettings { constexpr static size_t SALT_LEN = 32; // Size of the salt constexpr static uint64_t N = 1048576; // CPU/Memory cost constexpr static uint32_t r = 8; // Blocksize constexpr static uint32_t p = 16; // Parallelization }; struct SCryptDefaultSettings { constexpr static size_t SALT_LEN = 32; // Size of the salt constexpr static uint64_t N = 524288; // CPU/Memory cost constexpr static uint32_t r = 1; // Blocksize constexpr static uint32_t p = 1; // Parallelization }; class SCrypt { public: SCrypt() {} template DerivedKey generateKey(const std::string &password) { auto salt = Random::PseudoRandom().get(Settings::SALT_LEN); auto config = DerivedKeyConfig(std::move(salt), Settings::N, Settings::r, Settings::p); auto key = generateKeyFromConfig(password, config); return DerivedKey(std::move(config), key); } template FixedSizeData generateKeyFromConfig(const std::string &password, const DerivedKeyConfig &config) { auto key = FixedSizeData::Null(); int errorcode = crypto_scrypt(reinterpret_cast(password.c_str()), password.size(), reinterpret_cast(config.salt().data()), config.salt().size(), config.N(), config.r(), config.p(), static_cast(key.data()), KEYSIZE); if (errorcode != 0) { throw std::runtime_error("Error running scrypt key derivation."); } return key; } private: DISALLOW_COPY_AND_ASSIGN(SCrypt); }; } #endif