src/crypto/yescrypt/yescrypt-simd_c.h
/**
 * smix2(B, r, N, Nloop, flags, V, NROM, VROM, XY, ctx):
 * Compute second loop of B = SMix_r(B, N).  The input B must be 128r bytes in
 * length; the temporary storage V must be 128rN bytes in length; the temporary
 * storage XY must be 256r bytes in length.  The value N must be a power of 2
 * greater than 1.  The value Nloop must be even.  The array V must be aligned
 * to a multiple of 64 bytes, and arrays B and XY to a multiple of at least 16
 * bytes (aligning them to 64 bytes as well saves cache lines, but might result
 * in cache bank conflicts).
 */
smix2(B, r, N, Nloop, flags, V, NROM, VROM, XY, ctx):
Compute second loop of B = SMix_r(B, N).  The input B must be 128r bytes in
length; the temporary storage V must be 128rN bytes in length; the temporary
storage XY must be 256r bytes in length.  The value N must be a power of 2
greater than 1.  The value Nloop must be even.  The array V must be aligned
to a multiple of 64 bytes, and arrays B and XY to a multiple of at least 16
bytes (aligning them to 64 bytes as well saves cache lines, but might result
in cache bank conflicts).
smix2 ( B r N Nloop flags V NROM VROM XY ctx ) : Compute second loop of B = SMix_r ( B N ) . The input B must be 128r bytes in length ; the temporary storage V must be 128rN bytes in length ; the temporary storage XY must be 256r bytes in length . The value N must be a power of 2 greater than 1 . The value Nloop must be even . The array V must be aligned to a multiple of 64 bytes and arrays B and XY to a multiple of at least 16 bytes ( aligning them to 64 bytes as well saves cache lines but might result in cache bank conflicts ) .
static void
smix2(uint8_t * B, size_t r, uint32_t N, uint64_t Nloop,
    yescrypt_flags_t flags, salsa20_blk_t * V, uint32_t NROM,
    const salsa20_blk_t * VROM, salsa20_blk_t * XY, pwxform_ctx_t * ctx)
{
	size_t s = 2 * r;
	salsa20_blk_t * X = XY, * Y = &XY[s];
	uint64_t i;
	uint32_t j;
	size_t k;
	if (Nloop == 0)
		return;
	for (k = 0; k < 2 * r; k++) {
		for (i = 0; i < 16; i++) {
			X[k].w[i] = le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
		}
	}
	i = Nloop / 2;
	j = integerify(X, r) & (N - 1);
	if (VROM && (flags & YESCRYPT_RW)) {
		for (i = 0; i < Nloop; i += 2) {
			salsa20_blk_t * V_j = &V[j * s];
			const salsa20_blk_t * VROM_j;
			j = blockmix_xor_save(X, V_j, Y, r, ctx) & (NROM - 1);
			VROM_j = &VROM[j * s];
			j = blockmix_xor(Y, VROM_j, X, r, 1, ctx) & (N - 1);
			V_j = &V[j * s];
		}
	} else if (VROM) {
		for (i = 0; i < Nloop; i += 2) {
			const salsa20_blk_t * V_j = &V[j * s];
			j = blockmix_xor(X, V_j, Y, r, 0, ctx) & (NROM - 1);
			V_j = &VROM[j * s];
			j = blockmix_xor(Y, V_j, X, r, 1, ctx) & (N - 1);
			V_j = &V[j * s];
		}
	} else if (flags & YESCRYPT_RW) {
		do {
			salsa20_blk_t * V_j = &V[j * s];
			j = blockmix_xor_save(X, V_j, Y, r, ctx) & (N - 1);
			V_j = &V[j * s];
			j = blockmix_xor_save(Y, V_j, X, r, ctx) & (N - 1);
		} while (--i);
	} else if (ctx) {
		do {
			const salsa20_blk_t * V_j = &V[j * s];
			j = blockmix_xor(X, V_j, Y, r, 0, ctx) & (N - 1);
			V_j = &V[j * s];
			j = blockmix_xor(Y, V_j, X, r, 0, ctx) & (N - 1);
		} while (--i);
	} else {
		do {
			const salsa20_blk_t * V_j = &V[j * s];
			j = blockmix_salsa8_xor(X, V_j, Y, r) & (N - 1);
			V_j = &V[j * s];
			j = blockmix_salsa8_xor(Y, V_j, X, r) & (N - 1);
		} while (--i);
	}
	for (k = 0; k < 2 * r; k++) {
		for (i = 0; i < 16; i++) {
			le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], X[k].w[i]);
		}
	}
}
static void smix2 ( uint8_t * B , size_t r , uint32_t N , uint64_t Nloop , yescrypt_flags_t flags , salsa20_blk_t * V , uint32_t NROM , const salsa20_blk_t * VROM , salsa20_blk_t * XY , pwxform_ctx_t * ctx ) { size_t s = 2 * r ; salsa20_blk_t * X = XY , * Y = & XY [ s ] ; uint64_t i ; uint32_t j ; size_t k ; if ( Nloop == 0 ) return ; for ( k = 0 ; k < 2 * r ; k ++ ) { for ( i = 0 ; i < 16 ; i ++ ) { X [ k ] . w [ i ] = le32dec ( & B [ ( k * 16 + ( i * 5 % 16 ) ) * 4 ] ) ; } } i = Nloop / 2 ; j = integerify ( X , r ) & ( N - 1 ) ; if ( VROM && ( flags & YESCRYPT_RW ) ) { for ( i = 0 ; i < Nloop ; i += 2 ) { salsa20_blk_t * V_j = & V [ j * s ] ; const salsa20_blk_t * VROM_j ; j = blockmix_xor_save ( X , V_j , Y , r , ctx ) & ( NROM - 1 ) ; VROM_j = & VROM [ j * s ] ; j = blockmix_xor ( Y , VROM_j , X , r , 1 , ctx ) & ( N - 1 ) ; V_j = & V [ j * s ] ; } } else if ( VROM ) { for ( i = 0 ; i < Nloop ; i += 2 ) { const salsa20_blk_t * V_j = & V [ j * s ] ; j = blockmix_xor ( X , V_j , Y , r , 0 , ctx ) & ( NROM - 1 ) ; V_j = & VROM [ j * s ] ; j = blockmix_xor ( Y , V_j , X , r , 1 , ctx ) & ( N - 1 ) ; V_j = & V [ j * s ] ; } } else if ( flags & YESCRYPT_RW ) { do { salsa20_blk_t * V_j = & V [ j * s ] ; j = blockmix_xor_save ( X , V_j , Y , r , ctx ) & ( N - 1 ) ; V_j = & V [ j * s ] ; j = blockmix_xor_save ( Y , V_j , X , r , ctx ) & ( N - 1 ) ; } while ( -- i ) ; } else if ( ctx ) { do { const salsa20_blk_t * V_j = & V [ j * s ] ; j = blockmix_xor ( X , V_j , Y , r , 0 , ctx ) & ( N - 1 ) ; V_j = & V [ j * s ] ; j = blockmix_xor ( Y , V_j , X , r , 0 , ctx ) & ( N - 1 ) ; } while ( -- i ) ; } else { do { const salsa20_blk_t * V_j = & V [ j * s ] ; j = blockmix_salsa8_xor ( X , V_j , Y , r ) & ( N - 1 ) ; V_j = & V [ j * s ] ; j = blockmix_salsa8_xor ( Y , V_j , X , r ) & ( N - 1 ) ; } while ( -- i ) ; } for ( k = 0 ; k < 2 * r ; k ++ ) { for ( i = 0 ; i < 16 ; i ++ ) { le32enc ( & B [ ( k * 16 + ( i * 5 % 16 ) ) * 4 ] , X [ k ] . w [ i ] ) ; } } }
smix2(B, r, N, Nloop, flags, V, NROM, VROM, XY, ctx):
 Compute second loop of B = SMix_r(B, N).
