// scryptBlockMix implements the function described in RFC 7914, section 4. B' // is written to |out|. |out| and |B| may not alias and must be each one scrypt // block (2 * |r| Salsa20 blocks) long. static void scryptBlockMix(block_t *out, const block_t *B, uint64_t r) { assert(out != B); block_t X; OPENSSL_memcpy(&X, &B[r * 2 - 1], sizeof(X)); for (uint64_t i = 0; i < r * 2; i++) { xor_block(&X, &X, &B[i]); salsa208_word_specification(&X); // This implements the permutation in step 3. OPENSSL_memcpy(&out[i / 2 + (i & 1) * r], &X, sizeof(X)); } }
static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r) { uint64_t i, j; uint32_t X[16], *pB; memcpy(X, B + (r * 2 - 1) * 16, sizeof(X)); pB = B; for (i = 0; i < r * 2; i++) { for (j = 0; j < 16; j++) X[j] ^= *pB++; salsa208_word_specification(X); memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X)); } OPENSSL_cleanse(X, sizeof(X)); }