os/ossrv/ssl/libcrypto/src/crypto/des/des_locl.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* crypto/des/des_locl.h */
sl@0
     2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
sl@0
     3
 * All rights reserved.
sl@0
     4
 *
sl@0
     5
 * This package is an SSL implementation written
sl@0
     6
 * by Eric Young (eay@cryptsoft.com).
sl@0
     7
 * The implementation was written so as to conform with Netscapes SSL.
sl@0
     8
 * 
sl@0
     9
 * This library is free for commercial and non-commercial use as long as
sl@0
    10
 * the following conditions are aheared to.  The following conditions
sl@0
    11
 * apply to all code found in this distribution, be it the RC4, RSA,
sl@0
    12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
sl@0
    13
 * included with this distribution is covered by the same copyright terms
sl@0
    14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
sl@0
    15
 * 
sl@0
    16
 * Copyright remains Eric Young's, and as such any Copyright notices in
sl@0
    17
 * the code are not to be removed.
sl@0
    18
 * If this package is used in a product, Eric Young should be given attribution
sl@0
    19
 * as the author of the parts of the library used.
sl@0
    20
 * This can be in the form of a textual message at program startup or
sl@0
    21
 * in documentation (online or textual) provided with the package.
sl@0
    22
 * 
sl@0
    23
 * Redistribution and use in source and binary forms, with or without
sl@0
    24
 * modification, are permitted provided that the following conditions
sl@0
    25
 * are met:
sl@0
    26
 * 1. Redistributions of source code must retain the copyright
sl@0
    27
 *    notice, this list of conditions and the following disclaimer.
sl@0
    28
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    29
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    30
 *    documentation and/or other materials provided with the distribution.
sl@0
    31
 * 3. All advertising materials mentioning features or use of this software
sl@0
    32
 *    must display the following acknowledgement:
sl@0
    33
 *    "This product includes cryptographic software written by
sl@0
    34
 *     Eric Young (eay@cryptsoft.com)"
sl@0
    35
 *    The word 'cryptographic' can be left out if the rouines from the library
sl@0
    36
 *    being used are not cryptographic related :-).
sl@0
    37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
sl@0
    38
 *    the apps directory (application code) you must include an acknowledgement:
sl@0
    39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
sl@0
    40
 * 
sl@0
    41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
sl@0
    42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
    44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
sl@0
    45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
    46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
    47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
    49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
    50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
    51
 * SUCH DAMAGE.
sl@0
    52
 * 
sl@0
    53
 * The licence and distribution terms for any publically available version or
sl@0
    54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
sl@0
    55
 * copied and put under another distribution licence
sl@0
    56
 * [including the GNU Public Licence.]
sl@0
    57
 */
sl@0
    58
sl@0
    59
#ifndef HEADER_DES_LOCL_H
sl@0
    60
#define HEADER_DES_LOCL_H
sl@0
    61
sl@0
    62
#include <openssl/e_os2.h>
sl@0
    63
sl@0
    64
#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
sl@0
    65
#ifndef OPENSSL_SYS_MSDOS
sl@0
    66
#define OPENSSL_SYS_MSDOS
sl@0
    67
#endif
sl@0
    68
#endif
sl@0
    69
sl@0
    70
#include <stdio.h>
sl@0
    71
#include <stdlib.h>
sl@0
    72
sl@0
    73
#ifndef OPENSSL_SYS_MSDOS
sl@0
    74
#if !defined(OPENSSL_SYS_VMS) || defined(__DECC)
sl@0
    75
#ifdef OPENSSL_UNISTD
sl@0
    76
# include OPENSSL_UNISTD
sl@0
    77
#else
sl@0
    78
# include <unistd.h>
sl@0
    79
#endif
sl@0
    80
#include <math.h>
sl@0
    81
#endif
sl@0
    82
#endif
sl@0
    83
#include <openssl/des.h>
sl@0
    84
sl@0
    85
#ifdef OPENSSL_SYS_MSDOS		/* Visual C++ 2.1 (Windows NT/95) */
sl@0
    86
#include <stdlib.h>
sl@0
    87
#include <errno.h>
sl@0
    88
#include <time.h>
sl@0
    89
#include <io.h>
sl@0
    90
#endif
sl@0
    91
sl@0
    92
#if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS)
sl@0
    93
#include <string.h>
sl@0
    94
#endif
sl@0
    95
sl@0
    96
#ifdef OPENSSL_BUILD_SHLIBCRYPTO
sl@0
    97