smix2 ( B r N Nloop flags V NROM VROM XY ctx ) : Compute second loop of B = SMix_r ( B N ) .
/* X <-- B' */ /* 3: V_i <-- X */ /* 7: j <-- Integerify(X) mod N */ /*
 * Normally, VROM implies YESCRYPT_RW, but we check for these separately
 * because our SMix resets YESCRYPT_RW for the smix2() calls operating on the
 * entire V when p > 1.
 */ /* 6: for i = 0 to N - 1 do */ /* 8: X <-- H(X \xor V_j) */ /* V_j <-- Xprev \xor V_j */ /* j <-- Integerify(X) mod NROM */ /* X <-- H(X \xor VROM_j) */ /* 7: j <-- Integerify(X) mod N */ /* 6: for i = 0 to N - 1 do */ /* 8: X <-- H(X \xor V_j) */ /* V_j <-- Xprev \xor V_j */ /* j <-- Integerify(X) mod NROM */ /* X <-- H(X \xor VROM_j) */ /* 7: j <-- Integerify(X) mod N */ /* 6: for i = 0 to N - 1 do */ /* 8: X <-- H(X \xor V_j) */ /* V_j <-- Xprev \xor V_j */ /* 7: j <-- Integerify(X) mod N */ /* 8: X <-- H(X \xor V_j) */ /* V_j <-- Xprev \xor V_j */ /* 7: j <-- Integerify(X) mod N */ /* 6: for i = 0 to N - 1 do */ /* 8: X <-- H(X \xor V_j) */ /* 7: j <-- Integerify(X) mod N */ /* 8: X <-- H(X \xor V_j) */ /* 7: j <-- Integerify(X) mod N */ /* 6: for i = 0 to N - 1 do */ /* 8: X <-- H(X \xor V_j) */ /* 7: j <-- Integerify(X) mod N */ /* 8: X <-- H(X \xor V_j) */ /* 7: j <-- Integerify(X) mod N */ /* 10: B' <-- X */