21 ANONYMOUS_NAMESPACE_BEGIN
24 using CryptoPP::word32;
25 using CryptoPP::word64;
31 using CryptoPP::AlignedSecByteBlock;
33 static inline void LE32ENC(byte* out, word32 in)
38 static inline word32 LE32DEC(
const byte* in)
43 static inline word64 LE64DEC(
const byte* in)
48 static inline void BlockCopy(byte* dest, byte* src,
size_t len)
50 for (
size_t i = 0; i < len; ++i)
54 static inline void BlockXOR(byte* dest, byte* src,
size_t len)
57 for (
size_t i = 0; i < len; ++i)
61 static inline void PBKDF2_SHA256(byte* buf,
size_t dkLen,
62 const byte* passwd,
size_t passwdlen,
63 const byte* salt,
size_t saltlen, byte count)
65 using CryptoPP::SHA256;
66 using CryptoPP::PKCS5_PBKDF2_HMAC;
69 pbkdf.
DeriveKey(buf, dkLen, 0, passwd, passwdlen, salt, saltlen, count, 0.0f);
72 static inline void Salsa20_8(byte B[64])
76 for (
size_t i = 0; i < 16; ++i)
77 B32[i] = LE32DEC(&B[i * 4]);
81 for (
size_t i = 0; i < 16; ++i)
82 LE32ENC(&B[4 * i], B32[i]);
85 static inline void BlockMix(byte* B, byte* Y,
size_t r)
90 BlockCopy(X, &B[(2 * r - 1) * 64], 64);
93 for (
size_t i = 0; i < 2 * r; ++i)
96 BlockXOR(X, &B[i * 64], 64);
100 BlockCopy(&Y[i * 64], X, 64);
104 for (
size_t i = 0; i < r; ++i)
105 BlockCopy(&B[i * 64], &Y[(i * 2) * 64], 64);
107 for (
size_t i = 0; i < r; ++i)
108 BlockCopy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64);
111 static inline word64 Integerify(byte* B,
size_t r)
113 byte* X = &B[(2 * r - 1) * 64];
117 static inline void Smix(byte* B,
size_t r, word64 N, byte* V, byte* XY)
123 BlockCopy(X, B, 128 * r);
126 for (word64 i = 0; i < N; ++i)
129 BlockCopy(&V[i * (128 * r)], X, 128 * r);
136 for (word64 i = 0; i < N; ++i)
139 word64 j = Integerify(X, r) & (N - 1);
142 BlockXOR(X, &V[j * (128 * r)], 128 * r);
147 BlockCopy(B, X, 128 * r);
150 ANONYMOUS_NAMESPACE_END
154 size_t
Scrypt::GetValidDerivedLength(
size_t keylength)
const 156 if (keylength > MaxDerivedLength())
157 return MaxDerivedLength();
161 void Scrypt::ValidateParameters(
size_t derivedLen, word64 cost, word64 blockSize, word64 parallelization)
const 164 if (std::numeric_limits<size_t>::max() > std::numeric_limits<word32>::max())
166 const word64 maxLen = ((
static_cast<word64
>(1) << 32) - 1) * 32;
167 if (derivedLen > maxLen) {
168 std::ostringstream oss;
169 oss <<
"derivedLen " << derivedLen <<
" is larger than " << maxLen;
178 const word64 prod =
static_cast<word64
>(blockSize) * parallelization;
181 if (prod >= (1U << 30)) {
182 std::ostringstream oss;
183 oss <<
"r*p " << prod <<
" is larger than " << (1U << 30);
193 #if defined(CRYPTOPP_WORD128_AVAILABLE) 194 const word128 maxElems =
static_cast<word128
>(
SIZE_MAX);
195 bool bLimit = (maxElems >=
static_cast<word128
>(cost) * blockSize * 128U);
196 bool xyLimit = (maxElems >=
static_cast<word128
>(parallelization) * blockSize * 128U);
197 bool vLimit = (maxElems >=
static_cast<word128
>(blockSize) * 256U + 64U);
199 const word64 maxElems =
static_cast<word64
>(
SIZE_MAX);
200 bool bLimit = (blockSize < maxElems / 128U / cost);
201 bool xyLimit = (blockSize < maxElems / 128U / parallelization);
202 bool vLimit = (blockSize < (maxElems - 64U) / 256U);
206 if (!bLimit || !xyLimit || !vLimit)
207 throw std::bad_alloc();
211 const byte*secret,
size_t secretLen,
const NameValuePairs& params)
const 217 word64 cost=0, blockSize=0, parallelization=0;
218 if(params.
GetValue(
"Cost", cost) ==
false)
221 if(params.
GetValue(
"BlockSize", blockSize) ==
false)
222 blockSize = defaultBlockSize;
224 if(params.
GetValue(
"Parallelization", parallelization) ==
false)
225 parallelization = defaultParallelization;
228 (void)params.
GetValue(
"Salt", salt);
230 return DeriveKey(derived, derivedLen, secret, secretLen, salt.
begin(), salt.
size(), cost, blockSize, parallelization);
234 const byte*salt,
size_t saltLen, word64 cost, word64 blockSize, word64 parallel)
const 240 ThrowIfInvalidDerivedLength(derivedLen);
241 ValidateParameters(derivedLen, cost, blockSize, parallel);
246 PBKDF2_SHA256(B, B.
size(), secret, secretLen, salt, saltLen, 1);
249 int threads =
STDMIN(omp_get_max_threads(),
250 static_cast<int>(
STDMIN(static_cast<size_t>(parallel),
251 static_cast<size_t>(std::numeric_limits<int>::max()))));
255 #pragma omp parallel num_threads(threads) 263 for (
size_t i = 0; i < static_cast<size_t>(parallel); ++i)
266 const ptrdiff_t offset =
static_cast<ptrdiff_t
>(blockSize*i*128);
267 Smix(B+offset, static_cast<size_t>(blockSize), cost, V, XY);
272 PBKDF2_SHA256(derived, derivedLen, secret, secretLen, B, B.
size(), 1);
Used to pass byte array input as part of a NameValuePairs object.
Standard names for retrieving values by name when working with NameValuePairs.
An invalid argument was detected.
Classes for working with NameValuePairs.
Utility functions for the Crypto++ library.
size_t size() const
Length of the memory block.
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULL)
Access a block of memory.
size_t MaxDerivedLength() const
Determine maximum number of bytes.
byte order is little-endian
size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, const NameValuePairs ¶ms=g_nullNameValuePairs) const
Derive a key from a seed.
T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
Access a block of memory.
const byte * begin() const
Pointer to the first byte in the memory block.
T rotlConstant(T x)
Performs a left rotate.
void Salsa20_Core(word32 *data, unsigned int rounds)
Salsa20 core transform.
bool IsPowerOf2(const T &value)
Tests whether a value is a power of 2.
SecBlock using AllocatorWithCleanup<byte, true> typedef.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Classes for Scrypt from RFC 7914.
Classes for SHA-1 and SHA-2 family of message digests.
Classes for Salsa and Salsa20 stream ciphers.
Password based key derivation functions.
size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, const NameValuePairs ¶ms) const
Derive a key from a seed.
Crypto++ library namespace.
bool GetValue(const char *name, T &value) const
Get a named value.
Scrypt key derivation function.
size_type size() const
Provides the count of elements in the SecBlock.
#define SIZE_MAX
The maximum value of a machine word.
Interface for retrieving values given their names.