# undef OPENSSL_EXTERN
sl@0
    98
# define OPENSSL_EXTERN OPENSSL_EXPORT
sl@0
    99
#endif
sl@0
   100
sl@0
   101
#define ITERATIONS 16
sl@0
   102
#define HALF_ITERATIONS 8
sl@0
   103
sl@0
   104
/* used in des_read and des_write */
sl@0
   105
#define MAXWRITE	(1024*16)
sl@0
   106
#define BSIZE		(MAXWRITE+4)
sl@0
   107
sl@0
   108
#define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
sl@0
   109
			 l|=((DES_LONG)(*((c)++)))<< 8L, \
sl@0
   110
			 l|=((DES_LONG)(*((c)++)))<<16L, \
sl@0
   111
			 l|=((DES_LONG)(*((c)++)))<<24L)
sl@0
   112
sl@0
   113
/* NOTE - c is not incremented as per c2l */
sl@0
   114
#define c2ln(c,l1,l2,n)	{ \
sl@0
   115
			c+=n; \
sl@0
   116
			l1=l2=0; \
sl@0
   117
			switch (n) { \
sl@0
   118
			case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
sl@0
   119
			case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
sl@0
   120
			case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
sl@0
   121
			case 5: l2|=((DES_LONG)(*(--(c))));     \
sl@0
   122
			case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
sl@0
   123
			case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
sl@0
   124
			case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
sl@0
   125
			case 1: l1|=((DES_LONG)(*(--(c))));     \
sl@0
   126
				} \
sl@0
   127
			}
sl@0
   128
sl@0
   129
#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
sl@0
   130
			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
sl@0
   131
			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
sl@0
   132
			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
sl@0
   133
sl@0
   134
/* replacements for htonl and ntohl since I have no idea what to do
sl@0
   135
 * when faced with machines with 8 byte longs. */
sl@0
   136
#define HDRSIZE 4
sl@0
   137
sl@0
   138
#define n2l(c,l)	(l =((DES_LONG)(*((c)++)))<<24L, \
sl@0
   139
			 l|=((DES_LONG)(*((c)++)))<<16L, \
sl@0
   140
			 l|=((DES_LONG)(*((c)++)))<< 8L, \
sl@0
   141
			 l|=((DES_LONG)(*((c)++))))
sl@0
   142
sl@0
   143
#define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
sl@0
   144
			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
sl@0
   145
			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
sl@0
   146
			 *((c)++)=(unsigned char)(((l)     )&0xff))
sl@0
   147
sl@0
   148
/* NOTE - c is not incremented as per l2c */
sl@0
   149
#define l2cn(l1,l2,c,n)	{ \
sl@0
   150
			c+=n; \
sl@0
   151
			switch (n) { \
sl@0
   152
			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
sl@0
   153
			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
sl@0
   154
			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
sl@0
   155
			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
sl@0
   156
			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
sl@0
   157
			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
sl@0
   158
			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
sl@0
   159
			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
sl@0
   160
				} \
sl@0
   161
			}
sl@0
   162
sl@0
   163
#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
sl@0
   164
#define	ROTATE(a,n)	(_lrotr(a,n))
sl@0
   165
#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
sl@0
   166
# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
sl@0
   167
#  define ROTATE(a,n)	({ register unsigned int ret;	\
sl@0
   168
				asm ("rorl %1,%0"	\
sl@0
   169
					: "=r"(ret)	\
sl@0
   170
					: "I"(n),"0"(a)	\
sl@0
   171
					: "cc");	\
sl@0
   172
			   ret;				\
sl@0
   173
			})
sl@0
   174
# endif
sl@0
   175
#endif
sl@0
   176
#ifndef ROTATE
sl@0
   177
#define	ROTATE(a,n)	(((a)>>(n))+((a)<<(32-(n))))
sl@0
   178
#endif
sl@0
   179
sl@0
   180
/* Don't worry about the LOAD_DATA() stuff, that is used by
sl@0
   181
 * fcrypt() to add it's little bit to the front */
sl@0
   182
sl@0
   183
#ifdef DES_FCRYPT
sl@0
   184
sl@0
   185
