static void gcm_init_4bit(u128 Htable[16], u64 H[2])
{
	u128 V;
#if defined(OPENSSL_SMALL_FOOTPRINT)
	int  i;
#endif
#define REDUCE(V) do { \
	if (sizeof(size_t)==8) { \
		u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \
		V.lo  = (V.hi<<63)|(V.lo>>1); \
		V.hi  = (V.hi>>1 )^T; \
	} \
	else { \
		u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \
		V.lo  = (V.hi<<63)|(V.lo>>1); \
		V.hi  = (V.hi>>1 )^((u64)T<<32); \
	} \
} while(0)
	Htable[0].hi = 0;
	Htable[0].lo = 0;
	V.hi = H[0];
	V.lo = H[1];
#if defined(OPENSSL_SMALL_FOOTPRINT)
	for (Htable[8]=V, i=4; i>0; i>>=1) {
		REDUCE(V);
		Htable[i] = V;
	}
	for (i=2; i<16; i<<=1) {
		u128 *Hi = Htable+i;
		int   j;
		for (V=*Hi, j=1; j<i; ++j) {
			Hi[j].hi = V.hi^Htable[j].hi;
			Hi[j].lo = V.lo^Htable[j].lo;
		}
	}
#else
	Htable[8] = V;
	REDUCE(V);
	Htable[4] = V;
	REDUCE(V);
	Htable[2] = V;
	REDUCE(V);
	Htable[1] = V;
	Htable[3].hi  = V.hi^Htable[2].hi, Htable[3].lo  = V.lo^Htable[2].lo;
	V=Htable[4];
	Htable[5].hi  = V.hi^Htable[1].hi, Htable[5].lo  = V.lo^Htable[1].lo;
	Htable[6].hi  = V.hi^Htable[2].hi, Htable[6].lo  = V.lo^Htable[2].lo;
	Htable[7].hi  = V.hi^Htable[3].hi, Htable[7].lo  = V.lo^Htable[3].lo;
	V=Htable[8];
	Htable[9].hi  = V.hi^Htable[1].hi, Htable[9].lo  = V.lo^Htable[1].lo;
	Htable[10].hi = V.hi^Htable[2].hi, Htable[10].lo = V.lo^Htable[2].lo;
	Htable[11].hi = V.hi^Htable[3].hi, Htable[11].lo = V.lo^Htable[3].lo;
	Htable[12].hi = V.hi^Htable[4].hi, Htable[12].lo = V.lo^Htable[4].lo;
	Htable[13].hi = V.hi^Htable[5].hi, Htable[13].lo = V.lo^Htable[5].lo;
	Htable[14].hi = V.hi^Htable[6].hi, Htable[14].lo = V.lo^Htable[6].lo;
	Htable[15].hi = V.hi^Htable[7].hi, Htable[15].lo = V.lo^Htable[7].lo;
#endif
#if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm))
	{
	int j;
	const union { long one; char little; } is_endian = {1};
	if (is_endian.little)
		for (j=0;j<16;++j) {
			V = Htable[j];
			Htable[j].hi = V.lo;
			Htable[j].lo = V.hi;
		}
	else
		for (j=0;j<16;++j) {
			V = Htable[j];
			Htable[j].hi = V.lo<<32|V.lo>>32;
			Htable[j].lo = V.hi<<32|V.hi>>32;
		}
	}
#endif
#undef	REDUCE
}
['void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block)\n{\n\tconst union { long one; char little; } is_endian = {1};\n\tmemset(ctx,0,sizeof(*ctx));\n\tctx->block = block;\n\tctx->key   = key;\n\t(*block)(ctx->H.c,ctx->H.c,key);\n\tif (is_endian.little) {\n#ifdef BSWAP8\n\t\tctx->H.u[0] = BSWAP8(ctx->H.u[0]);\n\t\tctx->H.u[1] = BSWAP8(ctx->H.u[1]);\n#else\n\t\tu8 *p = ctx->H.c;\n\t\tu64 hi,lo;\n\t\thi = (u64)GETU32(p)  <<32|GETU32(p+4);\n\t\tlo = (u64)GETU32(p+8)<<32|GETU32(p+12);\n\t\tctx->H.u[0] = hi;\n\t\tctx->H.u[1] = lo;\n#endif\n\t}\n#if\tTABLE_BITS==8\n\tgcm_init_8bit(ctx->Htable,ctx->H.u);\n#elif\tTABLE_BITS==4\n\tgcm_init_4bit(ctx->Htable,ctx->H.u);\n#endif\n}', 'static void gcm_init_4bit(u128 Htable[16], u64 H[2])\n{\n\tu128 V;\n#if defined(OPENSSL_SMALL_FOOTPRINT)\n\tint  i;\n#endif\n#define REDUCE(V) do { \\\n\tif (sizeof(size_t)==8) { \\\n\t\tu64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \\\n\t\tV.lo  = (V.hi<<63)|(V.lo>>1); \\\n\t\tV.hi  = (V.hi>>1 )^T; \\\n\t} \\\n\telse { \\\n\t\tu32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \\\n\t\tV.lo  = (V.hi<<63)|(V.lo>>1); \\\n\t\tV.hi  = (V.hi>>1 )^((u64)T<<32); \\\n\t} \\\n} while(0)\n\tHtable[0].hi = 0;\n\tHtable[0].lo = 0;\n\tV.hi = H[0];\n\tV.lo = H[1];\n#if defined(OPENSSL_SMALL_FOOTPRINT)\n\tfor (Htable[8]=V, i=4; i>0; i>>=1) {\n\t\tREDUCE(V);\n\t\tHtable[i] = V;\n\t}\n\tfor (i=2; i<16; i<<=1) {\n\t\tu128 *Hi = Htable+i;\n\t\tint   j;\n\t\tfor (V=*Hi, j=1; j<i; ++j) {\n\t\t\tHi[j].hi = V.hi^Htable[j].hi;\n\t\t\tHi[j].lo = V.lo^Htable[j].lo;\n\t\t}\n\t}\n#else\n\tHtable[8] = V;\n\tREDUCE(V);\n\tHtable[4] = V;\n\tREDUCE(V);\n\tHtable[2] = V;\n\tREDUCE(V);\n\tHtable[1] = V;\n\tHtable[3].hi  = V.hi^Htable[2].hi, Htable[3].lo  = V.lo^Htable[2].lo;\n\tV=Htable[4];\n\tHtable[5].hi  = V.hi^Htable[1].hi, Htable[5].lo  = V.lo^Htable[1].lo;\n\tHtable[6].hi  = V.hi^Htable[2].hi, Htable[6].lo  = V.lo^Htable[2].lo;\n\tHtable[7].hi  = V.hi^Htable[3].hi, Htable[7].lo  = V.lo^Htable[3].lo;\n\tV=Htable[8];\n\tHtable[9].hi  = V.hi^Htable[1].hi, Htable[9].lo  = V.lo^Htable[1].lo;\n\tHtable[10].hi = V.hi^Htable[2].hi, Htable[10].lo = V.lo^Htable[2].lo;\n\tHtable[11].hi = V.hi^Htable[3].hi, Htable[11].lo = V.lo^Htable[3].lo;\n\tHtable[12].hi = V.hi^Htable[4].hi, Htable[12].lo = V.lo^Htable[4].lo;\n\tHtable[13].hi = V.hi^Htable[5].hi, Htable[13].lo = V.lo^Htable[5].lo;\n\tHtable[14].hi = V.hi^Htable[6].hi, Htable[14].lo = V.lo^Htable[6].lo;\n\tHtable[15].hi = V.hi^Htable[7].hi, Htable[15].lo = V.lo^Htable[7].lo;\n#endif\n#if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm))\n\t{\n\tint j;\n\tconst union { long one; char little; } is_endian = {1};\n\tif (is_endian.little)\n\t\tfor (j=0;j<16;++j) {\n\t\t\tV = Htable[j];\n\t\t\tHtable[j].hi = V.lo;\n\t\t\tHtable[j].lo = V.hi;\n\t\t}\n\telse\n\t\tfor (j=0;j<16;++j) {\n\t\t\tV = Htable[j];\n\t\t\tHtable[j].hi = V.lo<<32|V.lo>>32;\n\t\t\tHtable[j].lo = V.hi<<32|V.hi>>32;\n\t\t}\n\t}\n#endif\n#undef\tREDUCE\n}']