/* cpu and memory intensive function to transform a 80 byte buffer into a 32 byte output scratchpad size needs to be at least 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) bytes */ void scrypt_N_R_1_256_sp(const char* input, char* output, char* scratchpad, uint32_t N, uint32_t R, uint32_t len) { uint8_t * B; uint32_t * V; uint32_t * XY; uint32_t i; //const uint32_t N = 1024; uint32_t r=R; const uint32_t p = 1; B = (uint8_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); XY = (uint32_t *)(B + (128 * r * p)); V = (uint32_t *)(B + (128 * r * p) + (256 * r + 64)); /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ PBKDF2_SHA256((const uint8_t*)input, len, (const uint8_t*)input, len, 1, B, p * 128 * r); /* 2: for i = 0 to p - 1 do */ for (i = 0; i < p; i++) { /* 3: B_i <-- MF(B_i, N) */ smix(&B[i * 128 * r], r, N, V, XY); } /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ PBKDF2_SHA256((const uint8_t*)input, len, B, p * 128 * r, 1, (uint8_t*)output, 32); }
/** * scrypt (passwd, passwdlen, salt, saltlen, N, r, p, res, res_len): * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, * p, res_len) and write the result into res. The parameters r, p, and res_len * must satisfy r * p < 2^30 and res_len <= (2^32 - 1) * 32. The parameter N * must be a power of 2. * * Return 0 on success; or -1 on error. */ int scrypt ( const uint8_t * password, size_t password_len, const uint8_t * salt, size_t salt_len, uint64_t N, uint32_t r, uint32_t p, uint8_t * res, size_t res_len) { uint8_t * B; uint8_t * V; uint8_t * XY; uint32_t i; #if SIZE_MAX > UINT32_MAX if (res_len > (((uint64_t)(1) << 32) - 1) * 32) { errno = EFBIG; goto err0; } #endif if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { errno = EFBIG; goto err0; } if (((N & (N - 1)) != 0) || (N == 0)) { errno = EINVAL; goto err0; } if ((r > SIZE_MAX / 128 / p) || #if SIZE_MAX / 256 <= UINT32_MAX (r > SIZE_MAX / 256) || #endif (N > SIZE_MAX / 128 / r)) { errno = ENOMEM; goto err0; } if ((B = malloc(128 * r * p)) == NULL) goto err0; if ((XY = malloc(256 * r)) == NULL) goto err1; if ((V = malloc(128 * r * N)) == NULL) goto err2; /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ PBKDF2_SHA256(password, password_len, salt, salt_len, 1, B, p * 128 * r); /* 2: for i = 0 to p - 1 do */ for (i = 0; i < p; i++) { /* 3: B_i <-- MF(B_i, N) */ smix(&B[i * 128 * r], r, N, V, XY); } /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ PBKDF2_SHA256(password, password_len, B, p * 128 * r, 1, res, res_len); free(V); free(XY); free(B); return (0); err2: free(XY); err1: free(B); err0: return (-1); }
static void scrypt(const void* input, size_t inputlen, uint32_t *res, void *scratchpad) { uint32_t *V; uint32_t X[32]; V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); PBKDF2_SHA256((const uint8_t*)input, inputlen, (const uint8_t*)input, sizeof(block_header), 1, (uint8_t *)X, 128); scrypt_core(X, V); PBKDF2_SHA256((const uint8_t*)input, inputlen, (uint8_t *)X, 128, 1, (uint8_t*)res, 32); }
uint256 scrypt(const void* data, size_t datalen, const void* salt, size_t saltlen, void *scratchpad) { unsigned int *V; unsigned int X[32]; uint256 result = 0; V = (unsigned int *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); PBKDF2_SHA256((const uint8_t*)data, datalen, (const uint8_t*)salt, saltlen, 1, (uint8_t *)X, 128); scrypt_core(X, V); PBKDF2_SHA256((const uint8_t*)data, datalen, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32); return result; }
uint256 scrypt_nosalt(const void* input, size_t inputlen, void *scratchpad) { uint32_t *V; uint32_t X[32]; uint256 result = 0; V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); PBKDF2_SHA256((const uint8_t*)input, inputlen, (const uint8_t*)input, inputlen, 1, (uint8_t *)X, 128); scrypt_core(X, V); PBKDF2_SHA256((const uint8_t*)input, inputlen, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32); return result; }
static void scrypt_2way(const void *input1, const void *input2, size_t input1len, size_t input2len, uint32_t *res1, uint32_t *res2, void *scratchpad) { uint32_t *V; uint32_t X[32], Y[32]; V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); PBKDF2_SHA256((const uint8_t*)input1, input1len, (const uint8_t*)input1, input1len, 1, (uint8_t *)X, 128); PBKDF2_SHA256((const uint8_t*)input2, input2len, (const uint8_t*)input2, input2len, 1, (uint8_t *)Y, 128); scrypt_core_2way(X, Y, V); PBKDF2_SHA256((const uint8_t*)input1, input1len, (uint8_t *)X, 128, 1, (uint8_t*)res1, 32); PBKDF2_SHA256((const uint8_t*)input2, input2len, (uint8_t *)Y, 128, 1, (uint8_t*)res2, 32); }
uint256 scrypt_blockhash(const uint8_t* input) { uint8_t scratchpad[SCRYPT_BUFFER_SIZE]; ::uint32_t X[32]; uint256 result = 0; ::uint32_t *V = (::uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); PBKDF2_SHA256(input, 80, input, 80, 1, (uint8_t *)X, 128); scrypt_core(X, V); PBKDF2_SHA256(input, 80, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32); return result; }
/** * proto_crypt_dhmac(K, nonce_l, nonce_r, dhmac_l, dhmac_r, decr): * Using the key file hash ${K}, and the local and remote nonces ${nonce_l} * and ${nonce_r}, compute the local and remote diffie-hellman parameter MAC * keys ${dhmac_l} and ${dhmac_r}. If ${decr} is non-zero, "local" == "S" * and "remote" == "C"; otherwise the assignments are opposite. */ void proto_crypt_dhmac(const struct proto_secret * K, const uint8_t nonce_l[PCRYPT_NONCE_LEN], const uint8_t nonce_r[PCRYPT_NONCE_LEN], uint8_t dhmac_l[PCRYPT_DHMAC_LEN], uint8_t dhmac_r[PCRYPT_DHMAC_LEN], int decr) { uint8_t nonce_CS[PCRYPT_NONCE_LEN * 2]; uint8_t dk_1[PCRYPT_DHMAC_LEN * 2]; const uint8_t * nonce_c, * nonce_s; uint8_t * dhmac_c, * dhmac_s; /* Figure out how {c, s} maps to {l, r}. */ nonce_c = decr ? nonce_r : nonce_l; dhmac_c = decr ? dhmac_r : dhmac_l; nonce_s = decr ? nonce_l : nonce_r; dhmac_s = decr ? dhmac_l : dhmac_r; /* Copy in nonces (in the right order). */ memcpy(&nonce_CS[0], nonce_c, PCRYPT_NONCE_LEN); memcpy(&nonce_CS[PCRYPT_NONCE_LEN], nonce_s, PCRYPT_NONCE_LEN); /* Compute dk_1. */ PBKDF2_SHA256(K->K, 32, nonce_CS, PCRYPT_NONCE_LEN * 2, 1, dk_1, PCRYPT_DHMAC_LEN * 2); /* Copy out diffie-hellman parameter MAC keys (in the right order). */ memcpy(dhmac_c, &dk_1[0], PCRYPT_DHMAC_LEN); memcpy(dhmac_s, &dk_1[PCRYPT_DHMAC_LEN], PCRYPT_DHMAC_LEN); }
void ramhog_run_iterations(const uint8_t *input, size_t input_size, uint8_t *output, size_t output_size, uint32_t N, uint32_t C, uint32_t I, uint64_t **scratchpads) { xorshift_ctx ctx; uint32_t i, padIndex; uint64_t X; uint64_t finalChunks[N * 32]; uint64_t finalSalt[32] = {N, C, I, input_size, output_size}; for (padIndex=0; padIndex < N; padIndex++) { memcpy(&finalChunks[padIndex * 32], &scratchpads[padIndex][C - 1 - 32], sizeof(uint64_t) * 32); } xorshift_pbkdf2_seed(&ctx, input, input_size, (uint8_t *)&finalChunks[0], sizeof(uint64_t) * N); X = xorshift_next(&ctx); for (i=0; i < I - (32 - 5); i++) { X = scratchpads[(X & 0xffffffff00000000L) % N][(X & 0x00000000ffffffffL) % C] ^ xorshift_next(&ctx); } for (i=5; i < 32; i++) { X = scratchpads[(X & 0xffffffff00000000L) % N][(X & 0x00000000ffffffffL) % C] ^ xorshift_next(&ctx); finalSalt[i] = X; } PBKDF2_SHA256(input, input_size, (uint8_t *)finalSalt, sizeof(uint64_t)*32, 1, (uint8_t *)output, output_size); }
void scrypt_N_1_1_256_sp_sse2(const char *input, char *output, char *scratchpad, unsigned char Nfactor) { uint8_t B[128]; union { __m128i i128[8]; uint32_t u32[32]; } X; __m128i *V; uint32_t i, j, k, N; V = (__m128i *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); PBKDF2_SHA256((const uint8_t *)input, 80, (const uint8_t *)input, 80, 1, B, 128); for (k = 0; k < 2; k++) { for (i = 0; i < 16; i++) { X.u32[k * 16 + i] = le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]); } } N = (1 << (Nfactor + 1)); for (i = 0; i < N; i++) { for (k = 0; k < 8; k++) V[i * 8 + k] = X.i128[k]; xor_salsa8_sse2(&X.i128[0], &X.i128[4]); xor_salsa8_sse2(&X.i128[4], &X.i128[0]); } for (i = 0; i < N; i++) { //j = 8 * (X.u32[16] & 1023); j = 8 * (X.u32[16] & (N-1)); for (k = 0; k < 8; k++) X.i128[k] = _mm_xor_si128(X.i128[k], V[j + k]); xor_salsa8_sse2(&X.i128[0], &X.i128[4]); xor_salsa8_sse2(&X.i128[4], &X.i128[0]); } for (k = 0; k < 2; k++) { for (i = 0; i < 16; i++) { le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], X.u32[k * 16 + i]); } } PBKDF2_SHA256((const uint8_t *)input, 80, B, 128, 1, (uint8_t *)output, 32); }
static void xorshift_pbkdf2_seed(xorshift_ctx *ctx, const uint8_t *seed, size_t seedlen, const uint8_t *salt, size_t saltlen) { uint64_t fullSeed[65]; PBKDF2_SHA256(seed, seedlen, salt, saltlen, 128, (uint8_t *)fullSeed, sizeof(uint64_t)*65); memcpy(ctx->s, &fullSeed[0], sizeof(uint64_t)*64); ctx->p = (uint8_t)(fullSeed[16] & 63); }
void scrypt_8_4_1_256_sp_sse2(const char *input, char *output, char *scratchpad) { const int N=123; uint8_t B[128]; union { __m128i i128[8]; uint32_t u32[32]; } X; __m128i *V; uint32_t i, j, k; V = (__m128i *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); PBKDF2_SHA256((const uint8_t *)input, 80, (const uint8_t *)input, 80, 1, B, 128); for (k = 0; k < 2; k++) { for (i = 0; i < 16; i++) { X.u32[k * 16 + i] = le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]); } } for (i = 0; i < N; i++) { for (k = 0; k < 8; k++) V[i * 8 + k] = X.i128[k]; xor_salsa8_sse2(&X.i128[0], &X.i128[4]); xor_salsa8_sse2(&X.i128[4], &X.i128[0]); } for (i = 0; i < N i++) { j = 8 * (X.u32[16] % (N)); for (k = 0; k < 8; k++) X.i128[k] = _mm_xor_si128(X.i128[k], V[j + k]); xor_salsa8_sse2(&X.i128[0], &X.i128[4]); xor_salsa8_sse2(&X.i128[4], &X.i128[0]); } for (k = 0; k < 2; k++) { for (i = 0; i < 16; i++) { le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], X.u32[k * 16 + i]); } } PBKDF2_SHA256((const uint8_t *)input, 80, B, 128, 1, (uint8_t *)output, 32); }
/** * proto_crypt_mkkeys(K, nonce_l, nonce_r, yh_r, x, nofps, decr, eh_c, eh_s): * Using the protocol secret ${K}, the local and remote nonces ${nonce_l} and * ${nonce_r}, the remote MACed diffie-hellman handshake parameter ${yh_r}, * and the local diffie-hellman secret ${x}, generate the keys ${eh_c} and * ${eh_s}. If ${nofps} is non-zero, we are performing weak handshaking and * y_SC is set to 1 rather than being computed. If ${decr} is non-zero, * "local" == "S" and "remote" == "C"; otherwise the assignments are opposite. */ int proto_crypt_mkkeys(const struct proto_secret * K, const uint8_t nonce_l[PCRYPT_NONCE_LEN], const uint8_t nonce_r[PCRYPT_NONCE_LEN], const uint8_t yh_r[PCRYPT_YH_LEN], const uint8_t x[PCRYPT_X_LEN], int nofps, int decr, struct proto_keys ** eh_c, struct proto_keys ** eh_s) { uint8_t nonce_y[PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN]; uint8_t dk_2[128]; const uint8_t * nonce_c, * nonce_s; /* Copy in nonces (in the right order). */ nonce_c = decr ? nonce_r : nonce_l; nonce_s = decr ? nonce_l : nonce_r; memcpy(&nonce_y[0], nonce_c, PCRYPT_NONCE_LEN); memcpy(&nonce_y[PCRYPT_NONCE_LEN], nonce_s, PCRYPT_NONCE_LEN); /* Are we bypassing the diffie-hellman computation? */ if (nofps) { /* We sent y_l = 1, so y_SC is also 1. */ memset(&nonce_y[PCRYPT_NONCE_LEN * 2], 0, CRYPTO_DH_KEYLEN - 1); nonce_y[PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN - 1] = 1; } else { /* Perform the diffie-hellman computation. */ if (crypto_dh_compute(yh_r, x, &nonce_y[PCRYPT_NONCE_LEN * 2])) goto err0; } /* Compute dk_2. */ PBKDF2_SHA256(K->K, 32, nonce_y, PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN, 1, dk_2, 128); /* Create key structures. */ if ((*eh_c = mkkeypair(&dk_2[0])) == NULL) goto err0; if ((*eh_s = mkkeypair(&dk_2[64])) == NULL) goto err1; /* Success! */ return (0); err1: proto_crypt_free(*eh_c); err0: /* Failure! */ return (-1); }
/** * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, * p, buflen) and write the result into buf. The parameters r, p, and buflen * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N * must be a power of 2 greater than 1. * * Return 0 on success; or -1 on error. */ int crypto_scrypt(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, uint8_t * buf, size_t buflen) { void * B0, * V0, * XY0; uint8_t * B; uint32_t * V; uint32_t * XY; uint32_t i; /* Sanity-check parameters. */ #if SIZE_MAX > UINT32_MAX if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { errno = EFBIG; goto err0; } #endif if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { errno = EFBIG; goto err0; } if (((N & (N - 1)) != 0) || (N == 0)) { errno = EINVAL; goto err0; } if ((r > SIZE_MAX / 128 / p) || #if SIZE_MAX / 256 <= UINT32_MAX (r > (SIZE_MAX - 64) / 256) || #endif (N > SIZE_MAX / 128 / r)) { errno = ENOMEM; goto err0; } /* Allocate memory. */ #ifdef HAVE_POSIX_MEMALIGN if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0) goto err0; B = (uint8_t *)(B0); if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0) goto err1; XY = (uint32_t *)(XY0); #ifndef MAP_ANON if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0) goto err2; V = (uint32_t *)(V0); #endif #else if ((B0 = malloc(128 * r * p + 63)) == NULL) goto err0; B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63)); if ((XY0 = malloc(256 * r + 64 + 63)) == NULL) goto err1; XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63)); #ifndef MAP_ANON if ((V0 = malloc(128 * r * N + 63)) == NULL) goto err2; V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63)); #endif #endif #ifdef MAP_ANON if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE, #ifdef MAP_NOCORE MAP_ANON | MAP_PRIVATE | MAP_NOCORE, #else MAP_ANON | MAP_PRIVATE, #endif -1, 0)) == MAP_FAILED) goto err2; V = (uint32_t *)(V0); #endif /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r); /* 2: for i = 0 to p - 1 do */ for (i = 0; i < p; i++) { /* 3: B_i <-- MF(B_i, N) */ smix(&B[i * 128 * r], r, N, V, XY); } /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen); /* Free memory. */ #ifdef MAP_ANON if (munmap(V0, 128 * r * N)) goto err2; #else free(V0); #endif free(XY0); free(B0); /* Success! */ return (0); err2: free(XY0); err1: free(B0); err0: /* Failure! */ return (-1); }
/** * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, * p, buflen) and write the result into buf. The parameters r, p, and buflen * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N * must be a power of 2. * * Return 0 on success; or -1 on error. */ int scrypt(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, uint8_t * buf, size_t buflen) { uint8_t * B; uint8_t * V; uint8_t * XY; uint32_t i; /* Sanity-check parameters. */ #if SIZE_MAX > UINT32_MAX if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { errno = EFBIG; goto err0; } #endif if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { errno = EFBIG; goto err0; } if (((N & (N - 1)) != 0) || (N == 0)) { errno = EINVAL; goto err0; } if ((r > SIZE_MAX / 128 / p) || #if SIZE_MAX / 256 <= UINT32_MAX (r > SIZE_MAX / 256) || #endif (N > SIZE_MAX / 128 / r)) { errno = ENOMEM; goto err0; } /* Allocate memory. */ if ((B = malloc(128 * r * p)) == NULL) goto err0; if ((XY = malloc(256 * r)) == NULL) goto err1; if ((V = malloc(128 * r * N)) == NULL) goto err2; /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r); /* 2: for i = 0 to p - 1 do */ for (i = 0; i < p; i++) { /* 3: B_i <-- MF(B_i, N) */ smix(&B[i * 128 * r], r, N, V, XY); } /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen); /* Free memory. */ free(V); free(XY); free(B); /* Success! */ return (0); err2: free(XY); err1: free(B); err0: /* Failure! */ return (-1); }
/** * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, * p, buflen) and write the result into buf. The parameters r, p, and buflen * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N * must be a power of 2 greater than 1. * * Return 0 on success; or -1 on error. */ int crypto_scrypt(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, uint8_t * buf, size_t buflen) { void * B0, * V0, * XY0; uint8_t * B; uint32_t * V; uint32_t * XY; uint32_t i; /* Sanity-check parameters. */ if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { errno = EFBIG; goto err0; } if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { errno = EFBIG; goto err0; } if (((N & (N - 1)) != 0) || (N == 0)) { errno = EINVAL; goto err0; } if ((r > SIZE_MAX / 128 / p) || (N > SIZE_MAX / 128 / r)) { errno = ENOMEM; goto err0; } /* Allocate memory. */ B0 = folly_ext::aligned_malloc(128 * r * p, 64); if (!B0) { goto err0; } XY0 = folly_ext::aligned_malloc(256 * r + 64, 64); if (!XY0) { goto err1; } B = (uint8_t *)(B0); XY = (uint32_t *)(XY0); if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE, #ifdef MAP_NOCORE MAP_ANON | MAP_PRIVATE | MAP_NOCORE, #else MAP_ANON | MAP_PRIVATE, #endif -1, 0)) == MAP_FAILED) goto err2; V = (uint32_t *)(V0); /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r); /* 2: for i = 0 to p - 1 do */ for (i = 0; i < p; i++) { /* 3: B_i <-- MF(B_i, N) */ smix(&B[i * 128 * r], r, N, V, XY); } /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen); /* Free memory. */ if (munmap(V0, 128 * r * N)) goto err2; folly_ext::aligned_free(XY0); folly_ext::aligned_free(B0); /* Success! */ return (0); err2: folly_ext::aligned_free(XY0); err1: folly_ext::aligned_free(B0); err0: /* Failure! */ return (-1); }