#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
sl@0
   186
	{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
sl@0
   187
sl@0
   188
#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
sl@0
   189
	t=R^(R>>16L); \
sl@0
   190
	u=t&E0; t&=E1; \
sl@0
   191
	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
sl@0
   192
	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
sl@0
   193
#else
sl@0
   194
#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
sl@0
   195
#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
sl@0
   196
	u=R^s[S  ]; \
sl@0
   197
	t=R^s[S+1]
sl@0
   198
#endif
sl@0
   199
sl@0
   200
/* The changes to this macro may help or hinder, depending on the
sl@0
   201
 * compiler and the architecture.  gcc2 always seems to do well :-).
sl@0
   202
 * Inspired by Dana How <how@isl.stanford.edu>
sl@0
   203
 * DO NOT use the alternative version on machines with 8 byte longs.
sl@0
   204
 * It does not seem to work on the Alpha, even when DES_LONG is 4
sl@0
   205
 * bytes, probably an issue of accessing non-word aligned objects :-( */
sl@0
   206
#ifdef DES_PTR
sl@0
   207
sl@0
   208
/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
sl@0
   209
 * is no reason to not xor all the sub items together.  This potentially
sl@0
   210
 * saves a register since things can be xored directly into L */
sl@0
   211
sl@0
   212
#if defined(DES_RISC1) || defined(DES_RISC2)
sl@0
   213
#ifdef DES_RISC1
sl@0
   214
#define D_ENCRYPT(LL,R,S) { \
sl@0
   215
	unsigned int u1,u2,u3; \
sl@0
   216
	LOAD_DATA(R,S,u,t,E0,E1,u1); \
sl@0
   217
	u2=(int)u>>8L; \
sl@0
   218
	u1=(int)u&0xfc; \
sl@0
   219
	u2&=0xfc; \
sl@0
   220
	t=ROTATE(t,4); \
sl@0
   221
	u>>=16L; \
sl@0
   222
	LL^= *(const DES_LONG *)(des_SP      +u1); \
sl@0
   223
	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
sl@0
   224
	u3=(int)(u>>8L); \
sl@0
   225
	u1=(int)u&0xfc; \
sl@0
   226
	u3&=0xfc; \
sl@0
   227
	LL^= *(const DES_LONG *)(des_SP+0x400+u1); \
sl@0
   228
	LL^= *(const DES_LONG *)(des_SP+0x600+u3); \
sl@0
   229
	u2=(int)t>>8L; \
sl@0
   230
	u1=(int)t&0xfc; \
sl@0
   231
	u2&=0xfc; \
sl@0
   232
	t>>=16L; \
sl@0
   233
	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
sl@0
   234
	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
sl@0
   235
	u3=(int)t>>8L; \
sl@0
   236
	u1=(int)t&0xfc; \
sl@0
   237
	u3&=0xfc; \
sl@0
   238
	LL^= *(const DES_LONG *)(des_SP+0x500+u1); \
sl@0
   239
	LL^= *(const DES_LONG *)(des_SP+0x700+u3); }
sl@0
   240
#endif
sl@0
   241
#ifdef DES_RISC2
sl@0
   242
#define D_ENCRYPT(LL,R,S) { \
sl@0
   243
	unsigned int u1,u2,s1,s2; \
sl@0
   244
	LOAD_DATA(R,S,u,t,E0,E1,u1); \
sl@0
   245
	u2=(int)u>>8L; \
sl@0
   246
	u1=(int)u&0xfc; \
sl@0
   247
	u2&=0xfc; \
sl@0
   248
	t=ROTATE(t,4); \
sl@0
   249
	LL^= *(const DES_LONG *)(des_SP      +u1); \
sl@0
   250
	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
sl@0
   251
	s1=(int)(u>>16L); \
sl@0
   252
	s2=(int)(u>>24L); \
sl@0
   253
	s1&=0xfc; \
sl@0
   254
	s2&=0xfc; \
sl@0
   255
	LL^= *(const DES_LONG *)(des_SP+0x400+s1); \
sl@0
   256
	LL^= *(const DES_LONG *)(des_SP+0x600+s2); \
sl@0
   257
	u2=(int)t>>8L; \
sl@0
   258
	u1=(int)t&0xfc; \
sl@0
   259
	u2&=0xfc; \
sl@0
   260
	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
sl@0
   261
	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
sl@0
   262
	s1=(int)(t>>16L); \
sl@0
   263
	s2=(int)(t>>24L); \
sl@0
   264
	s1&=0xfc; \
sl@0
   265
	s2&=0xfc; \
sl@0
   266
	LL^= *(const DES_LONG *)(des_SP+0x500+s1); \
sl@0
   267
	LL^= *(const DES_LONG *)(des_SP+0x700+s2); }
sl@0
   268
#endif
sl@0
   269
