Botan 3.13.0
Crypto and TLS for C&
Botan::Scrypt_Family Class Referencefinal

#include <scrypt.h>

Inheritance diagram for Botan::Scrypt_Family:
Botan::PasswordHashFamily

Public Member Functions

std::unique_ptr< PasswordHashdefault_params () const override
std::unique_ptr< PasswordHashfrom_iterations (size_t iter) const override
std::unique_ptr< PasswordHashfrom_params (size_t N, size_t r, size_t p) const override
std::string name () const override
std::unique_ptr< PasswordHashtune (size_t output_length, std::chrono::milliseconds msec, size_t max_memory_usage_mb=0, std::chrono::milliseconds tuning_msec=std::chrono::milliseconds(10)) const
std::unique_ptr< PasswordHashtune_params (size_t output_len, uint64_t desired_runtime_msec, std::optional< size_t > max_memory, uint64_t tune_msec) const override

Static Public Member Functions

static std::unique_ptr< PasswordHashFamilycreate (std::string_view algo_spec, std::string_view provider="")
static std::unique_ptr< PasswordHashFamilycreate_or_throw (std::string_view algo_spec, std::string_view provider="")
static std::vector< std::string > providers (std::string_view algo_spec)

Detailed Description

Definition at line 49 of file scrypt.h.

Member Function Documentation

◆ create()

std::unique_ptr< PasswordHashFamily > Botan::PasswordHashFamily::create ( std::string_view algo_spec,
std::string_view provider = "" )
staticinherited

Create an instance based on a name If provider is empty then best available is chosen.

Parameters
algo_specalgorithm name
providerprovider implementation to choose
Returns
a null pointer if the algo/provider combination cannot be found

Definition at line 58 of file pwdhash.cpp.

58 {
59 const SCAN_Name req(algo_spec);
60
61#if defined(BOTAN_HAS_PBKDF2)
62 if(req.algo_name() == "PBKDF2") {
63 if(provider.empty() || provider == "base") {
64 if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) {
65 return std::make_unique<PBKDF2_Family>(std::move(mac));
66 }
67
68 if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
69 return std::make_unique<PBKDF2_Family>(std::move(mac));
70 }
71 }
72
73 return nullptr;
74 }
75#endif
76
77#if defined(BOTAN_HAS_SCRYPT)
78 if(req.algo_name() == "Scrypt") {
79 return std::make_unique<Scrypt_Family>();
80 }
81#endif
82
83#if defined(BOTAN_HAS_ARGON2)
84 if(req.algo_name() == "Argon2d") {
85 return std::make_unique<Argon2_Family>(static_cast<uint8_t>(0));
86 } else if(req.algo_name() == "Argon2i") {
87 return std::make_unique<Argon2_Family>(static_cast<uint8_t>(1));
88 } else if(req.algo_name() == "Argon2id") {
89 return std::make_unique<Argon2_Family>(static_cast<uint8_t>(2));
90 }
91#endif
92
93#if defined(BOTAN_HAS_PBKDF_BCRYPT)
94 if(req.algo_name() == "Bcrypt-PBKDF") {
95 return std::make_unique<Bcrypt_PBKDF_Family>();
96 }
97#endif
98
99#if defined(BOTAN_HAS_PGP_S2K)
100 if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) {
101 if(auto hash = HashFunction::create(req.arg(0))) {
102 return std::make_unique<RFC4880_S2K_Family>(std::move(hash));
103 }
104 }
105#endif
106
107#if defined(BOTAN_HAS_PKCS12_KDF)
108 if(req.algo_name() == "PKCS12-KDF" && req.arg_count() == 2) {
109 if(auto hash = HashFunction::create(req.arg(0))) {
110 const auto id_param = req.arg_as_integer(1);
111 return std::make_unique<PKCS12_KDF_Family>(std::move(hash), id_param);
112 }
113 }
114#endif
115
116 BOTAN_UNUSED(req);
117 BOTAN_UNUSED(provider);
118
119 return nullptr;
120}
#define BOTAN_UNUSED
Definition assert.h:144
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:111
static std::unique_ptr< MessageAuthenticationCode > create(std::string_view algo_spec, std::string_view provider="")
Definition mac.cpp:50

References Botan::SCAN_Name::algo_name(), Botan::SCAN_Name::arg(), Botan::SCAN_Name::arg_as_integer(), Botan::SCAN_Name::arg_count(), BOTAN_UNUSED, Botan::HashFunction::create(), and Botan::MessageAuthenticationCode::create().

Referenced by botan_pwdhash(), botan_pwdhash_timed(), and create_or_throw().

◆ create_or_throw()

std::unique_ptr< PasswordHashFamily > Botan::PasswordHashFamily::create_or_throw ( std::string_view algo_spec,
std::string_view provider = "" )
staticinherited

Create an instance based on a name, or throw if the algo/provider combination cannot be found. If provider is empty then best available is chosen.

Definition at line 123 of file pwdhash.cpp.

