src/crypto/yescrypt/yescrypt-simd_c.h
/**
 * smix1(B, r, N, flags, V, NROM, VROM, XY, ctx):
 * Compute first 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 128r bytes in length.  The value N must be even and no
 * smaller than 2.  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).
 */
smix1(B, r, N, flags, V, NROM, VROM, XY, ctx):
Compute first 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 128r bytes in length.  The value N must be even and no
smaller than 2.  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).
smix1 ( B r N flags V NROM VROM XY ctx ) : Compute first 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 128r bytes in length . The value N must be even and no smaller than 2 . 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
smix1(uint8_t * B, size_t r, uint32_t N, 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 = V, * Y;
	uint32_t i, j;
	size_t k;
	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]);
		}
	}
	if (VROM) {
		uint32_t n;
		salsa20_blk_t * V_n;
		const salsa20_blk_t * V_j;
		Y = &V[s];
		blockmix(X, Y, r, ctx);
		X = &V[2 * s];
		j = integerify(Y, r) & (NROM - 1);
		V_j = &VROM[j * s];
		j = blockmix_xor(Y, V_j, X, r, 1, ctx);
		for (n = 2; n < N; n <<= 1) {
			uint32_t m = (n < N / 2) ? n : (N - 1 - n);
			V_n = &V[n * s];
			for (i = 1; i < m; i += 2) {
				j &= n - 1;
				j += i - 1;
				V_j = &V[j * s];
				Y = &V_n[i * s];
				j = blockmix_xor(X, V_j, Y, r, 0, ctx) & (NROM - 1);
				V_j = &VROM[j * s];
				X = &V_n[(i + 1) * s];
				j = blockmix_xor(Y, V_j, X, r, 1, ctx);
			}
		}
		n >>= 1;
		j &= n - 1;
		j += N - 2 - n;
		V_j = &V[j * s];
		Y = &V[(N - 1) * s];
		j = blockmix_xor(X, V_j, Y, r, 0, ctx) & (NROM - 1);
		V_j = &VROM[j * s];
		X = XY;
		blockmix_xor(Y, V_j, X, r, 1, ctx);
	} else if (flags & YESCRYPT_RW) {
		uint32_t n;
		salsa20_blk_t * V_n, * V_j;
		Y = &V[s];
		blockmix(X, Y, r, ctx);
		X = &V[2 * s];
		blockmix(Y, X, r, ctx);
		j = integerify(X, r);
		for (n = 2; n < N; n <<= 1) {
			uint32_t m = (n < N / 2) ? n : (N - 1 - n);
			V_n = &V[n * s];
			for (i = 1; i < m; i += 2) {
				Y = &V_n[i * s];
				j &= n - 1;
				j += i - 1;
				V_j = &V[j * s];
				j = blockmix_xor(X, V_j, Y, r, 0, ctx);
				j &= n - 1;
				j += i;
				V_j = &V[j * s];
				X = &V_n[(i + 1) * s];
				j = blockmix_xor(Y, V_j, X, r, 0, ctx);
			}
		}
		n >>= 1;
		j &= n - 1;
		j += N - 2 - n;
		V_j = &V[j * s];
		Y = &V[(N - 1) * s];
		j = blockmix_xor(X, V_j, Y, r, 0, ctx);
		j &= n - 1;
		j += N - 1 - n;
		V_j = &V[j * s];
		X = XY;
		blockmix_xor(Y, V_j, X, r, 0, ctx);
	} else {
		for (i = 1; i < N - 1; i += 2) {
			Y = &V[i * s];
			blockmix_salsa8(X, Y, r);
			X = &V[(i + 1) * s];
			blockmix_salsa8(Y, X, r);
		}
		Y = &V[i * s];
		blockmix_salsa8(X, Y, r);
		X = XY;
		blockmix_salsa8(Y, X, r);
	}
	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 smix1 ( uint8_t * B , size_t r , uint32_t N , 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 = V , * Y ; uint32_t i , j ; size_t k ; 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 ] ) ; } } if ( VROM ) { uint32_t n ; salsa20_blk_t * V_n ; const salsa20_blk_t * V_j ; Y = & V [ s ] ; blockmix ( X , Y , r , ctx ) ; X = & V [ 2 * s ] ; j = integerify ( Y , r ) & ( NROM - 1 ) ; V_j = & VROM [ j * s ] ; j = blockmix_xor ( Y , V_j , X , r , 1 , ctx ) ; for ( n = 2 ; n < N ; n <<= 1 ) { uint32_t m = ( n < N / 2 ) ? n : ( N - 1 - n ) ; V_n = & V [ n * s ] ; for ( i = 1 ; i < m ; i += 2 ) { j &= n - 1 ; j += i - 1 ; V_j = & V [ j * s ] ; Y = & V_n [ i * s ] ; j = blockmix_xor ( X , V_j , Y , r , 0 , ctx ) & ( NROM - 1 ) ; V_j = & VROM [ j * s ] ; X = & V_n [ ( i + 1 ) * s ] ; j = blockmix_xor ( Y , V_j , X , r , 1 , ctx ) ; } } n >>= 1 ; j &= n - 1 ; j += N - 2 - n ; V_j = & V [ j * s ] ; Y = & V [ ( N - 1 ) * s ] ; j = blockmix_xor ( X , V_j , Y , r , 0 , ctx ) & ( NROM - 1 ) ; V_j = & VROM [ j * s ] ; X = XY ; blockmix_xor ( Y , V_j , X , r , 1 , ctx ) ; } else if ( flags & YESCRYPT_RW ) { uint32_t n ; salsa20_blk_t * V_n , * V_j ; Y = & V [ s ] ; blockmix ( X , Y , r , ctx ) ; X = & V [ 2 * s ] ; blockmix ( Y , X , r , ctx ) ; j = integerify ( X , r ) ; for ( n = 2 ; n < N ; n <<= 1 ) { uint32_t m = ( n < N / 2 ) ? n : ( N - 1 - n ) ; V_n = & V [ n * s ] ; for ( i = 1 ; i < m ; i += 2 ) { Y = & V_n [ i * s ] ; j &= n - 1 ; j += i - 1 ; V_j = & V [ j * s ] ; j = blockmix_xor ( X , V_j , Y , r , 0 , ctx ) ; j &= n - 1 ; j += i ; V_j = & V [ j * s ] ; X = & V_n [ ( i + 1 ) * s ] ; j = blockmix_xor ( Y , V_j , X , r , 0 , ctx ) ; } } n >>= 1 ; j &= n - 1 ; j += N - 2 - n ; V_j = & V [ j * s ] ; Y = & V [ ( N - 1 ) * s ] ; j = blockmix_xor ( X , V_j , Y , r , 0 , ctx ) ; j &= n - 1 ; j += N - 1 - n ; V_j = & V [ j * s ] ; X = XY ; blockmix_xor ( Y , V_j , X , r , 0 , ctx ) ; } else { for ( i = 1 ; i < N - 1 ; i += 2 ) { Y = & V [ i * s ] ; blockmix_salsa8 ( X , Y , r ) ; X = & V [ ( i + 1 ) * s ] ; blockmix_salsa8 ( Y , X , r ) ; } Y = & V [ i * s ] ; blockmix_salsa8 ( X , Y , r ) ; X = XY ; blockmix_salsa8 ( Y , X , r ) ; } 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 ] ) ; } } }
