diff options
author | Ulf Möller <ulf@openssl.org> | 1999-04-27 21:17:18 +0000 |
---|---|---|
committer | Ulf Möller <ulf@openssl.org> | 1999-04-27 21:17:18 +0000 |
commit | 8cd8a7b7a2cb2b69cd1ede5c525e3dbbee138a0c (patch) | |
tree | 30d450a439b3356fbb29b84189dd93bed2d10656 /crypto/bf/bf_locl.h | |
parent | 67a4728511cad54b22b871aa2674944d111f30d2 (diff) | |
download | openssl-8cd8a7b7a2cb2b69cd1ede5c525e3dbbee138a0c.tar.gz |
More portable blowfish macros.
Submitted by: Andy Polyakov <appro@fy.chalmers.se>
Diffstat (limited to 'crypto/bf/bf_locl.h')
-rw-r--r-- | crypto/bf/bf_locl.h | 89 |
1 files changed, 51 insertions, 38 deletions
diff --git a/crypto/bf/bf_locl.h b/crypto/bf/bf_locl.h index 7936e6c56a..3ebb145f88 100644 --- a/crypto/bf/bf_locl.h +++ b/crypto/bf/bf_locl.h @@ -151,56 +151,69 @@ /* This is actually a big endian algorithm, the most significate byte * is used to lookup array 0 */ -#define BF_M 0x3fc -#define BF_0 22L -#define BF_1 14L -#define BF_2 6L -#define BF_3 2L /* left shift */ - #if defined(BF_PTR2) -/* This is basically a special pentium verson */ -#define BF_ENC(LL,R,S,P) \ - { \ - BF_LONG t,u,v; \ - u=R>>BF_0; \ - v=R>>BF_1; \ - u&=BF_M; \ - v&=BF_M; \ - t= *(BF_LONG *)((unsigned char *)&(S[ 0])+u); \ - u=R>>BF_2; \ - t+= *(BF_LONG *)((unsigned char *)&(S[256])+v); \ - v=R<<BF_3; \ - u&=BF_M; \ - v&=BF_M; \ - t^= *(BF_LONG *)((unsigned char *)&(S[512])+u); \ - LL^=P; \ - t+= *(BF_LONG *)((unsigned char *)&(S[768])+v); \ - LL^=t; \ - } +/* + * This is basically a special Intel version. Point is that Intel + * doesn't have many registers, but offers a reach choice of addressing + * modes. So we spare some registers by directly traversing BF_KEY + * structure and hiring the most decorated addressing mode. The code + * generated by EGCS is *perfectly* competitive with assembler + * implementation! + */ +#define BF_ENC(LL,R,KEY,Pi) (\ + LL^=KEY[Pi], \ + t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \ + t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \ + LL^=t \ + ) #elif defined(BF_PTR) -/* This is normally very good */ +#ifndef BF_LONG_LOG2 +#define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */ +#endif +#define BF_M (0xFF<<BF_LONG_LOG2) +#define BF_0 (24-BF_LONG_LOG2) +#define BF_1 (16-BF_LONG_LOG2) +#define BF_2 ( 8-BF_LONG_LOG2) +#define BF_3 BF_LONG_LOG2 /* left shift */ + +/* + * This is normally very good on RISC platforms where normally you + * have to explicitely "multiplicate" array index by sizeof(BF_LONG) + * in order to caclulate the effective address. This implementation + * excuses CPU from this extra work. Power[PC] uses should have most + * fun as (R>>BF_i)&BF_M gets folded into a single instruction, namely + * rlwinm. So let'em double-check if their compiler does it. + */ -#define BF_ENC(LL,R,S,P) \ - LL^=P; \ +#define BF_ENC(LL,R,S,P) ( \ + LL^=P, \ LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \ *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \ *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \ - *(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M))); + *(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M))) \ + ) #else -/* This will always work, even on 64 bit machines and strangly enough, - * on the Alpha it is faster than the pointer versions (both 32 and 64 - * versions of BF_LONG) */ +/* + * This is a *generic* version. Seem to perform best on platforms that + * offer explicit support for extraction of 8-bit nibbles preferably + * complemented with "multiplying" of array index by sizeof(BF_LONG). + * For the moment of this writing the list comprises Alpha CPU featuring + * extbl and s[48]addq instructions. + */ -#define BF_ENC(LL,R,S,P) \ - LL^=P; \ - LL^=((( S[ (int)(R>>24L) ] + \ - S[0x0100+((int)(R>>16L)&0xff)])^ \ - S[0x0200+((int)(R>> 8L)&0xff)])+ \ - S[0x0300+((int)(R )&0xff)])&0xffffffffL; +#define BF_ENC(LL,R,S,P) ( \ + LL^=P, \ + LL^=((( S[ ((int)(R>>24)&0xff)] + \ + S[0x0100+((int)(R>>16)&0xff)])^ \ + S[0x0200+((int)(R>> 8)&0xff)])+ \ + S[0x0300+((int)(R )&0xff)])&0xffffffffL \ + ) #endif #endif |