124 {
125 if(auto pbkdf = PasswordHashFamily::create(algo, provider)) {
126 return pbkdf;
127 }
128 throw Lookup_Error("PasswordHashFamily", algo, provider);
129}
static std::unique_ptr< PasswordHashFamily > create(std::string_view algo_spec, std::string_view provider="")
Definition pwdhash.cpp:58

References create().

Referenced by Botan::argon2(), Botan::argon2_check_pwhash(), Botan::argon2_generate_pwhash(), Botan::bcrypt_pbkdf(), Botan::CryptoBox::decrypt_bin(), Botan::CryptoBox::encrypt(), Botan::scrypt(), and Botan::scrypt().

◆ default_params()

std::unique_ptr< PasswordHash > Botan::Scrypt_Family::default_params ( ) const
overridevirtual

Return some default parameter set for this PBKDF that should be good enough for most users. The value returned may change over time as processing power and attacks improve.

Implements Botan::PasswordHashFamily.

Definition at line 46 of file scrypt.cpp.

46 {
47 return std::make_unique<Scrypt>(32768, 8, 1);
48}

◆ from_iterations()

std::unique_ptr< PasswordHash > Botan::Scrypt_Family::from_iterations ( size_t iterations) const
overridevirtual

Return a parameter chosen based on a rough approximation with the specified iteration count. The exact value this returns for a particular algorithm may change from over time. Think of it as an alternative to tune, where time is expressed in terms of PBKDF2 iterations rather than milliseconds.

Implements Botan::PasswordHashFamily.

Definition at line 134 of file scrypt.cpp.

134 {
135 const size_t r = 8;
136 const size_t p = 1;
137
138 size_t N = 8192;
139
140 if(iter > 50000) {
141 N = 16384;
142 }
143 if(iter > 100000) {
144 N = 32768;
145 }
146 if(iter > 150000) {
147 N = 65536;
148 }
149
150 return std::make_unique<Scrypt>(N, r, p);
151}

◆ from_params()

std::unique_ptr< PasswordHash > Botan::Scrypt_Family::from_params ( size_t i1,
size_t i2,
size_t i3 ) const
overridevirtual

Create a password hash using some scheme specific format. Parameters are as follows:

  • For PBKDF2, PGP-S2K, and Bcrypt-PBKDF, i1 is iterations
  • Scrypt uses N, r, p for i{1-3}
  • Argon2 family uses memory (in KB), iterations, and parallelism for i{1-3}
  • PKCS12-KDF uses iterations for i1 (the hash and id are fixed by the family name, e.g. "PKCS12-KDF(SHA-256,1)")

All unneeded parameters should be set to 0 or left blank.

Implements Botan::PasswordHashFamily.

Definition at line 130 of file scrypt.cpp.

130 {
131 return std::make_unique<Scrypt>(N, r, p);
132}

Referenced by tune_params().

◆ name()

std::string Botan::Scrypt_Family::name ( ) const
overridevirtual

Return the name of this password hash family

Returns
name of this PasswordHash

Implements Botan::PasswordHashFamily.

Definition at line 42 of file scrypt.cpp.

42 {
43 return "Scrypt";
44}

◆ providers()

std::vector< std::string > Botan::PasswordHashFamily::providers ( std::string_view algo_spec)
staticinherited

List the providers available for a given password hash

Returns
list of available providers for this algorithm, empty if not available

Definition at line 131 of file pwdhash.cpp.

131 {
133}
std::vector< std::string > probe_providers_of(std::string_view algo_spec, const std::vector< std::string > &possible={"base"})
Definition scan_name.h:99

References Botan::probe_providers_of().

◆ tune()

std::unique_ptr< PasswordHash > Botan::PasswordHashFamily::tune ( size_t output_length,
std::chrono::milliseconds msec,
size_t max_memory_usage_mb = 0,
std::chrono::milliseconds tuning_msec = std::chrono::milliseconds(10) ) const
inlineinherited

Return a new parameter set tuned for this machine

Return a password hash instance tuned to run for approximately msec milliseconds when producing an output of length output_length. (Accuracy may vary, use the command line utility botan pbkdf_tune to check.)

The parameters will be selected to use at most max_memory_usage_mb megabytes of memory, or if left as zero any size is allowed.

This function works by running a short tuning loop to estimate the performance of the algorithm, then scaling the parameters appropriately to hit the target size. The length of time the tuning loop runs can be controlled using the tuning_msec parameter.

Parameters
output_lengthhow long the output length will be
msecthe desired execution time in milliseconds
max_memory_usage_mbsome password hash functions can use a tunable amount of memory, in this case max_memory_usage limits the amount of RAM the returned parameters will require, in mebibytes (2**20 bytes). It may require some small amount above the request. Set to zero to place no limit at all.
tuning_msechow long to run the tuning loop

TODO(Botan4) remove this

Definition at line 282 of file pwdhash.h.