#else
sl@0
   270
#define D_ENCRYPT(LL,R,S) { \
sl@0
   271
	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
sl@0
   272
	t=ROTATE(t,4); \
sl@0
   273
	LL^= \
sl@0
   274
	*(const DES_LONG *)(des_SP      +((u     )&0xfc))^ \
sl@0
   275
	*(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \
sl@0
   276
	*(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \
sl@0
   277
	*(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \
sl@0
   278
	*(const DES_LONG *)(des_SP+0x100+((t     )&0xfc))^ \
sl@0
   279
	*(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \
sl@0
   280
	*(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \
sl@0
   281
	*(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); }
sl@0
   282
#endif
sl@0
   283
sl@0
   284
#else /* original version */
sl@0
   285
sl@0
   286
#if defined(DES_RISC1) || defined(DES_RISC2)
sl@0
   287
#ifdef DES_RISC1
sl@0
   288
#define D_ENCRYPT(LL,R,S) {\
sl@0
   289
	unsigned int u1,u2,u3; \
sl@0
   290
	LOAD_DATA(R,S,u,t,E0,E1,u1); \
sl@0
   291
	u>>=2L; \
sl@0
   292
	t=ROTATE(t,6); \
sl@0
   293
	u2=(int)u>>8L; \
sl@0
   294
	u1=(int)u&0x3f; \
sl@0
   295
	u2&=0x3f; \
sl@0
   296
	u>>=16L; \
sl@0
   297
	LL^=DES_SPtrans[0][u1]; \
sl@0
   298
	LL^=DES_SPtrans[2][u2]; \
sl@0
   299
	u3=(int)u>>8L; \
sl@0
   300
	u1=(int)u&0x3f; \
sl@0
   301
	u3&=0x3f; \
sl@0
   302
	LL^=DES_SPtrans[4][u1]; \
sl@0
   303
	LL^=DES_SPtrans[6][u3]; \
sl@0
   304
	u2=(int)t>>8L; \
sl@0
   305
	u1=(int)t&0x3f; \
sl@0
   306
	u2&=0x3f; \
sl@0
   307
	t>>=16L; \
sl@0
   308
	LL^=DES_SPtrans[1][u1]; \
sl@0
   309
	LL^=DES_SPtrans[3][u2]; \
sl@0
   310
	u3=(int)t>>8L; \
sl@0
   311
	u1=(int)t&0x3f; \
sl@0
   312
	u3&=0x3f; \
sl@0
   313
	LL^=DES_SPtrans[5][u1]; \
sl@0
   314
	LL^=DES_SPtrans[7][u3]; }
sl@0
   315
#endif
sl@0
   316
#ifdef DES_RISC2
sl@0
   317
#define D_ENCRYPT(LL,R,S) {\
sl@0
   318
	unsigned int u1,u2,s1,s2; \
sl@0
   319
	LOAD_DATA(R,S,u,t,E0,E1,u1); \
sl@0
   320
	u>>=2L; \
sl@0
   321
	t=ROTATE(t,6); \
sl@0
   322
	u2=(int)u>>8L; \
sl@0
   323
	u1=(int)u&0x3f; \
sl@0
   324
	u2&=0x3f; \
sl@0
   325
	LL^=DES_SPtrans[0][u1]; \
sl@0
   326
	LL^=DES_SPtrans[2][u2]; \
sl@0
   327
	s1=(int)u>>16L; \
sl@0
   328
	s2=(int)u>>24L; \
sl@0
   329
	s1&=0x3f; \
sl@0
   330
	s2&=0x3f; \
sl@0
   331
	LL^=DES_SPtrans[4][s1]; \
sl@0
   332
	LL^=DES_SPtrans[6][s2]; \
sl@0
   333
	u2=(int)t>>8L; \
sl@0
   334
	u1=(int)t&0x3f; \
sl@0
   335
	u2&=0x3f; \
sl@0
   336
	LL^=DES_SPtrans[1][u1]; \
sl@0
   337
	LL^=DES_SPtrans[3][u2]; \
sl@0
   338
	s1=(int)t>>16; \
sl@0
   339
	s2=(int)t>>24L; \
sl@0
   340
	s1&=0x3f; \
sl@0
   341
	s2&=0x3f; \
sl@0
   342
	LL^=DES_SPtrans[5][s1]; \
sl@0
   343
	LL^=DES_SPtrans[7][s2]; }
sl@0
   344
#endif
sl@0
   345
sl@0
   346
#else
sl@0
   347
sl@0
   348
#define D_ENCRYPT(LL,R,S) {\
sl@0
   349
	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
sl@0
   350
	t=ROTATE(t,4); \
sl@0
   351
	LL^=\
sl@0
   352
		DES_SPtrans[0][(u>> 2L)&0x3f]^ \
sl@0
   353
		DES_SPtrans[2][(u>>10L)&0x3f]^ \
sl@0
   354
		DES_SPtrans[4][(u>>18L)&0x3f]^ \
sl@0
   355
		DES_SPtrans[6][(u>>26L)&0x3f]^ \
sl@0
   356
		DES_SPtrans[1][(t>> 2L)&0x3f]^ \
sl@0
   357
		DES_SPtrans[3][(t>>10L)&0x3f]^ \
sl@0
   358
		DES_SPtrans[5][(t>>18L)&0x3f]^ \
sl@0
   359
		DES_SPtrans[7][(t>>26L)&0x3f]; }
sl@0
   360
#endif
sl@0
   361
#endif
sl@0
   362
sl@0
   363
	/* IP and FP
sl@0
   364
	 * The problem is more of a geometric problem that random bit fiddling.
sl@0
   365
	 0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
sl@0
   366
	 8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
sl@0
   367
	16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
sl@0
   368
	24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
sl@0
   369
sl@0
   370
	32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
sl@0
   371
	40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
sl@0
   372
	48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
sl@0
   373
	56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
sl@0
   374
sl@0
   375
	The output has been subject to swaps of the form
sl@0
   376
	0 1 -> 3 1 but the odd and even bits have been put into
sl@0
   377
	2 3    2 0
sl@0
   378
	different words.  The main trick is to remember that
sl@0
   379
	t=((l>>size)^r)&(mask);
sl@0
   380
	r^=t;
sl@0
   381
	l^=(t<<size);
sl@0
   382
	can be used to swap and move bits between words.
sl@0
   383
sl@0
   384
	So l =  0  1  2  3  r = 16 17 18 19
sl@0
   385
	        4  5  6  7      20 21 22 23
sl@0
   386
	        8  9 10 11      24 25 26 27
sl@0
   387
	       12 13 14 15      28 29 30 31
sl@0
   388
	becomes (for size == 2 and mask == 0x3333)
sl@0
   389
	   t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
sl@0
   390
		 6^20  7^21 -- --        4  5 20 21       6  7 22 23
sl@0
   391
		10^24 11^25 -- --        8  9 24 25      10 11 24 25
sl@0
   392
		14^28 15^29 -- --       12 13 28 29      14 15 28 29
sl@0
   393
sl@0
   394
	Thanks for hints from Richard Outerbridge - he told me IP&FP
sl@0
   395
	could be done in 15 xor, 10 shifts and 5 ands.
sl@0
   396
	When I finally started to think of the problem in 2D
sl@0
   397
	I first got ~42 operations without xors.  When I remembered
sl@0
   398
	how to use xors :-) I got it to its final state.
sl@0
   399
	*/
sl@0
   400
#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
sl@0
   401
	(b)^=(t),\
sl@0
   402
	(a)^=((t)<<(n)))
sl@0
   403
sl@0
   404
#define IP(l,r) \
sl@0
   405
	{ \
sl@0
   406
	register DES_LONG tt; \
sl@0
   407
	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
sl@0
   408
	PERM_OP(l,r,tt,16,0x0000ffffL); \
sl@0
   409
	PERM_OP(r,l,tt, 2,0x33333333L); \
sl@0
   410
	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
sl@0
   411
	PERM_OP(r,l,tt, 1,0x55555555L); \
sl@0
   412
	}
sl@0
   413
sl@0
   414
#define FP(l,r) \
sl@0
   415
	{ \
sl@0
   416
	register DES_LONG tt; \
sl@0
   417
	PERM_OP(l,r,tt, 1,0x55555555L); \
sl@0
   418
	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
sl@0
   419
	PERM_OP(l,r,tt, 2,0x33333333L); \
sl@0
   420
	PERM_OP(r,l,tt,16,0x0000ffffL); \
sl@0
   421
	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
sl@0
   422
	}
sl@0
   423
sl@0
   424
extern const DES_LONG DES_SPtrans[8][64];
sl@0
   425
sl@0
   426
IMPORT_C void fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
sl@0
   427
		 DES_LONG Eswap0, DES_LONG Eswap1);
sl@0
   428
#endif