smix1(B, r, N, flags, V, NROM, VROM, XY, ctx):
 Compute first loop of B = SMix_r(B, N).
smix1 ( B r N flags V NROM VROM XY ctx ) : Compute first loop of B = SMix_r ( B N ) .
/* 1: X <-- B */ /* 3: V_i <-- X */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* j <-- Integerify(X) mod NROM */ /* X <-- H(X \xor VROM_j) */ /* 2: for i = 0 to N - 1 do */ /* j <-- Wrap(Integerify(X), i) */ /* X <-- X \xor V_j */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* j <-- Integerify(X) mod NROM */ /* X <-- H(X \xor VROM_j) */ /* j <-- Wrap(Integerify(X), i) */ /* X <-- X \xor V_j */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* j <-- Integerify(X) mod NROM */ /* X <-- X \xor V_j */ /* 4: X <-- H(X) */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* 2: for i = 0 to N - 1 do */ /* j <-- Wrap(Integerify(X), i) */ /* X <-- X \xor V_j */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* j <-- Wrap(Integerify(X), i) */ /* X <-- X \xor V_j */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* j <-- Wrap(Integerify(X), i) */ /* X <-- X \xor V_j */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* j <-- Wrap(Integerify(X), i) */ /* X <-- X \xor V_j */ /* 4: X <-- H(X) */ /* 2: for i = 0 to N - 1 do */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* 4: X <-- H(X) */ /* 3: V_i <-- X */ /* 4: X <-- H(X) */ /* B' <-- X */