285 {
286 std::optional<size_t> max_memory_opt;
287 if(max_memory_usage_mb > 0) {
288 max_memory_opt = max_memory_usage_mb;
289 }
290
291 return this->tune_params(output_length,
292 static_cast<uint64_t>(msec.count()),
293 max_memory_opt,
294 static_cast<uint64_t>(tuning_msec.count()));
295 }
virtual std::unique_ptr< PasswordHash > tune_params(size_t output_length, uint64_t desired_runtime_msec, std::optional< size_t > max_memory_usage_mb={}, uint64_t tuning_msec=10) const =0

References tune(), and tune_params().

Referenced by tune().

◆ tune_params()

std::unique_ptr< PasswordHash > Botan::Scrypt_Family::tune_params ( size_t output_length,
uint64_t desired_runtime_msec,
std::optional< size_t > max_memory_usage_mb,
uint64_t tuning_msec ) const
overridevirtual

Return a new parameter set tuned for this machine

Return a password hash instance tuned to run for approximately msec milliseconds when producing an output of length output_length. (Accuracy may vary, use the command line utility botan pbkdf_tune to check.)

The parameters will be selected to use at most max_memory_usage_mb megabytes of memory, or if left as zero any size is allowed.

This function works by running a short tuning loop to estimate the performance of the algorithm, then scaling the parameters appropriately to hit the target size. The length of time the tuning loop runs can be controlled using the tuning_msec parameter.

Parameters
output_lengthhow long the output length will be
desired_runtime_msecthe desired execution time in milliseconds
max_memory_usage_mbsome password hash functions can use a tunable amount of memory, in this case max_memory_usage limits the amount of RAM the returned parameters will require, in mebibytes (2**20 bytes). It may require some small amount above the request. Set to nullopt to place no limit at all.
tuning_msechow long to run the tuning loop

Implements Botan::PasswordHashFamily.

Definition at line 50 of file scrypt.cpp.

53 {
54 /*
55 * Some rough relations between scrypt parameters and runtime.
56 * Denote here by stime(N,r,p) the msec it takes to run scrypt.
57 *
58 * Empirically for smaller sizes:
59 * stime(N,8*r,p) / stime(N,r,p) is ~ 6-7
60 * stime(N,r,8*p) / stime(N,r,p) is ~ 7
61 * stime(2*N,r,p) / stime(N,r,p) is ~ 2
62 *
63 * Compute stime(8192,1,1) as baseline and extrapolate
64 */
65
66 // If max_memory is nullopt or zero this becomes zero and is ignored
67 const size_t max_memory_bytes = std::min(MAX_SCRYPT_MEMORY_BYTES, max_memory.value_or(0) * 1024 * 1024);
68
69 // In below code we invoke scrypt_memory_usage with p == 0 as p contributes
70 // (very slightly) to memory consumption, but N is the driving factor.
71 // Including p leads to using an N half as large as what the user would expect.
72
73 auto scrypt_parameters_acceptable = [&](size_t N, size_t r) -> bool {
74 if(N > MAX_SCRYPT_N) {
75 return false;
76 }
77 if(const auto consumed = scrypt_memory_usage(N, r, 0)) {
78 if(max_memory_bytes > 0 && *consumed > max_memory_bytes) {
79 return false;
80 } else {
81 return true;
82 }
83 } else {
84 return false;
85 }
86 };
87
88 // Starting parameters
89 size_t N = 8 * 1024;
90 size_t r = 1;
91 size_t p = 1;
92
93 auto pwdhash = this->from_params(N, r, p);
94
95 const uint64_t measured_time = measure_cost(tuning_msec, [&]() {
96 uint8_t output[32] = {0};
97 pwdhash->derive_key(output, sizeof(output), "test", 4, nullptr, 0);
98 });
99
100 const uint64_t target_nsec = desired_msec * static_cast<uint64_t>(1000000);
101
102 uint64_t est_nsec = measured_time;
103
104 // First increase r by 8x if possible
105 if(scrypt_parameters_acceptable(N, r * 8)) {
106 if(target_nsec / est_nsec >= 5) {
107 r *= 8;
108 est_nsec *= 5;
109 }
110 }
111
112 // Now double N as many times as we can
113 while(scrypt_parameters_acceptable(N * 2, r)) {
114 if(target_nsec / est_nsec >= 2) {
115 N *= 2;
116 est_nsec *= 2;
117 } else {
118 break;
119 }
120 }
121
122 // If we have extra runtime budget, increment p
123 if(target_nsec / est_nsec >= 2) {
124 p *= std::min<size_t>(1024, static_cast<size_t>(target_nsec / est_nsec));
125 }
126
127 return std::make_unique<Scrypt>(N, r, p);
128}
std::unique_ptr< PasswordHash > from_params(size_t N, size_t r, size_t p) const override
Definition scrypt.cpp:130
uint64_t measure_cost(uint64_t trial_msec, F func)
Definition time_utils.h:19

References from_params(), and Botan::measure_cost().


The documentation for this class was generated from the following files: