[CRYPTO] twofish: Do not unroll big stuff in twofish key setup

Currently twofish cipher key setup code
has unrolled loops - approximately 70-100
instructions are repeated 40 times.

As a result, twofish module is the biggest module
in crypto/*.

Unrolling produces x2.5 more code (+18k on i386), and speeds up key
setup by 7%:

	unrolled: twofish_setkey/sec: 41128
	    loop: twofish_setkey/sec: 38148
	CALC_K256: ~100 insns each
	CALC_K192: ~90 insns
	   CALC_K: ~70 insns

Attached patch removes this unrolling.

$ size */twofish_common.o
   text    data     bss     dec     hex filename
  37920       0       0   37920    9420 crypto.org/twofish_common.o
  13209       0       0   13209    3399 crypto/twofish_common.o

Run tested (modprobe tcrypt reports ok). Please apply.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Denys Vlasenko 2007-10-26 16:22:57 +08:00 committed by Herbert Xu
parent b7a30da61a
commit e2b21b5002

View file

@ -655,84 +655,48 @@ int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len)
CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
} }
/* Calculate whitening and round subkeys. The constants are /* CALC_K256/CALC_K192/CALC_K loops were unrolled.
* indices of subkeys, preprocessed through q0 and q1. */ * Unrolling produced x2.5 more code (+18k on i386),
CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3); * and speeded up key setup by 7%:
CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4); * unrolled: twofish_setkey/sec: 41128
CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B); * loop: twofish_setkey/sec: 38148
CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8); * CALC_K256: ~100 insns each
CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3); * CALC_K192: ~90 insns
CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B); * CALC_K: ~70 insns
CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D); */
CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B); /* Calculate whitening and round subkeys */
CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32); for ( i = 0; i < 8; i += 2 ) {
CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD); CALC_K256 (w, i, q0[i], q1[i], q0[i+1], q1[i+1]);
CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71); }
CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1); for ( i = 0; i < 32; i += 2 ) {
CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F); CALC_K256 (k, i, q0[i+8], q1[i+8], q0[i+9], q1[i+9]);
CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B); }
CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
} else if (key_len == 24) { /* 192-bit key */ } else if (key_len == 24) { /* 192-bit key */
/* Compute the S-boxes. */ /* Compute the S-boxes. */
for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) { for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
} }
/* Calculate whitening and round subkeys. The constants are /* Calculate whitening and round subkeys */
* indices of subkeys, preprocessed through q0 and q1. */ for ( i = 0; i < 8; i += 2 ) {
CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3); CALC_K192 (w, i, q0[i], q1[i], q0[i+1], q1[i+1]);
CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4); }
CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B); for ( i = 0; i < 32; i += 2 ) {
CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8); CALC_K192 (k, i, q0[i+8], q1[i+8], q0[i+9], q1[i+9]);
CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3); }
CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
} else { /* 128-bit key */ } else { /* 128-bit key */
/* Compute the S-boxes. */ /* Compute the S-boxes. */
for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) { for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
} }
/* Calculate whitening and round subkeys. The constants are /* Calculate whitening and round subkeys */
* indices of subkeys, preprocessed through q0 and q1. */ for ( i = 0; i < 8; i += 2 ) {
CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3); CALC_K (w, i, q0[i], q1[i], q0[i+1], q1[i+1]);
CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4); }
CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B); for ( i = 0; i < 32; i += 2 ) {
CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8); CALC_K (k, i, q0[i+8], q1[i+8], q0[i+9], q1[i+9]);
CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3); }
CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
} }
return 0; return 0;